configure.ac | 16 + debian/changelog | 7 debian/control | 2 man/radeon.man | 7 src/drmmode_display.c | 386 ++++++++++++++++++++++++++++++------------- src/drmmode_display.h | 13 - src/radeon.h | 41 ++-- src/radeon_bo_helper.c | 7 src/radeon_dri2.c | 103 ++++------- src/radeon_dri3.c | 39 ++++ src/radeon_drm_queue.c | 52 ++++- src/radeon_drm_queue.h | 16 - src/radeon_glamor.c | 84 ++++++--- src/radeon_glamor.h | 2 src/radeon_glamor_wrappers.c | 5 src/radeon_kms.c | 269 ++++++++++++++++++++--------- src/radeon_list.h | 1 src/radeon_present.c | 45 +++-- src/radeon_probe.c | 5 src/radeon_sync.c | 7 src/radeon_video.c | 2 21 files changed, 741 insertions(+), 368 deletions(-)
New commits: commit 8291a69def53ec610dda6f3eb188debfcc285e2f Author: Timo Aaltonen <tjaal...@debian.org> Date: Thu Apr 7 08:26:50 2016 +0300 release to unstable diff --git a/debian/changelog b/debian/changelog index 95bc649..86ab50e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -xserver-xorg-video-ati (1:7.7.0-1) UNRELEASED; urgency=medium +xserver-xorg-video-ati (1:7.7.0-1) unstable; urgency=medium * New upstream release. * control: Bump Standards-Version to 3.9.7 (no changes). - -- Timo Aaltonen <tjaal...@debian.org> Thu, 07 Apr 2016 08:08:05 +0300 + -- Timo Aaltonen <tjaal...@debian.org> Thu, 07 Apr 2016 08:26:30 +0300 xserver-xorg-video-ati (1:7.6.1-1) unstable; urgency=medium commit d46ba6086a91e251280aeb178ddcb2fc411483d7 Author: Timo Aaltonen <tjaal...@debian.org> Date: Thu Apr 7 08:21:20 2016 +0300 control: Bump Standards-Version to 3.9.7 (no changes). diff --git a/debian/changelog b/debian/changelog index 32ec4eb..95bc649 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +xserver-xorg-video-ati (1:7.7.0-1) UNRELEASED; urgency=medium + + * New upstream release. + * control: Bump Standards-Version to 3.9.7 (no changes). + + -- Timo Aaltonen <tjaal...@debian.org> Thu, 07 Apr 2016 08:08:05 +0300 + xserver-xorg-video-ati (1:7.6.1-1) unstable; urgency=medium [ Andreas Boll ] diff --git a/debian/control b/debian/control index fe27d06..2febad8 100644 --- a/debian/control +++ b/debian/control @@ -21,7 +21,7 @@ Build-Depends: x11proto-xf86dri-dev, libudev-dev [linux-any], xutils-dev (>= 1:7.5+4) -Standards-Version: 3.9.6 +Standards-Version: 3.9.7 Vcs-Git: https://anonscm.debian.org/git/pkg-xorg/driver/xserver-xorg-video-ati.git Vcs-Browser: https://anonscm.debian.org/cgit/pkg-xorg/driver/xserver-xorg-video-ati.git Homepage: https://wiki.freedesktop.org/xorg/RadeonFeature/ commit df6662864b56d1aeeea4c67d9b668e64197afb20 Author: Michel Dänzer <michel.daen...@amd.com> Date: Thu Apr 7 11:44:05 2016 +0900 Bump version for 7.7.0 release diff --git a/configure.ac b/configure.ac index 2409004..48e314b 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [7.6.99], + [7.7.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-video-ati]) commit c12614cfdc5729041c204e3ead1dbfde38011f0c Author: Michel Dänzer <michel.daen...@amd.com> Date: Mon Apr 4 14:59:41 2016 +0900 Update manpage entry for Option "TearFree" It's now effective for rotation as well. (Ported from amdgpu commit faf9d720b7d650f5f1ea657a874d08eac3972e60) Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> diff --git a/man/radeon.man b/man/radeon.man index fa55c6d..1acdc63 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -279,9 +279,10 @@ Pageflipping is supported on all radeon hardware. .TP .BI "Option \*qTearFree\*q \*q" boolean \*q Enable tearing prevention using the hardware page flipping mechanism. This -option currently doesn't have any effect for rotated CRTCs. It requires -allocating two separate scanout buffers for each non-rotated CRTC. Enabling -this option currently disables Option \*qEnablePageFlip\*q. The default is +option currently doesn't have any effect for CRTCs using transforms other than +rotation or reflection. It requires allocating two separate scanout buffers for +each supported CRTC. Enabling this option currently disables Option +\*qEnablePageFlip\*q. The default is .B off. .TP .BI "Option \*qAccelMethod\*q \*q" "string" \*q commit 4693b1bd5b5c381e8b7b68a6f7f0c6696d6a68df Author: Michel Dänzer <michel.daen...@amd.com> Date: Thu Mar 31 17:02:55 2016 +0900 Identify DRM event queue entries by sequence number instead of by pointer If the memory for an entry was allocated at the same address as that for a previously cancelled entry, the handler could theoretically be called prematurely, triggered by the DRM event which was submitted for the cancelled entry. Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 7331015..a368a41 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2660,7 +2660,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, int i; uint32_t tiling_flags = 0; drmmode_flipdata_ptr flipdata; - struct radeon_drm_queue_entry *drm_queue = NULL; + uintptr_t drm_queue_seq = 0; if (info->allowColorTiling) { if (info->ChipFamily >= CHIP_FAMILY_R600) @@ -2720,11 +2720,11 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, if (drmmode_crtc->hw_id == ref_crtc_hw_id) flipdata->fe_crtc = crtc; - drm_queue = radeon_drm_queue_alloc(crtc, client, id, - flipdata, - drmmode_flip_handler, - drmmode_flip_abort); - if (!drm_queue) { + drm_queue_seq = radeon_drm_queue_alloc(crtc, client, id, + flipdata, + drmmode_flip_handler, + drmmode_flip_abort); + if (!drm_queue_seq) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM queue event entry failed.\n"); goto error; @@ -2732,13 +2732,13 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, if (drmModePageFlip(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, drmmode->fb_id, DRM_MODE_PAGE_FLIP_EVENT, - drm_queue)) { + (void*)drm_queue_seq)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed: %s\n", strerror(errno)); goto error; } drmmode_crtc->flip_pending = TRUE; - drm_queue = NULL; + drm_queue_seq = 0; } if (flipdata->flip_count > 0) @@ -2750,8 +2750,8 @@ error: drmmode->fb_id = flipdata->old_fb_id; } - if (drm_queue) - radeon_drm_abort_entry(drm_queue); + if (drm_queue_seq) + radeon_drm_abort_entry(drm_queue_seq); else if (crtc) drmmode_flip_abort(crtc, flipdata); else if (flipdata && flipdata->flip_count <= 1) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 73e09d0..84cd031 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -516,7 +516,7 @@ typedef struct _DRI2FrameEvent { unsigned frame; xf86CrtcPtr crtc; OsTimerPtr timer; - struct radeon_drm_queue_entry *drm_queue; + uintptr_t drm_queue_seq; /* for swaps & flips only */ DRI2SwapEventPtr event_complete; @@ -1079,8 +1079,8 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) */ if (!event_info->crtc) { ErrorF("%s no crtc\n", __func__); - if (event_info->drm_queue) - radeon_drm_abort_entry(event_info->drm_queue); + if (event_info->drm_queue_seq) + radeon_drm_abort_entry(event_info->drm_queue_seq); else radeon_dri2_frame_event_abort(NULL, data); return 0; @@ -1092,9 +1092,9 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) if (ret) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s cannot get current time\n", __func__); - if (event_info->drm_queue) + if (event_info->drm_queue_seq) radeon_drm_queue_handler(info->dri2.drm_fd, 0, 0, 0, - event_info->drm_queue); + (void*)event_info->drm_queue_seq); else radeon_dri2_frame_event_handler(crtc, 0, 0, data); return 0; @@ -1108,9 +1108,10 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) delta_seq = delta_t * drmmode_crtc->dpms_last_fps; delta_seq /= 1000000; frame = (CARD64)drmmode_crtc->dpms_last_seq + delta_seq; - if (event_info->drm_queue) + if (event_info->drm_queue_seq) radeon_drm_queue_handler(info->dri2.drm_fd, frame, drm_now / 1000000, - drm_now % 1000000, event_info->drm_queue); + drm_now % 1000000, + (void*)event_info->drm_queue_seq); else radeon_dri2_frame_event_handler(crtc, frame, drm_now, data); return 0; @@ -1141,7 +1142,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONInfoPtr info = RADEONPTR(scrn); DRI2FrameEventPtr wait_info = NULL; - struct radeon_drm_queue_entry *wait = NULL; + uintptr_t drm_queue_seq = 0; xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE); uint32_t msc_delta; drmVBlank vbl; @@ -1197,15 +1198,15 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, current_msc = vbl.reply.sequence + msc_delta; current_msc &= 0xffffffff; - wait = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, - wait_info, radeon_dri2_frame_event_handler, - radeon_dri2_frame_event_abort); - if (!wait) { + drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, + wait_info, radeon_dri2_frame_event_handler, + radeon_dri2_frame_event_abort); + if (!drm_queue_seq) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM queue event entry failed.\n"); goto out_complete; } - wait_info->drm_queue = wait; + wait_info->drm_queue_seq = drm_queue_seq; /* * If divisor is zero, or current_msc is smaller than target_msc, @@ -1224,7 +1225,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; vbl.request.type |= radeon_populate_vbl_request_type(crtc); vbl.request.sequence = target_msc - msc_delta; - vbl.request.signal = (unsigned long)wait; + vbl.request.signal = drm_queue_seq; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -1255,7 +1256,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, if ((current_msc % divisor) >= remainder) vbl.request.sequence += divisor; - vbl.request.signal = (unsigned long)wait; + vbl.request.signal = drm_queue_seq; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -1307,7 +1308,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, drmVBlank vbl; int ret, flip = 0; DRI2FrameEventPtr swap_info = NULL; - struct radeon_drm_queue_entry *swap; + uintptr_t drm_queue_seq; CARD64 current_msc; BoxRec box; RegionRec region; @@ -1344,15 +1345,15 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, swap_info->back = back; swap_info->crtc = crtc; - swap = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, - swap_info, radeon_dri2_frame_event_handler, - radeon_dri2_frame_event_abort); - if (!swap) { + drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, + swap_info, radeon_dri2_frame_event_handler, + radeon_dri2_frame_event_abort); + if (!drm_queue_seq) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM queue entry failed.\n"); goto blit_fallback; } - swap_info->drm_queue = swap; + swap_info->drm_queue_seq = drm_queue_seq; /* * CRTC is in DPMS off state, fallback to blit, but calculate @@ -1421,7 +1422,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, *target_msc = current_msc; vbl.request.sequence = *target_msc - msc_delta; - vbl.request.signal = (unsigned long)swap; + vbl.request.signal = drm_queue_seq; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -1466,7 +1467,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, /* Account for 1 frame extra pageflip delay if flip > 0 */ vbl.request.sequence -= flip; - vbl.request.signal = (unsigned long)swap; + vbl.request.signal = drm_queue_seq; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index 25fb183..0d999dd 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -40,6 +40,7 @@ struct radeon_drm_queue_entry { struct xorg_list list; uint64_t id; + uintptr_t seq; void *data; ClientPtr client; xf86CrtcPtr crtc; @@ -49,6 +50,7 @@ struct radeon_drm_queue_entry { static int radeon_drm_queue_refcnt; static struct xorg_list radeon_drm_queue; +static uintptr_t radeon_drm_queue_seq; /* @@ -58,11 +60,11 @@ void radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *user_ptr) { - struct radeon_drm_queue_entry *user_data = user_ptr; + uintptr_t seq = (uintptr_t)user_ptr; struct radeon_drm_queue_entry *e, *tmp; xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { - if (e == user_data) { + if (e->seq == seq) { xorg_list_del(&e->list); if (e->handler) e->handler(e->crtc, frame, @@ -80,7 +82,7 @@ radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, * Enqueue a potential drm response; when the associated response * appears, we've got data to pass to the handler from here */ -struct radeon_drm_queue_entry * +uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, uint64_t id, void *data, radeon_drm_handler_proc handler, @@ -92,6 +94,9 @@ radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, if (!e) return NULL; + if (!radeon_drm_queue_seq) + radeon_drm_queue_seq = 1; + e->seq = radeon_drm_queue_seq++; e->client = client; e->crtc = crtc; e->id = id; @@ -101,7 +106,7 @@ radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, xorg_list_add(&e->list, &radeon_drm_queue); - return e; + return e->seq; } /* @@ -139,9 +144,16 @@ radeon_drm_abort_client(ClientPtr client) * Abort specific drm queue entry */ void -radeon_drm_abort_entry(struct radeon_drm_queue_entry *entry) +radeon_drm_abort_entry(uintptr_t seq) { - radeon_drm_abort_one(entry); + struct radeon_drm_queue_entry *e, *tmp; + + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { + if (e->seq == seq) { + radeon_drm_abort_one(e); + break; + } + } } /* diff --git a/src/radeon_drm_queue.h b/src/radeon_drm_queue.h index 5d8dedf..0d9d278 100644 --- a/src/radeon_drm_queue.h +++ b/src/radeon_drm_queue.h @@ -41,14 +41,12 @@ typedef void (*radeon_drm_abort_proc)(xf86CrtcPtr crtc, void *data); void radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, void *user_ptr); -struct radeon_drm_queue_entry *radeon_drm_queue_alloc(xf86CrtcPtr crtc, - ClientPtr client, - uint64_t id, - void *data, - radeon_drm_handler_proc handler, - radeon_drm_abort_proc abort); +uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, + uint64_t id, void *data, + radeon_drm_handler_proc handler, + radeon_drm_abort_proc abort); void radeon_drm_abort_client(ClientPtr client); -void radeon_drm_abort_entry(struct radeon_drm_queue_entry *entry); +void radeon_drm_abort_entry(uintptr_t seq); void radeon_drm_abort_id(uint64_t id); void radeon_drm_queue_init(); void radeon_drm_queue_close(ScrnInfoPtr scrn); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 555d736..c5310ea 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -491,7 +491,7 @@ static void radeon_scanout_update(xf86CrtcPtr xf86_crtc) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; - struct radeon_drm_queue_entry *drm_queue_entry; + uintptr_t drm_queue_seq; ScrnInfoPtr scrn; drmVBlank vbl; DamagePtr pDamage; @@ -520,13 +520,13 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) return; scrn = xf86_crtc->scrn; - drm_queue_entry = radeon_drm_queue_alloc(xf86_crtc, - RADEON_DRM_QUEUE_CLIENT_DEFAULT, - RADEON_DRM_QUEUE_ID_DEFAULT, - drmmode_crtc, - radeon_scanout_update_handler, - radeon_scanout_update_abort); - if (!drm_queue_entry) { + drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, + RADEON_DRM_QUEUE_CLIENT_DEFAULT, + RADEON_DRM_QUEUE_ID_DEFAULT, + drmmode_crtc, + radeon_scanout_update_handler, + radeon_scanout_update_abort); + if (!drm_queue_seq) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "radeon_drm_queue_alloc failed for scanout update\n"); return; @@ -535,12 +535,12 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc); vbl.request.sequence = 1; - vbl.request.signal = (unsigned long)drm_queue_entry; + vbl.request.signal = drm_queue_seq; if (drmWaitVBlank(RADEONPTR(scrn)->dri2.drm_fd, &vbl)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "drmWaitVBlank failed for scanout update: %s\n", strerror(errno)); - radeon_drm_abort_entry(drm_queue_entry); + radeon_drm_abort_entry(drm_queue_seq); return; } @@ -562,7 +562,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; ScrnInfoPtr scrn; - struct radeon_drm_queue_entry *drm_queue_entry; + uintptr_t drm_queue_seq; unsigned scanout_id; if (drmmode_crtc->scanout_update_pending) @@ -573,12 +573,12 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, return; scrn = xf86_crtc->scrn; - drm_queue_entry = radeon_drm_queue_alloc(xf86_crtc, - RADEON_DRM_QUEUE_CLIENT_DEFAULT, - RADEON_DRM_QUEUE_ID_DEFAULT, - drmmode_crtc, NULL, - radeon_scanout_flip_abort); - if (!drm_queue_entry) { + drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, + RADEON_DRM_QUEUE_CLIENT_DEFAULT, + RADEON_DRM_QUEUE_ID_DEFAULT, + drmmode_crtc, NULL, + radeon_scanout_flip_abort); + if (!drm_queue_seq) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM event queue entry failed.\n"); return; @@ -586,7 +586,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, if (drmModePageFlip(drmmode_crtc->drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, drmmode_crtc->scanout[scanout_id].fb_id, - DRM_MODE_PAGE_FLIP_EVENT, drm_queue_entry)) { + DRM_MODE_PAGE_FLIP_EVENT, (void*)drm_queue_seq)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", __func__, strerror(errno)); return; diff --git a/src/radeon_present.c b/src/radeon_present.c index 3be3360..8988fc6 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -156,7 +156,7 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) RADEONInfoPtr info = RADEONPTR(scrn); int crtc_id = drmmode_get_crtc_id(xf86_crtc); struct radeon_present_vblank_event *event; - struct radeon_drm_queue_entry *queue; + uintptr_t drm_queue_seq; drmVBlank vbl; int ret; @@ -164,24 +164,25 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) if (!event) return BadAlloc; event->event_id = event_id; - queue = radeon_drm_queue_alloc(xf86_crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, - event_id, event, - radeon_present_vblank_handler, - radeon_present_vblank_abort); - if (!queue) { + drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, + RADEON_DRM_QUEUE_CLIENT_DEFAULT, + event_id, event, + radeon_present_vblank_handler, + radeon_present_vblank_abort); + if (!drm_queue_seq) { free(event); return BadAlloc; } vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | crtc_select(crtc_id); vbl.request.sequence = msc; - vbl.request.signal = (unsigned long)queue; + vbl.request.signal = drm_queue_seq; for (;;) { ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (!ret) break; if (errno != EBUSY || !radeon_present_flush_drm_events(screen)) { - radeon_drm_abort_entry(queue); + radeon_drm_abort_entry(drm_queue_seq); return BadAlloc; } } commit 83734317e6bdaeebb4462a63f541e73a1d7c2f77 Author: Michel Dänzer <michel.daen...@amd.com> Date: Wed Mar 30 11:44:09 2016 +0900 Update pixmap pitch in radeon_set_pixmap_bo Stop second guessing it in drmmode_crtc_scanout_create. Fixes display corruption in some cases with TearFree enabled. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94751 Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 7ed8d6c..7331015 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -97,7 +97,6 @@ RADEONZaphodStringMatches(ScrnInfoPtr pScrn, const char *s, char *output_name) static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, int width, int height, int depth, int bpp, - int pitch, struct radeon_bo *bo, struct radeon_surface *psurf) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -112,7 +111,7 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, return NULL; if (!(*pScreen->ModifyPixmapHeader)(pixmap, width, height, - depth, bpp, pitch, NULL)) { + depth, bpp, -1, NULL)) { return NULL; } @@ -401,8 +400,7 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, } pixmap = drmmode_create_bo_pixmap(pScrn, fbcon->width, fbcon->height, - fbcon->depth, fbcon->bpp, - fbcon->pitch, bo, NULL); + fbcon->depth, fbcon->bpp, bo, NULL); info->fbcon_pixmap = pixmap; radeon_bo_unref(bo); out_free_fb: @@ -577,7 +575,6 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, ScrnInfoPtr pScrn = crtc->scrn; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; - unsigned long rotate_pitch; if (scanout->pixmap) { if (scanout->width == width && scanout->height == height) @@ -591,14 +588,10 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, return NULL; } - rotate_pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, drmmode->cpp, 0)) - * drmmode->cpp; - scanout->pixmap = drmmode_create_bo_pixmap(pScrn, width, height, pScrn->depth, pScrn->bitsPerPixel, - rotate_pitch, scanout->bo, NULL); if (scanout->pixmap == NULL) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, diff --git a/src/radeon.h b/src/radeon.h index 37d5fb6..011b66b 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -656,6 +656,8 @@ uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix); static inline void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) { + ScreenPtr pScreen = pPix->drawable.pScreen; + #ifdef USE_GLAMOR RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen)); @@ -691,7 +693,9 @@ static inline void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) radeon_bo_ref(bo); priv->bo = bo; - radeon_bo_get_tiling(bo, &priv->tiling_flags, &pitch); + if (radeon_bo_get_tiling(bo, &priv->tiling_flags, &pitch) == 0 && + pitch != pPix->devKind) + pScreen->ModifyPixmapHeader(pPix, -1, -1, -1, -1, pitch, NULL); } out: radeon_set_pixmap_private(pPix, priv); @@ -710,7 +714,9 @@ out: radeon_bo_ref(bo); driver_priv->bo = bo; - radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch); + if (radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch) == 0 && + pitch != pPix->devKind) + pScreen->ModifyPixmapHeader(pPix, -1, -1, -1, -1, pitch, NULL); } } } commit 0b3aac1de9db42bfca545fa331e4985836682ec7 Author: Michel Dänzer <michel.daen...@amd.com> Date: Mon Mar 28 18:43:36 2016 +0900 DRI3: Refuse to open DRM file descriptor for ssh clients (v2) Fixes hangs when attempting to use DRI3 on display connections forwarded via SSH. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93261 v2: Don't do this for Xorg > 1.18.99.1 since the corresponding xserver change has landed in Git master. Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> (v1) diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c index 1415a0d..43a073b 100644 --- a/src/radeon_dri3.c +++ b/src/radeon_dri3.c @@ -38,6 +38,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <errno.h> +#include <libgen.h> static int @@ -86,6 +87,38 @@ radeon_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out) return Success; } +#if DRI3_SCREEN_INFO_VERSION >= 1 && XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1,18,99,1,0) + +static int +radeon_dri3_open_client(ClientPtr client, ScreenPtr screen, + RRProviderPtr provider, int *out) +{ + const char *cmdname = GetClientCmdName(client); + Bool is_ssh = FALSE; + + /* If the executable name is "ssh", assume that this client connection + * is forwarded from another host via SSH + */ + if (cmdname) { + char *cmd = strdup(cmdname); + + /* Cut off any colon and whatever comes after it, see + * https://lists.freedesktop.org/archives/xorg-devel/2015-December/048164.html + */ + cmd = strtok(cmd, ":"); + + is_ssh = strcmp(basename(cmd), "ssh") == 0; + free(cmd); + } + + if (!is_ssh) + return radeon_dri3_open(screen, provider, out); + + return BadAccess; +} + +#endif /* DRI3_SCREEN_INFO_VERSION >= 1 && XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1,18,99,1,0) */ + static PixmapPtr radeon_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, @@ -179,9 +212,13 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen, } static dri3_screen_info_rec radeon_dri3_screen_info = { +#if DRI3_SCREEN_INFO_VERSION >= 1 && XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1,18,99,1,0) + .version = 1, + .open_client = radeon_dri3_open_client, +#else .version = 0, - .open = radeon_dri3_open, +#endif .pixmap_from_fd = radeon_dri3_pixmap_from_fd, .fd_from_pixmap = radeon_dri3_fd_from_pixmap }; commit 8a6cd4bda05b9569b3dd0a5a75b2cc385b9ecba9 Author: Michel Dänzer <michel.daen...@amd.com> Date: Fri Mar 25 11:50:15 2016 +0900 Revert "Use render node for DRI3 if available" This reverts commit cd94248ffa7d8fe0b57476f79e7e860dee66d1b0. It broke VDPAU<->GL interop with DRI3 enabled, because the Gallium VDPAU code doesn't support DRI3 yet. We can consider re-enabling this once there is a Mesa release where the Gallium VDPAU code supports DRI3. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94675 Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> diff --git a/configure.ac b/configure.ac index a4963c3..2409004 100644 --- a/configure.ac +++ b/configure.ac @@ -71,7 +71,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Checks for libraries. -PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.60]) +PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.58]) PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon]) # Obtain compiler/linker options for the driver dependencies diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c index de97f39..1415a0d 100644 --- a/src/radeon_dri3.c +++ b/src/radeon_dri3.c @@ -39,7 +39,9 @@ #include <fcntl.h> #include <errno.h> -static int open_master_node(ScreenPtr screen, int *out) + +static int +radeon_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONInfoPtr info = RADEONPTR(scrn); @@ -84,36 +86,6 @@ static int open_master_node(ScreenPtr screen, int *out) return Success; } -static int open_render_node(ScreenPtr screen, int *out) -{ - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - int fd; - - fd = open(pRADEONEnt->render_node, O_RDWR | O_CLOEXEC); - if (fd < 0) - return BadAlloc; - - *out = fd; - return Success; -} - -static int -radeon_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out) -{ - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - int ret = BadAlloc; - - if (pRADEONEnt->render_node) - ret = open_render_node(screen, out); - - if (ret != Success) - ret = open_master_node(screen, out); - - return ret; -} - static PixmapPtr radeon_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, @@ -218,9 +190,6 @@ Bool radeon_dri3_screen_init(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - - pRADEONEnt->render_node = drmGetRenderDeviceNameFromFd(pRADEONEnt->fd); if (!dri3_screen_init(screen, &radeon_dri3_screen_info)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 36e2ff6..258c7be 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -142,7 +142,6 @@ typedef struct #ifdef XSERVER_PLATFORM_BUS struct xf86_platform_device *platform_dev; #endif - char *render_node; } RADEONEntRec, *RADEONEntPtr; extern const OptionInfoRec *RADEONOptionsWeak(void); commit ed31cffba0d1bd4b14e5348a1456e4377277059c Author: Michel Dänzer <michel.daen...@amd.com> Date: Thu Mar 24 18:08:22 2016 +0900 Call RADEONBlockHandler_KMS before setting initial modes Doing it the other way around meant that there was still a possibility for the front buffer contents to be uninitialized when they start being scanned out. (Ported from amdgpu commit 4a60b4b1851a3cbc2d8ad9048d68eeb6947cf132) Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 3864281..555d736 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -633,9 +633,9 @@ static void RADEONBlockHandler_oneshot(BLOCKHANDLER_ARGS_DECL) ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(pScrn); - drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE); - RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS); + + drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE); } static void commit e592f32f8b5f5873fcc18b10a69dd5e4ccf11073 Author: Michel Dänzer <michel.daen...@amd.com> Date: Wed Mar 23 18:25:48 2016 +0900 Require xserver 1.9 or newer 1.9.0 was released in August 2010. We were already unintentionally relying on things not available in 1.8 for at least a year, and nobody has complained. Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> diff --git a/configure.ac b/configure.ac index eb97a6b..a4963c3 100644 --- a/configure.ac +++ b/configure.ac @@ -75,7 +75,7 @@ PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.60]) PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon]) # Obtain compiler/linker options for the driver dependencies -PKG_CHECK_MODULES(XORG, [xorg-server >= 1.8 xproto fontsproto xf86driproto $REQUIRED_MODULES]) +PKG_CHECK_MODULES(XORG, [xorg-server >= 1.9 xproto fontsproto xf86driproto $REQUIRED_MODULES]) PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1], HAVE_XEXTPROTO_71="yes"; AC_DEFINE(HAVE_XEXTPROTO_71, 1, [xextproto 7.1 available]), HAVE_XEXTPROTO_71="no") diff --git a/src/radeon.h b/src/radeon.h index b9afd8e..37d5fb6 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -272,19 +272,11 @@ struct radeon_pixmap { uint32_t handle; }; -#if HAS_DEVPRIVATEKEYREC extern DevPrivateKeyRec glamor_pixmap_index; -#else -extern int glamor_pixmap_index; -#endif static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap) { -#if HAS_DEVPRIVATEKEYREC return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index); -#else - return dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_index); -#endif } static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 474611a..73e09d0 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -70,18 +70,9 @@ struct dri2_window_priv { int vblank_delta; }; -#if HAS_DEVPRIVATEKEYREC - static DevPrivateKeyRec dri2_window_private_key_rec; #define dri2_window_private_key (&dri2_window_private_key_rec) -#else - -static int dri2_window_private_key_index; -DevPrivateKey dri2_window_private_key = &dri2_window_private_key_index; - -#endif /* HAS_DEVPRIVATEKEYREC */ - #define get_dri2_window_priv(window) \ ((struct dri2_window_priv*) \ dixLookupPrivate(&(window)->devPrivates, dri2_window_private_key)) @@ -1588,14 +1579,9 @@ radeon_dri2_screen_init(ScreenPtr pScreen) driverNames[1] = NULL; /* no VDPAU support */ if (DRI2InfoCnt == 0) { -#if HAS_DIXREGISTERPRIVATEKEY if (!dixRegisterPrivateKey(dri2_window_private_key, PRIVATE_WINDOW, sizeof(struct dri2_window_priv))) { -#else - if (!dixRequestPrivate(dri2_window_private_key, - sizeof(struct dri2_window_priv))) { -#endif xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to get DRI2 window private\n"); return FALSE; diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index cc2b1f2..f94e0fd 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c