From ec90c94881239791d0a66a02fc6d003c73a6c1f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 20 Oct 2017 16:51:16 +0200 Subject: Free pRADEONEnt memory in RADEONFreeRec We were leaking it. (Inspired by amdgpu commit 9d84934309e4ccd9a43c73d958b8ff10ef2fc990) Reviewed-by: Alex Deucher --- src/radeon_kms.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 9ef51693..df438768 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -218,7 +218,8 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn) pRADEONEnt->platform_dev->flags & XF86_PDEV_SERVER_FD)) #endif drmClose(pRADEONEnt->fd); - pRADEONEnt->fd = 0; + free(pPriv->ptr); + pPriv->ptr = NULL; } } -- cgit v1.2.3 From d588015f4f60ce270bcfd8433215fc981a84f143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 20 Oct 2017 17:13:36 +0200 Subject: Free memory returned by xf86GetEntityInfo We were leaking it. (Ported from amdgpu commit cfccf4c4e7e5c73fe4040fabeb1b43283cf29b33) Reviewed-by: Alex Deucher --- src/radeon_kms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index df438768..f79af341 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -228,6 +228,7 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn) info->accel_state = NULL; } + free(info->pEnt); free(pScrn->driverPrivate); pScrn->driverPrivate = NULL; } -- cgit v1.2.3 From 84c7d9c1c71d9cee9f50f96671032529b606cf04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 20 Oct 2017 17:19:09 +0200 Subject: Call TimerFree for timer created in LeaveVT We were leaking the memory allocated by TimerSet. (Ported from amdgpu commit 84aad09f18fed6b52b0c073f0bbd675a6de07807) Reviewed-by: Alex Deucher --- src/radeon_kms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index f79af341..06c8a47f 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2484,6 +2484,7 @@ CARD32 cleanup_black_fb(OsTimerPtr timer, CARD32 now, pointer data) drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL); } + TimerFree(timer); return 0; } -- cgit v1.2.3 From 0cd14777b7e39619f231b841a2d73f3122458030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 20 Oct 2017 17:20:30 +0200 Subject: Always call drmModeFreeProperty after drmModeGetProperty We were not doing so in all cases, leaking memory allocated by the latter. (Cherry picked from amdgpu commit f6b39bcd45cb06976ba8a3600df77fc471c63995) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 369c1efc..167ecfb4 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1913,8 +1913,8 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r drmModeFreeProperty(props); break; } - drmModeFreeProperty(props); } + drmModeFreeProperty(props); } kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); @@ -2003,8 +2003,8 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r drmModeFreeProperty(props); break; } - drmModeFreeProperty(props); } + drmModeFreeProperty(props); } if (dynamic) { -- cgit v1.2.3 From cafcb55768b58dc63a8c5682000eba21ad904689 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 25 Sep 2017 16:18:22 -0700 Subject: modesetting: Skip no-longer-present connectors when resetting BAD links Outputs may have NULL mode_output (connector) pointers if the connector disappears while the server is running. Skip these when resetting outputs with BAD link status. (Ported from xserver commit 37f4e7651a2fd51efa613a08a1e705553be33e76) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 167ecfb4..f57c4364 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2797,9 +2797,12 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode) for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; drmmode_output_private_ptr drmmode_output = output->driver_private; - uint32_t con_id = drmmode_output->mode_output->connector_id; + uint32_t con_id; drmModeConnectorPtr koutput; + if (drmmode_output->mode_output == NULL) + continue; + con_id = drmmode_output->mode_output->connector_id; /* Get an updated view of the properties for the current connector and * look for the link-status property */ -- cgit v1.2.3 From 6441210bc53978a2c46c572e9174215b14f9e813 Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Fri, 20 Oct 2017 10:05:35 +0200 Subject: modesetting: Check crtc before searching link-status property No need to lookup the link-status property if we don't have a crtc. Signed-off-by: Daniel Martin (Ported from xserver commit 8d7f7e24261e68459e6f0a865e243473f65fe7ad) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index f57c4364..7ad3235a 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2796,12 +2796,14 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode) */ for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; + xf86CrtcPtr crtc = output->crtc; drmmode_output_private_ptr drmmode_output = output->driver_private; uint32_t con_id; drmModeConnectorPtr koutput; - if (drmmode_output->mode_output == NULL) + if (!crtc || !drmmode_output->mode_output) continue; + con_id = drmmode_output->mode_output->connector_id; /* Get an updated view of the properties for the current connector and * look for the link-status property @@ -2813,10 +2815,6 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode) if (props && props->flags & DRM_MODE_PROP_ENUM && !strcmp(props->name, "link-status") && koutput->prop_values[j] == DRM_MODE_LINK_STATUS_BAD) { - xf86CrtcPtr crtc = output->crtc; - if (!crtc) - continue; - /* the connector got a link failure, re-set the current mode */ drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); -- cgit v1.2.3 From 15350bd5538c21cd4c6b406d565ca765b7e0218a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 15 Nov 2017 18:01:29 +0100 Subject: Use correct ScrnInfoPtr in redisplay_dirty We used the destination pixmap's screen for flushing drawing commands. But when we are the master screen, the destination pixmap is from the slave screen. Fixes crash when the slave screen isn't using the same acceleration architecture as us. Bugzilla: https://bugs.freedesktop.org/103613 Fixes: 01b040b4a807 ("Adapt to PixmapDirtyUpdateRec::src being a DrawablePtr") (Ported from amdgpu commit 3a4f7422913093ed9e26b73ecd7f9e773478cb1e) Reviewed-by: Alex Deucher --- src/radeon_kms.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 06c8a47f..5fcd8f0b 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -570,7 +570,11 @@ dirty_region(PixmapDirtyUpdatePtr dirty) static void redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region) { - ScrnInfoPtr pScrn = xf86ScreenToScrn(dirty->slave_dst->drawable.pScreen); +#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC + ScrnInfoPtr src_scrn = xf86ScreenToScrn(dirty->src->pScreen); +#else + ScrnInfoPtr src_scrn = xf86ScreenToScrn(dirty->src->drawable.pScreen); +#endif if (RegionNil(region)) goto out; @@ -584,7 +588,7 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region) PixmapSyncDirtyHelper(dirty, region); #endif - radeon_cs_flush_indirect(pScrn); + radeon_cs_flush_indirect(src_scrn); if (dirty->slave_dst->master_pixmap) DamageRegionProcessPending(&dirty->slave_dst->drawable); -- cgit v1.2.3 From fccfd75ecf9ccfa628a8ff9c1fbb7f60c0f10ea5 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Fri, 24 Nov 2017 17:27:09 +0100 Subject: Fix non GLAMOR build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Non GLAMOR builds needs pRADEONEnt so move the USE_GLAMOR define down to make pRADEONEnt defined in this case. Signed-off-by: Joakim Tjernlund Reviewed-by: Michel Dänzer --- src/radeon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/radeon.h b/src/radeon.h index d54e4990..3e04101c 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -712,9 +712,9 @@ uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix); static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) { -#ifdef USE_GLAMOR ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen); RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); +#ifdef USE_GLAMOR RADEONInfoPtr info = RADEONPTR(scrn); if (info->use_glamor) { -- cgit v1.2.3 From ee907e9b9563609cb4a4817e17215b50bb1c7177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 1 Dec 2017 15:49:11 +0100 Subject: Add radeon_dirty_src_drawable helper Allows tidying up radeon_dirty_src_equals and redisplay_dirty slightly. (Cherry picked from amdgpu commit 1d65ac395971571094df21ca0408d5972c6b56ec) Acked-by: Alex Deucher --- src/radeon.h | 18 +++++++++--------- src/radeon_kms.c | 7 ++----- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index 3e04101c..cc5dc09f 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -191,24 +191,24 @@ radeon_master_screen(ScreenPtr screen) static inline ScreenPtr radeon_dirty_master(PixmapDirtyUpdatePtr dirty) +{ + return radeon_master_screen(dirty->slave_dst->drawable.pScreen); +} + +static inline DrawablePtr +radeon_dirty_src_drawable(PixmapDirtyUpdatePtr dirty) { #ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC - ScreenPtr screen = dirty->src->pScreen; + return dirty->src; #else - ScreenPtr screen = dirty->src->drawable.pScreen; + return &dirty->src->drawable; #endif - - return radeon_master_screen(screen); } static inline Bool radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap) { -#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC - return dirty->src == &pixmap->drawable; -#else - return dirty->src == pixmap; -#endif + return radeon_dirty_src_drawable(dirty) == &pixmap->drawable; } diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 5fcd8f0b..a9300d40 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -570,11 +570,8 @@ dirty_region(PixmapDirtyUpdatePtr dirty) static void redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region) { -#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC - ScrnInfoPtr src_scrn = xf86ScreenToScrn(dirty->src->pScreen); -#else - ScrnInfoPtr src_scrn = xf86ScreenToScrn(dirty->src->drawable.pScreen); -#endif + ScrnInfoPtr src_scrn = + xf86ScreenToScrn(radeon_dirty_src_drawable(dirty)->pScreen); if (RegionNil(region)) goto out; -- cgit v1.2.3 From b4ce8913ac392df339081f6f3e28bf79a239ee75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 27 Dec 2017 17:05:26 +0100 Subject: Move cursor related ScreenInit calls into RADEONCursorInit_KMS And bail if xf86_cursors_init fails. (Ported from amdgpu commit dfccaa7043ccb157a1f8be7313123792bb7e7001) Reviewed-by: Alex Deucher --- src/radeon_kms.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index a9300d40..602a8fb7 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1982,12 +1982,29 @@ static Bool RADEONCursorInit_KMS(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(pScrn); - return xf86_cursors_init (pScreen, info->cursor_w, info->cursor_h, - (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | - HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | - HARDWARE_CURSOR_UPDATE_UNHIDDEN | - HARDWARE_CURSOR_ARGB)); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, + "Initializing Cursor\n"); + + /* Set Silken Mouse */ + xf86SetSilkenMouse(pScreen); + + /* Cursor setup */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) + return TRUE; + + if (!xf86_cursors_init(pScreen, info->cursor_w, info->cursor_h, + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | + HARDWARE_CURSOR_UPDATE_UNHIDDEN | + HARDWARE_CURSOR_ARGB)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86_cursors_init failed\n"); + return FALSE; + } + + return TRUE; } void @@ -2330,19 +2347,8 @@ Bool RADEONScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv) "Initializing DPMS\n"); xf86DPMSInit(pScreen, xf86DPMSSet, 0); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "Initializing Cursor\n"); - - /* Set Silken Mouse */ - xf86SetSilkenMouse(pScreen); - - /* Cursor setup */ - miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); - - if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) { - if (RADEONCursorInit_KMS(pScreen)) { - } - } + if (!RADEONCursorInit_KMS(pScreen)) + return FALSE; /* DGA setup */ #ifdef XFreeXDGA -- cgit v1.2.3 From 1fe8ca75974c5241c3b556b757f9c966c9ce5002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 27 Dec 2017 17:13:30 +0100 Subject: Keep track of how many SW cursors are visible on each screen And use this to determine when we cannot use page flipping for DRI clients. We previously did this based on whether the HW cursor cannot be used on at least one CRTC, which had at least two issues: * Even while the HW cursor cannot be used, no SW cursor may actually be visible (e.g. because all cursors are disabled), in which case we can use page flipping for DRI clients anyway * Even while the HW cursor can be used, there may be SW cursors visible from non-core pointer devices, in which case we cannot use page flipping for DRI clients anyway (Ported from amdgpu commit 69e20839bfeb3ee0b0a732d72de0a32d6c5435fc) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/drmmode_display.h | 4 ++++ src/radeon.h | 13 +++++++++++++ src/radeon_dri2.c | 2 +- src/radeon_kms.c | 28 ++++++++++++++++++++++++++++ src/radeon_present.c | 2 +- 6 files changed, 98 insertions(+), 2 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 7ad3235a..f55677f6 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -34,6 +34,7 @@ #include #include "cursorstr.h" #include "damagestr.h" +#include "inputstr.h" #include "list.h" #include "micmap.h" #include "xf86cmap.h" @@ -2628,6 +2629,56 @@ Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo } +static void drmmode_sprite_do_set_cursor(struct radeon_device_priv *device_priv, + ScrnInfoPtr scrn, int x, int y) +{ + RADEONInfoPtr info = RADEONPTR(scrn); + CursorPtr cursor = device_priv->cursor; + Bool sprite_visible = device_priv->sprite_visible; + + if (cursor) { + x -= cursor->bits->xhot; + y -= cursor->bits->yhot; + + device_priv->sprite_visible = + x < scrn->virtualX && y < scrn->virtualY && + (x + cursor->bits->width > 0) && + (y + cursor->bits->height > 0); + } else { + device_priv->sprite_visible = FALSE; + } + + info->sprites_visible += device_priv->sprite_visible - sprite_visible; +} + +void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + RADEONInfoPtr info = RADEONPTR(scrn); + struct radeon_device_priv *device_priv = + dixLookupScreenPrivate(&pDev->devPrivates, + &radeon_device_private_key, pScreen); + + device_priv->cursor = pCursor; + drmmode_sprite_do_set_cursor(device_priv, scrn, x, y); + + info->SetCursor(pDev, pScreen, pCursor, x, y); +} + +void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, + int y) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + RADEONInfoPtr info = RADEONPTR(scrn); + struct radeon_device_priv *device_priv = + dixLookupScreenPrivate(&pDev->devPrivates, + &radeon_device_private_key, pScreen); + + drmmode_sprite_do_set_cursor(device_priv, scrn, x, y); + + info->MoveCursor(pDev, pScreen, x, y); +} void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo) { diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 8387279f..39d2d94a 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -206,6 +206,10 @@ extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp); extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr); +extern void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y); +extern void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, + int y); extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo); void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y); extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, diff --git a/src/radeon.h b/src/radeon.h index cc5dc09f..9658e029 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -500,6 +500,13 @@ struct radeon_client_priv { uint_fast32_t needs_flush; }; +struct radeon_device_priv { + CursorPtr cursor; + Bool sprite_visible; +}; + +extern DevScreenPrivateKeyRec radeon_device_private_key; + typedef struct { EntityInfoPtr pEnt; pciVideoPtr PciInfo; @@ -550,6 +557,12 @@ typedef struct { CreateScreenResourcesProcPtr CreateScreenResources; CreateWindowProcPtr CreateWindow; WindowExposuresProcPtr WindowExposures; + void (*SetCursor) (DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y); + void (*MoveCursor) (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); + + /* Number of SW cursors currently visible on this screen */ + int sprites_visible; Bool IsSecondary; diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index b569bb4f..8376848c 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -723,7 +723,7 @@ can_flip(xf86CrtcPtr crtc, DrawablePtr draw, if (draw->type != DRAWABLE_WINDOW || !info->allowPageFlip || - info->hwcursor_disabled || + info->sprites_visible > 0 || info->drmmode.present_flipping || !pScrn->vtSema || !DRI2CanFlip(draw)) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 602a8fb7..c1f885eb 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -38,6 +38,7 @@ #include "radeon_reg.h" #include "radeon_probe.h" #include "micmap.h" +#include "mipointrst.h" #include "radeon_version.h" #include "shadow.h" @@ -66,6 +67,7 @@ #include "radeon_vbo.h" static DevScreenPrivateKeyRec radeon_client_private_key; +DevScreenPrivateKeyRec radeon_device_private_key; extern SymTabRec RADEONChipsets[]; static Bool radeon_setup_kernel_mem(ScreenPtr pScreen); @@ -1991,6 +1993,23 @@ static Bool RADEONCursorInit_KMS(ScreenPtr pScreen) /* Cursor setup */ miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + if (info->allowPageFlip) { + miPointerScreenPtr PointPriv = + dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); + + if (!dixRegisterScreenPrivateKey(&radeon_device_private_key, pScreen, + PRIVATE_DEVICE, + sizeof(struct radeon_device_priv))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "dixRegisterScreenPrivateKey failed\n"); + return FALSE; + } + + info->SetCursor = PointPriv->spriteFuncs->SetCursor; + info->MoveCursor = PointPriv->spriteFuncs->MoveCursor; + PointPriv->spriteFuncs->SetCursor = drmmode_sprite_set_cursor; + PointPriv->spriteFuncs->MoveCursor = drmmode_sprite_move_cursor; + } + if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) return TRUE; @@ -2147,6 +2166,15 @@ static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen) pScrn->vtSema = FALSE; xf86ClearPrimInitDone(info->pEnt->index); + + if (info->allowPageFlip) { + miPointerScreenPtr PointPriv = + dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); + + PointPriv->spriteFuncs->SetCursor = info->SetCursor; + PointPriv->spriteFuncs->MoveCursor = info->MoveCursor; + } + pScreen->BlockHandler = info->BlockHandler; pScreen->CloseScreen = info->CloseScreen; return pScreen->CloseScreen(pScreen); diff --git a/src/radeon_present.c b/src/radeon_present.c index 176853d9..d734b9d4 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -289,7 +289,7 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, if (!info->allowPageFlip) return FALSE; - if (info->hwcursor_disabled) + if (info->sprites_visible > 0) return FALSE; if (info->drmmode.dri2_flipping) -- cgit v1.2.3 From 21f6753462464acfd3c452393328c977a375ce26 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Mon, 22 Jan 2018 03:14:34 +0100 Subject: Define per x-screen individual drmmode_crtc_funcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows to en-/disable some functions depending on individual screen settings. Prep work for more efficient depth 30 support. Suggested-by: Michel Dänzer Signed-off-by: Mario Kleiner Reviewed-by: Michel Dänzer --- src/drmmode_display.c | 14 ++++++++++---- src/radeon.h | 2 ++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index f55677f6..b1c874c7 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1395,8 +1395,9 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res xf86CrtcPtr crtc; drmmode_crtc_private_ptr drmmode_crtc; RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + RADEONInfoPtr info = RADEONPTR(pScrn); - crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs); + crtc = xf86CrtcCreate(pScrn, &info->drmmode_crtc_funcs); if (crtc == NULL) return 0; @@ -2531,11 +2532,16 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "%d crtcs needed for screen.\n", crtcs_needed); + /* Need per-screen drmmode_crtc_funcs, based on our global template, + * so we can disable some functions, depending on screen settings. + */ + info->drmmode_crtc_funcs = drmmode_crtc_funcs; + if (info->r600_shadow_fb) { /* Rotation requires hardware acceleration */ - drmmode_crtc_funcs.shadow_allocate = NULL; - drmmode_crtc_funcs.shadow_create = NULL; - drmmode_crtc_funcs.shadow_destroy = NULL; + info->drmmode_crtc_funcs.shadow_allocate = NULL; + info->drmmode_crtc_funcs.shadow_create = NULL; + info->drmmode_crtc_funcs.shadow_destroy = NULL; } drmmode->count_crtcs = mode_res->count_crtcs; diff --git a/src/radeon.h b/src/radeon.h index 9658e029..5b717364 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -635,6 +635,8 @@ typedef struct { SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking; } glamor; #endif /* USE_GLAMOR */ + + xf86CrtcFuncsRec drmmode_crtc_funcs; } RADEONInfoRec, *RADEONInfoPtr; /* radeon_accel.c */ -- cgit v1.2.3 From 1f1d4b1fa7d4b22dd8553f7e71251bf17ca7a7b1 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Mon, 22 Jan 2018 03:14:35 +0100 Subject: Skip xf86HandleColormaps() at color depth 30. (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hardware gamma luts get bypassed at color depth 30 anyway, so skip their setup. v2: Also don't hook up drmmode_crtc_gamma_set() to .gamma_set for a screen with depth 30, so the server can spare itself the effort of updating and setting unused cluts. Suggested by Michel. Signed-off-by: Mario Kleiner Reviewed-by: Michel Dänzer --- src/drmmode_display.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index b1c874c7..21cc3c90 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2544,6 +2544,12 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) info->drmmode_crtc_funcs.shadow_destroy = NULL; } + /* Hw gamma lut's are currently bypassed by the hw at color depth 30, + * so spare the server the effort to compute and update the cluts. + */ + if (pScrn->depth == 30) + info->drmmode_crtc_funcs.gamma_set = NULL; + drmmode->count_crtcs = mode_res->count_crtcs; xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, mode_res->max_height); @@ -2787,8 +2793,10 @@ Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) "Initializing kms color map\n"); if (!miCreateDefColormap(pScreen)) return FALSE; - /* all radeons support 10 bit CLUTs */ - if (!xf86HandleColormaps(pScreen, 256, 10, + + /* All radeons support 10 bit CLUTs. They get bypassed at depth 30. */ + if (pScrn->depth != 30 && + !xf86HandleColormaps(pScreen, 256, 10, NULL, NULL, CMAP_PALETTED_TRUECOLOR #if 0 /* This option messes up text mode! (eich@suse.de) */ -- cgit v1.2.3 From ee7e6c25989e4faf1adfa4754b7edd5a9a4722ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Mon, 22 Jan 2018 03:14:36 +0100 Subject: exa: Accelerate ARGB2101010 pictures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested by Mario on a Radeon HD 4000 series for the r600 exa path, and on Radeon HD 5770 for the evergreen exa path. Signed-off-by: Fredrik Höglund Reviewed-and-Tested-by: Mario Kleiner Reviewed-by: Michel Dänzer --- src/evergreen_exa.c | 18 ++++++++++++++++++ src/r600_exa.c | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c index 90c9b6d9..85848133 100644 --- a/src/evergreen_exa.c +++ b/src/evergreen_exa.c @@ -668,6 +668,10 @@ struct formatinfo { }; static struct formatinfo EVERGREENTexFormats[] = { + {PICT_a2r10g10b10, FMT_2_10_10_10}, + {PICT_x2r10g10b10, FMT_2_10_10_10}, + {PICT_a2b10g10r10, FMT_2_10_10_10}, + {PICT_x2b10g10r10, FMT_2_10_10_10}, {PICT_a8r8g8b8, FMT_8_8_8_8}, {PICT_x8r8g8b8, FMT_8_8_8_8}, {PICT_a8b8g8r8, FMT_8_8_8_8}, @@ -723,6 +727,12 @@ static uint32_t EVERGREENGetBlendCntl(int op, PicturePtr pMask, uint32_t dst_for static Bool EVERGREENGetDestFormat(PicturePtr pDstPicture, uint32_t *dst_format) { switch (pDstPicture->format) { + case PICT_a2r10g10b10: + case PICT_x2r10g10b10: + case PICT_a2b10g10r10: + case PICT_x2b10g10r10: + *dst_format = COLOR_2_10_10_10; + break; case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a8b8g8r8: @@ -891,6 +901,7 @@ static Bool EVERGREENTextureSetup(PicturePtr pPict, PixmapPtr pPix, /* component swizzles */ switch (pPict->format) { + case PICT_a2r10g10b10: case PICT_a1r5g5b5: case PICT_a8r8g8b8: pix_r = SQ_SEL_Z; /* R */ @@ -898,12 +909,14 @@ static Bool EVERGREENTextureSetup(PicturePtr pPict, PixmapPtr pPix, pix_b = SQ_SEL_X; /* B */ pix_a = SQ_SEL_W; /* A */ break; + case PICT_a2b10g10r10: case PICT_a8b8g8r8: pix_r = SQ_SEL_X; /* R */ pix_g = SQ_SEL_Y; /* G */ pix_b = SQ_SEL_Z; /* B */ pix_a = SQ_SEL_W; /* A */ break; + case PICT_x2b10g10r10: case PICT_x8b8g8r8: pix_r = SQ_SEL_X; /* R */ pix_g = SQ_SEL_Y; /* G */ @@ -922,6 +935,7 @@ static Bool EVERGREENTextureSetup(PicturePtr pPict, PixmapPtr pPix, pix_b = SQ_SEL_W; /* B */ pix_a = SQ_SEL_1; /* A */ break; + case PICT_x2r10g10b10: case PICT_x1r5g5b5: case PICT_x8r8g8b8: case PICT_r5g6b5: @@ -1425,6 +1439,8 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture, cb_conf.surface = accel_state->dst_obj.surface; switch (pDstPicture->format) { + case PICT_a2r10g10b10: + case PICT_x2r10g10b10: case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a1r5g5b5: @@ -1432,6 +1448,8 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture, default: cb_conf.comp_swap = 1; /* ARGB */ break; + case PICT_a2b10g10r10: + case PICT_x2b10g10r10: case PICT_a8b8g8r8: case PICT_x8b8g8r8: cb_conf.comp_swap = 0; /* ABGR */ diff --git a/src/r600_exa.c b/src/r600_exa.c index 22d4b316..c69b8fce 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -727,6 +727,10 @@ struct formatinfo { }; static struct formatinfo R600TexFormats[] = { + {PICT_a2r10g10b10, FMT_2_10_10_10}, + {PICT_x2r10g10b10, FMT_2_10_10_10}, + {PICT_a2b10g10r10, FMT_2_10_10_10}, + {PICT_x2b10g10r10, FMT_2_10_10_10}, {PICT_a8r8g8b8, FMT_8_8_8_8}, {PICT_x8r8g8b8, FMT_8_8_8_8}, {PICT_a8b8g8r8, FMT_8_8_8_8}, @@ -782,6 +786,12 @@ static uint32_t R600GetBlendCntl(int op, PicturePtr pMask, uint32_t dst_format) static Bool R600GetDestFormat(PicturePtr pDstPicture, uint32_t *dst_format) { switch (pDstPicture->format) { + case PICT_a2r10g10b10: + case PICT_x2r10g10b10: + case PICT_a2b10g10r10: + case PICT_x2b10g10r10: + *dst_format = COLOR_2_10_10_10; + break; case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a8b8g8r8: @@ -906,6 +916,7 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix, /* component swizzles */ switch (pPict->format) { + case PICT_a2r10g10b10: case PICT_a1r5g5b5: case PICT_a8r8g8b8: pix_r = SQ_SEL_Z; /* R */ @@ -913,12 +924,14 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix, pix_b = SQ_SEL_X; /* B */ pix_a = SQ_SEL_W; /* A */ break; + case PICT_a2b10g10r10: case PICT_a8b8g8r8: pix_r = SQ_SEL_X; /* R */ pix_g = SQ_SEL_Y; /* G */ pix_b = SQ_SEL_Z; /* B */ pix_a = SQ_SEL_W; /* A */ break; + case PICT_x2b10g10r10: case PICT_x8b8g8r8: pix_r = SQ_SEL_X; /* R */ pix_g = SQ_SEL_Y; /* G */ @@ -937,6 +950,7 @@ static Bool R600TextureSetup(PicturePtr pPict, PixmapPtr pPix, pix_b = SQ_SEL_W; /* B */ pix_a = SQ_SEL_1; /* A */ break; + case PICT_x2r10g10b10: case PICT_x1r5g5b5: case PICT_x8r8g8b8: case PICT_r5g6b5: @@ -1464,6 +1478,8 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, cb_conf.surface = accel_state->dst_obj.surface; switch (pDstPicture->format) { + case PICT_a2r10g10b10: + case PICT_x2r10g10b10: case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a1r5g5b5: @@ -1471,6 +1487,8 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, default: cb_conf.comp_swap = 1; /* ARGB */ break; + case PICT_a2b10g10r10: + case PICT_x2b10g10r10: case PICT_a8b8g8r8: case PICT_x8b8g8r8: cb_conf.comp_swap = 0; /* ABGR */ -- cgit v1.2.3 From 574bfab4bf1fcd95163a8f33cea2889189429d30 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Mon, 22 Jan 2018 03:14:37 +0100 Subject: Support exa screen color depth 30 on Linux 3.16 and later. (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Linux 3.16's radeon-kms introduced 10 bpc fb support. Currently, as of X-Server 1.19, this works with exa accel, but not yet when using glamor acceleration. v2: Style fixes, check for glamor first, as suggested by Michel. Signed-off-by: Mario Kleiner Reviewed-by: Michel Dänzer --- man/radeon.man | 3 ++- src/radeon_kms.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/man/radeon.man b/man/radeon.man index f4441c4b..889355bb 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -18,7 +18,8 @@ following features: .PD 0 .TP 2 \(bu -Full support for 8-, 15-, 16- and 24-bit pixel depths; +Full support for 8-, 15-, 16- and 24-bit pixel depths, and for 30-bit depth on Linux 3.16 +and later with EXA acceleration; .TP \(bu RandR 1.2 and RandR 1.3 support; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index c1f885eb..bac98cb6 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1250,6 +1250,7 @@ static Bool RADEONPreInitVisual(ScrnInfoPtr pScrn) case 15: case 16: case 24: + case 30: break; default: @@ -1765,6 +1766,22 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) if (!RADEONPreInitAccel_KMS(pScrn)) goto fail; + /* Depth 30 not yet supported under glamor. */ + if (pScrn->depth == 30 && info->use_glamor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported under GLAMOR accel. Select EXA.\n", + pScrn->depth); + goto fail; + } + + /* Depth 30 only supported since Linux 3.16 / kms driver minor version 39 */ + if (pScrn->depth == 30 && info->dri2.pKernelDRMVersion->version_minor < 39) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported. Kernel too old. Needs Linux 3.16+\n", + pScrn->depth); + goto fail; + } + radeon_drm_queue_init(); info->allowColorTiling2D = FALSE; -- cgit v1.2.3 From 2d171c892d373b45ef9f1ee068648437e2529a78 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Wed, 24 Jan 2018 18:19:37 +0100 Subject: Add missing depth 30 -> cpp=4 handling for DRI2. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Missing this apparently didn't cause any ill side effects, only a bit of confusion when looking at xtrace's of DRI2 clients. Signed-off-by: Mario Kleiner Reviewed-by: Michel Dänzer --- src/radeon_dri2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 8376848c..9f373589 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -125,6 +125,7 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen, cpp = 2; break; case 24: + case 30: cpp = 4; break; default: -- cgit v1.2.3 From 83124426040bc1f2dba74c8eeb5a5a9c7c64e664 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Wed, 24 Jan 2018 18:19:38 +0100 Subject: Make XvMC extension initialize at depth 30. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mario Kleiner Reviewed-by: Michel Dänzer --- src/radeon_textured_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c index 63631c99..23bdfd1d 100644 --- a/src/radeon_textured_video.c +++ b/src/radeon_textured_video.c @@ -499,11 +499,11 @@ static XF86VideoEncodingRec DummyEncodingEG[1] = } }; -#define NUM_FORMATS 3 +#define NUM_FORMATS 4 static XF86VideoFormatRec Formats[NUM_FORMATS] = { - {15, TrueColor}, {16, TrueColor}, {24, TrueColor} + {15, TrueColor}, {16, TrueColor}, {24, TrueColor}, {30, TrueColor} }; #define NUM_ATTRIBUTES 2 -- cgit v1.2.3 From 733f606dd6ca8350e6e7f0858bfff5454ddc98ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 25 Jan 2018 16:59:30 +0100 Subject: Always use screen depth/bpp for KMS framebuffers DRI clients can use depth 32 pixmaps while the screen is depth 24, in which case page flipping would fail. Reported-by: Mario Kleiner Reviewed-and-Tested-by: Mario Kleiner --- src/drmmode_display.c | 5 ++--- src/radeon.h | 13 ++++++------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 21cc3c90..f94f70bf 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -943,9 +943,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (!fb) fb = radeon_pixmap_get_fb(pScreen->GetWindowPixmap(pScreen->root)); if (!fb) { - fb = radeon_fb_create(pRADEONEnt->fd, pScrn->virtualX, - pScrn->virtualY, pScrn->depth, - pScrn->bitsPerPixel, + fb = radeon_fb_create(pScrn, pRADEONEnt->fd, + pScrn->virtualX, pScrn->virtualY, pScrn->displayWidth * info->pixel_bytes, info->front_bo->handle); /* Prevent refcnt of ad-hoc FBs from reaching 2 */ diff --git a/src/radeon.h b/src/radeon.h index 5b717364..08e38c17 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -836,8 +836,8 @@ static inline Bool radeon_get_pixmap_shared(PixmapPtr pPix) } static inline struct drmmode_fb* -radeon_fb_create(int drm_fd, uint32_t width, uint32_t height, uint8_t depth, - uint8_t bpp, uint32_t pitch, uint32_t handle) +radeon_fb_create(ScrnInfoPtr scrn, int drm_fd, uint32_t width, uint32_t height, + uint32_t pitch, uint32_t handle) { struct drmmode_fb *fb = malloc(sizeof(*fb)); @@ -845,8 +845,8 @@ radeon_fb_create(int drm_fd, uint32_t width, uint32_t height, uint8_t depth, return NULL; fb->refcnt = 1; - if (drmModeAddFB(drm_fd, width, height, depth, bpp, pitch, handle, - &fb->handle) == 0) + if (drmModeAddFB(drm_fd, width, height, scrn->depth, scrn->bitsPerPixel, + pitch, handle, &fb->handle) == 0) return fb; free(fb); @@ -898,9 +898,8 @@ radeon_pixmap_get_fb(PixmapPtr pix) ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen); RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - *fb_ptr = radeon_fb_create(pRADEONEnt->fd, pix->drawable.width, - pix->drawable.height, pix->drawable.depth, - pix->drawable.bitsPerPixel, pix->devKind, + *fb_ptr = radeon_fb_create(scrn, pRADEONEnt->fd, pix->drawable.width, + pix->drawable.height, pix->devKind, handle); } } -- cgit v1.2.3 From 703cbb7177c6f69264836e975c1921e552fd60a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Feb 2018 17:28:10 +0100 Subject: glamor: Allow depth 30 with Xorg >= 1.19.99.1 Corresponding to amdgpu commit 6aee5770fb913713bb1b9a1af8f0d0892a66f21a. Reviewed-by: Alex Deucher --- man/radeon.man | 2 +- src/radeon_kms.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/man/radeon.man b/man/radeon.man index 889355bb..dcebf537 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -19,7 +19,7 @@ following features: .TP 2 \(bu Full support for 8-, 15-, 16- and 24-bit pixel depths, and for 30-bit depth on Linux 3.16 -and later with EXA acceleration; +and later; .TP \(bu RandR 1.2 and RandR 1.3 support; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index bac98cb6..25b889a6 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1767,7 +1767,8 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) if (!RADEONPreInitAccel_KMS(pScrn)) goto fail; /* Depth 30 not yet supported under glamor. */ - if (pScrn->depth == 30 && info->use_glamor) { + if (pScrn->depth == 30 && info->use_glamor && + xorgGetVersion() < XORG_VERSION_NUMERIC(1,19,99,1,0)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given depth (%d) is not supported under GLAMOR accel. Select EXA.\n", pScrn->depth); -- cgit v1.2.3 From 8a55e66bfd77dcb2553a43e86215b9d3c87b03f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Feb 2018 18:13:16 +0100 Subject: Don't use RADEONEntPriv in RADEONFreeRec It crashes if info == NULL. (Ported from amdgpu commits fb8444e731765588c0ff1e9053c1c7b73f5f0907 & cfccf4c4e7e5c73fe4040fabeb1b43283cf29b33) Reviewed-by: Alex Deucher --- src/radeon_kms.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 25b889a6..6b1dc38b 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -194,18 +194,33 @@ static Bool RADEONGetRec(ScrnInfoPtr pScrn) /* Free our private RADEONInfoRec */ static void RADEONFreeRec(ScrnInfoPtr pScrn) { + DevUnion *pPriv; RADEONEntPtr pRADEONEnt; RADEONInfoPtr info; + EntityInfoPtr pEnt; - if (!pScrn || !pScrn->driverPrivate) return; + if (!pScrn) + return; info = RADEONPTR(pScrn); + if (info) { + if (info->fbcon_pixmap) + pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap); - if (info->fbcon_pixmap) - pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap); + if (info->accel_state) { + free(info->accel_state); + info->accel_state = NULL; + } - pRADEONEnt = RADEONEntPriv(pScrn); + pEnt = info->pEnt; + free(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; + } else { + pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); + } + pPriv = xf86GetEntityPrivate(pEnt->index, gRADEONEntityIndex); + pRADEONEnt = pPriv->ptr; if (pRADEONEnt->fd > 0) { DevUnion *pPriv; RADEONEntPtr pRADEONEnt; @@ -225,14 +240,7 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn) } } - if (info->accel_state) { - free(info->accel_state); - info->accel_state = NULL; - } - - free(info->pEnt); - free(pScrn->driverPrivate); - pScrn->driverPrivate = NULL; + free(pEnt); } static void * -- cgit v1.2.3 From 6b44b8c584f3b63712858be11277842c97d03426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Feb 2018 18:06:18 +0100 Subject: Don't call RADEONFreeRec from RADEONPreInit_KMS If the latter fails, Xorg will call RADEONFreeScreen_KMS, which calls the former. (Ported from amdgpu commit 103b7285845b786929fb509083c57e074c48f9be) Reviewed-by: Alex Deucher --- src/radeon_kms.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 6b1dc38b..06f7883e 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1712,7 +1712,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) && info->pEnt->location.type != BUS_PLATFORM #endif ) - goto fail; + return FALSE; pPriv = xf86GetEntityPrivate(pScrn->entityList[0], getRADEONEntityIndex()); @@ -1739,24 +1739,24 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) pScrn->monitor = pScrn->confScreen->monitor; if (!RADEONPreInitVisual(pScrn)) - goto fail; + return FALSE; xf86CollectOptions(pScrn, NULL); if (!(info->Options = malloc(sizeof(RADEONOptions_KMS)))) - goto fail; + return FALSE; memcpy(info->Options, RADEONOptions_KMS, sizeof(RADEONOptions_KMS)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options); if (!RADEONPreInitWeight(pScrn)) - goto fail; + return FALSE; if (!RADEONPreInitChipType_KMS(pScrn)) - goto fail; + return FALSE; if (radeon_open_drm_master(pScrn) == FALSE) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); - goto fail; + return FALSE; } info->dri2.available = FALSE; @@ -1765,14 +1765,15 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) if (info->dri2.pKernelDRMVersion == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RADEONDRIGetVersion failed to get the DRM version\n"); - goto fail; + return FALSE; } /* Get ScreenInit function */ if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; - if (!RADEONPreInitAccel_KMS(pScrn)) goto fail; + if (!RADEONPreInitAccel_KMS(pScrn)) + return FALSE; /* Depth 30 not yet supported under glamor. */ if (pScrn->depth == 30 && info->use_glamor && @@ -1780,7 +1781,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given depth (%d) is not supported under GLAMOR accel. Select EXA.\n", pScrn->depth); - goto fail; + return FALSE; } /* Depth 30 only supported since Linux 3.16 / kms driver minor version 39 */ @@ -1788,7 +1789,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given depth (%d) is not supported. Kernel too old. Needs Linux 3.16+\n", pScrn->depth); - goto fail; + return FALSE; } radeon_drm_queue_init(); @@ -1901,7 +1902,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); - goto fail; + return FALSE; } RADEONSetupCapabilities(pScrn); @@ -1995,14 +1996,10 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) #endif ) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); - goto fail; - } + return FALSE; + } return TRUE; - fail: - RADEONFreeRec(pScrn); - return FALSE; - } static Bool RADEONCursorInit_KMS(ScreenPtr pScreen) -- cgit v1.2.3 From 16954fab59f95bdca4540c4496b2ec0759c447e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Feb 2018 18:20:04 +0100 Subject: Call RADEONFreeRec from RADEONFreeScreen_KMS even if info == NULL It's safe now. (Ported from amdgpu commit c9bd1399a13cea2e1331af2c826ca054b88db071) Reviewed-by: Alex Deucher --- src/radeon_kms.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 06f7883e..6e5bf781 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2206,14 +2206,9 @@ static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen) void RADEONFreeScreen_KMS(ScrnInfoPtr pScrn) { - RADEONInfoPtr info = RADEONPTR(pScrn); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONFreeScreen\n"); - /* when server quits at PreInit, we don't need do this anymore*/ - if (!info) return; - RADEONFreeRec(pScrn); } -- cgit v1.2.3 From 680b4ab43f00b1f635f9359281e13a031d09ad24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 24 Jan 2018 12:29:17 +0100 Subject: If glamor is too old for depth 30, fall back to EXA or ShadowFB Instead of not starting up at all. Corresponding to amdgpu commit 37c7260bdef3a53b0f0295a531f33938e9aad8cf. Reviewed-by: Alex Deucher --- src/radeon_glamor.c | 8 ++++++++ src/radeon_kms.c | 9 --------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index 5f378743..7c09abba 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -119,6 +119,14 @@ radeon_glamor_pre_init(ScrnInfoPtr scrn) return FALSE; } + if (scrn->depth == 30 && + xorgGetVersion() < XORG_VERSION_NUMERIC(1,19,99,1,0)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "Depth 30 is not supported by GLAMOR with Xorg < " + "1.19.99.1\n"); + return FALSE; + } + #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,15,0,0,0) if (!xf86LoaderCheckSymbol("glamor_egl_init")) { xf86DrvMsg(scrn->scrnIndex, s ? X_ERROR : X_WARNING, diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 6e5bf781..b268f7ea 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1775,15 +1775,6 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) if (!RADEONPreInitAccel_KMS(pScrn)) return FALSE; - /* Depth 30 not yet supported under glamor. */ - if (pScrn->depth == 30 && info->use_glamor && - xorgGetVersion() < XORG_VERSION_NUMERIC(1,19,99,1,0)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Given depth (%d) is not supported under GLAMOR accel. Select EXA.\n", - pScrn->depth); - return FALSE; - } - /* Depth 30 only supported since Linux 3.16 / kms driver minor version 39 */ if (pScrn->depth == 30 && info->dri2.pKernelDRMVersion->version_minor < 39) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, -- cgit v1.2.3 From 2d63748667d0bcfcd9999e4e41f775eba87897a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 15 Feb 2018 17:47:14 +0100 Subject: Simplify depth 30 "kernel too old" error message We know it's depth 30, no need to have xf86DrvMsg fill it in. Reviewed-by: Alex Deucher --- src/radeon_kms.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index b268f7ea..85390e30 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1778,8 +1778,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) /* Depth 30 only supported since Linux 3.16 / kms driver minor version 39 */ if (pScrn->depth == 30 && info->dri2.pKernelDRMVersion->version_minor < 39) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Given depth (%d) is not supported. Kernel too old. Needs Linux 3.16+\n", - pScrn->depth); + "Depth 30 is not supported. Kernel too old. Needs Linux 3.16+\n"); return FALSE; } -- cgit v1.2.3 From f777e909fd23e063729ecb038997db445f82ef5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 16 Feb 2018 16:55:03 +0100 Subject: Don't bail from drmmode_set_desired_modes immediately If we fail to find or set the mode for a CRTC, keep trying for the remaining CRTCs, and only return FALSE if we failed for all CRTCs that should be on. (Ported from amdgpu commit f5ac5f385f41d1547cfd7ccc8bb35a537a8fffeb) --- src/drmmode_display.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index f94f70bf..517ec8fb 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2717,6 +2717,7 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + unsigned num_desired = 0, num_on = 0; int c; for (c = 0; c < config->num_crtc; c++) { @@ -2753,14 +2754,19 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, if (!output) continue; + num_desired++; + /* Mark that we'll need to re-set the mode for sure */ memset(&crtc->mode, 0, sizeof(crtc->mode)); if (!crtc->desiredMode.CrtcHDisplay) { DisplayModePtr mode = xf86OutputFindClosestMode (output, pScrn->currentMode); - if (!mode) - return FALSE; + if (!mode) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to find mode for CRTC %d\n", c); + continue; + } crtc->desiredMode = *mode; crtc->desiredRotation = RR_Rotate_0; crtc->desiredX = 0; @@ -2768,18 +2774,30 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, } if (set_hw) { - if (!crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation, - crtc->desiredX, crtc->desiredY)) - return FALSE; + if (crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, + crtc->desiredRotation, + crtc->desiredX, + crtc->desiredY)) { + num_on++; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to set mode on CRTC %d\n", c); + } } else { crtc->mode = crtc->desiredMode; crtc->rotation = crtc->desiredRotation; crtc->x = crtc->desiredX; crtc->y = crtc->desiredY; - if (!drmmode_handle_transform(crtc)) - return FALSE; + if (drmmode_handle_transform(crtc)) + num_on++; } } + + if (num_on == 0 && num_desired > 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to enable any CRTC\n"); + return FALSE; + } + return TRUE; } -- cgit v1.2.3 From f2915eb7a4beb6140ebec183aeac02111fc6ba77 Mon Sep 17 00:00:00 2001 From: Christoph Haag Date: Thu, 1 Mar 2018 15:07:00 +0100 Subject: fix include order for present.h configure test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xorg-server.h defines _XSERVER64 which is used in X.h to choose the correct definition of XID this prevents a failure in the present.h configure test that disables DRI3 on X.Org 1.20 Reviewed-and-Tested-by: Michel Dänzer --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index a11ba2a4..6bf9671a 100644 --- a/configure.ac +++ b/configure.ac @@ -181,8 +181,8 @@ AC_CHECK_HEADERS([misyncshm.h], [], [], AC_CHECK_HEADERS([present.h], [], [], [#include #include - #include - #include "xorg-server.h"]) + #include "xorg-server.h" + #include ]) AC_CHECK_HEADERS([dri3.h], [], [], [#include -- cgit v1.2.3 From ace1e3871c39a86becdf473a47fdc096e8ef39f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 21 Feb 2018 17:53:59 +0100 Subject: Disable all unused CRTCs before setting desired modes This might avoid modeset failures in some cases where a CRTC which isn't used by Xorg was enabled before. (Ported from amdgpu commit e3aae7a24296f640c0153d1459f3e0820485468a) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 517ec8fb..d8bb9cc9 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2720,24 +2720,33 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, unsigned num_desired = 0, num_on = 0; int c; + /* First, disable all unused CRTCs */ + if (set_hw) { + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + /* Skip disabled CRTCs */ + if (crtc->enabled) + continue; + + drmmode_do_crtc_dpms(crtc, DPMSModeOff); + drmModeSetCrtc(pRADEONEnt->fd, + drmmode_crtc->mode_crtc->crtc_id, + 0, 0, 0, NULL, 0, NULL); + drmmode_fb_reference(pRADEONEnt->fd, + &drmmode_crtc->fb, NULL); + } + } + + /* Then, try setting the chosen mode on each CRTC */ for (c = 0; c < config->num_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; xf86OutputPtr output = NULL; int o; - /* Skip disabled CRTCs */ - if (!crtc->enabled) { - if (set_hw) { - drmmode_do_crtc_dpms(crtc, DPMSModeOff); - drmModeSetCrtc(pRADEONEnt->fd, - drmmode_crtc->mode_crtc->crtc_id, - 0, 0, 0, NULL, 0, NULL); - drmmode_fb_reference(pRADEONEnt->fd, - &drmmode_crtc->fb, NULL); - } + if (!crtc->enabled) continue; - } if (config->output[config->compat_output]->crtc == crtc) output = config->output[config->compat_output]; -- cgit v1.2.3 From 1ef12a92ca53cd6fbfed3ef8628616445b007c9a Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Fri, 2 Mar 2018 12:08:09 +0100 Subject: modesetting: Use helper to fetch drmModeProperty(Blob)s Replace the various loops to lookup drmModeProperty(Blob)s by introducing helper functions. Signed-off-by: Daniel Martin (Ported from amdgpu commit fb58e06acd6c6bd59de2dbdadbca27eb1dd0025b) --- src/drmmode_display.c | 121 ++++++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 52 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index d8bb9cc9..606f3f90 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1449,6 +1449,51 @@ drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) return MODE_OK; } +static int +koutput_get_prop_idx(int fd, drmModeConnectorPtr koutput, + int type, const char *name) +{ + int idx = -1; + + for (int i = 0; i < koutput->count_props; i++) { + drmModePropertyPtr prop = drmModeGetProperty(fd, koutput->props[i]); + + if (!prop) + continue; + + if (drm_property_type_is(prop, type) && !strcmp(prop->name, name)) + idx = i; + + drmModeFreeProperty(prop); + + if (idx > -1) + break; + } + + return idx; +} + +static int +koutput_get_prop_id(int fd, drmModeConnectorPtr koutput, + int type, const char *name) +{ + int idx = koutput_get_prop_idx(fd, koutput, type, name); + + return (idx > -1) ? koutput->props[idx] : -1; +} + +static drmModePropertyBlobPtr +koutput_get_prop_blob(int fd, drmModeConnectorPtr koutput, const char *name) +{ + drmModePropertyBlobPtr blob = NULL; + int idx = koutput_get_prop_idx(fd, koutput, DRM_MODE_PROP_BLOB, name); + + if (idx > -1) + blob = drmModeGetPropertyBlob(fd, koutput->prop_values[idx]); + + return blob; +} + static DisplayModePtr drmmode_output_get_modes(xf86OutputPtr output) { @@ -1457,25 +1502,16 @@ drmmode_output_get_modes(xf86OutputPtr output) RADEONEntPtr pRADEONEnt = RADEONEntPriv(output->scrn); int i; DisplayModePtr Modes = NULL, Mode; - drmModePropertyPtr props; xf86MonPtr mon = NULL; if (!koutput) return NULL; + drmModeFreePropertyBlob(drmmode_output->edid_blob); + /* look for an EDID property */ - for (i = 0; i < koutput->count_props; i++) { - props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[i]); - if (props && (props->flags & DRM_MODE_PROP_BLOB)) { - if (!strcmp(props->name, "EDID")) { - if (drmmode_output->edid_blob) - drmModeFreePropertyBlob(drmmode_output->edid_blob); - drmmode_output->edid_blob = drmModeGetPropertyBlob(pRADEONEnt->fd, koutput->prop_values[i]); - } - } - if (props) - drmModeFreeProperty(props); - } + drmmode_output->edid_blob = + koutput_get_prop_blob(pRADEONEnt->fd, koutput, "EDID"); if (drmmode_output->edid_blob) { mon = xf86InterpretEDID(output->scrn->scrnIndex, @@ -1896,7 +1932,6 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r drmModeConnectorPtr koutput; drmModeEncoderPtr *kencoders = NULL; drmmode_output_private_ptr drmmode_output; - drmModePropertyPtr props; drmModePropertyBlobPtr path_blob = NULL; char name[32]; int i; @@ -1906,17 +1941,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r if (!koutput) return 0; - for (i = 0; i < koutput->count_props; i++) { - props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[i]); - if (props && (props->flags & DRM_MODE_PROP_BLOB)) { - if (!strcmp(props->name, "PATH")) { - path_blob = drmModeGetPropertyBlob(pRADEONEnt->fd, koutput->prop_values[i]); - drmModeFreeProperty(props); - break; - } - } - drmModeFreeProperty(props); - } + path_blob = koutput_get_prop_blob(pRADEONEnt->fd, koutput, "PATH"); kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); if (!kencoders) { @@ -1996,17 +2021,9 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r /* work out the possible clones later */ output->possible_clones = 0; - for (i = 0; i < koutput->count_props; i++) { - props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[i]); - if (props && (props->flags & DRM_MODE_PROP_ENUM)) { - if (!strcmp(props->name, "DPMS")) { - drmmode_output->dpms_enum_id = koutput->props[i]; - drmModeFreeProperty(props); - break; - } - } - drmModeFreeProperty(props); - } + drmmode_output->dpms_enum_id = + koutput_get_prop_id(pRADEONEnt->fd, koutput, DRM_MODE_PROP_ENUM, + "DPMS"); if (dynamic) { output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output); @@ -2889,7 +2906,7 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode) xf86OutputPtr output = config->output[i]; xf86CrtcPtr crtc = output->crtc; drmmode_output_private_ptr drmmode_output = output->driver_private; - uint32_t con_id; + uint32_t con_id, idx; drmModeConnectorPtr koutput; if (!crtc || !drmmode_output->mode_output) @@ -2900,22 +2917,22 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode) * look for the link-status property */ koutput = drmModeGetConnectorCurrent(pRADEONEnt->fd, con_id); - for (j = 0; koutput && j < koutput->count_props; j++) { - drmModePropertyPtr props; - props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[j]); - if (props && props->flags & DRM_MODE_PROP_ENUM && - !strcmp(props->name, "link-status") && - koutput->prop_values[j] == DRM_MODE_LINK_STATUS_BAD) { - /* the connector got a link failure, re-set the current mode */ - drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, - crtc->x, crtc->y); + if (!koutput) + continue; - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "hotplug event: connector %u's link-state is BAD, " - "tried resetting the current mode. You may be left " - "with a black screen if this fails...\n", con_id); - } - drmModeFreeProperty(props); + idx = koutput_get_prop_idx(pRADEONEnt->fd, koutput, + DRM_MODE_PROP_ENUM, "link-status"); + + if ((idx > -1) && + (koutput->prop_values[idx] == DRM_MODE_LINK_STATUS_BAD)) { + /* the connector got a link failure, re-set the current mode */ + drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, + crtc->x, crtc->y); + + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "hotplug event: connector %u's link-state is BAD, " + "tried resetting the current mode. You may be left" + "with a black screen if this fails...\n", con_id); } drmModeFreeConnector(koutput); } -- cgit v1.2.3 From aef8fe6e9e94ebecbbb6adf940160d3a7ab4d5ac Mon Sep 17 00:00:00 2001 From: Daniel Martin Date: Fri, 2 Mar 2018 12:12:09 +0100 Subject: modesetting: Reset output_id if drmModeGetConnector failed If drmModeGetConnector() fails in drmmode_output_detect(), we have to reset the output_id to -1 too. Yet another spot leading to a potential NULL dereference when handling the mode_output member as output_id was != -1. Though, this case should be very hard to hit. Signed-off-by: Daniel Martin (Ported from amdgpu commit 10054b6c3d9a755b30abb43020121b9631fa296d) --- src/drmmode_display.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 606f3f90..525ded25 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1424,9 +1424,12 @@ drmmode_output_detect(xf86OutputPtr output) xf86OutputStatus status; drmModeFreeConnector(drmmode_output->mode_output); - drmmode_output->mode_output = drmModeGetConnector(pRADEONEnt->fd, drmmode_output->output_id); - if (!drmmode_output->mode_output) + drmmode_output->mode_output = + drmModeGetConnector(pRADEONEnt->fd, drmmode_output->output_id); + if (!drmmode_output->mode_output) { + drmmode_output->output_id = -1; return XF86OutputStatusDisconnected; + } switch (drmmode_output->mode_output->connection) { case DRM_MODE_CONNECTED: -- cgit v1.2.3 From e0d23092337efe4c1e406c9124ca8d8856863e65 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 2 Mar 2018 12:13:43 +0100 Subject: modesetting: Update property values at detect and uevent time We were updating the link-status property when a uevent came in, but we also want to update the non-desktop property, and potentially others as well. We also want to check at detect time in case we don't get a hotplug event. This patch updates every property provided by the kernel, sending changes to DIX so it can track things as well. Signed-off-by: Keith Packard (Ported from amdgpu commit 374cb8fef4fdbb648af089ee80803ec78321f1b2) --- src/drmmode_display.c | 104 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 18 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 525ded25..b1f5c488 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1415,6 +1415,72 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res return 1; } +/* + * Update all of the property values for an output + */ +static void +drmmode_output_update_properties(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + int i, j, k; + int err; + drmModeConnectorPtr koutput; + + /* Use the most recently fetched values from the kernel */ + koutput = drmmode_output->mode_output; + + if (!koutput) + return; + + for (i = 0; i < drmmode_output->num_props; i++) { + drmmode_prop_ptr p = &drmmode_output->props[i]; + + for (j = 0; j < koutput->count_props; j++) { + if (koutput->props[j] != p->mode_prop->prop_id) + continue; + + /* Check to see if the property value has changed */ + if (koutput->prop_values[j] == p->value) + break; + + p->value = koutput->prop_values[j]; + + if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { + INT32 value = p->value; + + err = RRChangeOutputProperty(output->randr_output, + p->atoms[0], XA_INTEGER, + 32, PropModeReplace, 1, + &value, FALSE, TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", + err); + } + } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { + for (k = 0; k < p->mode_prop->count_enums; k++) { + if (p->mode_prop->enums[k].value == p->value) + break; + } + if (k < p->mode_prop->count_enums) { + err = RRChangeOutputProperty(output->randr_output, + p->atoms[0], XA_ATOM, + 32, PropModeReplace, 1, + &p->atoms[k + 1], FALSE, + TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", + err); + } + } + } + + break; + } + } +} + static xf86OutputStatus drmmode_output_detect(xf86OutputPtr output) { @@ -1431,6 +1497,8 @@ drmmode_output_detect(xf86OutputPtr output) return XF86OutputStatusDisconnected; } + drmmode_output_update_properties(output); + switch (drmmode_output->mode_output->connection) { case DRM_MODE_CONNECTED: status = XF86OutputStatusConnected; @@ -2909,35 +2977,35 @@ radeon_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode) xf86OutputPtr output = config->output[i]; xf86CrtcPtr crtc = output->crtc; drmmode_output_private_ptr drmmode_output = output->driver_private; - uint32_t con_id, idx; - drmModeConnectorPtr koutput; + + drmmode_output_detect(output); if (!crtc || !drmmode_output->mode_output) continue; - con_id = drmmode_output->mode_output->connector_id; /* Get an updated view of the properties for the current connector and * look for the link-status property */ - koutput = drmModeGetConnectorCurrent(pRADEONEnt->fd, con_id); - if (!koutput) - continue; + for (j = 0; j < drmmode_output->num_props; j++) { + drmmode_prop_ptr p = &drmmode_output->props[j]; - idx = koutput_get_prop_idx(pRADEONEnt->fd, koutput, - DRM_MODE_PROP_ENUM, "link-status"); + if (!strcmp(p->mode_prop->name, "link-status")) { + if (p->value != DRM_MODE_LINK_STATUS_BAD) + break; - if ((idx > -1) && - (koutput->prop_values[idx] == DRM_MODE_LINK_STATUS_BAD)) { - /* the connector got a link failure, re-set the current mode */ - drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, - crtc->x, crtc->y); + /* the connector got a link failure, re-set the current mode */ + drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, + crtc->x, crtc->y); - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "hotplug event: connector %u's link-state is BAD, " - "tried resetting the current mode. You may be left" - "with a black screen if this fails...\n", con_id); + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "hotplug event: connector %u's link-state is BAD, " + "tried resetting the current mode. You may be left" + "with a black screen if this fails...\n", + drmmode_output->mode_output->connector_id); + + break; + } } - drmModeFreeConnector(koutput); } mode_res = drmModeGetResources(pRADEONEnt->fd); -- cgit v1.2.3 From 504b8721b17a672caf1ed3eab087027c02458cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 5 Mar 2018 18:41:44 +0100 Subject: Only change Set/MoveCursor hooks from what we expect Since xf86CursorCloseScreen runs after RADEONCloseScreen_KMS, PointPriv->spriteFuncs doesn't point to the same struct in the latter as in RADEONCursorInit_KMS. So we were restoring info->Set/MoveCursor to the wrong struct. Then in the next server generation, info->Set/MoveCursor would end up pointing to drmmode_sprite_set/move_cursor, resulting in an infinite loop if one of them was called. To avoid this, only change the Set/MoveCursor hooks if their values match our expectations, otherwise leave them as is. This is kind of a hack, but the alternative would be invasive and thus risky changes to the way we're wrapping CloseScreen, and it's not even clear that can work without changing xserver code. Fixes: 1fe8ca75974c ("Keep track of how many SW cursors are visible on each screen") Acked-by: Alex Deucher --- src/radeon_kms.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 85390e30..790d4be1 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2017,10 +2017,12 @@ static Bool RADEONCursorInit_KMS(ScreenPtr pScreen) return FALSE; } - info->SetCursor = PointPriv->spriteFuncs->SetCursor; - info->MoveCursor = PointPriv->spriteFuncs->MoveCursor; - PointPriv->spriteFuncs->SetCursor = drmmode_sprite_set_cursor; - PointPriv->spriteFuncs->MoveCursor = drmmode_sprite_move_cursor; + if (PointPriv->spriteFuncs->SetCursor != drmmode_sprite_set_cursor) { + info->SetCursor = PointPriv->spriteFuncs->SetCursor; + info->MoveCursor = PointPriv->spriteFuncs->MoveCursor; + PointPriv->spriteFuncs->SetCursor = drmmode_sprite_set_cursor; + PointPriv->spriteFuncs->MoveCursor = drmmode_sprite_move_cursor; + } } if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) @@ -2184,8 +2186,10 @@ static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen) miPointerScreenPtr PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); - PointPriv->spriteFuncs->SetCursor = info->SetCursor; - PointPriv->spriteFuncs->MoveCursor = info->MoveCursor; + if (PointPriv->spriteFuncs->SetCursor == drmmode_sprite_set_cursor) { + PointPriv->spriteFuncs->SetCursor = info->SetCursor; + PointPriv->spriteFuncs->MoveCursor = info->MoveCursor; + } } pScreen->BlockHandler = info->BlockHandler; -- cgit v1.2.3 From 7e18aea984e186dd2ab1144470b0c0e832562ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 6 Mar 2018 18:15:45 +0100 Subject: Bump version for 18.0.0 release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6bf9671a..4d7d7ae9 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [7.10.99], + [18.0.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) -- cgit v1.2.3 From b915e8e6fb956e983c2ce2a5565c20838c85707c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 7 Mar 2018 17:28:55 +0100 Subject: Wrap the whole miPointerScreenFuncRec, instead of only Set/MoveCursor We were clobbering entries in mi's global miSpritePointerFuncs struct, which cannot work correctly with multiple primary screens. Instead, assign a pointer to our own wrapper struct to PointPriv->spriteFuncs. Fixes crashes with multiple primary screens. Fixes: 1fe8ca75974c ("Keep track of how many SW cursors are visible on each screen") Reported-by: Mario Kleiner --- src/drmmode_display.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++----- src/drmmode_display.h | 7 +++--- src/radeon.h | 4 +--- src/radeon_kms.c | 14 ++++-------- 4 files changed, 63 insertions(+), 23 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index b1f5c488..93261dc8 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -37,6 +37,7 @@ #include "inputstr.h" #include "list.h" #include "micmap.h" +#include "mipointrst.h" #include "xf86cmap.h" #include "xf86Priv.h" #include "radeon.h" @@ -2750,8 +2751,8 @@ static void drmmode_sprite_do_set_cursor(struct radeon_device_priv *device_priv, info->sprites_visible += device_priv->sprite_visible - sprite_visible; } -void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, - CursorPtr pCursor, int x, int y) +static void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y) { ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(scrn); @@ -2762,11 +2763,11 @@ void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, device_priv->cursor = pCursor; drmmode_sprite_do_set_cursor(device_priv, scrn, x, y); - info->SetCursor(pDev, pScreen, pCursor, x, y); + info->SpriteFuncs->SetCursor(pDev, pScreen, pCursor, x, y); } -void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, - int y) +static void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y) { ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(scrn); @@ -2776,9 +2777,57 @@ void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, drmmode_sprite_do_set_cursor(device_priv, scrn, x, y); - info->MoveCursor(pDev, pScreen, x, y); + info->SpriteFuncs->MoveCursor(pDev, pScreen, x, y); } +static Bool drmmode_sprite_realize_realize_cursor(DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + RADEONInfoPtr info = RADEONPTR(scrn); + + return info->SpriteFuncs->RealizeCursor(pDev, pScreen, pCursor); +} + +static Bool drmmode_sprite_realize_unrealize_cursor(DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + RADEONInfoPtr info = RADEONPTR(scrn); + + return info->SpriteFuncs->UnrealizeCursor(pDev, pScreen, pCursor); +} + +static Bool drmmode_sprite_device_cursor_initialize(DeviceIntPtr pDev, + ScreenPtr pScreen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + RADEONInfoPtr info = RADEONPTR(scrn); + + return info->SpriteFuncs->DeviceCursorInitialize(pDev, pScreen); +} + +static void drmmode_sprite_device_cursor_cleanup(DeviceIntPtr pDev, + ScreenPtr pScreen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + RADEONInfoPtr info = RADEONPTR(scrn); + + info->SpriteFuncs->DeviceCursorCleanup(pDev, pScreen); +} + +miPointerSpriteFuncRec drmmode_sprite_funcs = { + .RealizeCursor = drmmode_sprite_realize_realize_cursor, + .UnrealizeCursor = drmmode_sprite_realize_unrealize_cursor, + .SetCursor = drmmode_sprite_set_cursor, + .MoveCursor = drmmode_sprite_move_cursor, + .DeviceCursorInitialize = drmmode_sprite_device_cursor_initialize, + .DeviceCursorCleanup = drmmode_sprite_device_cursor_cleanup, +}; + + void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 39d2d94a..e0b97e72 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -206,10 +206,6 @@ extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp); extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr); -extern void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, - CursorPtr pCursor, int x, int y); -extern void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, - int y); extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo); void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y); extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, @@ -249,5 +245,8 @@ Bool drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type, uint64_t *ust, uint32_t *result_seq); +miPointerSpriteFuncRec drmmode_sprite_funcs; + + #endif diff --git a/src/radeon.h b/src/radeon.h index 08e38c17..0815cd98 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -557,9 +557,7 @@ typedef struct { CreateScreenResourcesProcPtr CreateScreenResources; CreateWindowProcPtr CreateWindow; WindowExposuresProcPtr WindowExposures; - void (*SetCursor) (DeviceIntPtr pDev, ScreenPtr pScreen, - CursorPtr pCursor, int x, int y); - void (*MoveCursor) (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); + miPointerSpriteFuncPtr SpriteFuncs; /* Number of SW cursors currently visible on this screen */ int sprites_visible; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 790d4be1..8c3d15eb 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2017,12 +2017,8 @@ static Bool RADEONCursorInit_KMS(ScreenPtr pScreen) return FALSE; } - if (PointPriv->spriteFuncs->SetCursor != drmmode_sprite_set_cursor) { - info->SetCursor = PointPriv->spriteFuncs->SetCursor; - info->MoveCursor = PointPriv->spriteFuncs->MoveCursor; - PointPriv->spriteFuncs->SetCursor = drmmode_sprite_set_cursor; - PointPriv->spriteFuncs->MoveCursor = drmmode_sprite_move_cursor; - } + info->SpriteFuncs = PointPriv->spriteFuncs; + PointPriv->spriteFuncs = &drmmode_sprite_funcs; } if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) @@ -2186,10 +2182,8 @@ static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen) miPointerScreenPtr PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); - if (PointPriv->spriteFuncs->SetCursor == drmmode_sprite_set_cursor) { - PointPriv->spriteFuncs->SetCursor = info->SetCursor; - PointPriv->spriteFuncs->MoveCursor = info->MoveCursor; - } + if (PointPriv->spriteFuncs == &drmmode_sprite_funcs) + PointPriv->spriteFuncs = info->SpriteFuncs; } pScreen->BlockHandler = info->BlockHandler; -- cgit v1.2.3 From e0f5020117d0a6340f4208ec52bd3e3b3aa99a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Mar 2018 16:54:52 +0100 Subject: Pass extents to radeon_scanout_do_update by value radeon_scanout_extents_intersect could leave the scanout damage region in an invalid state, triggering debugging checks in pixman: *** BUG *** In pixman_region_append_non_o: The expression r->x1 < r->x2 was false Set a breakpoint on '_pixman_log_error' to debug (Ported from amdgpu commit 8af989546907ad9fb491d940e1936d3bfc89276b) --- src/drmmode_display.c | 4 ++-- src/radeon.h | 2 +- src/radeon_kms.c | 24 ++++++++++++------------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 93261dc8..f056bf3b 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -817,7 +817,7 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, radeon_scanout_do_update(crtc, scanout_id, screen->GetWindowPixmap(screen->root), - box); + *box); radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo); } } @@ -3282,7 +3282,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, } radeon_scanout_do_update(crtc, scanout_id, new_front, - &extents); + extents); drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, drmmode_crtc->scanout_update_pending); diff --git a/src/radeon.h b/src/radeon.h index 0815cd98..598a83c1 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -672,7 +672,7 @@ Bool radeon_dri3_screen_init(ScreenPtr screen); /* radeon_kms.c */ Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, - PixmapPtr src_pix, BoxPtr extents); + PixmapPtr src_pix, BoxRec extents); void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) , RegionPtr pBSRegion diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 8c3d15eb..26810e08 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -903,10 +903,10 @@ radeon_dirty_update(ScrnInfoPtr scrn) Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, - PixmapPtr src_pix, BoxPtr extents) + PixmapPtr src_pix, BoxRec extents) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; - RegionRec region = { .extents = *extents, .data = NULL }; + RegionRec region = { .extents = extents, .data = NULL }; ScrnInfoPtr scrn = xf86_crtc->scrn; ScreenPtr pScreen = scrn->pScreen; RADEONInfoPtr info = RADEONPTR(scrn); @@ -915,11 +915,11 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, if (!xf86_crtc->enabled || !drmmode_crtc->scanout[scanout_id].pixmap || - extents->x1 >= extents->x2 || extents->y1 >= extents->y2) + extents.x1 >= extents.x2 || extents.y1 >= extents.y2) return FALSE; pDraw = &drmmode_crtc->scanout[scanout_id].pixmap->drawable; - if (!radeon_scanout_extents_intersect(xf86_crtc, extents)) + if (!radeon_scanout_extents_intersect(xf86_crtc, &extents)) return FALSE; if (drmmode_crtc->tear_free) { @@ -965,9 +965,9 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, pScreen->SourceValidate = NULL; CompositePicture(PictOpSrc, src, NULL, dst, - extents->x1, extents->y1, 0, 0, extents->x1, - extents->y1, extents->x2 - extents->x1, - extents->y2 - extents->y1); + extents.x1, extents.y1, 0, 0, extents.x1, + extents.y1, extents.x2 - extents.x1, + extents.y2 - extents.y1); pScreen->SourceValidate = SourceValidate; free_dst: @@ -981,9 +981,9 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, ValidateGC(pDraw, gc); (*gc->ops->CopyArea)(&src_pix->drawable, pDraw, gc, - xf86_crtc->x + extents->x1, xf86_crtc->y + extents->y1, - extents->x2 - extents->x1, extents->y2 - extents->y1, - extents->x1, extents->y1); + xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1, + extents.x2 - extents.x1, extents.y2 - extents.y1, + extents.x1, extents.y1); FreeScratchGC(gc); } @@ -1015,7 +1015,7 @@ radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, drmmode_crtc->dpms_mode == DPMSModeOn) { if (radeon_scanout_do_update(crtc, drmmode_crtc->scanout_id, screen->GetWindowPixmap(screen->root), - ®ion->extents)) + region->extents)) RegionEmpty(region); } @@ -1096,7 +1096,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, scanout_id = drmmode_crtc->scanout_id ^ 1; if (!radeon_scanout_do_update(xf86_crtc, scanout_id, pScreen->GetWindowPixmap(pScreen->root), - ®ion->extents)) + region->extents)) return; RegionEmpty(region); -- cgit v1.2.3 From fdba5373522c008f43e9ca5a9e76e35c6e7ad73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 15 Mar 2018 17:19:59 +0100 Subject: Bump version for 18.0.1 release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4d7d7ae9..11efdf0a 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [18.0.0], + [18.0.1], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) -- cgit v1.2.3 From 3dcfce8d0f495d09d7836caf98ef30d625b78a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 17 May 2018 09:50:50 +0200 Subject: Bail from dri2_create_buffer2 if we can't get a pixmap We would store the NULL pointer and continue, which would lead to a crash down the road. Bugzilla: https://bugs.freedesktop.org/106293 Reviewed-by: Alex Deucher --- src/radeon_dri2.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 9f373589..3b75f66f 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -233,37 +233,36 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen, flags | RADEON_CREATE_PIXMAP_DRI2); } + if (!pixmap) + return NULL; + buffers = calloc(1, sizeof *buffers); if (buffers == NULL) goto error; - if (pixmap) { - if (!info->use_glamor) { - info->exa_force_create = TRUE; - exaMoveInPixmap(pixmap); - info->exa_force_create = FALSE; - if (exaGetPixmapDriverPrivate(pixmap) == NULL) { - /* this happen if pixmap is non accelerable */ - goto error; - } - } else if (is_glamor_pixmap) { - pixmap = radeon_glamor_set_pixmap_bo(drawable, pixmap); - pixmap->refcnt++; - } - - if (!radeon_get_flink_name(pRADEONEnt, pixmap, &buffers->name)) + if (!info->use_glamor) { + info->exa_force_create = TRUE; + exaMoveInPixmap(pixmap); + info->exa_force_create = FALSE; + if (exaGetPixmapDriverPrivate(pixmap) == NULL) { + /* this happen if pixmap is non accelerable */ goto error; + } + } else if (is_glamor_pixmap) { + pixmap = radeon_glamor_set_pixmap_bo(drawable, pixmap); + pixmap->refcnt++; } + if (!radeon_get_flink_name(pRADEONEnt, pixmap, &buffers->name)) + goto error; + privates = calloc(1, sizeof(struct dri2_buffer_priv)); if (privates == NULL) goto error; buffers->attachment = attachment; - if (pixmap) { - buffers->pitch = pixmap->devKind; - buffers->cpp = cpp; - } + buffers->pitch = pixmap->devKind; + buffers->cpp = cpp; buffers->driverPrivate = privates; buffers->format = format; buffers->flags = 0; /* not tiled */ @@ -275,8 +274,7 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen, error: free(buffers); - if (pixmap) - (*pScreen->DestroyPixmap)(pixmap); + (*pScreen->DestroyPixmap)(pixmap); return NULL; } -- cgit v1.2.3 From 65c9dfea4e841b7d6f795c7489fede58c5e9631f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 15 May 2018 18:59:30 +0200 Subject: glamor: Bail CreatePixmap on unsupported pixmap depth Fixes crash in that case. Bugzilla: https://bugs.freedesktop.org/106293 Reviewed-by: Alex Deucher --- src/radeon_glamor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index 7c09abba..10d513ea 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -214,6 +214,9 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, struct radeon_pixmap *priv; PixmapPtr pixmap, new_pixmap = NULL; + if (!xf86GetPixFormat(scrn, depth)) + return NULL; + if (!RADEON_CREATE_PIXMAP_SHARED(usage)) { if (info->shadow_primary) { if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) -- cgit v1.2.3 From 25836375e0aab17a2e6bd91acb1c19b837ae2109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 17 May 2018 18:18:42 +0200 Subject: Drop unused drmmode_create_bo_pixmap surface parameter Reviewed-by: Alex Deucher --- src/drmmode_display.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index f056bf3b..958532fb 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -111,7 +111,7 @@ 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) + struct radeon_bo *bo) { RADEONInfoPtr info = RADEONPTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; @@ -137,9 +137,7 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, if (info->ChipFamily >= CHIP_FAMILY_R600) { surface = radeon_get_pixmap_surface(pixmap); - if (surface && psurf) - *surface = *psurf; - else if (surface) { + if (surface) { memset(surface, 0, sizeof(struct radeon_surface)); surface->npix_x = width; surface->npix_y = height; @@ -444,7 +442,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); + bo); info->fbcon_pixmap = pixmap; radeon_bo_unref(bo); out_free_fb: @@ -581,7 +579,7 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, width, height, pScrn->depth, pScrn->bitsPerPixel, - pitch, scanout->bo, NULL); + pitch, scanout->bo); if (!scanout->pixmap) { ErrorF("failed to create CRTC scanout pixmap\n"); goto error; -- cgit v1.2.3 From ac18a993a3a68629805b8f272a339e25444c0897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 23 May 2018 12:18:36 +0200 Subject: EXA: Remove old RADEONEXACreatePixmap hook Not used by any supported version of xserver. Reviewed-by: Alex Deucher --- src/evergreen_exa.c | 1 - src/evergreen_state.h | 1 - src/r600_exa.c | 1 - src/r600_state.h | 1 - src/radeon_exa.c | 29 ----------------------------- src/radeon_exa_funcs.c | 1 - 6 files changed, 34 deletions(-) diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c index 85848133..41edd345 100644 --- a/src/evergreen_exa.c +++ b/src/evergreen_exa.c @@ -2065,7 +2065,6 @@ EVERGREENDrawInit(ScreenPtr pScreen) info->accel_state->exa->MarkSync = EVERGREENMarkSync; info->accel_state->exa->WaitMarker = EVERGREENSync; - info->accel_state->exa->CreatePixmap = RADEONEXACreatePixmap; info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap; info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen; info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS; diff --git a/src/evergreen_state.h b/src/evergreen_state.h index 795d4472..ef331002 100644 --- a/src/evergreen_state.h +++ b/src/evergreen_state.h @@ -345,7 +345,6 @@ R600SetAccelState(ScrnInfoPtr pScrn, extern Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index); extern void RADEONFinishAccess_CS(PixmapPtr pPix, int index); -extern void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align); extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch); diff --git a/src/r600_exa.c b/src/r600_exa.c index c69b8fce..a111dd45 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -2044,7 +2044,6 @@ R600DrawInit(ScreenPtr pScreen) info->accel_state->exa->MarkSync = R600MarkSync; info->accel_state->exa->WaitMarker = R600Sync; - info->accel_state->exa->CreatePixmap = RADEONEXACreatePixmap; info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap; info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen; info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS; diff --git a/src/r600_state.h b/src/r600_state.h index fda297d3..4898e8de 100644 --- a/src/r600_state.h +++ b/src/r600_state.h @@ -316,7 +316,6 @@ R600SetAccelState(ScrnInfoPtr pScrn, extern Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index); extern void RADEONFinishAccess_CS(PixmapPtr pPix, int index); -extern void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align); extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch); diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 9106d5c6..ef60bc0c 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -235,35 +235,6 @@ void RADEONFinishAccess_CS(PixmapPtr pPix, int index) } -void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align) -{ - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - RADEONInfoPtr info = RADEONPTR(pScrn); - struct radeon_exa_pixmap_priv *new_priv; - - if (size != 0 && !info->exa_force_create && - info->exa_pixmaps == FALSE) - return NULL; - - new_priv = calloc(1, sizeof(struct radeon_exa_pixmap_priv)); - if (!new_priv) - return NULL; - - if (size == 0) - return new_priv; - - new_priv->bo = radeon_bo_open(info->bufmgr, 0, size, align, - RADEON_GEM_DOMAIN_VRAM, 0); - if (!new_priv->bo) { - free(new_priv); - ErrorF("Failed to alloc memory\n"); - return NULL; - } - - return new_priv; - -} - void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch) diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index da0524ed..add89458 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -638,7 +638,6 @@ Bool RADEONDrawInit(ScreenPtr pScreen) } #endif - info->accel_state->exa->CreatePixmap = RADEONEXACreatePixmap; info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap; info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen; info->accel_state->exa->PrepareAccess = RADEONPrepareAccess_CS; -- cgit v1.2.3 From eec4a41925127ae490f0a5156a881a08d521e28e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 17 May 2018 18:25:37 +0200 Subject: Only initialize libdrm_radeon surface manager for >= R600 Not used with older GPUs. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 5 +++-- src/radeon_bo_helper.c | 7 ++++--- src/radeon_kms.c | 18 +++++++++++------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 958532fb..f99667fb 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -135,7 +135,7 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, if (!radeon_set_pixmap_bo(pixmap, bo)) goto fail; - if (info->ChipFamily >= CHIP_FAMILY_R600) { + if (info->surf_man) { surface = radeon_get_pixmap_surface(pixmap); if (surface) { memset(surface, 0, sizeof(struct radeon_surface)); @@ -2301,7 +2301,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) aligned_height = RADEON_ALIGN(height, drmmode_get_height_align(scrn, tiling_flags)); screen_size = RADEON_ALIGN(pitch * aligned_height, RADEON_GPU_PAGE_SIZE); base_align = 4096; - if (info->ChipFamily >= CHIP_FAMILY_R600) { + + if (info->surf_man) { memset(&surface, 0, sizeof(struct radeon_surface)); surface.npix_x = width; surface.npix_y = height; diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index 0366f613..8245d624 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -107,9 +107,10 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, cpp, tiling)) * cpp; base_align = drmmode_get_base_align(pScrn, cpp, tiling); size = RADEON_ALIGN(heighta * pitch, RADEON_GPU_PAGE_SIZE); - memset(&surface, 0, sizeof(struct radeon_surface)); - if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) { + if (info->surf_man) { + memset(&surface, 0, sizeof(struct radeon_surface)); + if (width) { surface.npix_x = width; /* need to align height to 8 for old kernel */ @@ -340,7 +341,7 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle, if (!ret) goto error; - if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) { + if (info->surf_man) { uint32_t tiling_flags; #ifdef USE_GLAMOR diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 26810e08..861fbf97 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2228,7 +2228,16 @@ Bool RADEONScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv) if (info->r600_shadow_fb == FALSE) info->directRenderingEnabled = radeon_dri2_screen_init(pScreen); - info->surf_man = radeon_surface_manager_new(pRADEONEnt->fd); + if (info->ChipFamily >= CHIP_FAMILY_R600) { + info->surf_man = radeon_surface_manager_new(pRADEONEnt->fd); + + if (!info->surf_man) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "Failed to initialize surface manager\n"); + return FALSE; + } + } + if (!info->bufmgr) info->bufmgr = radeon_bo_manager_gem_ctor(pRADEONEnt->fd); if (!info->bufmgr) { @@ -2694,12 +2703,7 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) pitch = RADEON_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp; screen_size = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)) * pitch; base_align = drmmode_get_base_align(pScrn, cpp, tiling_flags); - if (info->ChipFamily >= CHIP_FAMILY_R600) { - if(!info->surf_man) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "failed to initialise surface manager\n"); - return FALSE; - } + if (info->surf_man) { memset(&surface, 0, sizeof(struct radeon_surface)); surface.npix_x = pScrn->virtualX; surface.npix_y = pScrn->virtualY; -- cgit v1.2.3 From ba5d5402b3e2e807d7e47205ac83f930b6c8caf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 17 May 2018 12:36:29 +0200 Subject: glamor: Don't store radeon_surfaces in pixmaps Only EXA needs them. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 77 +++++++++++++++++++++++++------------------------- src/radeon.h | 19 ++----------- src/radeon_bo_helper.c | 22 ++++++--------- src/radeon_glamor.c | 8 ++---- src/radeon_kms.c | 11 ++++---- 5 files changed, 55 insertions(+), 82 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index f99667fb..8dc776fa 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -116,7 +116,6 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, RADEONInfoPtr info = RADEONPTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; PixmapPtr pixmap; - struct radeon_surface *surface; uint32_t tiling; pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, @@ -135,41 +134,41 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, if (!radeon_set_pixmap_bo(pixmap, bo)) goto fail; - if (info->surf_man) { - surface = radeon_get_pixmap_surface(pixmap); - if (surface) { - memset(surface, 0, sizeof(struct radeon_surface)); - surface->npix_x = width; - surface->npix_y = height; - surface->npix_z = 1; - surface->blk_w = 1; - surface->blk_h = 1; - surface->blk_d = 1; - surface->array_size = 1; - surface->last_level = 0; - surface->bpe = bpp / 8; - surface->nsamples = 1; - surface->flags = RADEON_SURF_SCANOUT; - /* we are requiring a recent enough libdrm version */ - surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); - surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); - tiling = radeon_get_pixmap_tiling_flags(pixmap); - if (tiling & RADEON_TILING_MICRO) { - surface->flags = RADEON_SURF_CLR(surface->flags, MODE); - surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); - } - if (tiling & RADEON_TILING_MACRO) { - surface->flags = RADEON_SURF_CLR(surface->flags, MODE); - surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); - } - if (radeon_surface_best(info->surf_man, surface)) { - goto fail; - } - if (radeon_surface_init(info->surf_man, surface)) { - goto fail; - } + if (info->surf_man && !info->use_glamor) { + struct radeon_surface *surface = radeon_get_pixmap_surface(pixmap); + + memset(surface, 0, sizeof(struct radeon_surface)); + surface->npix_x = width; + surface->npix_y = height; + surface->npix_z = 1; + surface->blk_w = 1; + surface->blk_h = 1; + surface->blk_d = 1; + surface->array_size = 1; + surface->last_level = 0; + surface->bpe = bpp / 8; + surface->nsamples = 1; + surface->flags = RADEON_SURF_SCANOUT; + /* we are requiring a recent enough libdrm version */ + surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; + surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); + tiling = radeon_get_pixmap_tiling_flags(pixmap); + + if (tiling & RADEON_TILING_MICRO) { + surface->flags = RADEON_SURF_CLR(surface->flags, MODE); + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); } + if (tiling & RADEON_TILING_MACRO) { + surface->flags = RADEON_SURF_CLR(surface->flags, MODE); + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); + } + + if (radeon_surface_best(info->surf_man, surface)) + goto fail; + + if (radeon_surface_init(info->surf_man, surface)) + goto fail; } if (!info->use_glamor || @@ -2272,7 +2271,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) int cpp = info->pixel_bytes; struct radeon_bo *front_bo; struct radeon_surface surface; - struct radeon_surface *psurface; uint32_t tiling_flags = 0, base_align; PixmapPtr ppix = screen->GetScreenPixmap(screen); void *fb_shadow; @@ -2353,7 +2351,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) default: break; } - info->front_surface = surface; + if (!info->use_glamor) + info->front_surface = surface; } xf86DrvMsg(scrn->scrnIndex, X_INFO, @@ -2394,8 +2393,8 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) radeon_bo_set_tiling(info->front_bo, tiling_flags, pitch); if (!info->r600_shadow_fb) { - psurface = radeon_get_pixmap_surface(ppix); - *psurface = info->front_surface; + if (info->surf_man && !info->use_glamor) + *radeon_get_pixmap_surface(ppix) = info->front_surface; screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch, NULL); } else { diff --git a/src/radeon.h b/src/radeon.h index 598a83c1..63b6cf1f 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -304,8 +304,6 @@ radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap) #ifdef USE_GLAMOR struct radeon_pixmap { - struct radeon_surface surface; - uint_fast32_t gpu_read; uint_fast32_t gpu_write; @@ -703,22 +701,9 @@ extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn); static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix) { -#ifdef USE_GLAMOR - RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen)); - - if (info->use_glamor) { - struct radeon_pixmap *priv; - priv = radeon_get_pixmap_private(pPix); - return priv ? &priv->surface : NULL; - } else -#endif - { - struct radeon_exa_pixmap_priv *driver_priv; - driver_priv = exaGetPixmapDriverPrivate(pPix); - return &driver_priv->surface; - } + struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix); - return NULL; + return &driver_priv->surface; } uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix); diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index 8245d624..be879aad 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -174,6 +174,9 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, break; } } + + if (new_surface) + *new_surface = surface; } if (tiling) @@ -185,7 +188,6 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, if (bo && tiling && radeon_bo_set_tiling(bo, tiling, pitch) == 0) *new_tiling = tiling; - *new_surface = surface; *new_pitch = pitch; return bo; } @@ -335,26 +337,18 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle, if (!bo) goto error; - memset(surface, 0, sizeof(struct radeon_surface)); - ret = radeon_set_pixmap_bo(ppix, bo); if (!ret) goto error; - if (info->surf_man) { + if (surface) { + struct radeon_exa_pixmap_priv *driver_priv; uint32_t tiling_flags; -#ifdef USE_GLAMOR - if (info->use_glamor) { - tiling_flags = radeon_get_pixmap_private(ppix)->tiling_flags; - } else -#endif - { - struct radeon_exa_pixmap_priv *driver_priv; + driver_priv = exaGetPixmapDriverPrivate(ppix); + tiling_flags = driver_priv->tiling_flags; - driver_priv = exaGetPixmapDriverPrivate(ppix); - tiling_flags = driver_priv->tiling_flags; - } + memset(surface, 0, sizeof(struct radeon_surface)); surface->npix_x = ppix->drawable.width; surface->npix_y = ppix->drawable.height; diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index 10d513ea..6cff72e1 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -250,8 +250,7 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, priv->bo = radeon_alloc_pixmap_bo(scrn, w, h, depth, usage, pixmap->drawable.bitsPerPixel, - &stride, - &priv->surface, + &stride, NULL, &priv->tiling_flags); if (!priv->bo) goto fallback_priv; @@ -391,15 +390,12 @@ radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct radeon_surface surface; struct radeon_pixmap *priv; - if (!radeon_set_shared_pixmap_backing(pixmap, handle, &surface)) + if (!radeon_set_shared_pixmap_backing(pixmap, handle, NULL)) return FALSE; priv = radeon_get_pixmap_private(pixmap); - priv->surface = surface; - if (!radeon_glamor_create_textured_pixmap(pixmap, priv)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to get PRIME drawable for glamor pixmap.\n"); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 861fbf97..0066c4e9 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -326,7 +326,6 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(pScrn); PixmapPtr pixmap; - struct radeon_surface *surface; pScreen->CreateScreenResources = info->CreateScreenResources; if (!(*pScreen->CreateScreenResources)(pScreen)) @@ -364,10 +363,9 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); if (!radeon_set_pixmap_bo(pPix, info->front_bo)) return FALSE; - surface = radeon_get_pixmap_surface(pPix); - if (surface) { - *surface = info->front_surface; - } + + if (info->surf_man && !info->use_glamor) + *radeon_get_pixmap_surface(pPix) = info->front_surface; } } @@ -2758,7 +2756,8 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) default: break; } - info->front_surface = surface; + if (!info->use_glamor) + info->front_surface = surface; } { int cursor_size; -- cgit v1.2.3 From 5da2bf43e64f2d702fe05016263f617c10f8f134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 May 2018 18:35:32 +0200 Subject: Factor out radeon_surface_initialize helper Reviewed-by: Alex Deucher --- src/drmmode_display.c | 66 ++------------ src/radeon.h | 5 ++ src/radeon_bo_helper.c | 231 +++++++++++++++++++++++++------------------------ src/radeon_kms.c | 35 +------- 4 files changed, 131 insertions(+), 206 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 8dc776fa..c7bec59c 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -116,7 +116,6 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, RADEONInfoPtr info = RADEONPTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; PixmapPtr pixmap; - uint32_t tiling; pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, RADEON_CREATE_PIXMAP_SCANOUT); @@ -137,37 +136,8 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, if (info->surf_man && !info->use_glamor) { struct radeon_surface *surface = radeon_get_pixmap_surface(pixmap); - memset(surface, 0, sizeof(struct radeon_surface)); - surface->npix_x = width; - surface->npix_y = height; - surface->npix_z = 1; - surface->blk_w = 1; - surface->blk_h = 1; - surface->blk_d = 1; - surface->array_size = 1; - surface->last_level = 0; - surface->bpe = bpp / 8; - surface->nsamples = 1; - surface->flags = RADEON_SURF_SCANOUT; - /* we are requiring a recent enough libdrm version */ - surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); - surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); - tiling = radeon_get_pixmap_tiling_flags(pixmap); - - if (tiling & RADEON_TILING_MICRO) { - surface->flags = RADEON_SURF_CLR(surface->flags, MODE); - surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); - } - if (tiling & RADEON_TILING_MACRO) { - surface->flags = RADEON_SURF_CLR(surface->flags, MODE); - surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); - } - - if (radeon_surface_best(info->surf_man, surface)) - goto fail; - - if (radeon_surface_init(info->surf_man, surface)) + if (!radeon_surface_initialize(info, surface, width, height, bpp / 8, + radeon_get_pixmap_tiling_flags(pixmap), 0)) goto fail; } @@ -2301,36 +2271,10 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) base_align = 4096; if (info->surf_man) { - memset(&surface, 0, sizeof(struct radeon_surface)); - surface.npix_x = width; - surface.npix_y = height; - surface.npix_z = 1; - surface.blk_w = 1; - surface.blk_h = 1; - surface.blk_d = 1; - surface.array_size = 1; - surface.last_level = 0; - surface.bpe = cpp; - surface.nsamples = 1; - surface.flags = RADEON_SURF_SCANOUT; - /* we are requiring a recent enough libdrm version */ - surface.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; - surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); - surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); - if (tiling_flags & RADEON_TILING_MICRO) { - surface.flags = RADEON_SURF_CLR(surface.flags, MODE); - surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); - } - if (tiling_flags & RADEON_TILING_MACRO) { - surface.flags = RADEON_SURF_CLR(surface.flags, MODE); - surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); - } - if (radeon_surface_best(info->surf_man, &surface)) { - return FALSE; - } - if (radeon_surface_init(info->surf_man, &surface)) { + if (!radeon_surface_initialize(info, &surface, width, height, + cpp, tiling_flags, 0)) return FALSE; - } + screen_size = surface.bo_size; base_align = surface.bo_alignment; pitch = surface.level[0].pitch_bytes; diff --git a/src/radeon.h b/src/radeon.h index 63b6cf1f..c2ae6606 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -643,6 +643,11 @@ extern void RADEONInit3DEngine(ScrnInfoPtr pScrn); extern int radeon_cs_space_remaining(ScrnInfoPtr pScrn); /* radeon_bo_helper.c */ +extern Bool +radeon_surface_initialize(RADEONInfoPtr info, struct radeon_surface *surface, + int width, int height, int cpp, uint32_t tiling_flags, + int usage_hint); + extern Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle); /* radeon_commonfuncs.c */ diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index be879aad..37658942 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -59,6 +59,89 @@ static Bool RADEONMacroSwitch(int width, int height, int bpp, } } +static unsigned eg_tile_split_opp(unsigned tile_split) +{ + switch (tile_split) { + case 0: tile_split = 64; break; + case 1: tile_split = 128; break; + case 2: tile_split = 256; break; + case 3: tile_split = 512; break; + default: + case 4: tile_split = 1024; break; + case 5: tile_split = 2048; break; + case 6: tile_split = 4096; break; + } + return tile_split; +} + +Bool +radeon_surface_initialize(RADEONInfoPtr info, struct radeon_surface *surface, + int width, int height, int cpp, uint32_t tiling_flags, + int usage_hint) +{ + memset(surface, 0, sizeof(struct radeon_surface)); + + surface->npix_x = width; + /* need to align height to 8 for old kernel */ + surface->npix_y = RADEON_ALIGN(height, 8); + surface->npix_z = 1; + surface->blk_w = 1; + surface->blk_h = 1; + surface->blk_d = 1; + surface->array_size = 1; + surface->last_level = 0; + surface->bpe = cpp; + surface->nsamples = 1; + if (height < 128) { + /* disable 2d tiling for small surface to work around + * the fact that ddx align height to 8 pixel for old + * obscure reason i can't remember + */ + tiling_flags &= ~RADEON_TILING_MACRO; + } + + surface->flags = RADEON_SURF_SCANOUT | RADEON_SURF_HAS_TILE_MODE_INDEX | + RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); + + if (usage_hint & RADEON_CREATE_PIXMAP_SZBUFFER) { + surface->flags |= RADEON_SURF_ZBUFFER; + surface->flags |= RADEON_SURF_SBUFFER; + } + + if ((tiling_flags & RADEON_TILING_MACRO)) { + surface->flags = RADEON_SURF_CLR(surface->flags, MODE); + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); + } else if ((tiling_flags & RADEON_TILING_MICRO)) { + surface->flags = RADEON_SURF_CLR(surface->flags, MODE); + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); + } else + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE); + + if (info->ChipFamily >= CHIP_FAMILY_CEDAR) { + surface->bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & + RADEON_TILING_EG_BANKW_MASK; + surface->bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & + RADEON_TILING_EG_BANKH_MASK; + surface->tile_split = eg_tile_split_opp((tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & + RADEON_TILING_EG_TILE_SPLIT_MASK); + if (surface->flags & RADEON_SURF_SBUFFER) { + surface->stencil_tile_split = + (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & + RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK; + } + surface->mtilea = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & + RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK; + } + + if (radeon_surface_best(info->surf_man, surface)) + return FALSE; + + if (radeon_surface_init(info->surf_man, surface)) + return FALSE; + + return TRUE; +} + /* Calculate appropriate tiling and pitch for a pixmap and allocate a BO that * can hold it. */ @@ -108,77 +191,37 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, base_align = drmmode_get_base_align(pScrn, cpp, tiling); size = RADEON_ALIGN(heighta * pitch, RADEON_GPU_PAGE_SIZE); - if (info->surf_man) { - memset(&surface, 0, sizeof(struct radeon_surface)); - - if (width) { - surface.npix_x = width; - /* need to align height to 8 for old kernel */ - surface.npix_y = RADEON_ALIGN(height, 8); - surface.npix_z = 1; - surface.blk_w = 1; - surface.blk_h = 1; - surface.blk_d = 1; - surface.array_size = 1; - surface.last_level = 0; - surface.bpe = cpp; - surface.nsamples = 1; - if (height < 128) { - /* disable 2d tiling for small surface to work around - * the fact that ddx align height to 8 pixel for old - * obscure reason i can't remember - */ - tiling &= ~RADEON_TILING_MACRO; - } - surface.flags = RADEON_SURF_SCANOUT; - /* we are requiring a recent enough libdrm version */ - surface.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; - surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); - surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE); - if ((tiling & RADEON_TILING_MICRO)) { - surface.flags = RADEON_SURF_CLR(surface.flags, MODE); - surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); - } - if ((tiling & RADEON_TILING_MACRO)) { - surface.flags = RADEON_SURF_CLR(surface.flags, MODE); - surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); - } - if (usage_hint & RADEON_CREATE_PIXMAP_SZBUFFER) { - surface.flags |= RADEON_SURF_ZBUFFER; - surface.flags |= RADEON_SURF_SBUFFER; - } - if (radeon_surface_best(info->surf_man, &surface)) { - return NULL; - } - if (radeon_surface_init(info->surf_man, &surface)) { - return NULL; - } - size = surface.bo_size; - base_align = surface.bo_alignment; - pitch = surface.level[0].pitch_bytes; - tiling = 0; - switch (surface.level[0].mode) { - case RADEON_SURF_MODE_2D: - tiling |= RADEON_TILING_MACRO; - tiling |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT; - tiling |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT; - tiling |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT; - if (surface.tile_split) - tiling |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT; - tiling |= eg_tile_split(surface.stencil_tile_split) << RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT; - break; - case RADEON_SURF_MODE_1D: - tiling |= RADEON_TILING_MICRO; - break; - default: - break; - } - } - - if (new_surface) - *new_surface = surface; + if (width && info->surf_man) { + if (!radeon_surface_initialize(info, &surface, width, height, cpp, + tiling, usage_hint)) + return NULL; + + size = surface.bo_size; + base_align = surface.bo_alignment; + pitch = surface.level[0].pitch_bytes; + tiling = 0; + switch (surface.level[0].mode) { + case RADEON_SURF_MODE_2D: + tiling |= RADEON_TILING_MACRO; + tiling |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT; + tiling |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT; + tiling |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT; + if (surface.tile_split) + tiling |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT; + if (surface.flags & RADEON_SURF_SBUFFER) + tiling |= eg_tile_split(surface.stencil_tile_split) << RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT; + break; + case RADEON_SURF_MODE_1D: + tiling |= RADEON_TILING_MICRO; + break; + default: + break; } + if (new_surface) + *new_surface = surface; + } + if (tiling) flags |= RADEON_GEM_NO_CPU_ACCESS; @@ -308,21 +351,6 @@ Bool radeon_share_pixmap_backing(struct radeon_bo *bo, void **handle_p) return TRUE; } -static unsigned eg_tile_split_opp(unsigned tile_split) -{ - switch (tile_split) { - case 0: tile_split = 64; break; - case 1: tile_split = 128; break; - case 2: tile_split = 256; break; - case 3: tile_split = 512; break; - default: - case 4: tile_split = 1024; break; - case 5: tile_split = 2048; break; - case 6: tile_split = 4096; break; - } - return tile_split; -} - Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle, struct radeon_surface *surface) { @@ -348,39 +376,14 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle, driver_priv = exaGetPixmapDriverPrivate(ppix); tiling_flags = driver_priv->tiling_flags; - memset(surface, 0, sizeof(struct radeon_surface)); - - surface->npix_x = ppix->drawable.width; - surface->npix_y = ppix->drawable.height; - surface->npix_z = 1; - surface->blk_w = 1; - surface->blk_h = 1; - surface->blk_d = 1; - surface->array_size = 1; - surface->bpe = ppix->drawable.bitsPerPixel / 8; - surface->nsamples = 1; - /* we are requiring a recent enough libdrm version */ - surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; - surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); - if (tiling_flags & RADEON_TILING_MACRO) - surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); - else if (tiling_flags & RADEON_TILING_MICRO) - surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); - else - surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); - surface->bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK; - surface->bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK; - surface->tile_split = eg_tile_split_opp((tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK); - surface->stencil_tile_split = (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK; - surface->mtilea = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK; - if (radeon_surface_best(info->surf_man, surface)) { - ret = FALSE; - goto error; - } - if (radeon_surface_init(info->surf_man, surface)) { + if (!radeon_surface_initialize(info, surface, ppix->drawable.width, + ppix->drawable.height, + ppix->drawable.bitsPerPixel / 8, + tiling_flags, 0)) { ret = FALSE; goto error; } + /* we have to post hack the surface to reflect the actual size of the shared pixmap */ surface->level[0].pitch_bytes = ppix->devKind; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 0066c4e9..7ff66bf3 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2702,38 +2702,11 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) screen_size = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)) * pitch; base_align = drmmode_get_base_align(pScrn, cpp, tiling_flags); if (info->surf_man) { - memset(&surface, 0, sizeof(struct radeon_surface)); - surface.npix_x = pScrn->virtualX; - surface.npix_y = pScrn->virtualY; - surface.npix_z = 1; - surface.blk_w = 1; - surface.blk_h = 1; - surface.blk_d = 1; - surface.array_size = 1; - surface.last_level = 0; - surface.bpe = cpp; - surface.nsamples = 1; - surface.flags = RADEON_SURF_SCANOUT; - /* we are requiring a recent enough libdrm version */ - surface.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; - surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); - surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); - if (tiling_flags & RADEON_TILING_MICRO) { - surface.flags = RADEON_SURF_CLR(surface.flags, MODE); - surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); - } - if (tiling_flags & RADEON_TILING_MACRO) { - surface.flags = RADEON_SURF_CLR(surface.flags, MODE); - surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); - } - if (radeon_surface_best(info->surf_man, &surface)) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "radeon_surface_best failed\n"); - return FALSE; - } - if (radeon_surface_init(info->surf_man, &surface)) { + if (!radeon_surface_initialize(info, &surface, pScrn->virtualX, + pScrn->virtualY, cpp, + tiling_flags, 0)) { xf86DrvMsg(pScreen->myNum, X_ERROR, - "radeon_surface_init failed\n"); + "radeon_surface_initialize failed\n"); return FALSE; } pitch = surface.level[0].pitch_bytes; -- cgit v1.2.3 From 90b94d40449f665f2d12874598062a5e5e5b64cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 15 Jun 2018 18:27:46 +0200 Subject: Move flush from radeon_scanout_do_update to its callers No functional change intended. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 2 ++ src/radeon_kms.c | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index c7bec59c..54b09730 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -785,6 +785,7 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, radeon_scanout_do_update(crtc, scanout_id, screen->GetWindowPixmap(screen->root), *box); + radeon_cs_flush_indirect(scrn); radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo); } } @@ -3225,6 +3226,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, radeon_scanout_do_update(crtc, scanout_id, new_front, extents); + radeon_cs_flush_indirect(crtc->scrn); drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, drmmode_crtc->scanout_update_pending); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 7ff66bf3..8579aaf8 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -985,8 +985,6 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id, FreeScratchGC(gc); } - radeon_cs_flush_indirect(scrn); - info->accel_state->force = force; return TRUE; @@ -1013,8 +1011,10 @@ radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, drmmode_crtc->dpms_mode == DPMSModeOn) { if (radeon_scanout_do_update(crtc, drmmode_crtc->scanout_id, screen->GetWindowPixmap(screen->root), - region->extents)) + region->extents)) { + radeon_cs_flush_indirect(crtc->scrn); RegionEmpty(region); + } } radeon_scanout_update_abort(crtc, event_data); @@ -1096,6 +1096,8 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, pScreen->GetWindowPixmap(pScreen->root), region->extents)) return; + + radeon_cs_flush_indirect(scrn); RegionEmpty(region); drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, -- cgit v1.2.3 From 6c986e997159ad0086f940294b244fc4c30b61fc Mon Sep 17 00:00:00 2001 From: Jammy Zhou Date: Fri, 15 Jun 2018 18:41:34 +0200 Subject: Remove throttling from radeon_dri2_copy_region2 Throttling should be handled by the client-side drivers. Signed-off-by: Jammy Zhou (Ported from amdgpu commit 8a34a8149860ac15e83ccdbd8d9a527d8d3e5997) Reviewed-by: Alex Deucher --- src/radeon_dri2.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 3b75f66f..6f469127 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -336,9 +336,7 @@ radeon_dri2_copy_region2(ScreenPtr pScreen, Bool vsync; Bool translate = FALSE; int off_x = 0, off_y = 0; - PixmapPtr dst_ppix; - dst_ppix = dst_private->pixmap; src_drawable = &src_private->pixmap->drawable; dst_drawable = &dst_private->pixmap->drawable; @@ -355,7 +353,6 @@ radeon_dri2_copy_region2(ScreenPtr pScreen, dst_drawable = DRI2UpdatePrime(drawable, dest_buffer); if (!dst_drawable) return; - dst_ppix = (PixmapPtr)dst_drawable; if (dst_drawable != drawable) translate = TRUE; } else @@ -379,26 +376,7 @@ radeon_dri2_copy_region2(ScreenPtr pScreen, (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0); ValidateGC(dst_drawable, gc); - /* If this is a full buffer swap or frontbuffer flush, throttle on the - * previous one - */ - if (dst_private->attachment == DRI2BufferFrontLeft) { - if (REGION_NUM_RECTS(region) == 1) { - BoxPtr extents = REGION_EXTENTS(pScreen, region); - - if (extents->x1 == 0 && extents->y1 == 0 && - extents->x2 == drawable->width && - extents->y2 == drawable->height) { - struct radeon_bo *bo = radeon_get_pixmap_bo(dst_ppix); - - if (bo) - radeon_bo_wait(bo); - } - } - } - vsync = info->accel_state->vsync; - /* Driver option "SwapbuffersWait" defines if we vsync DRI2 copy-swaps. */ info->accel_state->vsync = info->swapBuffersWait; info->accel_state->force = TRUE; -- cgit v1.2.3 From 37ba075b34130c41bb7a2261bd666af5b29ffaf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 15 Jun 2018 18:23:53 +0200 Subject: Refactor radeon_finish helper Reviewed-by: Alex Deucher --- src/drmmode_display.c | 16 +++------------- src/radeon.h | 1 + src/radeon_bo_helper.c | 10 ++++++++++ src/radeon_bo_helper.h | 3 +++ src/radeon_glamor_wrappers.c | 21 ++++++++++----------- src/radeon_kms.c | 6 ++---- src/radeon_present.c | 4 +--- 7 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 54b09730..3c4d94fd 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -726,8 +726,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, gc, 0, 0, mode->HDisplay, mode->VDisplay, 0, 0); FreeScratchGC(gc); - radeon_cs_flush_indirect(scrn); - radeon_bo_wait(drmmode_crtc->scanout[0].bo); + radeon_finish(scrn, drmmode_crtc->scanout[0].bo); } } @@ -785,8 +784,7 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, radeon_scanout_do_update(crtc, scanout_id, screen->GetWindowPixmap(screen->root), *box); - radeon_cs_flush_indirect(scrn); - radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo); + radeon_finish(scrn, drmmode_crtc->scanout[scanout_id].bo); } } @@ -2240,7 +2238,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) int aligned_height; uint32_t screen_size; int cpp = info->pixel_bytes; - struct radeon_bo *front_bo; struct radeon_surface surface; uint32_t tiling_flags = 0, base_align; PixmapPtr ppix = screen->GetScreenPixmap(screen); @@ -2249,12 +2246,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) if (scrn->virtualX == width && scrn->virtualY == height) return TRUE; - front_bo = info->front_bo; - radeon_cs_flush_indirect(scrn); - - if (front_bo) - radeon_bo_wait(front_bo); - if (info->allowColorTiling && !info->shadow_primary) { if (info->ChipFamily >= CHIP_FAMILY_R600) { if (info->allowColorTiling2D) { @@ -2364,8 +2355,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) } radeon_pixmap_clear(ppix); - radeon_cs_flush_indirect(scrn); - radeon_bo_wait(info->front_bo); + radeon_finish(scrn, info->front_bo); for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; diff --git a/src/radeon.h b/src/radeon.h index c2ae6606..499e89f9 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -895,6 +895,7 @@ radeon_pixmap_get_fb(PixmapPtr pix) return *fb_ptr; } + #define CP_PACKET0(reg, n) \ (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) #define CP_PACKET1(reg0, reg1) \ diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index 37658942..7cfe9126 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -235,6 +235,16 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, return bo; } + +/* Flush and wait for the BO to become idle */ +void +radeon_finish(ScrnInfoPtr scrn, struct radeon_bo *bo) +{ + radeon_cs_flush_indirect(scrn); + radeon_bo_wait(bo); +} + + /* Clear the pixmap contents to black */ void radeon_pixmap_clear(PixmapPtr pixmap) diff --git a/src/radeon_bo_helper.h b/src/radeon_bo_helper.h index e1856adb..fa99201b 100644 --- a/src/radeon_bo_helper.h +++ b/src/radeon_bo_helper.h @@ -28,6 +28,9 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch, struct radeon_surface *new_surface, uint32_t *new_tiling); +extern void +radeon_finish(ScrnInfoPtr scrn, struct radeon_bo *bo); + extern void radeon_pixmap_clear(PixmapPtr pixmap); diff --git a/src/radeon_glamor_wrappers.c b/src/radeon_glamor_wrappers.c index d7374252..94700a7b 100644 --- a/src/radeon_glamor_wrappers.c +++ b/src/radeon_glamor_wrappers.c @@ -58,13 +58,13 @@ radeon_glamor_prepare_access_cpu(ScrnInfoPtr scrn, RADEONInfoPtr info, struct radeon_bo *bo = priv->bo; int ret; - /* When falling back to swrast, flush all pending operations */ - if (need_sync) { - glamor_block_handler(scrn->pScreen); - info->gpu_flushed++; - } - if (!pixmap->devPrivate.ptr) { + /* When falling back to swrast, flush all pending operations */ + if (need_sync) { + glamor_block_handler(scrn->pScreen); + info->gpu_flushed++; + } + ret = radeon_bo_map(bo, 1); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -76,11 +76,10 @@ radeon_glamor_prepare_access_cpu(ScrnInfoPtr scrn, RADEONInfoPtr info, } pixmap->devPrivate.ptr = bo->ptr; - info->gpu_synced = info->gpu_flushed; - } else if (need_sync) { - radeon_bo_wait(bo); - info->gpu_synced = info->gpu_flushed; - } + } else if (need_sync) + radeon_finish(scrn, bo); + + info->gpu_synced = info->gpu_flushed; return TRUE; } diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 8579aaf8..d4b59e81 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1681,8 +1681,7 @@ void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion pScreen->WindowExposures(pWin, pRegion); #endif - radeon_cs_flush_indirect(pScrn); - radeon_bo_wait(info->front_bo); + radeon_finish(pScrn, info->front_bo); drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE); } @@ -2585,8 +2584,7 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn) radeon_pixmap_get_fb(black_scanout.pixmap); radeon_pixmap_clear(black_scanout.pixmap); - radeon_cs_flush_indirect(pScrn); - radeon_bo_wait(black_scanout.bo); + radeon_finish(pScrn, black_scanout.bo); for (i = 0; i < xf86_config->num_crtc; i++) { crtc = xf86_config->crtc[i]; diff --git a/src/radeon_present.c b/src/radeon_present.c index d734b9d4..66805d7d 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -404,8 +404,6 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) FLIP_ASYNC : FLIP_VSYNC; int i; - radeon_cs_flush_indirect(scrn); - if (!radeon_present_check_unflip(scrn)) goto modeset; @@ -424,7 +422,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) return; modeset: - radeon_bo_wait(info->front_bo); + radeon_finish(scrn, info->front_bo); for (i = 0; i < config->num_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; -- cgit v1.2.3 From b85b7b11f5b5e792f21951b881bd8433d3d70858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 18 May 2018 18:49:35 +0200 Subject: Add struct radeon_buffer Inspired by amdgpu, preparation for the following change. For now, this is mostly a wrapper around struct radeon_bo, no functional change intended. Reviewed-by: Alex Deucher --- src/drmmode_display.c | 123 +++++++++++++----------------------- src/drmmode_display.h | 2 +- src/evergreen_exa.c | 40 ++++++------ src/evergreen_state.h | 1 - src/evergreen_textured_videofuncs.c | 2 +- src/r600_exa.c | 40 ++++++------ src/r600_state.h | 1 - src/r600_textured_videofuncs.c | 2 +- src/radeon.h | 31 +++++---- src/radeon_bo_helper.c | 34 ++++++---- src/radeon_bo_helper.h | 38 ++++++++++- src/radeon_dri2.c | 22 +++---- src/radeon_dri3.c | 4 +- src/radeon_exa.c | 17 +++-- src/radeon_exa_funcs.c | 43 +++++++------ src/radeon_exa_shared.c | 2 +- src/radeon_exa_shared.h | 3 +- src/radeon_glamor.c | 10 +-- src/radeon_glamor_wrappers.c | 6 +- src/radeon_kms.c | 104 +++++++++++------------------- src/radeon_present.c | 2 +- src/radeon_textured_videofuncs.c | 24 ++++--- 22 files changed, 267 insertions(+), 284 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 3c4d94fd..c91f5bb2 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -111,7 +111,7 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, int width, int height, int depth, int bpp, int pitch, - struct radeon_bo *bo) + struct radeon_buffer *bo) { RADEONInfoPtr info = RADEONPTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; @@ -379,7 +379,7 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); PixmapPtr pixmap = info->fbcon_pixmap; - struct radeon_bo *bo; + struct radeon_buffer *bo; drmModeFBPtr fbcon; struct drm_gem_flink flink; @@ -402,10 +402,18 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, goto out_free_fb; } - bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0); + bo = calloc(1, sizeof(struct radeon_buffer)); + if (!bo) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate BO for fbcon handle\n"); + goto out_free_fb; + } + bo->ref_count = 1; + + bo->bo.radeon = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0); if (bo == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't allocate bo for fbcon handle\n"); + "Couldn't open BO for fbcon handle\n"); goto out_free_fb; } @@ -413,7 +421,7 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, fbcon->depth, fbcon->bpp, fbcon->pitch, bo); info->fbcon_pixmap = pixmap; - radeon_bo_unref(bo); + radeon_buffer_unref(&bo); out_free_fb: drmModeFreeFB(fbcon); return pixmap; @@ -496,11 +504,7 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, scanout->pixmap = NULL; } - if (scanout->bo) { - radeon_bo_unmap(scanout->bo); - radeon_bo_unref(scanout->bo); - scanout->bo = NULL; - } + radeon_buffer_unref(&scanout->bo); } void @@ -913,7 +917,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, fb = radeon_fb_create(pScrn, pRADEONEnt->fd, pScrn->virtualX, pScrn->virtualY, pScrn->displayWidth * info->pixel_bytes, - info->front_bo->handle); + info->front_buffer->bo.radeon->handle); /* Prevent refcnt of ad-hoc FBs from reaching 2 */ drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL); drmmode_crtc->fb = fb; @@ -2232,14 +2236,12 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); RADEONInfoPtr info = RADEONPTR(scrn); - struct radeon_bo *old_front = NULL; + struct radeon_buffer *old_front = NULL; ScreenPtr screen = xf86ScrnToScreen(scrn); int i, pitch, old_width, old_height, old_pitch; - int aligned_height; - uint32_t screen_size; + int usage = CREATE_PIXMAP_USAGE_BACKING_PIXMAP; int cpp = info->pixel_bytes; - struct radeon_surface surface; - uint32_t tiling_flags = 0, base_align; + uint32_t tiling_flags; PixmapPtr ppix = screen->GetScreenPixmap(screen); void *fb_shadow; @@ -2247,71 +2249,34 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) return TRUE; if (info->allowColorTiling && !info->shadow_primary) { - if (info->ChipFamily >= CHIP_FAMILY_R600) { - if (info->allowColorTiling2D) { - tiling_flags |= RADEON_TILING_MACRO; - } else { - tiling_flags |= RADEON_TILING_MICRO; - } - } else - tiling_flags |= RADEON_TILING_MACRO; - } - - pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(scrn, cpp, tiling_flags)) * cpp; - aligned_height = RADEON_ALIGN(height, drmmode_get_height_align(scrn, tiling_flags)); - screen_size = RADEON_ALIGN(pitch * aligned_height, RADEON_GPU_PAGE_SIZE); - base_align = 4096; - - if (info->surf_man) { - if (!radeon_surface_initialize(info, &surface, width, height, - cpp, tiling_flags, 0)) - return FALSE; - - screen_size = surface.bo_size; - base_align = surface.bo_alignment; - pitch = surface.level[0].pitch_bytes; - tiling_flags = 0; - switch (surface.level[0].mode) { - case RADEON_SURF_MODE_2D: - tiling_flags |= RADEON_TILING_MACRO; - tiling_flags |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT; - tiling_flags |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT; - tiling_flags |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT; - if (surface.tile_split) - tiling_flags |= eg_tile_split(surface.tile_split) - << RADEON_TILING_EG_TILE_SPLIT_SHIFT; - break; - case RADEON_SURF_MODE_1D: - tiling_flags |= RADEON_TILING_MICRO; - break; - default: - break; - } - if (!info->use_glamor) - info->front_surface = surface; + if (info->ChipFamily < CHIP_FAMILY_R600 || info->allowColorTiling2D) + usage |= RADEON_CREATE_PIXMAP_TILING_MACRO; + else + usage |= RADEON_CREATE_PIXMAP_TILING_MICRO; } - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "Allocate new frame buffer %dx%d stride %d\n", - width, height, pitch / cpp); + xf86DrvMsg(scrn->scrnIndex, X_INFO, "Allocate new frame buffer %dx%d\n", + width, height); old_width = scrn->virtualX; old_height = scrn->virtualY; old_pitch = scrn->displayWidth; - old_front = info->front_bo; + old_front = info->front_buffer; scrn->virtualX = width; scrn->virtualY = height; - scrn->displayWidth = pitch / cpp; - info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, base_align, - info->shadow_primary ? - RADEON_GEM_DOMAIN_GTT : - RADEON_GEM_DOMAIN_VRAM, - tiling_flags ? RADEON_GEM_NO_CPU_ACCESS : 0); - if (!info->front_bo) + info->front_buffer = radeon_alloc_pixmap_bo(scrn, scrn->virtualX, + scrn->virtualY, scrn->depth, + usage, scrn->bitsPerPixel, + &pitch, + &info->front_surface, + &tiling_flags); + if (!info->front_buffer) goto fail; + scrn->displayWidth = pitch / cpp; + #if X_BYTE_ORDER == X_BIG_ENDIAN switch (cpp) { case 4: @@ -2326,7 +2291,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) tiling_flags |= RADEON_TILING_SURFACE; #endif if (tiling_flags) - radeon_bo_set_tiling(info->front_bo, tiling_flags, pitch); + radeon_bo_set_tiling(info->front_buffer->bo.radeon, tiling_flags, pitch); if (!info->r600_shadow_fb) { if (info->surf_man && !info->use_glamor) @@ -2334,9 +2299,9 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch, NULL); } else { - if (radeon_bo_map(info->front_bo, 1)) + if (radeon_bo_map(info->front_buffer->bo.radeon, 1)) goto fail; - fb_shadow = calloc(1, screen_size); + fb_shadow = calloc(1, pitch * scrn->virtualY); if (fb_shadow == NULL) goto fail; free(info->fb_shadow); @@ -2350,12 +2315,12 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) radeon_glamor_create_screen_resources(scrn->pScreen); if (!info->r600_shadow_fb) { - if (!radeon_set_pixmap_bo(ppix, info->front_bo)) + if (!radeon_set_pixmap_bo(ppix, info->front_buffer)) goto fail; } radeon_pixmap_clear(ppix); - radeon_finish(scrn, info->front_bo); + radeon_finish(scrn, info->front_buffer); for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; @@ -2367,16 +2332,14 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) crtc->rotation, crtc->x, crtc->y); } - if (old_front) - radeon_bo_unref(old_front); + radeon_buffer_unref(&old_front); - radeon_kms_update_vram_limit(scrn, screen_size); + radeon_kms_update_vram_limit(scrn, pitch * scrn->virtualY); return TRUE; fail: - if (info->front_bo) - radeon_bo_unref(info->front_bo); - info->front_bo = old_front; + radeon_buffer_unref(&info->front_buffer); + info->front_buffer = old_front; scrn->virtualX = old_width; scrn->virtualY = old_height; scrn->displayWidth = old_pitch; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index e0b97e72..23460fdc 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -72,7 +72,7 @@ struct drmmode_fb { }; struct drmmode_scanout { - struct radeon_bo *bo; + struct radeon_buffer *bo; PixmapPtr pixmap; int width, height; }; diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c index 41edd345..dae8b6a1 100644 --- a/src/evergreen_exa.c +++ b/src/evergreen_exa.c @@ -71,7 +71,7 @@ EVERGREENPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) if (!RADEONValidPM(pm, pPix->drawable.bitsPerPixel)) RADEON_FALLBACK(("invalid planemask\n")); - dst.bo = radeon_get_pixmap_bo(pPix); + dst.bo = radeon_get_pixmap_bo(pPix)->bo.radeon; dst.tiling_flags = radeon_get_pixmap_tiling(pPix); dst.surface = radeon_get_pixmap_surface(pPix); @@ -466,13 +466,13 @@ EVERGREENPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, accel_state->same_surface = FALSE; - src_obj.bo = radeon_get_pixmap_bo(pSrc); - dst_obj.bo = radeon_get_pixmap_bo(pDst); + src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon; + dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon; dst_obj.surface = radeon_get_pixmap_surface(pDst); src_obj.surface = radeon_get_pixmap_surface(pSrc); dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); - if (radeon_get_pixmap_bo(pSrc) == radeon_get_pixmap_bo(pDst)) + if (src_obj.bo == dst_obj.bo) accel_state->same_surface = TRUE; src_obj.width = pSrc->drawable.width; @@ -1301,7 +1301,7 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture, return FALSE; if (pSrc) { - src_obj.bo = radeon_get_pixmap_bo(pSrc); + src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon; src_obj.surface = radeon_get_pixmap_surface(pSrc); src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); src_obj.pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel / 8); @@ -1311,7 +1311,7 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture, src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT; } - dst_obj.bo = radeon_get_pixmap_bo(pDst); + dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon; dst_obj.surface = radeon_get_pixmap_surface(pDst); dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); dst_obj.pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8); @@ -1325,7 +1325,7 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture, if (pMaskPicture) { if (pMask) { - mask_obj.bo = radeon_get_pixmap_bo(pMask); + mask_obj.bo = radeon_get_pixmap_bo(pMask)->bo.radeon; mask_obj.tiling_flags = radeon_get_pixmap_tiling(pMask); mask_obj.pitch = exaGetPixmapPitch(pMask) / (pMask->drawable.bitsPerPixel / 8); mask_obj.surface = radeon_get_pixmap_surface(pMask); @@ -1673,16 +1673,16 @@ EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, return FALSE; driver_priv = exaGetPixmapDriverPrivate(pDst); - if (!driver_priv || !driver_priv->bo) + if (!driver_priv || !driver_priv->bo->bo.radeon) return FALSE; /* If we know the BO won't be busy / in VRAM, don't bother with a scratch */ - copy_dst = driver_priv->bo; + copy_dst = driver_priv->bo->bo.radeon; copy_pitch = pDst->devKind; if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) { - if (!radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { + if (!radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) { flush = FALSE; - if (!radeon_bo_is_busy(driver_priv->bo, &dst_domain) && + if (!radeon_bo_is_busy(driver_priv->bo->bo.radeon, &dst_domain) && !(dst_domain & RADEON_GEM_DOMAIN_VRAM)) goto copy; } @@ -1711,7 +1711,7 @@ EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, dst_obj.height = pDst->drawable.height; dst_obj.bpp = bpp; dst_obj.domain = RADEON_GEM_DOMAIN_VRAM; - dst_obj.bo = radeon_get_pixmap_bo(pDst); + dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon; dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); dst_obj.surface = radeon_get_pixmap_surface(pDst); @@ -1739,7 +1739,7 @@ copy: r = TRUE; size = w * bpp / 8; dst = copy_dst->ptr; - if (copy_dst == driver_priv->bo) + if (copy_dst == driver_priv->bo->bo.radeon) dst += y * copy_pitch + x * bpp / 8; for (i = 0; i < h; i++) { memcpy(dst + i * copy_pitch, src, size); @@ -1789,15 +1789,15 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, return FALSE; driver_priv = exaGetPixmapDriverPrivate(pSrc); - if (!driver_priv || !driver_priv->bo) + if (!driver_priv || !driver_priv->bo->bo.radeon) return FALSE; /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */ - copy_src = driver_priv->bo; + copy_src = driver_priv->bo->bo.radeon; copy_pitch = pSrc->devKind; if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) { - if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { - src_domain = radeon_bo_get_src_domain(driver_priv->bo); + if (radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) { + src_domain = radeon_bo_get_src_domain(driver_priv->bo->bo.radeon); if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) src_domain = 0; @@ -1806,7 +1806,7 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, } if (!src_domain) - radeon_bo_is_busy(driver_priv->bo, &src_domain); + radeon_bo_is_busy(driver_priv->bo->bo.radeon, &src_domain); if (src_domain & ~(uint32_t)RADEON_GEM_DOMAIN_VRAM) goto copy; @@ -1841,7 +1841,7 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, src_obj.height = pSrc->drawable.height; src_obj.bpp = bpp; src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT; - src_obj.bo = radeon_get_pixmap_bo(pSrc); + src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon; src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); src_obj.surface = radeon_get_pixmap_surface(pSrc); @@ -1883,7 +1883,7 @@ copy: } r = TRUE; w *= bpp / 8; - if (copy_src == driver_priv->bo) + if (copy_src == driver_priv->bo->bo.radeon) size = y * copy_pitch + x * bpp / 8; else size = 0; diff --git a/src/evergreen_state.h b/src/evergreen_state.h index ef331002..7e54e1c7 100644 --- a/src/evergreen_state.h +++ b/src/evergreen_state.h @@ -349,7 +349,6 @@ extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch); extern void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv); -extern struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix); extern Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix); extern Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **handle_p); extern Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *handle); diff --git a/src/evergreen_textured_videofuncs.c b/src/evergreen_textured_videofuncs.c index 20805ff4..53675600 100644 --- a/src/evergreen_textured_videofuncs.c +++ b/src/evergreen_textured_videofuncs.c @@ -140,7 +140,7 @@ EVERGREENDisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) CLEAR (vs_const_conf); CLEAR (ps_const_conf); - dst_obj.bo = radeon_get_pixmap_bo(pPixmap); + dst_obj.bo = radeon_get_pixmap_bo(pPixmap)->bo.radeon; dst_obj.tiling_flags = radeon_get_pixmap_tiling(pPixmap); dst_obj.surface = radeon_get_pixmap_surface(pPixmap); diff --git a/src/r600_exa.c b/src/r600_exa.c index a111dd45..bd824c87 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -150,7 +150,7 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) if (!RADEONValidPM(pm, pPix->drawable.bitsPerPixel)) RADEON_FALLBACK(("invalid planemask\n")); - dst.bo = radeon_get_pixmap_bo(pPix); + dst.bo = radeon_get_pixmap_bo(pPix)->bo.radeon; dst.tiling_flags = radeon_get_pixmap_tiling(pPix); dst.surface = radeon_get_pixmap_surface(pPix); @@ -534,13 +534,13 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, accel_state->same_surface = FALSE; - src_obj.bo = radeon_get_pixmap_bo(pSrc); - dst_obj.bo = radeon_get_pixmap_bo(pDst); + src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon; + dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon; dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); src_obj.surface = radeon_get_pixmap_surface(pSrc); dst_obj.surface = radeon_get_pixmap_surface(pDst); - if (radeon_get_pixmap_bo(pSrc) == radeon_get_pixmap_bo(pDst)) + if (src_obj.bo == dst_obj.bo) accel_state->same_surface = TRUE; src_obj.width = pSrc->drawable.width; @@ -1344,7 +1344,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, return FALSE; if (pSrc) { - src_obj.bo = radeon_get_pixmap_bo(pSrc); + src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon; src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); src_obj.surface = radeon_get_pixmap_surface(pSrc); src_obj.pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel / 8); @@ -1354,7 +1354,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT; } - dst_obj.bo = radeon_get_pixmap_bo(pDst); + dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon; dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); dst_obj.surface = radeon_get_pixmap_surface(pDst); dst_obj.pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8); @@ -1368,7 +1368,7 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, if (pMaskPicture) { if (pMask) { - mask_obj.bo = radeon_get_pixmap_bo(pMask); + mask_obj.bo = radeon_get_pixmap_bo(pMask)->bo.radeon; mask_obj.tiling_flags = radeon_get_pixmap_tiling(pMask); mask_obj.surface = radeon_get_pixmap_surface(pMask); mask_obj.pitch = exaGetPixmapPitch(pMask) / (pMask->drawable.bitsPerPixel / 8); @@ -1700,16 +1700,16 @@ R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, return FALSE; driver_priv = exaGetPixmapDriverPrivate(pDst); - if (!driver_priv || !driver_priv->bo) + if (!driver_priv || !driver_priv->bo->bo.radeon) return FALSE; /* If we know the BO won't be busy / in VRAM, don't bother with a scratch */ - copy_dst = driver_priv->bo; + copy_dst = driver_priv->bo->bo.radeon; copy_pitch = pDst->devKind; if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) { - if (!radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { + if (!radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) { flush = FALSE; - if (!radeon_bo_is_busy(driver_priv->bo, &dst_domain) && + if (!radeon_bo_is_busy(driver_priv->bo->bo.radeon, &dst_domain) && !(dst_domain & RADEON_GEM_DOMAIN_VRAM)) goto copy; } @@ -1741,7 +1741,7 @@ R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, dst_obj.height = pDst->drawable.height; dst_obj.bpp = bpp; dst_obj.domain = RADEON_GEM_DOMAIN_VRAM; - dst_obj.bo = radeon_get_pixmap_bo(pDst); + dst_obj.bo = radeon_get_pixmap_bo(pDst)->bo.radeon; dst_obj.tiling_flags = radeon_get_pixmap_tiling(pDst); dst_obj.surface = radeon_get_pixmap_surface(pDst); @@ -1769,7 +1769,7 @@ copy: r = TRUE; size = w * bpp / 8; dst = copy_dst->ptr; - if (copy_dst == driver_priv->bo) + if (copy_dst == driver_priv->bo->bo.radeon) dst += y * copy_pitch + x * bpp / 8; for (i = 0; i < h; i++) { memcpy(dst + i * copy_pitch, src, size); @@ -1819,15 +1819,15 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, return FALSE; driver_priv = exaGetPixmapDriverPrivate(pSrc); - if (!driver_priv || !driver_priv->bo) + if (!driver_priv || !driver_priv->bo->bo.radeon) return FALSE; /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */ - copy_src = driver_priv->bo; + copy_src = driver_priv->bo->bo.radeon; copy_pitch = pSrc->devKind; if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) { - if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { - src_domain = radeon_bo_get_src_domain(driver_priv->bo); + if (radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) { + src_domain = radeon_bo_get_src_domain(driver_priv->bo->bo.radeon); if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) src_domain = 0; @@ -1836,7 +1836,7 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, } if (!src_domain) - radeon_bo_is_busy(driver_priv->bo, &src_domain); + radeon_bo_is_busy(driver_priv->bo->bo.radeon, &src_domain); if (src_domain & ~(uint32_t)RADEON_GEM_DOMAIN_VRAM) goto copy; @@ -1867,7 +1867,7 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, src_obj.height = pSrc->drawable.height; src_obj.bpp = bpp; src_obj.domain = RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT; - src_obj.bo = radeon_get_pixmap_bo(pSrc); + src_obj.bo = radeon_get_pixmap_bo(pSrc)->bo.radeon; src_obj.tiling_flags = radeon_get_pixmap_tiling(pSrc); src_obj.surface = radeon_get_pixmap_surface(pSrc); @@ -1909,7 +1909,7 @@ copy: } r = TRUE; w *= bpp / 8; - if (copy_src == driver_priv->bo) + if (copy_src == driver_priv->bo->bo.radeon) size = y * copy_pitch + x * bpp / 8; else size = 0; diff --git a/src/r600_state.h b/src/r600_state.h index 4898e8de..34345996 100644 --- a/src/r600_state.h +++ b/src/r600_state.h @@ -320,7 +320,6 @@ extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch); extern void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv); -extern struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix); extern Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix); extern Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **handle_p); extern Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *handle); diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c index d20df7e2..c8a9b197 100644 --- a/src/r600_textured_videofuncs.c +++ b/src/r600_textured_videofuncs.c @@ -152,7 +152,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) CLEAR (vs_conf); CLEAR (ps_conf); - dst_obj.bo = radeon_get_pixmap_bo(pPixmap); + dst_obj.bo = radeon_get_pixmap_bo(pPixmap)->bo.radeon; dst_obj.tiling_flags = radeon_get_pixmap_tiling(pPixmap); dst_obj.surface = radeon_get_pixmap_surface(pPixmap); diff --git a/src/radeon.h b/src/radeon.h index 499e89f9..648fd98a 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -83,6 +83,7 @@ #include "radeon_dri2.h" #include "drmmode_display.h" #include "radeon_surface.h" +#include "radeon_bo_helper.h" /* Render support */ #ifdef RENDER @@ -300,14 +301,13 @@ radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap) #define CURSOR_WIDTH_CIK 128 #define CURSOR_HEIGHT_CIK 128 - #ifdef USE_GLAMOR struct radeon_pixmap { uint_fast32_t gpu_read; uint_fast32_t gpu_write; - struct radeon_bo *bo; + struct radeon_buffer *bo; struct drmmode_fb *fb; uint32_t tiling_flags; @@ -333,7 +333,7 @@ static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pix struct radeon_exa_pixmap_priv { - struct radeon_bo *bo; + struct radeon_buffer *bo; struct drmmode_fb *fb; uint32_t tiling_flags; struct radeon_surface surface; @@ -567,7 +567,7 @@ typedef struct { void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB struct radeon_2d_state state_2d; - struct radeon_bo *front_bo; + struct radeon_buffer *front_buffer; struct radeon_bo_manager *bufmgr; struct radeon_cs_manager *csm; struct radeon_cs *cs; @@ -713,7 +713,7 @@ static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix) uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix); -static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) +static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_buffer *bo) { ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen); RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); @@ -732,7 +732,7 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) if (priv->bo == bo) return TRUE; - radeon_bo_unref(priv->bo); + radeon_buffer_unref(&priv->bo); } drmmode_fb_reference(pRADEONEnt->fd, &priv->fb, NULL); @@ -752,10 +752,10 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) return FALSE; } - radeon_bo_ref(bo); + radeon_buffer_ref(bo); priv->bo = bo; - radeon_bo_get_tiling(bo, &priv->tiling_flags, &pitch); + radeon_bo_get_tiling(bo->bo.radeon, &priv->tiling_flags, &pitch); } radeon_set_pixmap_private(pPix, priv); @@ -769,15 +769,14 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) if (driver_priv) { uint32_t pitch; - if (driver_priv->bo) - radeon_bo_unref(driver_priv->bo); - + radeon_buffer_unref(&driver_priv->bo); drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL); - radeon_bo_ref(bo); + radeon_buffer_ref(bo); driver_priv->bo = bo; - radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch); + radeon_bo_get_tiling(bo->bo.radeon, &driver_priv->tiling_flags, + &pitch); return TRUE; } @@ -785,7 +784,7 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) } } -static inline struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix) +static inline struct radeon_buffer *radeon_get_pixmap_bo(PixmapPtr pPix) { #ifdef USE_GLAMOR RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen)); @@ -1004,7 +1003,7 @@ do { \ #define EMIT_OFFSET(reg, value, pPix, rd, wd) do { \ driver_priv = exaGetPixmapDriverPrivate(pPix); \ OUT_RING_REG((reg), (value)); \ - OUT_RING_RELOC(driver_priv->bo, (rd), (wd)); \ + OUT_RING_RELOC(driver_priv->bo->bo.radeon, (rd), (wd)); \ } while(0) #define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0) @@ -1018,7 +1017,7 @@ do { \ #define EMIT_COLORPITCH(reg, value, pPix) do { \ driver_priv = exaGetPixmapDriverPrivate(pPix); \ OUT_RING_REG((reg), value); \ - OUT_RING_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); \ + OUT_RING_RELOC(driver_priv->bo->bo.radeon, 0, RADEON_GEM_DOMAIN_VRAM); \ } while(0) static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn) diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index 7cfe9126..2b836bbf 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -145,7 +145,7 @@ radeon_surface_initialize(RADEONInfoPtr info, struct radeon_surface *surface, /* Calculate appropriate tiling and pitch for a pixmap and allocate a BO that * can hold it. */ -struct radeon_bo* +struct radeon_buffer * radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch, struct radeon_surface *new_surface, uint32_t *new_tiling) @@ -156,7 +156,7 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, int cpp = bitsPerPixel / 8; uint32_t tiling = 0, flags = 0; struct radeon_surface surface; - struct radeon_bo *bo; + struct radeon_buffer *bo; int domain = RADEON_GEM_DOMAIN_VRAM; if (usage_hint) { if (info->allowColorTiling) { @@ -225,10 +225,15 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, if (tiling) flags |= RADEON_GEM_NO_CPU_ACCESS; - bo = radeon_bo_open(info->bufmgr, 0, size, base_align, - domain, flags); + bo = calloc(1, sizeof(struct radeon_buffer)); + if (!bo) + return NULL; + + bo->ref_count = 1; + bo->bo.radeon = radeon_bo_open(info->bufmgr, 0, size, base_align, + domain, flags); - if (bo && tiling && radeon_bo_set_tiling(bo, tiling, pitch) == 0) + if (bo && tiling && radeon_bo_set_tiling(bo->bo.radeon, tiling, pitch) == 0) *new_tiling = tiling; *new_pitch = pitch; @@ -238,10 +243,10 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, /* Flush and wait for the BO to become idle */ void -radeon_finish(ScrnInfoPtr scrn, struct radeon_bo *bo) +radeon_finish(ScrnInfoPtr scrn, struct radeon_buffer *bo) { radeon_cs_flush_indirect(scrn); - radeon_bo_wait(bo); + radeon_bo_wait(bo->bo.radeon); } @@ -269,7 +274,7 @@ radeon_pixmap_clear(PixmapPtr pixmap) /* Get GEM handle for the pixmap */ Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle) { - struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap); + struct radeon_buffer *bo = radeon_get_pixmap_bo(pixmap); #ifdef USE_GLAMOR ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); @@ -278,7 +283,7 @@ Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle) #endif if (bo) { - *handle = bo->handle; + *handle = bo->bo.radeon->handle; return TRUE; } @@ -366,15 +371,20 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle, { ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen); RADEONInfoPtr info = RADEONPTR(pScrn); - struct radeon_bo *bo; + struct radeon_buffer *bo; int ihandle = (int)(long)fd_handle; uint32_t size = ppix->devKind * ppix->drawable.height; Bool ret = FALSE; - bo = radeon_gem_bo_open_prime(info->bufmgr, ihandle, size); + bo = (struct radeon_buffer *)calloc(1, sizeof(struct radeon_buffer)); + if (!bo) + goto error; + + bo->bo.radeon = radeon_gem_bo_open_prime(info->bufmgr, ihandle, size); if (!bo) goto error; + bo->ref_count = 1; ret = radeon_set_pixmap_bo(ppix, bo); if (!ret) goto error; @@ -404,6 +414,6 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle, close(ihandle); /* we have a reference from the alloc and one from set pixmap bo, drop one */ - radeon_bo_unref(bo); + radeon_buffer_unref(&bo); return ret; } diff --git a/src/radeon_bo_helper.h b/src/radeon_bo_helper.h index fa99201b..53af87c3 100644 --- a/src/radeon_bo_helper.h +++ b/src/radeon_bo_helper.h @@ -23,13 +23,22 @@ #ifndef RADEON_BO_HELPER_H #define RADEON_BO_HELPER_H 1 -extern struct radeon_bo* +#define RADEON_BO_FLAGS_GBM 0x1 + +struct radeon_buffer { + union { + struct radeon_bo *radeon; + } bo; + uint32_t ref_count; +}; + +extern struct radeon_buffer * radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch, struct radeon_surface *new_surface, uint32_t *new_tiling); extern void -radeon_finish(ScrnInfoPtr scrn, struct radeon_bo *bo); +radeon_finish(ScrnInfoPtr scrn, struct radeon_buffer *bo); extern void radeon_pixmap_clear(PixmapPtr pixmap); @@ -60,4 +69,29 @@ static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable) return drawable->pScreen->GetWindowPixmap((WindowPtr)drawable); } +static inline void +radeon_buffer_ref(struct radeon_buffer *buffer) +{ + buffer->ref_count++; +} + +static inline void +radeon_buffer_unref(struct radeon_buffer **buffer) +{ + struct radeon_buffer *buf = *buffer; + + if (!buf) + return; + + if (buf->ref_count > 1) { + buf->ref_count--; + return; + } + + radeon_bo_unmap(buf->bo.radeon); + radeon_bo_unref(buf->bo.radeon); + free(buf); + *buffer = NULL; +} + #endif /* RADEON_BO_HELPER_H */ diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 6f469127..584a1d9d 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -79,7 +79,7 @@ static DevPrivateKeyRec dri2_window_private_key_rec; static Bool radeon_get_flink_name(RADEONEntPtr pRADEONEnt, PixmapPtr pixmap, uint32_t *name) { - struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap); + struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap)->bo.radeon; struct drm_gem_flink flink; if (bo) @@ -719,7 +719,7 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt { struct dri2_buffer_priv *front_priv = front->driverPrivate; struct dri2_buffer_priv *back_priv = back->driverPrivate; - struct radeon_bo *front_bo, *back_bo; + struct radeon_buffer *front_buffer, *back_buffer; ScreenPtr screen; RADEONInfoPtr info; RegionRec region; @@ -737,19 +737,19 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt back->name = tmp; /* Swap pixmap bos */ - front_bo = radeon_get_pixmap_bo(front_priv->pixmap); - back_bo = radeon_get_pixmap_bo(back_priv->pixmap); - radeon_set_pixmap_bo(front_priv->pixmap, back_bo); - radeon_set_pixmap_bo(back_priv->pixmap, front_bo); + front_buffer = radeon_get_pixmap_bo(front_priv->pixmap); + back_buffer = radeon_get_pixmap_bo(back_priv->pixmap); + radeon_set_pixmap_bo(front_priv->pixmap, back_buffer); + radeon_set_pixmap_bo(back_priv->pixmap, front_buffer); /* Do we need to update the Screen? */ screen = draw->pScreen; info = RADEONPTR(xf86ScreenToScrn(screen)); - if (front_bo == info->front_bo) { - radeon_bo_ref(back_bo); - radeon_bo_unref(info->front_bo); - info->front_bo = back_bo; - radeon_set_pixmap_bo(screen->GetScreenPixmap(screen), back_bo); + if (front_buffer == info->front_buffer) { + radeon_buffer_ref(back_buffer); + radeon_buffer_unref(&info->front_buffer); + info->front_buffer = back_buffer; + radeon_set_pixmap_bo(screen->GetScreenPixmap(screen), back_buffer); } radeon_glamor_exchange_buffers(front_priv->pixmap, back_priv->pixmap); diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c index 3e689ffd..b199c793 100644 --- a/src/radeon_dri3.c +++ b/src/radeon_dri3.c @@ -214,7 +214,7 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen, struct radeon_bo *bo; int fd; - bo = radeon_get_pixmap_bo(pixmap); + bo = radeon_get_pixmap_bo(pixmap)->bo.radeon; if (!bo) { #ifdef USE_GLAMOR ScrnInfoPtr scrn = xf86ScreenToScrn(screen); @@ -225,7 +225,7 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen, #endif exaMoveInPixmap(pixmap); - bo = radeon_get_pixmap_bo(pixmap); + bo = radeon_get_pixmap_bo(pixmap)->bo.radeon; if (!bo) return -1; } diff --git a/src/radeon_exa.c b/src/radeon_exa.c index ef60bc0c..90d92d7b 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -184,11 +184,11 @@ Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index) return FALSE; /* if we have more refs than just the BO then flush */ - if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { + if (radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) { flush = TRUE; if (can_fail) { - possible_domains = radeon_bo_get_src_domain(driver_priv->bo); + possible_domains = radeon_bo_get_src_domain(driver_priv->bo->bo.radeon); if (possible_domains == RADEON_GEM_DOMAIN_VRAM) return FALSE; /* use DownloadFromScreen */ } @@ -196,7 +196,7 @@ Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index) /* if the BO might end up in VRAM, prefer DownloadFromScreen */ if (can_fail && (possible_domains & RADEON_GEM_DOMAIN_VRAM)) { - radeon_bo_is_busy(driver_priv->bo, ¤t_domain); + radeon_bo_is_busy(driver_priv->bo->bo.radeon, ¤t_domain); if (current_domain & possible_domains) { if (current_domain == RADEON_GEM_DOMAIN_VRAM) @@ -209,14 +209,14 @@ Bool RADEONPrepareAccess_CS(PixmapPtr pPix, int index) radeon_cs_flush_indirect(pScrn); /* flush IB */ - ret = radeon_bo_map(driver_priv->bo, 1); + ret = radeon_bo_map(driver_priv->bo->bo.radeon, 1); if (ret) { FatalError("failed to map pixmap %d\n", ret); return FALSE; } driver_priv->bo_mapped = TRUE; - pPix->devPrivate.ptr = driver_priv->bo->ptr; + pPix->devPrivate.ptr = driver_priv->bo->bo.radeon->ptr; return TRUE; } @@ -229,7 +229,7 @@ void RADEONFinishAccess_CS(PixmapPtr pPix, int index) if (!driver_priv || !driver_priv->bo_mapped) return; - radeon_bo_unmap(driver_priv->bo); + radeon_bo_unmap(driver_priv->bo->bo.radeon); driver_priv->bo_mapped = FALSE; pPix->devPrivate.ptr = NULL; } @@ -277,8 +277,7 @@ void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv) if (!driverPriv) return; - if (driver_priv->bo) - radeon_bo_unref(driver_priv->bo); + radeon_buffer_unref(&driver_priv->bo); drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL); free(driverPriv); } @@ -287,7 +286,7 @@ Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **fd_hand { struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(ppix); - if (!radeon_share_pixmap_backing(driver_priv->bo, fd_handle)) + if (!radeon_share_pixmap_backing(driver_priv->bo->bo.radeon, fd_handle)) return FALSE; driver_priv->shared = TRUE; diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index add89458..819b4258 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -138,7 +138,8 @@ RADEONPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) radeon_cs_space_reset_bos(info->cs); driver_priv = exaGetPixmapDriverPrivate(pPix); - radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo->bo.radeon, 0, + RADEON_GEM_DOMAIN_VRAM); ret = radeon_cs_space_check(info->cs); if (ret) @@ -146,7 +147,7 @@ RADEONPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) driver_priv = exaGetPixmapDriverPrivate(pPix); if (driver_priv) { - info->state_2d.dst_bo = driver_priv->bo; + info->state_2d.dst_bo = driver_priv->bo->bo.radeon; info->state_2d.dst_domain = driver_priv->shared ? RADEON_GEM_DOMAIN_GTT : RADEON_GEM_DOMAIN_VRAM; } @@ -256,13 +257,15 @@ RADEONPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, radeon_cs_space_reset_bos(info->cs); driver_priv = exaGetPixmapDriverPrivate(pSrc); - radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - info->state_2d.src_bo = driver_priv->bo; + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo->bo.radeon, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + info->state_2d.src_bo = driver_priv->bo->bo.radeon; driver_priv = exaGetPixmapDriverPrivate(pDst); - info->state_2d.dst_bo = driver_priv->bo; + info->state_2d.dst_bo = driver_priv->bo->bo.radeon; info->state_2d.dst_domain = driver_priv->shared ? RADEON_GEM_DOMAIN_GTT : RADEON_GEM_DOMAIN_VRAM; - radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, info->state_2d.dst_domain); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo->bo.radeon, 0, + info->state_2d.dst_domain); ret = radeon_cs_space_check(info->cs); if (ret) @@ -389,7 +392,7 @@ RADEONUploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, return FALSE; driver_priv = exaGetPixmapDriverPrivate(pDst); - if (!driver_priv || !driver_priv->bo) + if (!driver_priv || !driver_priv->bo->bo.radeon) return FALSE; #if X_BYTE_ORDER == X_BIG_ENDIAN @@ -404,12 +407,12 @@ RADEONUploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, #endif /* If we know the BO won't be busy / in VRAM, don't bother with a scratch */ - copy_dst = driver_priv->bo; + copy_dst = driver_priv->bo->bo.radeon; copy_pitch = pDst->devKind; if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) { - if (!radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { + if (!radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) { flush = FALSE; - if (!radeon_bo_is_busy(driver_priv->bo, &dst_domain) && + if (!radeon_bo_is_busy(driver_priv->bo->bo.radeon, &dst_domain) && !(dst_domain & RADEON_GEM_DOMAIN_VRAM)) goto copy; } @@ -446,7 +449,7 @@ copy: r = TRUE; size = w * bpp / 8; dst = copy_dst->ptr; - if (copy_dst == driver_priv->bo) + if (copy_dst == driver_priv->bo->bo.radeon) dst += y * copy_pitch + x * bpp / 8; for (i = 0; i < h; i++) { RADEONCopySwap(dst + i * copy_pitch, (uint8_t*)src, size, swap); @@ -458,7 +461,7 @@ copy: RADEONGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype); RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset); RADEON_SWITCH_TO_2D(); - RADEONBlitChunk(pScrn, scratch, driver_priv->bo, datatype, scratch_pitch << 16, + RADEONBlitChunk(pScrn, scratch, driver_priv->bo->bo.radeon, datatype, scratch_pitch << 16, dst_pitch_offset, 0, 0, x, y, w, h, RADEON_GEM_DOMAIN_GTT, RADEON_GEM_DOMAIN_VRAM); } @@ -493,7 +496,7 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, return FALSE; driver_priv = exaGetPixmapDriverPrivate(pSrc); - if (!driver_priv || !driver_priv->bo) + if (!driver_priv || !driver_priv->bo->bo.radeon) return FALSE; #if X_BYTE_ORDER == X_BIG_ENDIAN @@ -508,11 +511,11 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, #endif /* If we know the BO won't end up in VRAM anyway, don't bother with a scratch */ - copy_src = driver_priv->bo; + copy_src = driver_priv->bo->bo.radeon; copy_pitch = pSrc->devKind; if (!(driver_priv->tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) { - if (radeon_bo_is_referenced_by_cs(driver_priv->bo, info->cs)) { - src_domain = radeon_bo_get_src_domain(driver_priv->bo); + if (radeon_bo_is_referenced_by_cs(driver_priv->bo->bo.radeon, info->cs)) { + src_domain = radeon_bo_get_src_domain(driver_priv->bo->bo.radeon); if ((src_domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) src_domain = 0; @@ -521,7 +524,7 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, } if (!src_domain) - radeon_bo_is_busy(driver_priv->bo, &src_domain); + radeon_bo_is_busy(driver_priv->bo->bo.radeon, &src_domain); if (src_domain & ~(uint32_t)RADEON_GEM_DOMAIN_VRAM) goto copy; @@ -541,8 +544,8 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, RADEONGetDatatypeBpp(pSrc->drawable.bitsPerPixel, &datatype); RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset); RADEON_SWITCH_TO_2D(); - RADEONBlitChunk(pScrn, driver_priv->bo, scratch, datatype, src_pitch_offset, - scratch_pitch << 16, x, y, 0, 0, w, h, + RADEONBlitChunk(pScrn, driver_priv->bo->bo.radeon, scratch, datatype, + src_pitch_offset, scratch_pitch << 16, x, y, 0, 0, w, h, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, RADEON_GEM_DOMAIN_GTT); copy_src = scratch; @@ -561,7 +564,7 @@ copy: } r = TRUE; w *= bpp / 8; - if (copy_src == driver_priv->bo) + if (copy_src == driver_priv->bo->bo.radeon) size = y * copy_pitch + x * bpp / 8; else size = 0; diff --git a/src/radeon_exa_shared.c b/src/radeon_exa_shared.c index cca1c67e..94238a5a 100644 --- a/src/radeon_exa_shared.c +++ b/src/radeon_exa_shared.c @@ -129,7 +129,7 @@ PixmapPtr RADEONSolidPixmap(ScreenPtr pScreen, uint32_t solid) struct radeon_bo *bo; exaMoveInPixmap(pPix); - bo = radeon_get_pixmap_bo(pPix); + bo = radeon_get_pixmap_bo(pPix)->bo.radeon; if (radeon_bo_map(bo, 1)) { pScreen->DestroyPixmap(pPix); diff --git a/src/radeon_exa_shared.h b/src/radeon_exa_shared.h index 3df7fa20..fe28c230 100644 --- a/src/radeon_exa_shared.h +++ b/src/radeon_exa_shared.h @@ -66,7 +66,8 @@ static inline void radeon_add_pixmap(struct radeon_cs *cs, PixmapPtr pPix, int r { struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix); - radeon_cs_space_add_persistent_bo(cs, driver_priv->bo, read_domains, write_domain); + radeon_cs_space_add_persistent_bo(cs, driver_priv->bo->bo.radeon, + read_domains, write_domain); } extern void radeon_ib_discard(ScrnInfoPtr pScrn); diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index 6cff72e1..c1d96160 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -62,7 +62,7 @@ radeon_glamor_create_screen_resources(ScreenPtr screen) #endif if (!glamor_egl_create_textured_screen(screen, - info->front_bo->handle, + info->front_buffer->bo.radeon->handle, scrn->displayWidth * info->pixel_bytes)) return FALSE; @@ -166,7 +166,7 @@ radeon_glamor_pre_init(ScrnInfoPtr scrn) Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *priv) { - return glamor_egl_create_textured_pixmap(pixmap, priv->bo->handle, + return glamor_egl_create_textured_pixmap(pixmap, priv->bo->bo.radeon->handle, pixmap->devKind); } @@ -180,10 +180,10 @@ static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap) if (pixmap->refcnt == 1) { if (pixmap->devPrivate.ptr) { - struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap); + struct radeon_buffer *bo = radeon_get_pixmap_bo(pixmap); if (bo) - radeon_bo_unmap(bo); + radeon_bo_unmap(bo->bo.radeon); } #ifdef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP @@ -289,7 +289,7 @@ fallback_glamor: * afterwards. */ new_pixmap = glamor_create_pixmap(screen, w, h, depth, usage); - radeon_bo_unref(priv->bo); + radeon_buffer_unref(&priv->bo); fallback_priv: free(priv); fallback_pixmap: diff --git a/src/radeon_glamor_wrappers.c b/src/radeon_glamor_wrappers.c index 94700a7b..79d98cc7 100644 --- a/src/radeon_glamor_wrappers.c +++ b/src/radeon_glamor_wrappers.c @@ -55,7 +55,7 @@ radeon_glamor_prepare_access_cpu(ScrnInfoPtr scrn, RADEONInfoPtr info, PixmapPtr pixmap, struct radeon_pixmap *priv, Bool need_sync) { - struct radeon_bo *bo = priv->bo; + struct radeon_buffer *bo = priv->bo; int ret; if (!pixmap->devPrivate.ptr) { @@ -65,7 +65,7 @@ radeon_glamor_prepare_access_cpu(ScrnInfoPtr scrn, RADEONInfoPtr info, info->gpu_flushed++; } - ret = radeon_bo_map(bo, 1); + ret = radeon_bo_map(bo->bo.radeon, 1); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map (tiling_flags %d) failed: %s\n", @@ -75,7 +75,7 @@ radeon_glamor_prepare_access_cpu(ScrnInfoPtr scrn, RADEONInfoPtr info, return FALSE; } - pixmap->devPrivate.ptr = bo->ptr; + pixmap->devPrivate.ptr = bo->bo.radeon->ptr; } else if (need_sync) radeon_finish(scrn, bo); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index d4b59e81..d3eeebea 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -254,7 +254,7 @@ radeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode, stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8; *size = stride; - return ((uint8_t *)info->front_bo->ptr + row * stride + offset); + return ((uint8_t *)info->front_buffer->bo.radeon->ptr + row * stride + offset); } static void @@ -359,9 +359,9 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) } if (info->dri2.enabled || info->use_glamor) { - if (info->front_bo) { + if (info->front_buffer) { PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); - if (!radeon_set_pixmap_bo(pPix, info->front_bo)) + if (!radeon_set_pixmap_bo(pPix, info->front_buffer)) return FALSE; if (info->surf_man && !info->use_glamor) @@ -1681,7 +1681,7 @@ void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion pScreen->WindowExposures(pWin, pRegion); #endif - radeon_finish(pScrn, info->front_bo); + radeon_finish(pScrn, info->front_buffer); drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE); } @@ -2269,7 +2269,7 @@ Bool RADEONScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "radeon_setup_kernel_mem failed\n"); return FALSE; } - front_ptr = info->front_bo->ptr; + front_ptr = info->front_buffer->bo.radeon->ptr; if (info->r600_shadow_fb) { info->fb_shadow = calloc(1, @@ -2478,15 +2478,17 @@ Bool RADEONEnterVT_KMS(ScrnInfoPtr pScrn) if (info->r600_shadow_fb) { int base_align = drmmode_get_base_align(pScrn, info->pixel_bytes, 0); struct radeon_bo *front_bo = radeon_bo_open(info->bufmgr, 0, - info->front_bo->size, + pScrn->displayWidth * + info->pixel_bytes * + pScrn->virtualY, base_align, RADEON_GEM_DOMAIN_VRAM, 0); if (front_bo) { if (radeon_bo_map(front_bo, 1) == 0) { memset(front_bo->ptr, 0, front_bo->size); - radeon_bo_unref(info->front_bo); - info->front_bo = front_bo; + radeon_bo_unref(info->front_buffer->bo.radeon); + info->front_buffer->bo.radeon = front_bo; } else { radeon_bo_unref(front_bo); front_bo = NULL; @@ -2633,7 +2635,8 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn) pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt); } else { - memset(info->front_bo->ptr, 0, info->front_bo->size); + memset(info->front_buffer->bo.radeon->ptr, 0, + pScrn->displayWidth * info->pixel_bytes * pScrn->virtualY); } TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen); @@ -2671,10 +2674,8 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) RADEONInfoPtr info = RADEONPTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int cpp = info->pixel_bytes; - uint32_t screen_size; - int pitch, base_align; + int pitch; uint32_t tiling_flags = 0; - struct radeon_surface surface; if (info->accel_state->exa != NULL) { xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n"); @@ -2688,50 +2689,6 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) } } - if (info->allowColorTiling && !info->shadow_primary) { - if (info->ChipFamily >= CHIP_FAMILY_R600) { - if (info->allowColorTiling2D) { - tiling_flags |= RADEON_TILING_MACRO; - } else { - tiling_flags |= RADEON_TILING_MICRO; - } - } else - tiling_flags |= RADEON_TILING_MACRO; - } - pitch = RADEON_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp; - screen_size = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)) * pitch; - base_align = drmmode_get_base_align(pScrn, cpp, tiling_flags); - if (info->surf_man) { - if (!radeon_surface_initialize(info, &surface, pScrn->virtualX, - pScrn->virtualY, cpp, - tiling_flags, 0)) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "radeon_surface_initialize failed\n"); - return FALSE; - } - pitch = surface.level[0].pitch_bytes; - screen_size = surface.bo_size; - base_align = surface.bo_alignment; - tiling_flags = 0; - switch (surface.level[0].mode) { - case RADEON_SURF_MODE_2D: - tiling_flags |= RADEON_TILING_MACRO; - tiling_flags |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT; - tiling_flags |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT; - tiling_flags |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT; - if (surface.tile_split) - tiling_flags |= eg_tile_split(surface.tile_split) - << RADEON_TILING_EG_TILE_SPLIT_SHIFT; - break; - case RADEON_SURF_MODE_1D: - tiling_flags |= RADEON_TILING_MICRO; - break; - default: - break; - } - if (!info->use_glamor) - info->front_surface = surface; - } { int cursor_size; int c; @@ -2758,17 +2715,27 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) } } - screen_size = RADEON_ALIGN(screen_size, RADEON_GPU_PAGE_SIZE); + if (info->front_buffer == NULL) { + int usage = CREATE_PIXMAP_USAGE_BACKING_PIXMAP; + + if (info->allowColorTiling && !info->shadow_primary) { + if (info->ChipFamily < CHIP_FAMILY_R600 || info->allowColorTiling2D) + usage |= RADEON_CREATE_PIXMAP_TILING_MACRO; + else + usage |= RADEON_CREATE_PIXMAP_TILING_MICRO; + } + + info->front_buffer = radeon_alloc_pixmap_bo(pScrn, pScrn->virtualX, + pScrn->virtualY, + pScrn->depth, + usage, + pScrn->bitsPerPixel, + &pitch, + &info->front_surface, + &tiling_flags); - if (info->front_bo == NULL) { - info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size, - base_align, - info->shadow_primary ? - RADEON_GEM_DOMAIN_GTT : - RADEON_GEM_DOMAIN_VRAM, - tiling_flags ? RADEON_GEM_NO_CPU_ACCESS : 0); if (info->r600_shadow_fb == TRUE) { - if (radeon_bo_map(info->front_bo, 1)) { + if (radeon_bo_map(info->front_buffer->bo.radeon, 1)) { ErrorF("Failed to map cursor buffer memory\n"); } } @@ -2786,13 +2753,14 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) tiling_flags |= RADEON_TILING_SURFACE; #endif if (tiling_flags) - radeon_bo_set_tiling(info->front_bo, tiling_flags, pitch); + radeon_bo_set_tiling(info->front_buffer->bo.radeon, tiling_flags, pitch); } pScrn->displayWidth = pitch / cpp; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", info->front_bo->size/1024); - radeon_kms_update_vram_limit(pScrn, screen_size); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", + pitch * pScrn->virtualY / 1024); + radeon_kms_update_vram_limit(pScrn, pitch * pScrn->virtualY); return TRUE; } diff --git a/src/radeon_present.c b/src/radeon_present.c index 66805d7d..2982d728 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -422,7 +422,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id) return; modeset: - radeon_finish(scrn, info->front_bo); + radeon_finish(scrn, info->front_buffer); for (i = 0; i < config->num_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c index 653de44d..0959b119 100644 --- a/src/radeon_textured_videofuncs.c +++ b/src/radeon_textured_videofuncs.c @@ -63,10 +63,12 @@ RADEONPrepareTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) radeon_cs_space_add_persistent_bo(info->cs, src_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); if (pPriv->bicubic_enabled) - radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); driver_priv = exaGetPixmapDriverPrivate(pPixmap); - radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo->bo.radeon, 0, + RADEON_GEM_DOMAIN_VRAM); ret = radeon_cs_space_check(info->cs); if (ret) { @@ -433,10 +435,12 @@ R200PrepareTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) radeon_cs_space_add_persistent_bo(info->cs, src_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); if (pPriv->bicubic_enabled) - radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); driver_priv = exaGetPixmapDriverPrivate(pPixmap); - radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo->bo.radeon, 0, + RADEON_GEM_DOMAIN_VRAM); ret = radeon_cs_space_check(info->cs); if (ret) { @@ -958,10 +962,12 @@ R300PrepareTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) radeon_cs_space_add_persistent_bo(info->cs, src_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); if (pPriv->bicubic_enabled) - radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); driver_priv = exaGetPixmapDriverPrivate(pPixmap); - radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo->bo.radeon, 0, + RADEON_GEM_DOMAIN_VRAM); ret = radeon_cs_space_check(info->cs); if (ret) { @@ -2376,10 +2382,12 @@ R500PrepareTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) radeon_cs_space_add_persistent_bo(info->cs, src_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); if (pPriv->bicubic_enabled) - radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + radeon_cs_space_add_persistent_bo(info->cs, info->bicubic_bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); driver_priv = exaGetPixmapDriverPrivate(pPixmap); - radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(info->cs, driver_priv->bo->bo.radeon, 0, + RADEON_GEM_DOMAIN_VRAM); ret = radeon_cs_space_check(info->cs); if (ret) { -- cgit v1.2.3 From 3c4c0213c11d623cba7adbc28dde652694f2f758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 29 Jun 2018 17:57:03 +0200 Subject: glamor: Use GBM for BO allocation when possible Inspired by amdgpu. This avoids various issues due to a GEM handle lifetime conflict between us and Mesa with current glamor. Bugzilla: https://bugs.freedesktop.org/105381 Tested-by: Konstantin Kharlamov Reviewed-by: Alex Deucher --- configure.ac | 10 +++++ src/Makefile.am | 4 +- src/drmmode_display.c | 39 +++++++++------- src/radeon.h | 7 ++- src/radeon_bo_helper.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++- src/radeon_bo_helper.h | 20 ++++++++- src/radeon_dri2.c | 7 +-- src/radeon_dri3.c | 13 +++--- src/radeon_glamor.c | 47 +++++++++++++------- src/radeon_glamor.h | 28 +++++++++++- src/radeon_kms.c | 40 +++++++++++------ 11 files changed, 266 insertions(+), 67 deletions(-) diff --git a/configure.ac b/configure.ac index 11efdf0a..f5614749 100644 --- a/configure.ac +++ b/configure.ac @@ -138,12 +138,22 @@ if test "x$GLAMOR" != "xno"; then [Have glamor_egl_destroy_textured_pixmap API])], [], [#include "xorg-server.h" #include "glamor.h"]) + + AC_CHECK_DECL(glamor_finish, + [AC_DEFINE(HAVE_GLAMOR_FINISH, 1, + [Have glamor_finish API])], + [PKG_CHECK_MODULES(LIBGL, [gl])], + [#include "xorg-server.h" + #include "glamor.h"]) fi if test "x$GLAMOR_XSERVER" != xyes; then PKG_CHECK_MODULES(LIBGLAMOR, [glamor >= 0.6.0]) PKG_CHECK_MODULES(LIBGLAMOR_EGL, [glamor-egl]) fi + + PKG_CHECK_MODULES(GBM, [gbm >= 10.6]) + AC_DEFINE(USE_GLAMOR, 1, [Enable glamor acceleration]) else AC_MSG_RESULT([$GLAMOR]) diff --git a/src/Makefile.am b/src/Makefile.am index ed1bfa9e..df4a95e4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,8 +62,8 @@ radeon_drv_la_SOURCES = \ $(RADEON_KMS_SRCS) if GLAMOR -AM_CFLAGS += @LIBGLAMOR_CFLAGS@ -radeon_drv_la_LIBADD += @LIBGLAMOR_LIBS@ +AM_CFLAGS += @LIBGLAMOR_CFLAGS@ @GBM_CFLAGS@ +radeon_drv_la_LIBADD += @LIBGLAMOR_LIBS@ @GBM_LIBS@ radeon_drv_la_SOURCES += \ radeon_glamor_wrappers.c \ radeon_glamor.c diff --git a/src/drmmode_display.c b/src/drmmode_display.c index c91f5bb2..2773ce67 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -142,8 +142,7 @@ static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, } if (!info->use_glamor || - radeon_glamor_create_textured_pixmap(pixmap, - radeon_get_pixmap_private(pixmap))) + radeon_glamor_create_textured_pixmap(pixmap, bo)) return pixmap; fail: @@ -435,8 +434,14 @@ destroy_pixmap_for_fbcon(ScrnInfoPtr pScrn) /* XXX: The current GPUVM support in the kernel doesn't allow removing * the virtual address range for this BO, so we need to keep around * the pixmap to avoid breaking glamor with GPUVM + * + * Similarly, need to keep around the pixmap with current glamor, to + * avoid issues due to a GEM handle lifetime conflict between us and + * Mesa */ - if (info->use_glamor && info->ChipFamily >= CHIP_FAMILY_CAYMAN) + if (info->use_glamor && + (info->ChipFamily >= CHIP_FAMILY_CAYMAN || + xorgGetVersion() >= XORG_VERSION_NUMERIC(1,19,99,1,0))) return; if (info->fbcon_pixmap) @@ -2277,21 +2282,23 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) scrn->displayWidth = pitch / cpp; + if (!info->use_glamor) { #if X_BYTE_ORDER == X_BIG_ENDIAN - switch (cpp) { - case 4: - tiling_flags |= RADEON_TILING_SWAP_32BIT; - break; - case 2: - tiling_flags |= RADEON_TILING_SWAP_16BIT; - break; - } - if (info->ChipFamily < CHIP_FAMILY_R600 && - info->r600_shadow_fb && tiling_flags) - tiling_flags |= RADEON_TILING_SURFACE; + switch (cpp) { + case 4: + tiling_flags |= RADEON_TILING_SWAP_32BIT; + break; + case 2: + tiling_flags |= RADEON_TILING_SWAP_16BIT; + break; + } + if (info->ChipFamily < CHIP_FAMILY_R600 && + info->r600_shadow_fb && tiling_flags) + tiling_flags |= RADEON_TILING_SURFACE; #endif - if (tiling_flags) - radeon_bo_set_tiling(info->front_buffer->bo.radeon, tiling_flags, pitch); + if (tiling_flags) + radeon_bo_set_tiling(info->front_buffer->bo.radeon, tiling_flags, pitch); + } if (!info->r600_shadow_fb) { if (info->surf_man && !info->use_glamor) diff --git a/src/radeon.h b/src/radeon.h index 648fd98a..2bcfa41b 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -606,6 +606,8 @@ typedef struct { unsigned hwcursor_disabled; #ifdef USE_GLAMOR + struct gbm_device *gbm; + struct { CreateGCProcPtr SavedCreateGC; RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr, int, int, @@ -744,8 +746,6 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_buffer *bo } if (bo) { - uint32_t pitch; - if (!priv) { priv = calloc(1, sizeof (struct radeon_pixmap)); if (!priv) @@ -754,11 +754,10 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_buffer *bo radeon_buffer_ref(bo); priv->bo = bo; - - radeon_bo_get_tiling(bo->bo.radeon, &priv->tiling_flags, &pitch); } radeon_set_pixmap_private(pPix, priv); + radeon_get_pixmap_tiling_flags(pPix); return TRUE; } else #endif /* USE_GLAMOR */ diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index 2b836bbf..79e8ff1b 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -28,6 +28,37 @@ #include "radeon_glamor.h" #include "radeon_bo_gem.h" + +#ifdef USE_GLAMOR + +static uint32_t +radeon_get_gbm_format(int depth, int bitsPerPixel) +{ + switch (depth) { +#ifdef GBM_FORMAT_R8 + case 8: + return GBM_FORMAT_R8; +#endif + case 16: + return GBM_FORMAT_RGB565; + case 32: + return GBM_FORMAT_ARGB8888; + case 30: + return GBM_FORMAT_XRGB2101010; + case 24: + if (bitsPerPixel == 32) + return GBM_FORMAT_XRGB8888; + /* fall through */ + default: + ErrorF("%s: Unsupported depth/bpp %d/%d\n", __func__, depth, + bitsPerPixel); + return ~0U; + } +} + +#endif /* USE_GLAMOR */ + + static const unsigned MicroBlockTable[5][3][2] = { /*linear tiled square-tiled */ {{32, 1}, {8, 4}, {0, 0}}, /* 8 bits per pixel */ @@ -158,6 +189,46 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, struct radeon_surface surface; struct radeon_buffer *bo; int domain = RADEON_GEM_DOMAIN_VRAM; + +#ifdef USE_GLAMOR + if (info->use_glamor && + !(usage_hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP && + info->shadow_primary)) { + uint32_t bo_use = GBM_BO_USE_RENDERING; + uint32_t gbm_format = radeon_get_gbm_format(depth, bitsPerPixel); + + if (gbm_format == ~0U) + return NULL; + + bo = calloc(1, sizeof(struct radeon_buffer)); + if (!bo) + return NULL; + + bo->ref_count = 1; + + if (bitsPerPixel == pScrn->bitsPerPixel) + bo_use |= GBM_BO_USE_SCANOUT; + + if ((usage_hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP && + info->shadow_primary) || + (usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED) + bo_use |= GBM_BO_USE_LINEAR; + + bo->bo.gbm = gbm_bo_create(info->gbm, width, height, gbm_format, bo_use); + if (!bo->bo.gbm) { + free(bo); + return NULL; + } + + bo->flags |= RADEON_BO_FLAGS_GBM; + + if (new_pitch) + *new_pitch = gbm_bo_get_stride(bo->bo.gbm); + + return bo; + } +#endif + if (usage_hint) { if (info->allowColorTiling) { if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MACRO) @@ -245,6 +316,13 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth, void radeon_finish(ScrnInfoPtr scrn, struct radeon_buffer *bo) { + RADEONInfoPtr info = RADEONPTR(scrn); + + if (info->use_glamor) { + radeon_glamor_finish(scrn); + return; + } + radeon_cs_flush_indirect(scrn); radeon_bo_wait(bo->bo.radeon); } @@ -282,7 +360,7 @@ Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle) RADEONInfoPtr info = RADEONPTR(scrn); #endif - if (bo) { + if (bo && !(bo->flags & RADEON_BO_FLAGS_GBM)) { *handle = bo->bo.radeon->handle; return TRUE; } @@ -380,6 +458,44 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle, if (!bo) goto error; +#ifdef USE_GLAMOR + if (info->use_glamor) { + struct gbm_import_fd_data data; + uint32_t bo_use = GBM_BO_USE_RENDERING; + + data.format = radeon_get_gbm_format(ppix->drawable.depth, + ppix->drawable.bitsPerPixel); + if (data.format == ~0U) + goto error; + + bo->ref_count = 1; + + data.fd = ihandle; + data.width = ppix->drawable.width; + data.height = ppix->drawable.height; + data.stride = ppix->devKind; + + if (ppix->drawable.bitsPerPixel == pScrn->bitsPerPixel) + bo_use |= GBM_BO_USE_SCANOUT; + + bo->bo.gbm = gbm_bo_import(info->gbm, GBM_BO_IMPORT_FD, &data, bo_use); + if (!bo->bo.gbm) + goto error; + + bo->flags |= RADEON_BO_FLAGS_GBM; + + if (!radeon_glamor_create_textured_pixmap(ppix, bo)) { + radeon_buffer_unref(&bo); + return FALSE; + } + + ret = radeon_set_pixmap_bo(ppix, bo); + /* radeon_set_pixmap_bo increments ref_count if it succeeds */ + radeon_buffer_unref(&bo); + return ret; + } +#endif + bo->bo.radeon = radeon_gem_bo_open_prime(info->bufmgr, ihandle, size); if (!bo) goto error; diff --git a/src/radeon_bo_helper.h b/src/radeon_bo_helper.h index 53af87c3..cc3d1d3b 100644 --- a/src/radeon_bo_helper.h +++ b/src/radeon_bo_helper.h @@ -23,13 +23,21 @@ #ifndef RADEON_BO_HELPER_H #define RADEON_BO_HELPER_H 1 +#ifdef USE_GLAMOR +#include +#endif + #define RADEON_BO_FLAGS_GBM 0x1 struct radeon_buffer { union { +#ifdef USE_GLAMOR + struct gbm_bo *gbm; +#endif struct radeon_bo *radeon; } bo; uint32_t ref_count; + uint32_t flags; }; extern struct radeon_buffer * @@ -88,8 +96,16 @@ radeon_buffer_unref(struct radeon_buffer **buffer) return; } - radeon_bo_unmap(buf->bo.radeon); - radeon_bo_unref(buf->bo.radeon); +#ifdef USE_GLAMOR + if (buf->flags & RADEON_BO_FLAGS_GBM) { + gbm_bo_destroy(buf->bo.gbm); + } else +#endif + { + radeon_bo_unmap(buf->bo.radeon); + radeon_bo_unref(buf->bo.radeon); + } + free(buf); *buffer = NULL; } diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 584a1d9d..ab3db6c5 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -79,11 +79,12 @@ static DevPrivateKeyRec dri2_window_private_key_rec; static Bool radeon_get_flink_name(RADEONEntPtr pRADEONEnt, PixmapPtr pixmap, uint32_t *name) { - struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap)->bo.radeon; + struct radeon_buffer *bo = radeon_get_pixmap_bo(pixmap); struct drm_gem_flink flink; - if (bo) - return radeon_gem_get_kernel_name(bo, name) == 0; + if (bo && !(bo->flags & RADEON_BO_FLAGS_GBM) && + radeon_gem_get_kernel_name(bo->bo.radeon, name) == 0) + return TRUE; if (radeon_get_pixmap_handle(pixmap, &flink.handle)) { if (drmIoctl(pRADEONEnt->fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c index b199c793..688e594e 100644 --- a/src/radeon_dri3.c +++ b/src/radeon_dri3.c @@ -213,17 +213,16 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen, { struct radeon_bo *bo; int fd; - - bo = radeon_get_pixmap_bo(pixmap)->bo.radeon; - if (!bo) { #ifdef USE_GLAMOR - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - RADEONInfoPtr info = RADEONPTR(scrn); + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONInfoPtr info = RADEONPTR(scrn); - if (info->use_glamor) - return glamor_fd_from_pixmap(screen, pixmap, stride, size); + if (info->use_glamor) + return glamor_fd_from_pixmap(screen, pixmap, stride, size); #endif + bo = radeon_get_pixmap_bo(pixmap)->bo.radeon; + if (!bo) { exaMoveInPixmap(pixmap); bo = radeon_get_pixmap_bo(pixmap)->bo.radeon; if (!bo) diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index c1d96160..fa634947 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -52,6 +52,7 @@ radeon_glamor_create_screen_resources(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONInfoPtr info = RADEONPTR(scrn); + uint32_t handle; if (!info->use_glamor) return TRUE; @@ -61,8 +62,12 @@ radeon_glamor_create_screen_resources(ScreenPtr screen) return FALSE; #endif - if (!glamor_egl_create_textured_screen(screen, - info->front_buffer->bo.radeon->handle, + if (info->front_buffer->flags & RADEON_BO_FLAGS_GBM) + handle = gbm_bo_get_handle(info->front_buffer->bo.gbm).u32; + else + handle = info->front_buffer->bo.radeon->handle; + + if (!glamor_egl_create_textured_screen(screen, handle, scrn->displayWidth * info->pixel_bytes)) return FALSE; @@ -136,6 +141,13 @@ radeon_glamor_pre_init(ScrnInfoPtr scrn) } #endif + info->gbm = gbm_create_device(pRADEONEnt->fd); + if (!info->gbm) { + xf86DrvMsg(scrn->scrnIndex, X_ERROR, + "gbm_create_device returned NULL\n"); + return FALSE; + } + /* Load glamor module */ if ((glamor_module = xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME))) { version = xf86GetModuleVersion(glamor_module); @@ -164,10 +176,21 @@ radeon_glamor_pre_init(ScrnInfoPtr scrn) } Bool -radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *priv) +radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_buffer *bo) { - return glamor_egl_create_textured_pixmap(pixmap, priv->bo->bo.radeon->handle, - pixmap->devKind); + ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); + RADEONInfoPtr info = RADEONPTR(scrn); + uint32_t handle; + + if (!info->use_glamor) + return TRUE; + + if (bo->flags & RADEON_BO_FLAGS_GBM) + handle = gbm_bo_get_handle(bo->bo.gbm).u32; + else + handle = bo->bo.radeon->handle; + + return glamor_egl_create_textured_pixmap(pixmap, handle, pixmap->devKind); } static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap) @@ -179,13 +202,6 @@ static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap) #endif if (pixmap->refcnt == 1) { - if (pixmap->devPrivate.ptr) { - struct radeon_buffer *bo = radeon_get_pixmap_bo(pixmap); - - if (bo) - radeon_bo_unmap(bo->bo.radeon); - } - #ifdef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP glamor_egl_destroy_textured_pixmap(pixmap); #endif @@ -259,7 +275,7 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL); - if (!radeon_glamor_create_textured_pixmap(pixmap, priv)) + if (!radeon_glamor_create_textured_pixmap(pixmap, priv->bo)) goto fallback_glamor; pixmap->devPrivate.ptr = NULL; @@ -390,13 +406,12 @@ radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct radeon_pixmap *priv; if (!radeon_set_shared_pixmap_backing(pixmap, handle, NULL)) return FALSE; - priv = radeon_get_pixmap_private(pixmap); - if (!radeon_glamor_create_textured_pixmap(pixmap, priv)) { + if (!radeon_glamor_create_textured_pixmap(pixmap, + radeon_get_pixmap_bo(pixmap))) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to get PRIME drawable for glamor pixmap.\n"); return FALSE; diff --git a/src/radeon_glamor.h b/src/radeon_glamor.h index ec42df1f..2740ab33 100644 --- a/src/radeon_glamor.h +++ b/src/radeon_glamor.h @@ -33,6 +33,12 @@ struct radeon_pixmap; #ifdef USE_GLAMOR +#ifndef HAVE_GLAMOR_FINISH +#include +#endif + +#include + #define GLAMOR_FOR_XORG 1 #include @@ -65,12 +71,27 @@ void radeon_glamor_screen_init(ScreenPtr screen); Bool radeon_glamor_create_screen_resources(ScreenPtr screen); void radeon_glamor_free_screen(int scrnIndex, int flags); -Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *priv); +Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_buffer *bo); void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst); PixmapPtr radeon_glamor_set_pixmap_bo(DrawablePtr drawable, PixmapPtr pixmap); XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt); +static inline void +radeon_glamor_finish(ScrnInfoPtr scrn) +{ + RADEONInfoPtr info = RADEONPTR(scrn); + +#if HAVE_GLAMOR_FINISH + glamor_finish(scrn->pScreen); +#else + glamor_block_handler(scrn); + glFinish(); +#endif + + info->gpu_flushed++; +} + #else static inline Bool radeon_glamor_pre_init(ScrnInfoPtr scrn) { return FALSE; } @@ -79,7 +100,7 @@ static inline void radeon_glamor_fini(ScreenPtr screen) { } static inline Bool radeon_glamor_create_screen_resources(ScreenPtr screen) { return FALSE; } static inline void radeon_glamor_free_screen(int scrnIndex, int flags) { } -static inline Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_pixmap *priv) { return TRUE; } +static inline Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_buffer *bo) { return TRUE; } static inline void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst) {} static inline PixmapPtr radeon_glamor_set_pixmap_bo(DrawablePtr drawable, PixmapPtr pixmap) { return pixmap; } @@ -87,6 +108,9 @@ static inline PixmapPtr radeon_glamor_set_pixmap_bo(DrawablePtr drawable, Pixmap static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap) { return NULL; } static inline XF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt) { return NULL; } + +static inline void radeon_glamor_finish(ScrnInfoPtr pScrn) { } + #endif #endif /* RADEON_GLAMOR_H */ diff --git a/src/radeon_kms.c b/src/radeon_kms.c index d3eeebea..72e60831 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -212,6 +212,11 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn) info->accel_state = NULL; } +#ifdef USE_GLAMOR + if (info->gbm) + gbm_device_destroy(info->gbm); +#endif + pEnt = info->pEnt; free(pScrn->driverPrivate); pScrn->driverPrivate = NULL; @@ -2269,7 +2274,11 @@ Bool RADEONScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "radeon_setup_kernel_mem failed\n"); return FALSE; } - front_ptr = info->front_buffer->bo.radeon->ptr; + + if (!(info->front_buffer->flags & RADEON_BO_FLAGS_GBM)) + front_ptr = info->front_buffer->bo.radeon->ptr; + else + front_ptr = NULL; if (info->r600_shadow_fb) { info->fb_shadow = calloc(1, @@ -2739,21 +2748,24 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) ErrorF("Failed to map cursor buffer memory\n"); } } + + if (!info->use_glamor) { #if X_BYTE_ORDER == X_BIG_ENDIAN - switch (cpp) { - case 4: - tiling_flags |= RADEON_TILING_SWAP_32BIT; - break; - case 2: - tiling_flags |= RADEON_TILING_SWAP_16BIT; - break; - } - if (info->ChipFamily < CHIP_FAMILY_R600 && - info->r600_shadow_fb && tiling_flags) - tiling_flags |= RADEON_TILING_SURFACE; + switch (cpp) { + case 4: + tiling_flags |= RADEON_TILING_SWAP_32BIT; + break; + case 2: + tiling_flags |= RADEON_TILING_SWAP_16BIT; + break; + } + if (info->ChipFamily < CHIP_FAMILY_R600 && + info->r600_shadow_fb && tiling_flags) + tiling_flags |= RADEON_TILING_SURFACE; #endif - if (tiling_flags) - radeon_bo_set_tiling(info->front_buffer->bo.radeon, tiling_flags, pitch); + if (tiling_flags) + radeon_bo_set_tiling(info->front_buffer->bo.radeon, tiling_flags, pitch); + } } pScrn->displayWidth = pitch / cpp; -- cgit v1.2.3 From 413622bcccc9d36a9c87679f379dc84b21a3c655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 17:23:24 +0200 Subject: Swap pixmap privates in radeon_dri2_exchange_buffers Instead of only the BOs. This matches what amdgpu does, and fixes issues with DRI2 page flipping. Reviewed-by: Alex Deucher --- src/radeon_dri2.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index ab3db6c5..70ad1d92 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -720,9 +720,8 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt { struct dri2_buffer_priv *front_priv = front->driverPrivate; struct dri2_buffer_priv *back_priv = back->driverPrivate; - struct radeon_buffer *front_buffer, *back_buffer; - ScreenPtr screen; - RADEONInfoPtr info; + ScreenPtr screen = draw->pScreen; + RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen)); RegionRec region; int tmp; @@ -737,23 +736,28 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt front->name = back->name; back->name = tmp; - /* Swap pixmap bos */ - front_buffer = radeon_get_pixmap_bo(front_priv->pixmap); - back_buffer = radeon_get_pixmap_bo(back_priv->pixmap); - radeon_set_pixmap_bo(front_priv->pixmap, back_buffer); - radeon_set_pixmap_bo(back_priv->pixmap, front_buffer); - - /* Do we need to update the Screen? */ - screen = draw->pScreen; - info = RADEONPTR(xf86ScreenToScrn(screen)); - if (front_buffer == info->front_buffer) { - radeon_buffer_ref(back_buffer); - radeon_buffer_unref(&info->front_buffer); - info->front_buffer = back_buffer; - radeon_set_pixmap_bo(screen->GetScreenPixmap(screen), back_buffer); - } + /* Swap pixmap privates */ +#ifdef USE_GLAMOR + if (info->use_glamor) { + struct radeon_pixmap *front_pix, *back_pix; + + front_pix = radeon_get_pixmap_private(front_priv->pixmap); + back_pix = radeon_get_pixmap_private(back_priv->pixmap); + radeon_set_pixmap_private(front_priv->pixmap, back_pix); + radeon_set_pixmap_private(back_priv->pixmap, front_pix); - radeon_glamor_exchange_buffers(front_priv->pixmap, back_priv->pixmap); + radeon_glamor_exchange_buffers(front_priv->pixmap, back_priv->pixmap); + } else +#endif + { + struct radeon_exa_pixmap_priv driver_priv = *(struct radeon_exa_pixmap_priv*) + exaGetPixmapDriverPrivate(front_priv->pixmap); + + *(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(front_priv->pixmap) = + *(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(back_priv->pixmap); + *(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(back_priv->pixmap) = + driver_priv; + } DamageRegionProcessPending(&front_priv->pixmap->drawable); } -- cgit v1.2.3 From cc1d0824a8a7ef29f8911b95695f7cb1b4abe9b8 Mon Sep 17 00:00:00 2001 From: Jim Qu Date: Tue, 10 Jul 2018 18:36:42 +0200 Subject: Wait for pending scanout update before calling drmmode_crtc_scanout_free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a case that when set screen from reverse to normal, the old scanout damage is freed in modesetting before scanout update handler, so it causes segment fault issue. Signed-off-by: Jim Qu [ Michel Dänzer: Only call drmmode_crtc_wait_pending_event before drmmode_crtc_scanout_free is actually called, slightly tweak commit message ] Signed-off-by: Michel Dänzer (Ported from amdgpu commit 9f6a8905611b5b1d8fcd31bebbc9af7ca1355cc3) Acked-by: Alex Deucher --- src/drmmode_display.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 2773ce67..b3e5cc99 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -985,9 +985,11 @@ done: if (drmmode_crtc->scanout[scanout_id].pixmap && fb != radeon_pixmap_get_fb(drmmode_crtc-> - scanout[scanout_id].pixmap)) + scanout[scanout_id].pixmap)) { + drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, + drmmode_crtc->scanout_update_pending); drmmode_crtc_scanout_free(drmmode_crtc); - else if (!drmmode_crtc->tear_free) { + } else if (!drmmode_crtc->tear_free) { drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]); } -- cgit v1.2.3 From 731d4b386a55cdb468e37b69d41284150952cf8c Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Tue, 10 Jul 2018 18:39:31 +0200 Subject: Do not export the DriverRec RADEON Unused externally and should not be exported. Signed-off-by: Emil Velikov (Ported from amdgpu commit 7fb8b49895e225b3908c8bd186539de23afe91d1) Acked-by: Alex Deucher --- src/radeon_probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/radeon_probe.c b/src/radeon_probe.c index 19295f00..04f9e559 100644 --- a/src/radeon_probe.c +++ b/src/radeon_probe.c @@ -278,7 +278,7 @@ radeon_platform_probe(DriverPtr pDriver, } #endif -_X_EXPORT DriverRec RADEON = +DriverRec RADEON = { RADEON_VERSION_CURRENT, RADEON_DRIVER_NAME, -- cgit v1.2.3 From d14ff6b77824d0e32728869907e88d6866243101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 18:41:43 +0200 Subject: Ignore RADEON_DRM_QUEUE_ERROR (0) in radeon_drm_abort_entry This allows a following change to be slightly simpler. (Ported from amdgpu commit 8fcc3a9b43d3907052a83a96e5a2423afab5ad3f) Acked-by: Alex Deucher --- src/radeon_drm_queue.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index 869f95c3..ac775f86 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -150,6 +150,9 @@ radeon_drm_abort_entry(uintptr_t seq) { struct radeon_drm_queue_entry *e, *tmp; + if (seq == RADEON_DRM_QUEUE_ERROR) + return; + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { if (e->seq == seq) { radeon_drm_abort_one(e); -- cgit v1.2.3 From 290291a11598ba9aa594417998502b0e0ac96970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 18:43:28 +0200 Subject: Track DRM event queue sequence number in scanout_update_pending Preparation for next change, no behaviour change intended. (Ported from amdgpu commit 04a5c5f7cfacad8d9ccffe81e388cc3da2036cb5) Acked-by: Alex Deucher --- src/drmmode_display.h | 2 +- src/radeon_kms.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 23460fdc..27c23c1a 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -88,7 +88,7 @@ typedef struct { Bool ignore_damage; RegionRec scanout_last_region; unsigned scanout_id; - Bool scanout_update_pending; + uintptr_t scanout_update_pending; Bool tear_free; PixmapPtr prime_scanout_pixmap; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 72e60831..cdda8962 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -526,7 +526,7 @@ radeon_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_crtc->scanout_update_pending = FALSE; + drmmode_crtc->scanout_update_pending = 0; drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, NULL); } @@ -611,7 +611,7 @@ radeon_prime_scanout_update_abort(xf86CrtcPtr crtc, void *event_data) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_crtc->scanout_update_pending = FALSE; + drmmode_crtc->scanout_update_pending = 0; } void @@ -752,7 +752,7 @@ radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t u drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; radeon_prime_scanout_do_update(crtc, 0); - drmmode_crtc->scanout_update_pending = FALSE; + drmmode_crtc->scanout_update_pending = 0; } static void @@ -793,7 +793,7 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) return; } - drmmode_crtc->scanout_update_pending = TRUE; + drmmode_crtc->scanout_update_pending = drm_queue_seq; } static void @@ -851,7 +851,7 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) } drmmode_crtc->scanout_id = scanout_id; - drmmode_crtc->scanout_update_pending = TRUE; + drmmode_crtc->scanout_update_pending = drm_queue_seq; } static void @@ -1000,7 +1000,7 @@ radeon_scanout_update_abort(xf86CrtcPtr crtc, void *event_data) { drmmode_crtc_private_ptr drmmode_crtc = event_data; - drmmode_crtc->scanout_update_pending = FALSE; + drmmode_crtc->scanout_update_pending = 0; } static void @@ -1077,7 +1077,7 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) return; } - drmmode_crtc->scanout_update_pending = TRUE; + drmmode_crtc->scanout_update_pending = drm_queue_seq; } static void @@ -1144,7 +1144,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, } drmmode_crtc->scanout_id = scanout_id; - drmmode_crtc->scanout_update_pending = TRUE; + drmmode_crtc->scanout_update_pending = drm_queue_seq; } static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) -- cgit v1.2.3 From 05390ae36a0abb19f1d533ff95a3fceaafdf79c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 18:45:51 +0200 Subject: Abort scanout_update_pending event when possible We don't need to wait for a non-TearFree scanout update before scanning out from the screen pixmap or before flipping, as the scanout update won't be visible anyway. Instead, just abort it. (Ported from amdgpu commit 36d01989cd842588f12fdae5b2cba5fdcf9c91dd) Acked-by: Alex Deucher --- src/drmmode_display.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index b3e5cc99..64dab316 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -986,8 +986,8 @@ done: if (drmmode_crtc->scanout[scanout_id].pixmap && fb != radeon_pixmap_get_fb(drmmode_crtc-> scanout[scanout_id].pixmap)) { - drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, - drmmode_crtc->scanout_update_pending); + radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending); + drmmode_crtc->scanout_update_pending = 0; drmmode_crtc_scanout_free(drmmode_crtc); } else if (!drmmode_crtc->tear_free) { drmmode_crtc_scanout_destroy(drmmode, @@ -3190,8 +3190,12 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, extents); radeon_cs_flush_indirect(crtc->scrn); - drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, - drmmode_crtc->scanout_update_pending); + if (drmmode_crtc->scanout_update_pending) { + drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, + drmmode_crtc->flip_pending); + radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending); + drmmode_crtc->scanout_update_pending = 0; + } } if (crtc == ref_crtc) { -- cgit v1.2.3 From e07c38649280b3f4361005bc4c256f2145a72537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 18:48:16 +0200 Subject: Update RandR CRTC state if set_mode_major fails in set_desired_modes Without this, RandR would report the CRTC and its outputs as enabled, even though they were actually off due to the failure. (Cherry picked from amdgpu commit 4dcda0b48d62944c841cd9540f4ad4c7ac8dee47) Acked-by: Alex Deucher --- src/drmmode_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 64dab316..fa05cda4 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2833,6 +2833,8 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, } else { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to set mode on CRTC %d\n", c); + RRCrtcSet(crtc->randr_crtc, NULL, crtc->x, crtc->y, + crtc->rotation, 0, NULL); } } else { crtc->mode = crtc->desiredMode; -- cgit v1.2.3 From 9f2409c4d3a9ecad8e769783e307e57a75b1255e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 18:49:05 +0200 Subject: Simplify drmmode_crtc_scanout_update Use our own BoxRec for the extents, and RegionEmpty for clearing the scanout damage region. (Ported from amdgpu commit 72c3e9c7308fbcdf85708b72f9be14a5f2f8e7b5) Acked-by: Alex Deucher --- src/drmmode_display.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index fa05cda4..b3b37f56 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -765,8 +765,8 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, if (drmmode_crtc->scanout[scanout_id].pixmap && (!drmmode_crtc->tear_free || drmmode_crtc->scanout[scanout_id ^ 1].pixmap)) { - RegionPtr region; - BoxPtr box; + BoxRec extents = { .x1 = 0, .y1 = 0, + .x2 = scrn->virtualX, .y2 = scrn->virtualY }; if (!drmmode_crtc->scanout_damage) { drmmode_crtc->scanout_damage = @@ -778,21 +778,13 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_crtc->scanout_damage); } - region = DamageRegion(drmmode_crtc->scanout_damage); - RegionUninit(region); - region->data = NULL; - box = RegionExtents(region); - box->x1 = 0; - box->y1 = 0; - box->x2 = max(box->x2, scrn->virtualX); - box->y2 = max(box->y2, scrn->virtualY); - *fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); *x = *y = 0; radeon_scanout_do_update(crtc, scanout_id, screen->GetWindowPixmap(screen->root), - *box); + extents); + RegionEmpty(DamageRegion(drmmode_crtc->scanout_damage)); radeon_finish(scrn, drmmode_crtc->scanout[scanout_id].bo); } } -- cgit v1.2.3 From 89d38e976fd6ba6e026cda7c5d05971f1f177f13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 18:51:00 +0200 Subject: Don't call scanout_flip/update with a legacy RandR scanout buffer It means we are not using our own scanout buffers. Fixes crash when TearFree is supposed to be enabled, but drmmode_handle_transform doesn't set crtc->driverIsPerformingTransform. Bugzilla: https://bugs.freedesktop.org/105736 (Ported from amdgpu commit 463477661c88cab3a87746499e5838c5b9f9a13b) Acked-by: Alex Deucher --- src/radeon_kms.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index cdda8962..15dca0de 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1167,6 +1167,9 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) xf86CrtcPtr crtc = xf86_config->crtc[c]; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + if (drmmode_crtc->rotate.pixmap) + continue; + if (drmmode_crtc->tear_free) radeon_scanout_flip(pScreen, info, crtc); else if (drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) -- cgit v1.2.3 From e9d2d149481e2a9c7cba50d43c6a5146124be3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 18:52:08 +0200 Subject: Simplify drmmode_handle_transform Set crtc->driverIsPerformingTransform for any case we can handle before calling xf86CrtcRotate. We already clear it afterwards when the latter clears crtc->transform_in_use. This should allow our separate scanout buffer mechanism to be used in more cases. (Cherry picked from amdgpu commit 8e544b4a0de6717feb4abf00052d57c5b726b5ce) Acked-by: Alex Deucher --- src/drmmode_display.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index b3b37f56..fce8723e 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -669,13 +669,9 @@ drmmode_handle_transform(xf86CrtcPtr crtc) Bool ret; #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,903,0) - if (crtc->transformPresent || crtc->rotation != RR_Rotate_0) - crtc->driverIsPerformingTransform = XF86DriverTransformOutput; - else - crtc->driverIsPerformingTransform = XF86DriverTransformNone; + crtc->driverIsPerformingTransform = XF86DriverTransformOutput; #else crtc->driverIsPerformingTransform = !crtc->transformPresent && - crtc->rotation != RR_Rotate_0 && (crtc->rotation & 0xf) == RR_Rotate_0; #endif -- cgit v1.2.3 From ee7e15746148122abf6728fb0f59d6c8ae329e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 18:53:06 +0200 Subject: Set drmmode_crtc->scanout_id = 0 when TearFree is disabled When disabling TearFree, drmmode_crtc->scanout_id could remain as 1, but drmmode_set_mode_major would destroy drmmode_crtc->scanout[1], so scanout_do_update() would keep bailing, and the scanout buffer would stop being updated. Fixes freeze after disabling TearFree on a CRTC with active RandR rotation or other transform. (Ported from amdgpu commit 7db0c8e9d7586cff4312d4b93684d35de3e6376f) Acked-by: Alex Deucher --- src/drmmode_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index fce8723e..df8ef320 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -885,6 +885,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_crtc_update_tear_free(crtc); if (drmmode_crtc->tear_free) scanout_id = drmmode_crtc->scanout_id; + else + drmmode_crtc->scanout_id = 0; drmmode_crtc_gamma_do_set(crtc, crtc->gamma_red, crtc->gamma_green, crtc->gamma_blue, crtc->gamma_size); -- cgit v1.2.3 From f01d8cf2bd9681b8f5f0e2eddec0a79614389771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 18:53:54 +0200 Subject: Refactor drmmode_output_set_tear_free helper Preparation for the following fix, no functional change intended. (Ported from amdgpu commit fa30f4601de7a44edfb4a95873bd648946fd4292) Acked-by: Alex Deucher --- src/drmmode_display.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index df8ef320..ae605eda 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1743,6 +1743,22 @@ drmmode_output_create_resources(xf86OutputPtr output) } } +static void +drmmode_output_set_tear_free(RADEONEntPtr pRADEONEnt, + drmmode_output_private_ptr drmmode_output, + xf86CrtcPtr crtc, int tear_free) +{ + if (drmmode_output->tear_free == tear_free) + return; + + drmmode_output->tear_free = tear_free; + + if (crtc) { + drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, + crtc->x, crtc->y); + } +} + static Bool drmmode_output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) @@ -1783,16 +1799,8 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property, for (j = 0; j < p->mode_prop->count_enums; j++) { if (!strcmp(p->mode_prop->enums[j].name, name)) { if (i == (drmmode_output->num_props - 1)) { - if (drmmode_output->tear_free != j) { - xf86CrtcPtr crtc = output->crtc; - - drmmode_output->tear_free = j; - if (crtc) { - drmmode_set_mode_major(crtc, &crtc->mode, - crtc->rotation, - crtc->x, crtc->y); - } - } + drmmode_output_set_tear_free(pRADEONEnt, drmmode_output, + output->crtc, j); } else { drmModeConnectorSetProperty(pRADEONEnt->fd, drmmode_output->output_id, -- cgit v1.2.3 From cf8bc72e3473cef2b511e2c938eb00aca82de909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 10 Jul 2018 18:57:49 +0200 Subject: Wait for pending flips in drmmode_output_set_tear_free This prevents a nested call to drmHandleEvent, which would hang. Fixes hangs when disabling TearFree on a CRTC while a DRI3 client is page flipping. (Ported from amdgpu commit 04947b83cce3a7782e59dece2c7797cc396c1e05) Acked-by: Alex Deucher --- src/drmmode_display.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index ae605eda..003fe51e 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1754,6 +1754,14 @@ drmmode_output_set_tear_free(RADEONEntPtr pRADEONEnt, drmmode_output->tear_free = tear_free; if (crtc) { + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + /* Wait for pending flips before drmmode_set_mode_major calls + * drmmode_crtc_update_tear_free, to prevent a nested + * drmHandleEvent call, which would hang + */ + drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, + drmmode_crtc->flip_pending); drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); } -- cgit v1.2.3 From 4050b0ad51b1c65945c6474981d1228888738cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 11 Jul 2018 18:42:58 +0200 Subject: Replace 'foo == NULL' with '!foo' Shorter and sweeter. :) (Ported from amdgpu commit e8e688f3852fb06b0c34ed5bce47c9493bcd1613) Acked-by: Alex Deucher --- src/ati.c | 4 ++-- src/drmmode_display.c | 8 ++++---- src/evergreen_exa.c | 10 +++++----- src/r600_exa.c | 10 +++++----- src/radeon.h | 2 +- src/radeon_dri2.c | 12 ++++++------ src/radeon_exa.c | 2 +- src/radeon_exa_funcs.c | 8 ++++---- src/radeon_exa_render.c | 6 +++--- src/radeon_glamor.c | 2 +- src/radeon_glamor_wrappers.c | 4 ++-- src/radeon_kms.c | 25 ++++++++++++------------- src/radeon_textured_video.c | 10 +++++----- src/radeon_video.c | 6 +++--- 14 files changed, 54 insertions(+), 55 deletions(-) diff --git a/src/ati.c b/src/ati.c index 6fd21567..837b0094 100644 --- a/src/ati.c +++ b/src/ati.c @@ -109,7 +109,7 @@ ati_device_get_primary(void) device_iter = pci_slot_match_iterator_create(NULL); - while ((device = pci_device_next(device_iter)) != NULL) { + while ((device = pci_device_next(device_iter))) { if (xf86IsPrimaryPci(device)) break; } @@ -128,7 +128,7 @@ ati_device_get_indexed(int index) device_iter = pci_slot_match_iterator_create(NULL); - while ((device = pci_device_next(device_iter)) != NULL) { + while ((device = pci_device_next(device_iter))) { if (device->vendor_id == PCI_VENDOR_ATI) { if (count == index) return device; diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 003fe51e..3117b8f1 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -386,7 +386,7 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, return pixmap; fbcon = drmModeGetFB(pRADEONEnt->fd, fbcon_id); - if (fbcon == NULL) + if (!fbcon) return NULL; if (fbcon->depth != pScrn->depth || @@ -410,7 +410,7 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode, bo->ref_count = 1; bo->bo.radeon = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0); - if (bo == NULL) { + if (!bo) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't open BO for fbcon handle\n"); goto out_free_fb; @@ -1365,7 +1365,7 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res RADEONInfoPtr info = RADEONPTR(pScrn); crtc = xf86CrtcCreate(pScrn, &info->drmmode_crtc_funcs); - if (crtc == NULL) + if (!crtc) return 0; drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); @@ -2317,7 +2317,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) if (radeon_bo_map(info->front_buffer->bo.radeon, 1)) goto fail; fb_shadow = calloc(1, pitch * scrn->virtualY); - if (fb_shadow == NULL) + if (!fb_shadow) goto fail; free(info->fb_shadow); info->fb_shadow = fb_shadow; diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c index dae8b6a1..447ed217 100644 --- a/src/evergreen_exa.c +++ b/src/evergreen_exa.c @@ -511,7 +511,7 @@ EVERGREENPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, accel_state->copy_area_bo = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); - if (accel_state->copy_area_bo == NULL) + if (!accel_state->copy_area_bo) RADEON_FALLBACK(("temp copy surface alloc failed\n")); radeon_cs_space_add_persistent_bo(info->cs, accel_state->copy_area_bo, @@ -1693,7 +1693,7 @@ EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, base_align = drmmode_get_base_align(pScrn, (bpp / 8), 0); size = scratch_pitch * height * (bpp / 8); scratch = radeon_bo_open(info->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_GTT, 0); - if (scratch == NULL) { + if (!scratch) { goto copy; } @@ -1821,7 +1821,7 @@ EVERGREENDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, base_align = drmmode_get_base_align(pScrn, (bpp / 8), 0); size = scratch_pitch * height * (bpp / 8); scratch = radeon_bo_open(info->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_GTT, 0); - if (scratch == NULL) { + if (!scratch) { goto copy; } radeon_cs_space_reset_bos(info->cs); @@ -1927,7 +1927,7 @@ EVERGREENAllocShaders(ScrnInfoPtr pScrn, ScreenPtr pScreen) accel_state->shaders_bo = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); - if (accel_state->shaders_bo == NULL) { + if (!accel_state->shaders_bo) { ErrorF("Allocating shader failed\n"); return FALSE; } @@ -2046,7 +2046,7 @@ EVERGREENDrawInit(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(pScrn); - if (info->accel_state->exa == NULL) { + if (!info->accel_state->exa) { xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map not set up\n"); return FALSE; } diff --git a/src/r600_exa.c b/src/r600_exa.c index bd824c87..99db0c40 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -575,7 +575,7 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, accel_state->copy_area_bo = radeon_bo_open(info->bufmgr, 0, size, align, RADEON_GEM_DOMAIN_VRAM, 0); - if (accel_state->copy_area_bo == NULL) + if (!accel_state->copy_area_bo) RADEON_FALLBACK(("temp copy surface alloc failed\n")); radeon_cs_space_add_persistent_bo(info->cs, accel_state->copy_area_bo, @@ -1723,7 +1723,7 @@ R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, base_align = drmmode_get_base_align(pScrn, (bpp / 8), 0); size = scratch_pitch * height * (bpp / 8); scratch = radeon_bo_open(info->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_GTT, 0); - if (scratch == NULL) { + if (!scratch) { goto copy; } @@ -1847,7 +1847,7 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, base_align = drmmode_get_base_align(pScrn, (bpp / 8), 0); size = scratch_pitch * height * (bpp / 8); scratch = radeon_bo_open(info->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_GTT, 0); - if (scratch == NULL) { + if (!scratch) { goto copy; } radeon_cs_space_reset_bos(info->cs); @@ -1960,7 +1960,7 @@ R600AllocShaders(ScrnInfoPtr pScrn, ScreenPtr pScreen) accel_state->shaders_bo = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_VRAM, 0); - if (accel_state->shaders_bo == NULL) { + if (!accel_state->shaders_bo) { ErrorF("Allocating shader failed\n"); return FALSE; } @@ -2025,7 +2025,7 @@ R600DrawInit(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); RADEONInfoPtr info = RADEONPTR(pScrn); - if (info->accel_state->exa == NULL) { + if (!info->accel_state->exa) { xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map not set up\n"); return FALSE; } diff --git a/src/radeon.h b/src/radeon.h index 2bcfa41b..450c69aa 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -726,7 +726,7 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_buffer *bo struct radeon_pixmap *priv; priv = radeon_get_pixmap_private(pPix); - if (priv == NULL && bo == NULL) + if (!priv && !bo) return TRUE; if (priv) { diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 70ad1d92..c36e06f2 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -238,14 +238,14 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen, return NULL; buffers = calloc(1, sizeof *buffers); - if (buffers == NULL) + if (!buffers) goto error; if (!info->use_glamor) { info->exa_force_create = TRUE; exaMoveInPixmap(pixmap); info->exa_force_create = FALSE; - if (exaGetPixmapDriverPrivate(pixmap) == NULL) { + if (!exaGetPixmapDriverPrivate(pixmap)) { /* this happen if pixmap is non accelerable */ goto error; } @@ -258,7 +258,7 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen, goto error; privates = calloc(1, sizeof(struct dri2_buffer_priv)); - if (privates == NULL) + if (!privates) goto error; buffers->attachment = attachment; @@ -923,7 +923,7 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE); /* Drawable not displayed, make up a value */ - if (crtc == NULL) { + if (!crtc) { *ust = 0; *msc = 0; return TRUE; @@ -1034,7 +1034,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, remainder &= 0xffffffff; /* Drawable not visible, return immediately */ - if (crtc == NULL) + if (!crtc) goto out_complete; msc_delta = radeon_get_msc_delta(draw, crtc); @@ -1193,7 +1193,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, radeon_dri2_ref_buffer(back); /* either off-screen or CRTC not usable... just complete the swap */ - if (crtc == NULL) + if (!crtc) goto blit_fallback; msc_delta = radeon_get_msc_delta(draw, crtc); diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 90d92d7b..93c2f056 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -150,7 +150,7 @@ Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset) */ Bool radeon_transform_is_affine_or_scaled(PictTransformPtr t) { - if (t == NULL) + if (!t) return TRUE; /* the shaders don't handle scaling either */ return t->matrix[2][0] == 0 && t->matrix[2][1] == 0 && t->matrix[2][2] == IntToxFixed(1); diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index 819b4258..b3200cc9 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -331,7 +331,7 @@ RADEONBlitChunk(ScrnInfoPtr pScrn, struct radeon_bo *src_bo, if (src_bo && dst_bo) { BEGIN_ACCEL_RELOC(6, 2); - } else if (src_bo && dst_bo == NULL) { + } else if (src_bo && !dst_bo) { BEGIN_ACCEL_RELOC(6, 1); } else { BEGIN_RING(2*6); @@ -423,7 +423,7 @@ RADEONUploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, size = scratch_pitch * h; scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0); - if (scratch == NULL) { + if (!scratch) { goto copy; } radeon_cs_space_reset_bos(info->cs); @@ -531,7 +531,7 @@ RADEONDownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, } size = scratch_pitch * h; scratch = radeon_bo_open(info->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_GTT, 0); - if (scratch == NULL) { + if (!scratch) { goto copy; } radeon_cs_space_reset_bos(info->cs); @@ -584,7 +584,7 @@ Bool RADEONDrawInit(ScreenPtr pScreen) { RINFO_FROM_SCREEN(pScreen); - if (info->accel_state->exa == NULL) { + if (!info->accel_state->exa) { xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map not set up\n"); return FALSE; } diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c index 9510f7f4..c61d83f4 100644 --- a/src/radeon_exa_render.c +++ b/src/radeon_exa_render.c @@ -630,7 +630,7 @@ static Bool R100PrepareComposite(int op, return FALSE; pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE; - if (pMask != NULL) { + if (pMask) { if (!R100TextureSetup(pMaskPicture, pMask, 1)) return FALSE; pp_cntl |= RADEON_TEX_1_ENABLE; @@ -992,7 +992,7 @@ static Bool R200PrepareComposite(int op, PicturePtr pSrcPicture, return FALSE; pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE; - if (pMask != NULL) { + if (pMask) { if (!R200TextureSetup(pMaskPicture, pMask, 1)) return FALSE; pp_cntl |= RADEON_TEX_1_ENABLE; @@ -1484,7 +1484,7 @@ static Bool R300PrepareComposite(int op, PicturePtr pSrcPicture, return FALSE; txenable = R300_TEX_0_ENABLE; - if (pMask != NULL) { + if (pMask) { if (!R300TextureSetup(pMaskPicture, pMask, 1)) return FALSE; txenable |= R300_TEX_1_ENABLE; diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index fa634947..b649bd18 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -261,7 +261,7 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, int stride; priv = calloc(1, sizeof (struct radeon_pixmap)); - if (priv == NULL) + if (!priv) goto fallback_pixmap; priv->bo = radeon_alloc_pixmap_bo(scrn, w, h, depth, usage, diff --git a/src/radeon_glamor_wrappers.c b/src/radeon_glamor_wrappers.c index 79d98cc7..edffd9ad 100644 --- a/src/radeon_glamor_wrappers.c +++ b/src/radeon_glamor_wrappers.c @@ -132,7 +132,7 @@ radeon_glamor_finish_access_cpu(PixmapPtr pixmap) static Bool radeon_glamor_prepare_access_gpu(struct radeon_pixmap *priv) { - return priv != NULL; + return !!priv; } static void @@ -201,7 +201,7 @@ radeon_glamor_picture_prepare_access_cpu_ro(ScrnInfoPtr scrn, PixmapPtr pixmap; struct radeon_pixmap *priv; - if (picture->pDrawable == NULL) + if (!picture->pDrawable) return TRUE; pixmap = get_drawable_pixmap(picture->pDrawable); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 15dca0de..36840ad3 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -639,7 +639,7 @@ master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) { ScreenPtr master_screen = radeon_dirty_master(dirty); - return master_screen->SyncSharedPixmap != NULL; + return !!master_screen->SyncSharedPixmap; } static Bool @@ -647,7 +647,7 @@ slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) { ScreenPtr slave_screen = dirty->slave_dst->drawable.pScreen; - return slave_screen->SyncSharedPixmap != NULL; + return !!slave_screen->SyncSharedPixmap; } static void @@ -1769,7 +1769,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) info->dri2.available = FALSE; info->dri2.enabled = FALSE; info->dri2.pKernelDRMVersion = drmGetVersion(pRADEONEnt->fd); - if (info->dri2.pKernelDRMVersion == NULL) { + if (!info->dri2.pKernelDRMVersion) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RADEONDRIGetVersion failed to get the DRM version\n"); return FALSE; @@ -1924,7 +1924,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) xf86OutputPtr output = xf86_config->output[i]; /* XXX: double check crtc mode */ - if ((output->probed_modes != NULL) && (output->crtc == NULL)) + if (output->probed_modes && !output->crtc) output->crtc = xf86_config->crtc[0]; } } @@ -1987,7 +1987,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE; } - if (pScrn->modes == NULL + if (!pScrn->modes #ifdef XSERVER_PLATFORM_BUS && !pScrn->is_gpu #endif @@ -2098,7 +2098,7 @@ static Bool RADEONSaveScreen_KMS(ScreenPtr pScreen, int mode) unblank = xf86IsUnblank(mode); if (unblank) SetTimeSinceLastInputEvent(); - if ((pScrn != NULL) && pScrn->vtSema) { + if (pScrn && pScrn->vtSema) { if (unblank) RADEONUnblank(pScrn); else @@ -2287,7 +2287,7 @@ Bool RADEONScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv) info->fb_shadow = calloc(1, pScrn->displayWidth * pScrn->virtualY * ((pScrn->bitsPerPixel + 7) >> 3)); - if (info->fb_shadow == NULL) { + if (!info->fb_shadow) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate shadow framebuffer\n"); return FALSE; @@ -2689,13 +2689,13 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) int pitch; uint32_t tiling_flags = 0; - if (info->accel_state->exa != NULL) { + if (info->accel_state->exa) { xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n"); return FALSE; } if (!info->use_glamor && info->r600_shadow_fb == FALSE) { info->accel_state->exa = exaDriverAlloc(); - if (info->accel_state->exa == NULL) { + if (!info->accel_state->exa) { xf86DrvMsg(pScreen->myNum, X_ERROR, "exaDriverAlloc failed\n"); return FALSE; } @@ -2709,7 +2709,7 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE); for (c = 0; c < xf86_config->num_crtc; c++) { /* cursor objects */ - if (info->cursor_bo[c] == NULL) { + if (!info->cursor_bo[c]) { info->cursor_bo[c] = radeon_bo_open(info->bufmgr, 0, cursor_size, 0, RADEON_GEM_DOMAIN_VRAM, 0); @@ -2727,7 +2727,7 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) } } - if (info->front_buffer == NULL) { + if (!info->front_buffer) { int usage = CREATE_PIXMAP_USAGE_BACKING_PIXMAP; if (info->allowColorTiling && !info->shadow_primary) { @@ -2787,9 +2787,8 @@ void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size) int c; for (c = 0; c < xf86_config->num_crtc; c++) { - if (info->cursor_bo[c] != NULL) { + if (info->cursor_bo[c]) new_fb_size += (64 * 4 * 64); - } } remain_size_bytes = info->vram_size - new_fb_size; diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c index 23bdfd1d..be71e408 100644 --- a/src/radeon_textured_video.c +++ b/src/radeon_textured_video.c @@ -153,7 +153,7 @@ radeon_allocate_video_bo(ScrnInfoPtr pScrn, static void RADEONFreeVideoMemory(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) { - if (pPriv->video_memory != NULL) { + if (pPriv->video_memory) { radeon_bo_unref(pPriv->video_memory); pPriv->video_memory = NULL; @@ -312,7 +312,7 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, RADEONFreeVideoMemory(pScrn, pPriv); } - if (pPriv->video_memory == NULL) { + if (!pPriv->video_memory) { Bool ret; ret = radeon_allocate_video_bo(pScrn, &pPriv->video_memory, @@ -329,7 +329,7 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn, /* Bicubic filter loading */ if (pPriv->bicubic_enabled) { - if (info->bicubic_bo == NULL) + if (!info->bicubic_bo) pPriv->bicubic_enabled = FALSE; } @@ -725,7 +725,7 @@ static void radeon_unload_bicubic_texture(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); - if (info->bicubic_memory != NULL) { + if (info->bicubic_memory) { radeon_bo_unref(info->bicubic_memory); info->bicubic_memory = NULL; } @@ -827,7 +827,7 @@ RADEONSetupImageTexturedVideo(ScreenPtr pScreen) adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports * (sizeof(RADEONPortPrivRec) + sizeof(DevUnion))); - if (adapt == NULL) + if (!adapt) return NULL; xvBicubic = MAKE_ATOM("XV_BICUBIC"); diff --git a/src/radeon_video.c b/src/radeon_video.c index e08d8e00..fc321184 100644 --- a/src/radeon_video.c +++ b/src/radeon_video.c @@ -144,7 +144,7 @@ void RADEONInitVideo(ScreenPtr pScreen) num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); newAdaptors = malloc((num_adaptors + 2) * sizeof(*newAdaptors)); - if (newAdaptors == NULL) + if (!newAdaptors) return; memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr)); @@ -152,7 +152,7 @@ void RADEONInitVideo(ScreenPtr pScreen) if (info->use_glamor) { texturedAdaptor = radeon_glamor_xv_init(pScreen, 16); - if (texturedAdaptor != NULL) { + if (texturedAdaptor) { adaptors[num_adaptors++] = texturedAdaptor; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video (glamor)\n"); } else @@ -161,7 +161,7 @@ void RADEONInitVideo(ScreenPtr pScreen) || (info->directRenderingEnabled) ) { texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen); - if (texturedAdaptor != NULL) { + if (texturedAdaptor) { adaptors[num_adaptors++] = texturedAdaptor; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n"); } else -- cgit v1.2.3 From 59441ee3dae15e0e81ed20688b0ba6dba12d7917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 11 Jul 2018 18:58:20 +0200 Subject: Call drmmode_do_crtc_dpms from drmmode_crtc_dpms as well Leo pointed out that drmmode_do_crtc_dpms wasn't getting called when turning off an output with xrandr --output --off This meant that the vblank sequence number and timestamp wouldn't be saved before turning off the CRTC in this case. Reported-by: Leo (Sunpeng) Li (Ported from amdgpu commit ceeacb455cd058492a493aac954deab8455804b5) Acked-by: Alex Deucher --- src/drmmode_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 3117b8f1..cf1f6e80 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -361,8 +361,7 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) /* Disable unused CRTCs */ if (!crtc->enabled || mode != DPMSModeOn) { - drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, - drmmode_crtc->flip_pending); + drmmode_do_crtc_dpms(crtc, DPMSModeOff); drmModeSetCrtc(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, NULL); -- cgit v1.2.3 From 6a0c01bbd4ed48c696c38952ee33ce21afec9f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 11 Jul 2018 18:59:58 +0200 Subject: Use drmmode_crtc_dpms in drmmode_set_desired_modes Simplifies the latter slightly. (Ported from amdgpu commit 74124f2c17dbb4b752707bb7eee398ae099e8a2c) Acked-by: Alex Deucher --- src/drmmode_display.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index cf1f6e80..25fcabfa 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2763,7 +2763,6 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); unsigned num_desired = 0, num_on = 0; int c; @@ -2771,18 +2770,12 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, if (set_hw) { for (c = 0; c < config->num_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; /* Skip disabled CRTCs */ if (crtc->enabled) continue; - drmmode_do_crtc_dpms(crtc, DPMSModeOff); - drmModeSetCrtc(pRADEONEnt->fd, - drmmode_crtc->mode_crtc->crtc_id, - 0, 0, 0, NULL, 0, NULL); - drmmode_fb_reference(pRADEONEnt->fd, - &drmmode_crtc->fb, NULL); + drmmode_crtc_dpms(crtc, DPMSModeOff); } } -- cgit v1.2.3 From 447ef0458fac047919d021f2ba1753a647f5c503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 11 Jul 2018 19:01:31 +0200 Subject: Check dimensions passed to drmmode_xf86crtc_resize When enabling a secondary GPU output, Xorg can try resizing the screen beyond the limit advertised by the driver, leading to drmModeAddFB failing and primary GPU outputs turning off. Check for this and bail instead. (Ported from amdgpu commit 940c8b39f79789d4d5ddb8ab8d25a8ae05932756) Acked-by: Alex Deucher --- src/drmmode_display.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 25fcabfa..4b5f9f45 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2260,6 +2260,14 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) if (scrn->virtualX == width && scrn->virtualY == height) return TRUE; + if (width > xf86_config->maxWidth || height > xf86_config->maxHeight) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "Xorg tried resizing screen to %dx%d, but maximum " + "supported is %dx%d\n", width, height, + xf86_config->maxWidth, xf86_config->maxHeight); + return FALSE; + } + if (info->allowColorTiling && !info->shadow_primary) { if (info->ChipFamily < CHIP_FAMILY_R600 || info->allowColorTiling2D) usage |= RADEON_CREATE_PIXMAP_TILING_MACRO; -- cgit v1.2.3 From 16ddc109660dbe813c457765eda66422fb745a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 11 Jul 2018 19:03:12 +0200 Subject: Remove #if 0'd code This has always been disabled, no need to keep it. (Ported from amdgpu commit 19a40758be04e1d451a030f452efb49e8aaad541) Acked-by: Alex Deucher --- src/drmmode_display.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 4b5f9f45..e301c0e6 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1835,15 +1835,6 @@ static const xf86OutputFuncsRec drmmode_output_funcs = { .create_resources = drmmode_output_create_resources, .set_property = drmmode_output_set_property, .get_property = drmmode_output_get_property, -#if 0 - - .save = drmmode_crt_save, - .restore = drmmode_crt_restore, - .mode_fixup = drmmode_crt_mode_fixup, - .prepare = drmmode_output_prepare, - .mode_set = drmmode_crt_mode_set, - .commit = drmmode_output_commit, -#endif .detect = drmmode_output_detect, .mode_valid = drmmode_output_mode_valid, @@ -2875,9 +2866,6 @@ Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) !xf86HandleColormaps(pScreen, 256, 10, NULL, NULL, CMAP_PALETTED_TRUECOLOR -#if 0 /* This option messes up text mode! (eich@suse.de) */ - | CMAP_LOAD_EVEN_IF_OFFSCREEN -#endif | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; } -- cgit v1.2.3 From 4b3e5f81c6032003237bb05c3ab96423c39524fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 11 Jul 2018 19:04:26 +0200 Subject: Call drmmode_crtc_gamma_do_set from drmmode_setup_colormap Instead of from drmmode_set_mode_major. There's no need to re-set the gamma LUT on every modeset, the kernel should preserve it. (Ported from amdgpu commit baea4fa492f635cdfe746a84be2e337d9aeae8a9) Acked-by: Alex Deucher --- src/drmmode_display.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index e301c0e6..03c850f8 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -887,9 +887,6 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, else drmmode_crtc->scanout_id = 0; - drmmode_crtc_gamma_do_set(crtc, crtc->gamma_red, crtc->gamma_green, - crtc->gamma_blue, crtc->gamma_size); - if (drmmode_crtc->prime_scanout_pixmap) { drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id, &fb, &x, &y); @@ -2854,6 +2851,7 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; if (xf86_config->num_crtc) { xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, @@ -2862,13 +2860,23 @@ Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) return FALSE; /* All radeons support 10 bit CLUTs. They get bypassed at depth 30. */ - if (pScrn->depth != 30 && - !xf86HandleColormaps(pScreen, 256, 10, - NULL, NULL, - CMAP_PALETTED_TRUECOLOR - | CMAP_RELOAD_ON_MODE_SWITCH)) - return FALSE; + if (pScrn->depth != 30) { + if (!xf86HandleColormaps(pScreen, 256, 10, NULL, NULL, + CMAP_PALETTED_TRUECOLOR + | CMAP_RELOAD_ON_MODE_SWITCH)) + return FALSE; + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + drmmode_crtc_gamma_do_set(crtc, crtc->gamma_red, + crtc->gamma_green, + crtc->gamma_blue, + crtc->gamma_size); + } + } } + return TRUE; } -- cgit v1.2.3 From 612bda0a5e769f23478b364cf89620222cfac349 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 11 Jul 2018 19:07:59 +0200 Subject: modesetting: Record non-desktop kernel property at PreInit time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Save any value of the kernel non-desktop property in the xf86Output structure to avoid non-desktop outputs in the default configuration. [Also bump randrproto requirement to a version that defines RR_PROPERTY_NON_DESKTOP - ajax] Signed-off-by: Keith Packard (Ported from xserver commit b91c787c4cd2d20685db69426c539938c556128a) Signed-off-by: Michel Dänzer (Ported from amdgpu commit 14db71a606128c4a207f43298809af279b77e2a8) Acked-by: Alex Deucher --- configure.ac | 2 +- src/drmmode_display.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index f5614749..65206e7f 100644 --- a/configure.ac +++ b/configure.ac @@ -64,7 +64,7 @@ AC_ARG_WITH(xorg-module-dir, [moduledir="$libdir/xorg/modules"]) # Store the list of server defined optional extensions in REQUIRED_MODULES -XORG_DRIVER_CHECK_EXT(RANDR, randrproto) +XORG_DRIVER_CHECK_EXT(RANDR, [randrproto >= 1.6.0]) XORG_DRIVER_CHECK_EXT(RENDER, renderproto) XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 03c850f8..27aa5a6c 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1975,6 +1975,9 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r drmModeEncoderPtr *kencoders = NULL; drmmode_output_private_ptr drmmode_output; drmModePropertyBlobPtr path_blob = NULL; +#if XF86_CRTC_VERSION >= 8 + Bool nonDesktop = FALSE; +#endif char name[32]; int i; const char *s; @@ -1985,6 +1988,13 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r path_blob = koutput_get_prop_blob(pRADEONEnt->fd, koutput, "PATH"); +#if XF86_CRTC_VERSION >= 8 + i = koutput_get_prop_idx(pRADEONEnt->fd, koutput, DRM_MODE_PROP_RANGE, + RR_PROPERTY_NON_DESKTOP); + if (i >= 0) + nonDesktop = koutput->prop_values[i] != 0; +#endif + kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); if (!kencoders) { goto out_free_encoders; @@ -2014,6 +2024,9 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r drmmode_output = output->driver_private; drmmode_output->output_id = mode_res->connectors[num]; drmmode_output->mode_output = koutput; +#if XF86_CRTC_VERSION >= 8 + output->non_desktop = nonDesktop; +#endif for (i = 0; i < koutput->count_encoders; i++) drmModeFreeEncoder(kencoders[i]); free(kencoders); @@ -2055,6 +2068,9 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r output->interlaceAllowed = TRUE; output->doubleScanAllowed = TRUE; output->driver_private = drmmode_output; +#if XF86_CRTC_VERSION >= 8 + output->non_desktop = nonDesktop; +#endif output->possible_crtcs = 0xffffffff; for (i = 0; i < koutput->count_encoders; i++) { -- cgit v1.2.3 From b4f0f44a9f67f2eafd4a2b5ab919e6ea7fa2acf7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 11 Jul 2018 19:10:20 +0200 Subject: modesetting: Create CONNECTOR_ID properties for outputs [v2] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This lets a DRM client map between X outputs and kernel connectors. v2: Change CONNECTOR_ID to enum -- Adam Jackson Signed-off-by: Keith Packard (Ported from xserver commit 023d4aba8d45e9e3630b944ecfb650c081799b96) Signed-off-by: Michel Dänzer (Ported from amdgpu commit ab7e39c5a03e24c3ce3ee2f22ada7572bc2d9aa7) Acked-by: Alex Deucher --- src/drmmode_display.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 27aa5a6c..d4bd76e1 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1643,6 +1643,33 @@ drmmode_output_create_resources(xf86OutputPtr output) RADEONEntPtr pRADEONEnt = RADEONEntPriv(output->scrn); drmModePropertyPtr drmmode_prop, tearfree_prop; int i, j, err; + Atom name; + + /* Create CONNECTOR_ID property */ + name = MakeAtom("CONNECTOR_ID", 12, TRUE); + if (name != BAD_RESOURCE) { + INT32 value = mode_output->connector_id; + + err = RRConfigureOutputProperty(output->randr_output, name, + FALSE, FALSE, TRUE, 1, &value); + if (err != Success) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + + err = RRChangeOutputProperty(output->randr_output, name, + XA_INTEGER, 32, PropModeReplace, 1, + &value, FALSE, FALSE); + if (err != Success) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + } + + drmmode_output->props = + calloc(mode_output->count_props + 1, sizeof(drmmode_prop_rec)); + if (!drmmode_output->props) + return; drmmode_output->props = calloc(mode_output->count_props + 1, sizeof(drmmode_prop_rec)); if (!drmmode_output->props) -- cgit v1.2.3 From f533b1f654952cee794de49d28d01947a6571daf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 11 Jul 2018 19:13:28 +0200 Subject: Add RandR leases support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Keith Packard (Ported from xserver commit e4e3447603b5fd3a38a92c3f972396d1f81168ad) Signed-off-by: Michel Dänzer (Ported from amdgpu commit 61040bdfa360975614fb47aa7ea1b3a1abac3427) Acked-by: Alex Deucher --- configure.ac | 2 +- src/drmmode_display.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++- src/drmmode_display.h | 6 ++ src/radeon_kms.c | 1 + 4 files changed, 166 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 65206e7f..15c7b212 100644 --- a/configure.ac +++ b/configure.ac @@ -70,7 +70,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Checks for libraries. -PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.78]) +PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.89]) PKG_CHECK_MODULES(LIBDRM_RADEON, [libdrm_radeon]) # Obtain compiler/linker options for the driver dependencies diff --git a/src/drmmode_display.c b/src/drmmode_display.c index d4bd76e1..2af64e3f 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2400,8 +2400,159 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) return FALSE; } +static void +drmmode_validate_leases(ScrnInfoPtr scrn) +{ +#ifdef XF86_LEASE_VERSION + ScreenPtr screen = scrn->pScreen; + rrScrPrivPtr scr_priv = rrGetScrPriv(screen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + drmModeLesseeListPtr lessees; + RRLeasePtr lease, next; + int l; + + /* We can't talk to the kernel about leases when VT switched */ + if (!scrn->vtSema) + return; + + lessees = drmModeListLessees(pRADEONEnt->fd); + if (!lessees) + return; + + xorg_list_for_each_entry_safe(lease, next, &scr_priv->leases, list) { + drmmode_lease_private_ptr lease_private = lease->devPrivate; + + for (l = 0; l < lessees->count; l++) { + if (lessees->lessees[l] == lease_private->lessee_id) + break; + } + + /* check to see if the lease has gone away */ + if (l == lessees->count) { + free(lease_private); + lease->devPrivate = NULL; + xf86CrtcLeaseTerminated(lease); + } + } + + free(lessees); +#endif +} + +#ifdef XF86_LEASE_VERSION + +static int +drmmode_create_lease(RRLeasePtr lease, int *fd) +{ + ScreenPtr screen = lease->screen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + drmmode_lease_private_ptr lease_private; + int noutput = lease->numOutputs; + int ncrtc = lease->numCrtcs; + uint32_t *objects; + size_t nobjects; + int lease_fd; + int c, o; + int i; + + nobjects = ncrtc + noutput; + if (nobjects == 0 || nobjects > (SIZE_MAX / 4) || + ncrtc > (SIZE_MAX - noutput)) + return BadValue; + + lease_private = calloc(1, sizeof (drmmode_lease_private_rec)); + if (!lease_private) + return BadAlloc; + + objects = malloc(nobjects * 4); + if (!objects) { + free(lease_private); + return BadAlloc; + } + + i = 0; + + /* Add CRTC ids */ + for (c = 0; c < ncrtc; c++) { + xf86CrtcPtr crtc = lease->crtcs[c]->devPrivate; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + objects[i++] = drmmode_crtc->mode_crtc->crtc_id; + } + + /* Add connector ids */ + for (o = 0; o < noutput; o++) { + xf86OutputPtr output = lease->outputs[o]->devPrivate; + drmmode_output_private_ptr drmmode_output = output->driver_private; + + objects[i++] = drmmode_output->mode_output->connector_id; + } + + /* call kernel to create lease */ + assert (i == nobjects); + + lease_fd = drmModeCreateLease(pRADEONEnt->fd, objects, nobjects, 0, + &lease_private->lessee_id); + + free(objects); + + if (lease_fd < 0) { + free(lease_private); + return BadMatch; + } + + lease->devPrivate = lease_private; + + xf86CrtcLeaseStarted(lease); + + *fd = lease_fd; + return Success; +} + +static void +drmmode_terminate_lease(RRLeasePtr lease) +{ + drmmode_lease_private_ptr lease_private = lease->devPrivate; + ScreenPtr screen = lease->screen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + + if (drmModeRevokeLease(pRADEONEnt->fd, lease_private->lessee_id) == 0) { + free(lease_private); + lease->devPrivate = NULL; + xf86CrtcLeaseTerminated(lease); + } +} + +#endif // XF86_LEASE_VERSION + +void +drmmode_terminate_leases(ScrnInfoPtr pScrn) +{ +#ifdef XF86_LEASE_VERSION + ScreenPtr screen = xf86ScrnToScreen(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + rrScrPrivPtr scr_priv = rrGetScrPriv(screen); + RRLeasePtr lease, next; + + xorg_list_for_each_entry_safe(lease, next, &scr_priv->leases, list) { + drmmode_lease_private_ptr lease_private = lease->devPrivate; + drmModeRevokeLease(pRADEONEnt->fd, lease_private->lessee_id); + free(lease_private); + lease->devPrivate = NULL; + RRLeaseTerminated(lease); + RRLeaseFree(lease); + } +#endif +} + static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { - drmmode_xf86crtc_resize + .resize = drmmode_xf86crtc_resize, +#ifdef XF86_LEASE_VERSION + .create_lease = drmmode_create_lease, + .terminate_lease = drmmode_terminate_lease +#endif }; static void @@ -2888,6 +3039,9 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, return FALSE; } + /* Validate leases on VT re-entry */ + drmmode_validate_leases(pScrn); + return TRUE; } @@ -3055,6 +3209,9 @@ restart_destroy: changed = TRUE; } + /* Check to see if a lessee has disappeared */ + drmmode_validate_leases(scrn); + if (changed && dixPrivateKeyRegistered(rrPrivKey)) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0) RRSetChanged(xf86ScrnToScreen(scrn)); diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 27c23c1a..4551e0c7 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -139,6 +139,10 @@ typedef struct { int tear_free; } drmmode_output_private_rec, *drmmode_output_private_ptr; +typedef struct { + uint32_t lessee_id; +} drmmode_lease_private_rec, *drmmode_lease_private_ptr; + enum drmmode_flip_sync { FLIP_VSYNC, @@ -223,6 +227,8 @@ PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc, extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); +extern void drmmode_terminate_leases(ScrnInfoPtr scrn); + Bool drmmode_set_mode(xf86CrtcPtr crtc, struct drmmode_fb *fb, DisplayModePtr mode, int x, int y); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 36840ad3..c8a5726a 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2154,6 +2154,7 @@ static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen) /* Clear mask of assigned crtc's in this generation */ pRADEONEnt->assigned_crtcs = 0; + drmmode_terminate_leases(pScrn); drmmode_uevent_fini(pScrn, &info->drmmode); radeon_drm_queue_close(pScrn); radeon_cs_flush_indirect(pScrn); -- cgit v1.2.3 From d9a139bc6d453d33593685de67d1425611f3ab6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 16 Jul 2018 12:51:26 +0200 Subject: glamor: Fix glamor_block_handler argument in radeon_glamor_finish I missed this before because this code isn't compiled with current xserver. Trivial. --- src/radeon_glamor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/radeon_glamor.h b/src/radeon_glamor.h index 2740ab33..61d54e36 100644 --- a/src/radeon_glamor.h +++ b/src/radeon_glamor.h @@ -85,7 +85,7 @@ radeon_glamor_finish(ScrnInfoPtr scrn) #if HAVE_GLAMOR_FINISH glamor_finish(scrn->pScreen); #else - glamor_block_handler(scrn); + glamor_block_handler(scrn->pScreen); glFinish(); #endif -- cgit v1.2.3 From 499d2f9d5d301ef1efd4ffc2952677609ef05122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 17 Jul 2018 11:43:12 +0200 Subject: glamor: Invalidate cached GEM handle in radeon_set_pixmap_bo We continued using the stale cached handle, causing issues e.g. when resizing the screen via RandR. Reported-by: iive on IRC Acked-by: Alex Deucher --- src/radeon.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/radeon.h b/src/radeon.h index 450c69aa..1a1edb1b 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -735,6 +735,7 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_buffer *bo return TRUE; radeon_buffer_unref(&priv->bo); + priv->handle_valid = FALSE; } drmmode_fb_reference(pRADEONEnt->fd, &priv->fb, NULL); -- cgit v1.2.3 From 64bd009d17986c71726724859f100ad40a6e3096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 19 Jul 2018 11:33:42 +0200 Subject: Don't allocate drmmode_output->props twice This was accidentally duplicated when porting RandR lease support from amdgpu. Trivial. --- src/drmmode_display.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 2af64e3f..000c7fc6 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1666,11 +1666,6 @@ drmmode_output_create_resources(xf86OutputPtr output) } } - drmmode_output->props = - calloc(mode_output->count_props + 1, sizeof(drmmode_prop_rec)); - if (!drmmode_output->props) - return; - drmmode_output->props = calloc(mode_output->count_props + 1, sizeof(drmmode_prop_rec)); if (!drmmode_output->props) return; -- cgit v1.2.3 From ffdbd46b0abcf8cbe73eb8930ddcd7fd2485d9b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 23 Jul 2018 11:02:32 +0200 Subject: Hardcode "non-desktop" RandR property name It's a bit silly to require current randrproto just for this definition, which can't really change anyway. Suggested-by: Qiang Yu (Ported from amdgpu commit ae8e02c6fc4ef5d5340b8cd4739e66b19b9e3386) Reviewed-by: Alex Deucher --- configure.ac | 2 +- src/drmmode_display.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 15c7b212..bea205c3 100644 --- a/configure.ac +++ b/configure.ac @@ -64,7 +64,7 @@ AC_ARG_WITH(xorg-module-dir, [moduledir="$libdir/xorg/modules"]) # Store the list of server defined optional extensions in REQUIRED_MODULES -XORG_DRIVER_CHECK_EXT(RANDR, [randrproto >= 1.6.0]) +XORG_DRIVER_CHECK_EXT(RANDR, randrproto) XORG_DRIVER_CHECK_EXT(RENDER, renderproto) XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 000c7fc6..ff098975 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2012,7 +2012,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r #if XF86_CRTC_VERSION >= 8 i = koutput_get_prop_idx(pRADEONEnt->fd, koutput, DRM_MODE_PROP_RANGE, - RR_PROPERTY_NON_DESKTOP); + "non-desktop"); if (i >= 0) nonDesktop = koutput->prop_values[i] != 0; #endif -- cgit v1.2.3 From d258413c956cd46a237d4b5b94a35817ca7ce8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 23 Jul 2018 18:54:40 +0200 Subject: Remove drmmode_terminate_leases The RandR screen private is already freed when our CloseScreen runs, so this can't do anything useful. This cleanup has to be done by the X server itself. (Ported from amdgpu commit 5f06d6b8ba570b500956ad26fee711d5ac427818) Acked-by: Alex Deucher --- src/drmmode_display.c | 20 -------------------- src/drmmode_display.h | 2 -- src/radeon_kms.c | 1 - 3 files changed, 23 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index ff098975..60c1cdc1 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2522,26 +2522,6 @@ drmmode_terminate_lease(RRLeasePtr lease) #endif // XF86_LEASE_VERSION -void -drmmode_terminate_leases(ScrnInfoPtr pScrn) -{ -#ifdef XF86_LEASE_VERSION - ScreenPtr screen = xf86ScrnToScreen(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - rrScrPrivPtr scr_priv = rrGetScrPriv(screen); - RRLeasePtr lease, next; - - xorg_list_for_each_entry_safe(lease, next, &scr_priv->leases, list) { - drmmode_lease_private_ptr lease_private = lease->devPrivate; - drmModeRevokeLease(pRADEONEnt->fd, lease_private->lessee_id); - free(lease_private); - lease->devPrivate = NULL; - RRLeaseTerminated(lease); - RRLeaseFree(lease); - } -#endif -} - static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { .resize = drmmode_xf86crtc_resize, #ifdef XF86_LEASE_VERSION diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 4551e0c7..c5a55891 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -227,8 +227,6 @@ PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc, extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); -extern void drmmode_terminate_leases(ScrnInfoPtr scrn); - Bool drmmode_set_mode(xf86CrtcPtr crtc, struct drmmode_fb *fb, DisplayModePtr mode, int x, int y); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index c8a5726a..36840ad3 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2154,7 +2154,6 @@ static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen) /* Clear mask of assigned crtc's in this generation */ pRADEONEnt->assigned_crtcs = 0; - drmmode_terminate_leases(pScrn); drmmode_uevent_fini(pScrn, &info->drmmode); radeon_drm_queue_close(pScrn); radeon_cs_flush_indirect(pScrn); -- cgit v1.2.3 From fed411290b696ecf9f0e799ec4bad054e4a95017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 24 Jul 2018 17:28:46 +0200 Subject: Use strcpy for RandR output property names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of strncpy with the string length. Avoids new warnings with GCC 8: ../../src/drmmode_display.c: In function ‘drmmode_output_create_resources’: ../../src/drmmode_display.c:2240:2: warning: ‘strncpy’ output truncated before terminating nul copying 8 bytes from a string of the same length [-Wstringop-truncation] strncpy(tearfree_prop->name, "TearFree", 8); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../src/drmmode_display.c:2244:2: warning: ‘strncpy’ output truncated before terminating nul copying 3 bytes from a string of the same length [-Wstringop-truncation] strncpy(tearfree_prop->enums[0].name, "off", 3); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../src/drmmode_display.c:2245:2: warning: ‘strncpy’ output truncated before terminating nul copying 2 bytes from a string of the same length [-Wstringop-truncation] strncpy(tearfree_prop->enums[1].name, "on", 2); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../src/drmmode_display.c:2247:2: warning: ‘strncpy’ output truncated before terminating nul copying 4 bytes from a string of the same length [-Wstringop-truncation] strncpy(tearfree_prop->enums[2].name, "auto", 4); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Ported from amdgpu commit f3b2ed37d683f8616a0a31ff63133ddb8fe1a4a3) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 60c1cdc1..6a0dba2c 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1686,14 +1686,14 @@ drmmode_output_create_resources(xf86OutputPtr output) /* Userspace-only property for TearFree */ tearfree_prop = calloc(1, sizeof(*tearfree_prop)); tearfree_prop->flags = DRM_MODE_PROP_ENUM; - strncpy(tearfree_prop->name, "TearFree", 8); + strcpy(tearfree_prop->name, "TearFree"); tearfree_prop->count_enums = 3; tearfree_prop->enums = calloc(tearfree_prop->count_enums, sizeof(*tearfree_prop->enums)); - strncpy(tearfree_prop->enums[0].name, "off", 3); - strncpy(tearfree_prop->enums[1].name, "on", 2); + strcpy(tearfree_prop->enums[0].name, "off"); + strcpy(tearfree_prop->enums[1].name, "on"); tearfree_prop->enums[1].value = 1; - strncpy(tearfree_prop->enums[2].name, "auto", 4); + strcpy(tearfree_prop->enums[2].name, "auto"); tearfree_prop->enums[2].value = 2; drmmode_output->props[j].mode_prop = tearfree_prop; drmmode_output->props[j].value = info->tear_free; -- cgit v1.2.3 From 7de4ea15880565c6536ed6859fd32ec89ce0b4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 27 Jul 2018 09:13:12 +0200 Subject: Bump version to 18.0.99 Forgot to do this after the 18.0.1 release. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index bea205c3..444862f3 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [18.0.1], + [18.0.99], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) -- cgit v1.2.3 From db28d35ce9fd07a2a4703f3df0633d4c8291ff9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 27 Jul 2018 11:30:57 +0200 Subject: glamor: Use glamor_egl_create_textured_pixmap_from_gbm_bo when possible Inspired by the modesetting driver. Fixes screen pixmap corruption with Xorg < 1.20, and as a bonus, simplifies the code slightly. Bugzilla: https://bugs.freedesktop.org/107385 Reviewed-by: Alex Deucher --- src/radeon_glamor.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index b649bd18..c733d192 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -50,9 +50,9 @@ radeon_glamor_exchange_buffers(PixmapPtr src, Bool radeon_glamor_create_screen_resources(ScreenPtr screen) { + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONInfoPtr info = RADEONPTR(scrn); - uint32_t handle; if (!info->use_glamor) return TRUE; @@ -62,17 +62,8 @@ radeon_glamor_create_screen_resources(ScreenPtr screen) return FALSE; #endif - if (info->front_buffer->flags & RADEON_BO_FLAGS_GBM) - handle = gbm_bo_get_handle(info->front_buffer->bo.gbm).u32; - else - handle = info->front_buffer->bo.radeon->handle; - - if (!glamor_egl_create_textured_screen(screen, handle, - scrn->displayWidth * - info->pixel_bytes)) - return FALSE; - - return TRUE; + return radeon_glamor_create_textured_pixmap(screen_pixmap, + info->front_buffer); } @@ -180,17 +171,22 @@ radeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_buffer *bo) { ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); RADEONInfoPtr info = RADEONPTR(scrn); - uint32_t handle; if (!info->use_glamor) return TRUE; - if (bo->flags & RADEON_BO_FLAGS_GBM) - handle = gbm_bo_get_handle(bo->bo.gbm).u32; - else - handle = bo->bo.radeon->handle; - - return glamor_egl_create_textured_pixmap(pixmap, handle, pixmap->devKind); + if (bo->flags & RADEON_BO_FLAGS_GBM) { + return glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, + bo->bo.gbm +#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,19,99,903,0) + , FALSE +#endif + ); + } else { + return glamor_egl_create_textured_pixmap(pixmap, + bo->bo.radeon->handle, + pixmap->devKind); + } } static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap) -- cgit v1.2.3 From ef2a6b818fa47ad571bb0bc105aa8193d51a2190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 2 Aug 2018 18:48:04 +0200 Subject: glamor: Set RADEON_CREATE_PIXMAP_DRI2 for DRI3 pixmaps Not doing this resulted in falling back to software for DRI3 client presentation operations with ShadowPrimary. (Ported from amdgpu commit 2989d40ef74d9966e8e8df2ef7727b2cc48d4960) Reviewed-by: Alex Deucher --- src/radeon_dri3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c index 688e594e..7e89a2f0 100644 --- a/src/radeon_dri3.c +++ b/src/radeon_dri3.c @@ -169,6 +169,7 @@ static PixmapPtr radeon_dri3_pixmap_from_fd(ScreenPtr screen, if (priv) { radeon_set_pixmap_private(pixmap, priv); + pixmap->usage_hint |= RADEON_CREATE_PIXMAP_DRI2; return pixmap; } -- cgit v1.2.3 From 740f0850f1e40403c8dd727e074eae36caeb1f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 2 Aug 2018 18:49:48 +0200 Subject: Store FB for each CRTC in drmmode_flipdata_rec We were only storing the FB provided by the client, but on CRTCs with TearFree enabled, we use a separate FB. This could cause drmmode_flip_handler to fail to clear drmmode_crtc->flip_pending, which could result in a hang when waiting for the pending flip to complete. We were trying to avoid that by always clearing drmmode_crtc->flip_pending when TearFree is enabled, but that wasn't reliable, because drmmode_crtc->tear_free can already be FALSE at this point when disabling TearFree. Now that we're keeping track of each CRTC's flip FB separately, drmmode_flip_handler can reliably clear flip_pending, and we no longer need the TearFree hack. (Ported from amdgpu commit 9b6782c821e0bdc53336d98f87ddde752faf7902) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 47 ++++++++++++++++++++++++++--------------------- src/drmmode_display.h | 2 +- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 6a0dba2c..0b92b70c 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2536,17 +2536,21 @@ drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data) drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); drmmode_flipdata_ptr flipdata = event_data; + int crtc_id = drmmode_get_crtc_id(crtc); + struct drmmode_fb **fb = &flipdata->fb[crtc_id]; + + if (drmmode_crtc->flip_pending == *fb) { + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + NULL); + } + drmmode_fb_reference(pRADEONEnt->fd, fb, NULL); if (--flipdata->flip_count == 0) { if (!flipdata->fe_crtc) flipdata->fe_crtc = crtc; flipdata->abort(flipdata->fe_crtc, flipdata->event_data); - drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, NULL); free(flipdata); } - - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, - NULL); } static void @@ -2555,6 +2559,8 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); drmmode_flipdata_ptr flipdata = event_data; + int crtc_id = drmmode_get_crtc_id(crtc); + struct drmmode_fb **fb = &flipdata->fb[crtc_id]; /* Is this the event whose info shall be delivered to higher level? */ if (crtc == flipdata->fe_crtc) { @@ -2563,13 +2569,12 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even flipdata->fe_usec = usec; } - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, - flipdata->fb); - if (drmmode_crtc->tear_free || - drmmode_crtc->flip_pending == flipdata->fb) { + if (drmmode_crtc->flip_pending == *fb) { drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, NULL); } + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, *fb); + drmmode_fb_reference(pRADEONEnt->fd, fb, NULL); if (--flipdata->flip_count == 0) { /* Deliver MSC & UST from reference/current CRTC to flip event @@ -2581,7 +2586,6 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even else flipdata->handler(crtc, frame, usec, flipdata->event_data); - drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, NULL); free(flipdata); } } @@ -3287,21 +3291,22 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcPtr crtc = NULL; drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; - int i; uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0; drmmode_flipdata_ptr flipdata; uintptr_t drm_queue_seq = 0; + struct drmmode_fb *fb; + int i = 0; - flipdata = calloc(1, sizeof(drmmode_flipdata_rec)); + flipdata = calloc(1, sizeof(*flipdata) + config->num_crtc * + sizeof(flipdata->fb[0])); if (!flipdata) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue: data alloc failed.\n"); goto error; } - drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, - radeon_pixmap_get_fb(new_front)); - if (!flipdata->fb) { + fb = radeon_pixmap_get_fb(new_front); + if (!fb) { ErrorF("Failed to get FB for flip\n"); goto error; } @@ -3322,8 +3327,6 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, flipdata->fe_crtc = ref_crtc; for (i = 0; i < config->num_crtc; i++) { - struct drmmode_fb *fb = flipdata->fb; - crtc = config->crtc[i]; drmmode_crtc = crtc->driver_private; @@ -3359,8 +3362,9 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, goto next; } - fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); - if (!fb) { + drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb[i], + radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap)); + if (!flipdata->fb[i]) { ErrorF("Failed to get FB for TearFree flip\n"); goto error; } @@ -3375,6 +3379,8 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending); drmmode_crtc->scanout_update_pending = 0; } + } else { + drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb[i], fb); } if (crtc == ref_crtc) { @@ -3400,8 +3406,8 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, } next: - drmmode_fb_reference(pRADEONEnt->fd, - &drmmode_crtc->flip_pending, fb); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + flipdata->fb[i]); drm_queue_seq = 0; } @@ -3419,7 +3425,6 @@ error: drmmode_flip_abort(crtc, flipdata); else { abort(NULL, data); - drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb, NULL); free(flipdata); } diff --git a/src/drmmode_display.h b/src/drmmode_display.h index c5a55891..46449c8e 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -56,7 +56,6 @@ typedef struct { } drmmode_rec, *drmmode_ptr; typedef struct { - struct drmmode_fb *fb; void *event_data; int flip_count; unsigned int fe_frame; @@ -64,6 +63,7 @@ typedef struct { xf86CrtcPtr fe_crtc; radeon_drm_handler_proc handler; radeon_drm_abort_proc abort; + struct drmmode_fb *fb[0]; } drmmode_flipdata_rec, *drmmode_flipdata_ptr; struct drmmode_fb { -- cgit v1.2.3 From 824189b3da9edc33e1a4f5c6130a043da73c1a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 16 Aug 2018 18:22:27 +0200 Subject: Use correct FB handle in radeon_do_pageflip We were always using the handle of the client provided FB, which prevented RandR transforms from working, and could result in a black screen. Bugzilla: https://bugs.freedesktop.org/107519 Fixes: 740f0850f1e4 "Store FB for each CRTC in drmmode_flipdata_rec" (Ported from amdgpu commit f6cd72e64e85896b6d155bee0930e59771dcb701) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 0b92b70c..68d6254d 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -3386,7 +3386,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, if (crtc == ref_crtc) { if (drmmode_page_flip_target_absolute(pRADEONEnt, drmmode_crtc, - fb->handle, + flipdata->fb[i]->handle, flip_flags, drm_queue_seq, target_msc) != 0) @@ -3394,7 +3394,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, } else { if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, - fb->handle, + flipdata->fb[i]->handle, flip_flags, drm_queue_seq, 0) != 0) goto flip_error; -- cgit v1.2.3 From ecdf0b7ec9378bc386ce8276f16fb16d09f72812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 16 Aug 2018 17:14:42 +0200 Subject: Move DRM event queue related initialization to radeon_drm_queue_init And make radeon_drm_queue_handler not directly accessible outside of radeon_drm_queue.c. (Ported from amdgpu commit 0148283984c77f7a6e97026edc3093497547e0a4) Acked-by: Alex Deucher --- src/drmmode_display.c | 4 ---- src/radeon_dri2.c | 14 ++++++++------ src/radeon_drm_queue.c | 11 +++++++++-- src/radeon_drm_queue.h | 5 +---- src/radeon_kms.c | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 68d6254d..385c5b3e 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2742,10 +2742,6 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) xf86InitialConfiguration(pScrn, TRUE); - drmmode->event_context.version = 2; - drmmode->event_context.vblank_handler = radeon_drm_queue_handler; - drmmode->event_context.page_flip_handler = radeon_drm_queue_handler; - pRADEONEnt->has_page_flip_target = drmmode_probe_page_flip_target(pRADEONEnt); drmModeFreeResources(mode_res); diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index c36e06f2..4d12fc09 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -968,13 +968,15 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) scrn = crtc->scrn; pRADEONEnt = RADEONEntPriv(scrn); + drmmode_crtc = event_info->crtc->driver_private; ret = drmmode_get_current_ust(pRADEONEnt->fd, &drm_now); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s cannot get current time\n", __func__); if (event_info->drm_queue_seq) - radeon_drm_queue_handler(pRADEONEnt->fd, 0, 0, 0, - (void*)event_info->drm_queue_seq); + drmmode_crtc->drmmode->event_context. + vblank_handler(pRADEONEnt->fd, 0, 0, 0, + (void*)event_info->drm_queue_seq); else radeon_dri2_frame_event_handler(crtc, 0, 0, data); return 0; @@ -983,15 +985,15 @@ CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) * calculate the frame number from current time * that would come from CRTC if it were running */ - drmmode_crtc = event_info->crtc->driver_private; delta_t = drm_now - (CARD64)drmmode_crtc->dpms_last_ust; 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_seq) - radeon_drm_queue_handler(pRADEONEnt->fd, frame, drm_now / 1000000, - drm_now % 1000000, - (void*)event_info->drm_queue_seq); + drmmode_crtc->drmmode->event_context. + vblank_handler(pRADEONEnt->fd, frame, drm_now / 1000000, + drm_now % 1000000, + (void*)event_info->drm_queue_seq); else radeon_dri2_frame_event_handler(crtc, frame, drm_now, data); return 0; diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index ac775f86..bff010fa 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -57,7 +57,7 @@ static uintptr_t radeon_drm_queue_seq; /* * Handle a DRM event */ -void +static void radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *user_ptr) { @@ -181,8 +181,15 @@ radeon_drm_abort_id(uint64_t id) * Initialize the DRM event queue */ void -radeon_drm_queue_init() +radeon_drm_queue_init(ScrnInfoPtr scrn) { + RADEONInfoPtr info = RADEONPTR(scrn); + drmmode_ptr drmmode = &info->drmmode; + + drmmode->event_context.version = 2; + drmmode->event_context.vblank_handler = radeon_drm_queue_handler; + drmmode->event_context.page_flip_handler = radeon_drm_queue_handler; + if (radeon_drm_queue_refcnt++) return; diff --git a/src/radeon_drm_queue.h b/src/radeon_drm_queue.h index c3e2076d..b6aab37c 100644 --- a/src/radeon_drm_queue.h +++ b/src/radeon_drm_queue.h @@ -40,9 +40,6 @@ typedef void (*radeon_drm_handler_proc)(xf86CrtcPtr crtc, uint32_t seq, uint64_t usec, void *data); 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); uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, uint64_t id, void *data, radeon_drm_handler_proc handler, @@ -50,7 +47,7 @@ uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, void radeon_drm_abort_client(ClientPtr client); 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_init(ScrnInfoPtr scrn); void radeon_drm_queue_close(ScrnInfoPtr scrn); #endif /* _RADEON_DRM_QUEUE_H_ */ diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 36840ad3..809d2446 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1789,7 +1789,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) return FALSE; } - radeon_drm_queue_init(); + radeon_drm_queue_init(pScrn); info->allowColorTiling2D = FALSE; -- cgit v1.2.3 From 93621e408c17dd9e082236c17f051c06558d7f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 16 Aug 2018 17:27:06 +0200 Subject: Add radeon_drm_wait_pending_flip function Replacing the drmmode_crtc_wait_pending_event macro. (Ported from amdgpu commit 6029794e8a35417faf825491a89b85f713c77fc1) Acked-by: Alex Deucher --- src/drmmode_display.c | 21 ++++----------------- src/radeon_drm_queue.c | 13 +++++++++++++ src/radeon_drm_queue.h | 1 + 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 385c5b3e..73eadeb1 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -100,13 +100,6 @@ RADEONZaphodStringMatches(ScrnInfoPtr pScrn, const char *s, char *output_name) } -/* Wait for the boolean condition to be FALSE */ -#define drmmode_crtc_wait_pending_event(drmmode_crtc, fd, condition) \ - do {} while ((condition) && \ - drmHandleEvent(fd, &drmmode_crtc->drmmode->event_context) \ - > 0); - - static PixmapPtr drmmode_create_bo_pixmap(ScrnInfoPtr pScrn, int width, int height, int depth, int bpp, @@ -306,8 +299,7 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) if (drmmode_crtc->dpms_mode == DPMSModeOn && mode != DPMSModeOn) { uint32_t seq; - drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, - drmmode_crtc->flip_pending); + radeon_drm_wait_pending_flip(crtc); /* * On->Off transition: record the last vblank time, @@ -918,8 +910,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, goto done; } - drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, - drmmode_crtc->flip_pending); + radeon_drm_wait_pending_flip(crtc); if (!drmmode_set_mode(crtc, fb, mode, x, y)) goto done; @@ -1772,14 +1763,11 @@ drmmode_output_set_tear_free(RADEONEntPtr pRADEONEnt, drmmode_output->tear_free = tear_free; if (crtc) { - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - /* Wait for pending flips before drmmode_set_mode_major calls * drmmode_crtc_update_tear_free, to prevent a nested * drmHandleEvent call, which would hang */ - drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, - drmmode_crtc->flip_pending); + radeon_drm_wait_pending_flip(crtc); drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); } @@ -3370,8 +3358,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, radeon_cs_flush_indirect(crtc->scrn); if (drmmode_crtc->scanout_update_pending) { - drmmode_crtc_wait_pending_event(drmmode_crtc, pRADEONEnt->fd, - drmmode_crtc->flip_pending); + radeon_drm_wait_pending_flip(crtc); radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending); drmmode_crtc->scanout_update_pending = 0; } diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index bff010fa..69474be2 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -177,6 +177,19 @@ radeon_drm_abort_id(uint64_t id) } } +/* + * Wait for pending page flip on given CRTC to complete + */ +void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + while (drmmode_crtc->flip_pending && + drmHandleEvent(pRADEONEnt->fd, &drmmode->event_context) > 0); +} + /* * Initialize the DRM event queue */ diff --git a/src/radeon_drm_queue.h b/src/radeon_drm_queue.h index b6aab37c..96f88bd3 100644 --- a/src/radeon_drm_queue.h +++ b/src/radeon_drm_queue.h @@ -47,6 +47,7 @@ uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, void radeon_drm_abort_client(ClientPtr client); void radeon_drm_abort_entry(uintptr_t seq); void radeon_drm_abort_id(uint64_t id); +void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc); void radeon_drm_queue_init(ScrnInfoPtr scrn); void radeon_drm_queue_close(ScrnInfoPtr scrn); -- cgit v1.2.3 From ba83a866af5a3784fc4822614375cc081e93197c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 16 Aug 2018 17:44:45 +0200 Subject: Add radeon_drm_handle_event wrapper for drmHandleEvent Instead of processing DRM events directly from drmHandleEvent's callbacks, there are three phases: 1. drmHandleEvent is called, and signalled events are re-queued to _signalled lists from its callbacks. 2. Signalled page flip completion events are processed. 3. Signalled vblank events are processed. This should make sure that we never call drmHandleEvent from one of its callbacks, which would usually result in blocking forever. (Ported from amdgpu commit 739181c8d3334ff14b5a607895dfdeb29b0d9020) Acked-by: Alex Deucher --- src/drmmode_display.c | 13 +++--- src/radeon_drm_queue.c | 110 ++++++++++++++++++++++++++++++++++++++----------- src/radeon_drm_queue.h | 1 + src/radeon_present.c | 2 +- 4 files changed, 96 insertions(+), 30 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 73eadeb1..b4c9783c 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2587,9 +2587,8 @@ static void drm_wakeup_handler(pointer data, int err, pointer p) #endif { - ScrnInfoPtr scrn = data; - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - RADEONInfoPtr info = RADEONPTR(scrn); + drmmode_ptr drmmode = data; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(drmmode->scrn); #if !HAVE_NOTIFY_FD fd_set *read_mask = p; @@ -2597,7 +2596,7 @@ drm_wakeup_handler(pointer data, int err, pointer p) if (err >= 0 && FD_ISSET(pRADEONEnt->fd, read_mask)) #endif { - drmHandleEvent(pRADEONEnt->fd, &info->drmmode.event_context); + radeon_drm_handle_event(pRADEONEnt->fd, &drmmode->event_context); } } @@ -2747,11 +2746,13 @@ void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode) info->drmmode_inited = TRUE; if (pRADEONEnt->fd_wakeup_registered != serverGeneration) { #if HAVE_NOTIFY_FD - SetNotifyFd(pRADEONEnt->fd, drm_notify_fd, X_NOTIFY_READ, pScrn); + SetNotifyFd(pRADEONEnt->fd, drm_notify_fd, X_NOTIFY_READ, + &info->drmmode); #else AddGeneralSocket(pRADEONEnt->fd); RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, - drm_wakeup_handler, pScrn); + drm_wakeup_handler, + &info->drmmode); #endif pRADEONEnt->fd_wakeup_registered = serverGeneration; pRADEONEnt->fd_wakeup_ref = 1; diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index 69474be2..3d2f4d15 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 usec; uint64_t id; uintptr_t seq; void *data; @@ -47,36 +48,73 @@ struct radeon_drm_queue_entry { xf86CrtcPtr crtc; radeon_drm_handler_proc handler; radeon_drm_abort_proc abort; + unsigned int frame; }; static int radeon_drm_queue_refcnt; static struct xorg_list radeon_drm_queue; +static struct xorg_list radeon_drm_flip_signalled; +static struct xorg_list radeon_drm_vblank_signalled; static uintptr_t radeon_drm_queue_seq; /* - * Handle a DRM event + * Process a DRM event */ static void -radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, - unsigned int usec, void *user_ptr) +radeon_drm_queue_handle_one(struct radeon_drm_queue_entry *e) { - 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->seq == seq) { - xorg_list_del(&e->list); - if (e->handler) - e->handler(e->crtc, frame, - (uint64_t)sec * 1000000 + usec, - e->data); - else - e->abort(e->crtc, e->data); - free(e); - break; - } + xorg_list_del(&e->list); + if (e->handler) { + e->handler(e->crtc, e->frame, e->usec, e->data); + } else + e->abort(e->crtc, e->data); + free(e); +} + +static void +radeon_drm_queue_handler(struct xorg_list *signalled, unsigned int frame, + unsigned int sec, unsigned int usec, void *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->seq == seq) { + if (!e->handler) { + e->abort(e->crtc, e->data); + break; + } + + xorg_list_del(&e->list); + e->usec = (uint64_t)sec * 1000000 + usec; + e->frame = frame; + xorg_list_append(&e->list, signalled); + break; } + } +} + +/* + * Signal a DRM page flip event + */ +static void +radeon_drm_page_flip_handler(int fd, unsigned int frame, unsigned int sec, + unsigned int usec, void *user_ptr) +{ + radeon_drm_queue_handler(&radeon_drm_flip_signalled, frame, sec, usec, + user_ptr); +} + +/* + * Signal a DRM vblank event + */ +static void +radeon_drm_vblank_handler(int fd, unsigned int frame, unsigned int sec, + unsigned int usec, void *user_ptr) +{ + radeon_drm_queue_handler(&radeon_drm_vblank_signalled, frame, sec, usec, + user_ptr); } /* @@ -177,6 +215,26 @@ radeon_drm_abort_id(uint64_t id) } } +/* + * drmHandleEvent wrapper + */ +int +radeon_drm_handle_event(int fd, drmEventContext *event_context) +{ + struct radeon_drm_queue_entry *e, *tmp; + int r; + + r = drmHandleEvent(fd, event_context); + + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_flip_signalled, list) + radeon_drm_queue_handle_one(e); + + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) + radeon_drm_queue_handle_one(e); + + return r; +} + /* * Wait for pending page flip on given CRTC to complete */ @@ -184,10 +242,14 @@ void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); - drmmode_ptr drmmode = drmmode_crtc->drmmode; + struct radeon_drm_queue_entry *e, *tmp; + + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_flip_signalled, list) + radeon_drm_queue_handle_one(e); - while (drmmode_crtc->flip_pending && - drmHandleEvent(pRADEONEnt->fd, &drmmode->event_context) > 0); + while (drmmode_crtc->flip_pending + && radeon_drm_handle_event(pRADEONEnt->fd, + &drmmode_crtc->drmmode->event_context) > 0); } /* @@ -200,13 +262,15 @@ radeon_drm_queue_init(ScrnInfoPtr scrn) drmmode_ptr drmmode = &info->drmmode; drmmode->event_context.version = 2; - drmmode->event_context.vblank_handler = radeon_drm_queue_handler; - drmmode->event_context.page_flip_handler = radeon_drm_queue_handler; + drmmode->event_context.vblank_handler = radeon_drm_vblank_handler; + drmmode->event_context.page_flip_handler = radeon_drm_page_flip_handler; if (radeon_drm_queue_refcnt++) return; xorg_list_init(&radeon_drm_queue); + xorg_list_init(&radeon_drm_flip_signalled); + xorg_list_init(&radeon_drm_vblank_signalled); } /* diff --git a/src/radeon_drm_queue.h b/src/radeon_drm_queue.h index 96f88bd3..59343361 100644 --- a/src/radeon_drm_queue.h +++ b/src/radeon_drm_queue.h @@ -47,6 +47,7 @@ uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, void radeon_drm_abort_client(ClientPtr client); void radeon_drm_abort_entry(uintptr_t seq); void radeon_drm_abort_id(uint64_t id); +int radeon_drm_handle_event(int fd, drmEventContext *event_context); void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc); void radeon_drm_queue_init(ScrnInfoPtr scrn); void radeon_drm_queue_close(ScrnInfoPtr scrn); diff --git a/src/radeon_present.c b/src/radeon_present.c index 2982d728..ffc14a0e 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -110,7 +110,7 @@ radeon_present_flush_drm_events(ScreenPtr screen) if (r <= 0) return 0; - return drmHandleEvent(pRADEONEnt->fd, &drmmode->event_context) >= 0; + return radeon_drm_handle_event(pRADEONEnt->fd, &drmmode->event_context) >= 0; } /* -- cgit v1.2.3 From c42f6e2e61d166c8d3ef3fcad175d7050a00288b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 20 Jul 2018 16:56:22 +0200 Subject: Defer vblank event handling while waiting for a pending flip This is to avoid submitting more flips while we are waiting for pending ones to complete. (Ported from amdgpu commit e52872da69ecc84dafb3355839e35b0383f0d228) Acked-by: Alex Deucher --- src/drmmode_display.c | 18 ++++++++++++------ src/drmmode_display.h | 4 ++++ src/radeon_drm_queue.c | 41 +++++++++++++++++++++++++++++++++++++++-- src/radeon_drm_queue.h | 1 + 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index b4c9783c..8445ef2a 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -324,6 +324,9 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) nominal_frame_rate /= pix_in_frame; drmmode_crtc->dpms_last_fps = nominal_frame_rate; } + + drmmode_crtc->dpms_mode = mode; + radeon_drm_queue_handle_deferred(crtc); } else if (drmmode_crtc->dpms_mode != DPMSModeOn && mode == DPMSModeOn) { /* * Off->On transition: calculate and accumulate the @@ -341,8 +344,9 @@ drmmode_do_crtc_dpms(xf86CrtcPtr crtc, int mode) drmmode_crtc->interpolated_vblanks += delta_seq; } + + drmmode_crtc->dpms_mode = DPMSModeOn; } - drmmode_crtc->dpms_mode = mode; } static void @@ -972,6 +976,7 @@ done: } } + radeon_drm_queue_handle_deferred(crtc); return ret; } @@ -1763,11 +1768,6 @@ drmmode_output_set_tear_free(RADEONEntPtr pRADEONEnt, drmmode_output->tear_free = tear_free; if (crtc) { - /* Wait for pending flips before drmmode_set_mode_major calls - * drmmode_crtc_update_tear_free, to prevent a nested - * drmHandleEvent call, which would hang - */ - radeon_drm_wait_pending_flip(crtc); drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); } @@ -3278,6 +3278,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0; drmmode_flipdata_ptr flipdata; + Bool handle_deferred = FALSE; uintptr_t drm_queue_seq = 0; struct drmmode_fb *fb; int i = 0; @@ -3360,6 +3361,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, if (drmmode_crtc->scanout_update_pending) { radeon_drm_wait_pending_flip(crtc); + handle_deferred = TRUE; radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending); drmmode_crtc->scanout_update_pending = 0; } @@ -3395,6 +3397,8 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, drm_queue_seq = 0; } + if (handle_deferred) + radeon_drm_queue_handle_deferred(ref_crtc); if (flipdata->flip_count > 0) return TRUE; @@ -3414,5 +3418,7 @@ error: xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n", strerror(errno)); + if (handle_deferred) + radeon_drm_queue_handle_deferred(ref_crtc); return FALSE; } diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 46449c8e..a039bf8f 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -103,6 +103,10 @@ typedef struct { * modeset) */ Bool need_modeset; + /* For keeping track of nested calls to drm_wait_pending_flip / + * drm_queue_handle_deferred + */ + int wait_flip_nesting_level; /* A flip to this FB is pending for this CRTC */ struct drmmode_fb *flip_pending; /* The FB currently being scanned out by this CRTC, if any */ diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index 3d2f4d15..857278fd 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -117,6 +117,30 @@ radeon_drm_vblank_handler(int fd, unsigned int frame, unsigned int sec, user_ptr); } +/* + * Handle deferred DRM vblank events + * + * This function must be called after radeon_drm_wait_pending_flip, once + * it's safe to attempt queueing a flip again + */ +void +radeon_drm_queue_handle_deferred(xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + struct radeon_drm_queue_entry *e, *tmp; + + if (drmmode_crtc->wait_flip_nesting_level == 0 || + --drmmode_crtc->wait_flip_nesting_level > 0) + return; + + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) { + drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private; + + if (drmmode_crtc->wait_flip_nesting_level == 0) + radeon_drm_queue_handle_one(e); + } +} + /* * Enqueue a potential drm response; when the associated response * appears, we've got data to pass to the handler from here @@ -191,6 +215,13 @@ radeon_drm_abort_entry(uintptr_t seq) if (seq == RADEON_DRM_QUEUE_ERROR) return; + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) { + if (e->seq == seq) { + radeon_drm_abort_one(e); + return; + } + } + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { if (e->seq == seq) { radeon_drm_abort_one(e); @@ -229,8 +260,12 @@ radeon_drm_handle_event(int fd, drmEventContext *event_context) xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_flip_signalled, list) radeon_drm_queue_handle_one(e); - xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) - radeon_drm_queue_handle_one(e); + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) { + drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private; + + if (drmmode_crtc->wait_flip_nesting_level == 0) + radeon_drm_queue_handle_one(e); + } return r; } @@ -244,6 +279,8 @@ void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc) RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); struct radeon_drm_queue_entry *e, *tmp; + drmmode_crtc->wait_flip_nesting_level++; + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_flip_signalled, list) radeon_drm_queue_handle_one(e); diff --git a/src/radeon_drm_queue.h b/src/radeon_drm_queue.h index 59343361..334c4ca6 100644 --- a/src/radeon_drm_queue.h +++ b/src/radeon_drm_queue.h @@ -40,6 +40,7 @@ typedef void (*radeon_drm_handler_proc)(xf86CrtcPtr crtc, uint32_t seq, uint64_t usec, void *data); typedef void (*radeon_drm_abort_proc)(xf86CrtcPtr crtc, void *data); +void radeon_drm_queue_handle_deferred(xf86CrtcPtr crtc); uintptr_t radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, uint64_t id, void *data, radeon_drm_handler_proc handler, -- cgit v1.2.3 From 60cd28bbbe4f9db391b4f27c5ff9289d5c2bef40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 16 Aug 2018 18:06:31 +0200 Subject: Remove drmmode_crtc_private_rec::present_vblank_* related code Not needed anymore with the more robust mechanisms for preventing nested drmHandleEvent calls introduced in the previous changes. (Ported from amdgpu commit 85cd8eef0cbed7b409b07f58d76dacd34aa3ddea) Acked-by: Alex Deucher --- src/drmmode_display.h | 8 -------- src/radeon_kms.c | 9 --------- src/radeon_present.c | 34 +++------------------------------- 3 files changed, 3 insertions(+), 48 deletions(-) diff --git a/src/drmmode_display.h b/src/drmmode_display.h index a039bf8f..bc66eda6 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -111,14 +111,6 @@ typedef struct { struct drmmode_fb *flip_pending; /* The FB currently being scanned out by this CRTC, if any */ struct drmmode_fb *fb; - -#ifdef HAVE_PRESENT_H - /* Deferred processing of Present vblank event */ - uint64_t present_vblank_event_id; - uint64_t present_vblank_usec; - unsigned present_vblank_msc; - Bool present_flip_expected; -#endif } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; typedef struct { diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 809d2446..a2477681 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -541,15 +541,6 @@ radeon_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec, drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, drmmode_crtc->flip_pending); radeon_scanout_flip_abort(crtc, event_data); - -#ifdef HAVE_PRESENT_H - if (drmmode_crtc->present_vblank_event_id) { - present_event_notify(drmmode_crtc->present_vblank_event_id, - drmmode_crtc->present_vblank_usec, - drmmode_crtc->present_vblank_msc); - drmmode_crtc->present_vblank_event_id = 0; - } -#endif } diff --git a/src/radeon_present.c b/src/radeon_present.c index ffc14a0e..d0a0c68c 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -52,7 +52,6 @@ static present_screen_info_rec radeon_present_screen_info; struct radeon_present_vblank_event { uint64_t event_id; - Bool vblank_for_flip; Bool unflip; }; @@ -120,26 +119,9 @@ static void radeon_present_vblank_handler(xf86CrtcPtr crtc, unsigned int msc, uint64_t usec, void *data) { - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; struct radeon_present_vblank_event *event = data; - if (event->vblank_for_flip && - drmmode_crtc->tear_free && - drmmode_crtc->scanout_update_pending) { - if (drmmode_crtc->present_vblank_event_id != 0) { - xf86DrvMsg(crtc->scrn->scrnIndex, X_WARNING, - "Need to handle previously deferred vblank event\n"); - present_event_notify(drmmode_crtc->present_vblank_event_id, - drmmode_crtc->present_vblank_usec, - drmmode_crtc->present_vblank_msc); - } - - drmmode_crtc->present_vblank_event_id = event->event_id; - drmmode_crtc->present_vblank_msc = msc; - drmmode_crtc->present_vblank_usec = usec; - } else - present_event_notify(event->event_id, usec, msc); - + present_event_notify(event->event_id, usec, msc); free(event); } @@ -162,7 +144,6 @@ static int radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) { xf86CrtcPtr xf86_crtc = crtc->devPrivate; - drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; ScreenPtr screen = crtc->pScreen; struct radeon_present_vblank_event *event; uintptr_t drm_queue_seq; @@ -171,8 +152,6 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) if (!event) return BadAlloc; event->event_id = event_id; - event->vblank_for_flip = drmmode_crtc->present_flip_expected; - drmmode_crtc->present_flip_expected = FALSE; drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, @@ -272,7 +251,6 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, Bool sync_flip) { xf86CrtcPtr xf86_crtc = crtc->devPrivate; - drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; ScreenPtr screen = window->drawable.pScreen; ScrnInfoPtr scrn = xf86_crtc->scrn; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); @@ -281,8 +259,6 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, int num_crtcs_on; int i; - drmmode_crtc->present_flip_expected = FALSE; - if (!scrn->vtSema) return FALSE; @@ -313,7 +289,6 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, if (num_crtcs_on == 0) return FALSE; - drmmode_crtc->present_flip_expected = TRUE; return TRUE; } @@ -354,7 +329,6 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, PixmapPtr pixmap, Bool sync_flip) { xf86CrtcPtr xf86_crtc = crtc->devPrivate; - drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; ScreenPtr screen = crtc->pScreen; ScrnInfoPtr scrn = xf86_crtc->scrn; RADEONInfoPtr info = RADEONPTR(scrn); @@ -362,11 +336,11 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, Bool ret = FALSE; if (!radeon_present_check_flip(crtc, screen->root, pixmap, sync_flip)) - goto out; + return ret; event = calloc(1, sizeof(struct radeon_present_vblank_event)); if (!event) - goto out; + return ret; event->event_id = event_id; @@ -383,8 +357,6 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, else info->drmmode.present_flipping = TRUE; - out: - drmmode_crtc->present_flip_expected = FALSE; return ret; } -- cgit v1.2.3 From 7b01c10137aba24c8f61dd9b2a19ea257ad24371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 23 Aug 2018 18:42:28 +0200 Subject: Add m4 directory Although normally it only warns about it, under some circumstances, aclocal can error out if this directory doesn't exist. Reported-by: John Lumby Acked-by: Alex Deucher --- .gitignore | 5 ----- m4/.gitignore | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 m4/.gitignore diff --git a/.gitignore b/.gitignore index 22bba424..49cbec78 100644 --- a/.gitignore +++ b/.gitignore @@ -26,12 +26,7 @@ INSTALL install-sh .libs/ libtool -libtool.m4 ltmain.sh -lt~obsolete.m4 -ltoptions.m4 -ltsugar.m4 -ltversion.m4 Makefile Makefile.in mdate-sh diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 00000000..464ba5ca --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1,5 @@ +libtool.m4 +lt~obsolete.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 -- cgit v1.2.3 From cba8fe4d64819aaa8ba516aa68dbe6d2aa153046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 23 Aug 2018 18:59:18 +0200 Subject: Use AC_CONFIG_MACRO_DIR instead of AC_CONFIG_MACRO_DIRS Older versions of autoconf only supported the former. Acked-by: Alex Deucher --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 444862f3..b6da673e 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ AC_INIT([xf86-video-ati], AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_MACRO_DIRS([m4]) +AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR(.) -- cgit v1.2.3 From 3c42bd04800211f64a17640c7ce7c4111ffd4978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 24 Aug 2018 10:55:49 +0200 Subject: EXA: Handle NULL BO pointer in radeon_set_pixmap_bo --- src/radeon.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index 1a1edb1b..b1d5f5af 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -772,11 +772,15 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_buffer *bo radeon_buffer_unref(&driver_priv->bo); drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL); - radeon_buffer_ref(bo); driver_priv->bo = bo; - radeon_bo_get_tiling(bo->bo.radeon, &driver_priv->tiling_flags, - &pitch); + if (bo) { + radeon_buffer_ref(bo); + radeon_bo_get_tiling(bo->bo.radeon, &driver_priv->tiling_flags, + &pitch); + } else + driver_priv->tiling_flags = 0; + return TRUE; } -- cgit v1.2.3 From 1799680f7bd84e0618f34f4c7486799521ddaf83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 24 Aug 2018 10:56:58 +0200 Subject: Handle ihandle == -1 in radeon_set_shared_pixmap_backing It means to stop using the shared pixmap backing. Fixes crash when changing PRIME slave output configuration. --- src/radeon_bo_helper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index 79e8ff1b..da5a484f 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -454,6 +454,9 @@ Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle, uint32_t size = ppix->devKind * ppix->drawable.height; Bool ret = FALSE; + if (ihandle == -1) + return radeon_set_pixmap_bo(ppix, NULL); + bo = (struct radeon_buffer *)calloc(1, sizeof(struct radeon_buffer)); if (!bo) goto error; -- cgit v1.2.3 From 84bde2df5b453f8aab35aa18b0cf1f20b8d20488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 24 Aug 2018 10:58:51 +0200 Subject: EXA: Handle ihandle == -1 in RADEONEXASharePixmapBacking --- src/radeon_exa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 93c2f056..268155ed 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -296,11 +296,12 @@ Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **fd_hand Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle) { struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(ppix); + int ihandle = (int)(long)fd_handle; if (!radeon_set_shared_pixmap_backing(ppix, fd_handle, &driver_priv->surface)) return FALSE; - driver_priv->shared = TRUE; + driver_priv->shared = ihandle != -1; return TRUE; } -- cgit v1.2.3 From de88ea2755611bdcb18d91d8234d2ab5be8ff2e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 24 Aug 2018 11:00:16 +0200 Subject: glamor: Handle ihandle == -1 in radeon_glamor_set_shared_pixmap_backing --- src/radeon_glamor.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index c733d192..bffc89ec 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -402,11 +402,13 @@ radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle) { ScreenPtr screen = pixmap->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + int ihandle = (int)(long)handle; if (!radeon_set_shared_pixmap_backing(pixmap, handle, NULL)) return FALSE; - if (!radeon_glamor_create_textured_pixmap(pixmap, + if (ihandle != -1 && + !radeon_glamor_create_textured_pixmap(pixmap, radeon_get_pixmap_bo(pixmap))) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to get PRIME drawable for glamor pixmap.\n"); -- cgit v1.2.3 From 87b9a3e516d19dd1b89a64f6cac990fae53fc1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 5 Sep 2018 11:27:25 +0200 Subject: Always delete entry from list in drm_queue_handler We left entries without a handler hook in the list, so the list could keep taking longer to process and use up more memory. (Ported from amdgpu commit 7eea3e2cd74eed22e982319144e18ae5b1087b78) --- src/radeon_drm_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index 857278fd..61a2f5ce 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -82,7 +82,7 @@ radeon_drm_queue_handler(struct xorg_list *signalled, unsigned int frame, xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { if (e->seq == seq) { if (!e->handler) { - e->abort(e->crtc, e->data); + radeon_drm_queue_handle_one(e); break; } -- cgit v1.2.3 From 4c7d5e50a5e469a541bc463cecb505fe850c0824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 5 Sep 2018 11:29:43 +0200 Subject: Don't use xorg_list_for_each_entry_safe for signalled flips drm_wait_pending_flip can get called from drm_handle_event, in which case xorg_list_for_each_entry_safe can end up processing the same entry in both. To avoid this, just process the first list entry until the list is empty. (Ported from amdgpu commit 26770be44b89b83bf39c28f2fe284c8cb92ed0c0) --- src/radeon_drm_queue.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index 61a2f5ce..bf1650ea 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -257,8 +257,11 @@ radeon_drm_handle_event(int fd, drmEventContext *event_context) r = drmHandleEvent(fd, event_context); - xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_flip_signalled, list) + while (!xorg_list_is_empty(&radeon_drm_flip_signalled)) { + e = xorg_list_first_entry(&radeon_drm_flip_signalled, + struct radeon_drm_queue_entry, list); radeon_drm_queue_handle_one(e); + } xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) { drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private; @@ -277,12 +280,15 @@ void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); - struct radeon_drm_queue_entry *e, *tmp; + struct radeon_drm_queue_entry *e; drmmode_crtc->wait_flip_nesting_level++; - xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_flip_signalled, list) + while (!xorg_list_is_empty(&radeon_drm_flip_signalled)) { + e = xorg_list_first_entry(&radeon_drm_flip_signalled, + struct radeon_drm_queue_entry, list); radeon_drm_queue_handle_one(e); + } while (drmmode_crtc->flip_pending && radeon_drm_handle_event(pRADEONEnt->fd, -- cgit v1.2.3 From 5d5d883496842da84d9418e91cb13454751da625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 7 Sep 2018 18:16:22 +0200 Subject: Bail early from drm_wait_pending_flip if there's no pending flip No need to process any events in that case. (Ported from amdgpu commit ca5eb9894fff153c0a1df7bdc4a4745713309e27) --- src/radeon_drm_queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index bf1650ea..ea78e8e2 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -284,7 +284,8 @@ void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc) drmmode_crtc->wait_flip_nesting_level++; - while (!xorg_list_is_empty(&radeon_drm_flip_signalled)) { + while (drmmode_crtc->flip_pending && + !xorg_list_is_empty(&radeon_drm_flip_signalled)) { e = xorg_list_first_entry(&radeon_drm_flip_signalled, struct radeon_drm_queue_entry, list); radeon_drm_queue_handle_one(e); -- cgit v1.2.3 From 2d58830c3feafc54dccc0b7bf761a466437d4a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 5 Sep 2018 18:23:29 +0200 Subject: Fix uninitialized use of local variable pitch in radeon_setup_kernel_mem Fixes server reset. Pointed out by clang: ../../src/radeon_kms.c:2721:9: warning: variable 'pitch' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] if (!info->front_buffer) { ^~~~~~~~~~~~~~~~~~~ ../../src/radeon_kms.c:2765:27: note: uninitialized use occurs here pScrn->displayWidth = pitch / cpp; ^~~~~ --- src/radeon_kms.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index a2477681..ae69f335 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2760,10 +2760,11 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) if (tiling_flags) radeon_bo_set_tiling(info->front_buffer->bo.radeon, tiling_flags, pitch); } - } - pScrn->displayWidth = pitch / cpp; + pScrn->displayWidth = pitch / cpp; + } + pitch = pScrn->displayWidth * cpp; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", pitch * pScrn->virtualY / 1024); radeon_kms_update_vram_limit(pScrn, pitch * pScrn->virtualY); -- cgit v1.2.3 From 80514b7b1b88f46f3965ff023035dea83b57e652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 14 Sep 2018 17:48:49 +0200 Subject: Bump version for 18.1.0 release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b6da673e..5edb188c 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [18.0.99], + [18.1.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) -- cgit v1.2.3 From f892d3791219d1041e0cbb1b866e15774004aa18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 15 Oct 2018 17:14:41 +0200 Subject: dri3: Handle radeon_get_pixmap_bo returning NULL We were trying to already, but testing the wrong pointer. Fixes: b85b7b11f5b5 "Add struct radeon_buffer" Bug: https://bugs.debian.org/910846 Reviewed-by: Alex Deucher --- src/radeon_dri3.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c index 7e89a2f0..25078bae 100644 --- a/src/radeon_dri3.c +++ b/src/radeon_dri3.c @@ -212,7 +212,7 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen, CARD16 *stride, CARD32 *size) { - struct radeon_bo *bo; + struct radeon_buffer *bo; int fd; #ifdef USE_GLAMOR ScrnInfoPtr scrn = xf86ScreenToScrn(screen); @@ -222,10 +222,10 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen, return glamor_fd_from_pixmap(screen, pixmap, stride, size); #endif - bo = radeon_get_pixmap_bo(pixmap)->bo.radeon; + bo = radeon_get_pixmap_bo(pixmap); if (!bo) { exaMoveInPixmap(pixmap); - bo = radeon_get_pixmap_bo(pixmap)->bo.radeon; + bo = radeon_get_pixmap_bo(pixmap); if (!bo) return -1; } @@ -233,11 +233,11 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen, if (pixmap->devKind > UINT16_MAX) return -1; - if (radeon_gem_prime_share_bo(bo, &fd) < 0) + if (radeon_gem_prime_share_bo(bo->bo.radeon, &fd) < 0) return -1; *stride = pixmap->devKind; - *size = bo->size; + *size = bo->bo.radeon->size; return fd; } -- cgit v1.2.3 From 86fe8d27b9a3f043e5288ce50eaf1f5fffd24516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 24 Oct 2018 18:14:02 +0200 Subject: Handle pending scanout update in drmmode_crtc_scanout_free We have to wait for a pending scanout flip or abort a pending scanout update, otherwise the corresponding event handler will likely crash after drmmode_crtc_scanout_free cleaned up the data structures. Fixes crash after VT switch while dedicated scanout pixmaps are enabled for any CRTC. (Ported from amdgpu commit 0cd2c337d2c02b8ec2bd994d6124b4aaaad10741) --- src/drmmode_display.c | 25 ++++++++++++++++--------- src/drmmode_display.h | 2 +- src/radeon_kms.c | 2 +- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 8445ef2a..7493d636 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -508,8 +508,17 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, } void -drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc) +drmmode_crtc_scanout_free(xf86CrtcPtr crtc) { + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + if (drmmode_crtc->scanout_update_pending) { + radeon_drm_wait_pending_flip(crtc); + radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending); + drmmode_crtc->scanout_update_pending = 0; + radeon_drm_queue_handle_deferred(crtc); + } + drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, &drmmode_crtc->scanout[0]); drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, @@ -967,9 +976,7 @@ done: if (drmmode_crtc->scanout[scanout_id].pixmap && fb != radeon_pixmap_get_fb(drmmode_crtc-> scanout[scanout_id].pixmap)) { - radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending); - drmmode_crtc->scanout_update_pending = 0; - drmmode_crtc_scanout_free(drmmode_crtc); + drmmode_crtc_scanout_free(crtc); } else if (!drmmode_crtc->tear_free) { drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]); @@ -1265,7 +1272,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) } } - drmmode_crtc_scanout_free(drmmode_crtc); + drmmode_crtc_scanout_free(crtc); drmmode_crtc->prime_scanout_pixmap = NULL; if (!ppix) @@ -1280,7 +1287,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) !drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], ppix->drawable.width, ppix->drawable.height)) { - drmmode_crtc_scanout_free(drmmode_crtc); + drmmode_crtc_scanout_free(crtc); return FALSE; } @@ -2770,6 +2777,9 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) if (info->dri2.pKernelDRMVersion->version_minor < 4 || !info->drmmode_inited) return; + for (c = 0; c < config->num_crtc; c++) + drmmode_crtc_scanout_free(config->crtc[c]); + if (pRADEONEnt->fd_wakeup_registered == serverGeneration && !--pRADEONEnt->fd_wakeup_ref) { #if HAVE_NOTIFY_FD @@ -2780,9 +2790,6 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) drm_wakeup_handler, pScrn); #endif } - - for (c = 0; c < config->num_crtc; c++) - drmmode_crtc_scanout_free(config->crtc[c]->driver_private); } diff --git a/src/drmmode_display.h b/src/drmmode_display.h index bc66eda6..bfc13010 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -215,7 +215,7 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); extern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, struct drmmode_scanout *scanout); -void drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc); +void drmmode_crtc_scanout_free(xf86CrtcPtr crtc); PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, int width, int height); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index ae69f335..50c7137c 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2614,7 +2614,7 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn) pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap, None, pRADEONEnt); } else { - drmmode_crtc_scanout_free(drmmode_crtc); + drmmode_crtc_scanout_free(crtc); } } } -- cgit v1.2.3 From c480fd066fe129fa6561fca8c09f037613b753e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 24 Oct 2018 18:19:42 +0200 Subject: Make wait_pending_flip / handle_deferred symmetric in set_mode_major We were always calling the latter, but not always the former, which could result in handling deferred DRM events prematurely. (Ported from amdgpu commit 955373a3e69baa241a1f267e96d04ddb902f689f) --- src/drmmode_display.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 7493d636..32ffe84e 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -857,6 +857,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + Bool handle_deferred = FALSE; unsigned scanout_id = 0; drmmode_ptr drmmode = drmmode_crtc->drmmode; int saved_x, saved_y; @@ -924,6 +925,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, } radeon_drm_wait_pending_flip(crtc); + handle_deferred = TRUE; if (!drmmode_set_mode(crtc, fb, mode, x, y)) goto done; @@ -983,7 +985,9 @@ done: } } - radeon_drm_queue_handle_deferred(crtc); + if (handle_deferred) + radeon_drm_queue_handle_deferred(crtc); + return ret; } -- cgit v1.2.3 From 5e6fa5c17a810127f0049816f20db6b871ca77e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 24 Oct 2018 18:22:05 +0200 Subject: Allow up to six instances in Zaphod mode Corresponding to up to six CRTCs being available in the hardware. (Ported from amdgpu commit c9d43c1deb9a9cfc41a8d6439caf46d12d220853) --- src/drmmode_display.c | 38 ++++++++++++++++++++++++-------------- src/radeon.h | 2 +- src/radeon_kms.c | 49 +++++++++++++++++++++++-------------------------- src/radeon_probe.h | 4 ++-- 4 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 32ffe84e..fbdf5e6d 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2060,9 +2060,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r if (!RADEONZaphodStringMatches(pScrn, s, name)) goto out_free_encoders; } else { - if (!info->IsSecondary && (num != 0)) - goto out_free_encoders; - else if (info->IsSecondary && (num != 1)) + if (info->instance_id != num) goto out_free_encoders; } } @@ -2680,6 +2678,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) int i, num_dvi = 0, num_hdmi = 0; drmModeResPtr mode_res; unsigned int crtcs_needed = 0; + unsigned int crtcs_got = 0; char *bus_id_string, *provider_name; xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); @@ -2718,16 +2717,26 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) drmmode->count_crtcs = mode_res->count_crtcs; xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, mode_res->max_height); - for (i = 0; i < mode_res->count_crtcs; i++) + for (i = 0; i < mode_res->count_crtcs; i++) { if (!xf86IsEntityShared(pScrn->entityList[0]) || - (crtcs_needed && !(pRADEONEnt->assigned_crtcs & (1 << i)))) - crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i); + (crtcs_got < crtcs_needed && + !(pRADEONEnt->assigned_crtcs & (1 << i)))) + crtcs_got += drmmode_crtc_init(pScrn, drmmode, mode_res, i); + } /* All ZaphodHeads outputs provided with matching crtcs? */ - if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0)) + if (crtcs_got < crtcs_needed) { + if (crtcs_got == 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No ZaphodHeads CRTC available, needed %u\n", + crtcs_needed); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%d ZaphodHeads crtcs unavailable. Some outputs will stay off.\n", crtcs_needed); + } /* workout clones */ drmmode_clones_init(pScrn, drmmode, mode_res); @@ -3170,13 +3179,14 @@ restart_destroy: /* find new output ids we don't have outputs for */ for (i = 0; i < mode_res->count_connectors; i++) { - if (drmmode_find_output(pRADEONEnt->primary_scrn, - mode_res->connectors[i], - &num_dvi, &num_hdmi) || - (pRADEONEnt->secondary_scrn && - drmmode_find_output(pRADEONEnt->secondary_scrn, - mode_res->connectors[i], - &num_dvi, &num_hdmi))) + for (j = 0; j < pRADEONEnt->num_scrns; j++) { + if (drmmode_find_output(pRADEONEnt->scrn[j], + mode_res->connectors[i], + &num_dvi, &num_hdmi)) + break; + } + + if (j < pRADEONEnt->num_scrns) continue; if (drmmode_output_init(scrn, drmmode, mode_res, i, &num_dvi, diff --git a/src/radeon.h b/src/radeon.h index b1d5f5af..cde922c6 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -560,7 +560,7 @@ typedef struct { /* Number of SW cursors currently visible on this screen */ int sprites_visible; - Bool IsSecondary; + int instance_id; Bool r600_shadow_fb; void *fb_shadow; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 50c7137c..cd5efd53 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -202,6 +202,10 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn) if (!pScrn) return; + pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); + pPriv = xf86GetEntityPrivate(pEnt->index, gRADEONEntityIndex); + pRADEONEnt = pPriv->ptr; + info = RADEONPTR(pScrn); if (info) { if (info->fbcon_pixmap) @@ -217,15 +221,12 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn) gbm_device_destroy(info->gbm); #endif - pEnt = info->pEnt; + pRADEONEnt->scrn[info->instance_id] = NULL; + pRADEONEnt->num_scrns--; free(pScrn->driverPrivate); pScrn->driverPrivate = NULL; - } else { - pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); } - pPriv = xf86GetEntityPrivate(pEnt->index, gRADEONEntityIndex); - pRADEONEnt = pPriv->ptr; if (pRADEONEnt->fd > 0) { DevUnion *pPriv; RADEONEntPtr pRADEONEnt; @@ -1689,7 +1690,6 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) RADEONInfoPtr info; RADEONEntPtr pRADEONEnt; MessageType from; - DevUnion* pPriv; Gamma zeros = { 0.0, 0.0, 0.0 }; uint32_t tiling = 0; int cpp; @@ -1700,10 +1700,23 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, "RADEONPreInit_KMS\n"); if (pScrn->numEntities != 1) return FALSE; + + pRADEONEnt = xf86GetEntityPrivate(pScrn->entityList[0], + getRADEONEntityIndex())->ptr; + if (pRADEONEnt->num_scrns == ARRAY_SIZE(pRADEONEnt->scrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Only up to %u Zaphod instances supported\n", + (unsigned)ARRAY_SIZE(pRADEONEnt->scrn)); + return FALSE; + } + if (!RADEONGetRec(pScrn)) return FALSE; info = RADEONPTR(pScrn); - info->IsSecondary = FALSE; + + info->instance_id = pRADEONEnt->num_scrns++; + pRADEONEnt->scrn[info->instance_id] = pScrn; + info->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); if (info->pEnt->location.type != BUS_PCI #ifdef XSERVER_PLATFORM_BUS @@ -1712,27 +1725,11 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) ) return FALSE; - pPriv = xf86GetEntityPrivate(pScrn->entityList[0], - getRADEONEntityIndex()); - pRADEONEnt = pPriv->ptr; - - if(xf86IsEntityShared(pScrn->entityList[0])) - { - if(xf86IsPrimInitDone(pScrn->entityList[0])) - { - info->IsSecondary = TRUE; - } - else - { - xf86SetPrimInitDone(pScrn->entityList[0]); - } + if (xf86IsEntityShared(pScrn->entityList[0]) && + info->instance_id == 0) { + xf86SetPrimInitDone(pScrn->entityList[0]); } - if (info->IsSecondary) - pRADEONEnt->secondary_scrn = pScrn; - else - pRADEONEnt->primary_scrn = pScrn; - info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); pScrn->monitor = pScrn->confScreen->monitor; diff --git a/src/radeon_probe.h b/src/radeon_probe.h index be82f9ae..7cb29b91 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -140,8 +140,8 @@ typedef struct unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */ int fd_wakeup_ref; unsigned int assigned_crtcs; - ScrnInfoPtr primary_scrn; - ScrnInfoPtr secondary_scrn; + unsigned int num_scrns; + ScrnInfoPtr scrn[6]; #ifdef XSERVER_PLATFORM_BUS struct xf86_platform_device *platform_dev; #endif -- cgit v1.2.3 From 33cbd449b5305b8e8c0319af8becc1ab1832c101 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Sun, 18 Nov 2018 12:22:16 -0800 Subject: Update README for gitlab migration Signed-off-by: Alan Coopersmith --- Makefile.am | 2 +- README | 25 ------------------------- README.md | 19 +++++++++++++++++++ 3 files changed, 20 insertions(+), 26 deletions(-) delete mode 100644 README create mode 100644 README.md diff --git a/Makefile.am b/Makefile.am index b8d99f32..d14ed8f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,4 +31,4 @@ INSTALL: ChangeLog: $(CHANGELOG_CMD) -EXTRA_DIST = ChangeLog INSTALL +EXTRA_DIST = ChangeLog INSTALL README.md diff --git a/README b/README deleted file mode 100644 index bf7c6407..00000000 --- a/README +++ /dev/null @@ -1,25 +0,0 @@ -xf86-video-ati - ATI/AMD Radeon video driver for the Xorg X server - -Patches and questions regarding this software should be directed at the -amd-gfx mailing list: - - https://lists.freedesktop.org/mailman/listinfo/amd-gfx - -Please submit bug reports to the Xorg bugzilla: - - https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon - -The master development code repository can be found at: - - git://anongit.freedesktop.org/git/xorg/driver/xf86-video-ati - - https://cgit.freedesktop.org/xorg/driver/xf86-video-ati - -For patch submission instructions, see: - - https://www.x.org/wiki/Development/Documentation/SubmittingPatches - -For more information on the git code manager, see: - - https://wiki.x.org/wiki/GitPage - diff --git a/README.md b/README.md new file mode 100644 index 00000000..7c9925c7 --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +xf86-video-ati - ATI/AMD Radeon video driver for the Xorg X server +------------------------------------------------------------------ + +Patches and questions regarding this software should be directed at the +amd-gfx mailing list: + + https://lists.freedesktop.org/mailman/listinfo/amd-gfx + +Please submit bug reports to the Xorg bugzilla: + + https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon + +The master development code repository can be found at: + + https://gitlab.freedesktop.org/xorg/driver/xf86-video-ati + +For patch submission instructions, see: + + https://www.x.org/wiki/Development/Documentation/SubmittingPatches -- cgit v1.2.3 From b559fd83b2b026b50fe39a2b69bdc0901fd3330c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 19 Nov 2018 11:38:22 +0100 Subject: Post-release version bump --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 5edb188c..84f25cfd 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [18.1.0], + [18.1.99], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) -- cgit v1.2.3 From 0058fd2ebf4c900b12f129984e98886a7ac84b2f Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Tue, 18 Dec 2018 11:40:35 +0100 Subject: Fix crash when page flipping in multi-X-Screen/Zaphod mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit radeon_do_pageflip() indexed the flipdata->fb[] array indexing over config->num_crtc, but the flip completion routines, e.g., drmmode_flip_handler(), index that array via the crtc hw id from drmmode_get_crtc_id(crtc). This is mismatched and causes indexing into the wrong array slot at flip completion -> Server crash. Always use drmmode_get_crtc_id(crtc) for indexing into the array to fix this. Tested on a dual-X-Screen setup with one video output assigned to each X-Screen, page-flipping an OpenGL app on either of both X-Screens. This used to crash when flipping on X-Screen 1, now it doesn't anymore. Fixes: 740f0850f1e4 "Store FB for each CRTC in drmmode_flipdata_rec" Reviewed-by: Michel Dänzer Signed-off-by: Mario Kleiner --- src/drmmode_display.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index fbdf5e6d..00d94449 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -3297,6 +3297,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcPtr crtc = NULL; drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; + int crtc_id; uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0; drmmode_flipdata_ptr flipdata; Bool handle_deferred = FALSE; @@ -3304,7 +3305,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, struct drmmode_fb *fb; int i = 0; - flipdata = calloc(1, sizeof(*flipdata) + config->num_crtc * + flipdata = calloc(1, sizeof(*flipdata) + drmmode_crtc->drmmode->count_crtcs * sizeof(flipdata->fb[0])); if (!flipdata) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -3336,6 +3337,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, for (i = 0; i < config->num_crtc; i++) { crtc = config->crtc[i]; drmmode_crtc = crtc->driver_private; + crtc_id = drmmode_get_crtc_id(crtc); if (!drmmode_crtc_can_flip(crtc) || (drmmode_crtc->tear_free && crtc != ref_crtc)) @@ -3369,9 +3371,9 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, goto next; } - drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb[i], + drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb[crtc_id], radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap)); - if (!flipdata->fb[i]) { + if (!flipdata->fb[crtc_id]) { ErrorF("Failed to get FB for TearFree flip\n"); goto error; } @@ -3387,13 +3389,13 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, drmmode_crtc->scanout_update_pending = 0; } } else { - drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb[i], fb); + drmmode_fb_reference(pRADEONEnt->fd, &flipdata->fb[crtc_id], fb); } if (crtc == ref_crtc) { if (drmmode_page_flip_target_absolute(pRADEONEnt, drmmode_crtc, - flipdata->fb[i]->handle, + flipdata->fb[crtc_id]->handle, flip_flags, drm_queue_seq, target_msc) != 0) @@ -3401,7 +3403,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, } else { if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, - flipdata->fb[i]->handle, + flipdata->fb[crtc_id]->handle, flip_flags, drm_queue_seq, 0) != 0) goto flip_error; @@ -3414,7 +3416,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, next: drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, - flipdata->fb[i]); + flipdata->fb[crtc_id]); drm_queue_seq = 0; } -- cgit v1.2.3 From 0c40a76d1c050d018e6d59bebb5efc9c62be308c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 20 Dec 2018 18:25:21 +0100 Subject: Detect and fix up non-premultiplied cursor data X server >= 1.18 already has code for this, but handle it with older X servers as well. (Ported from amdgpu commits ad6dfb0124860cf67730bde85867f81d9258c84d & 426f9a49655f01863cf4d898f525e5f95984e0c4) --- src/drmmode_display.c | 81 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 00d94449..9a9e092a 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1049,29 +1049,52 @@ drmmode_cursor_src_offset(Rotation rotation, int width, int height, #endif -static uint32_t -drmmode_cursor_gamma(xf86CrtcPtr crtc, uint32_t argb) +static Bool +drmmode_cursor_pixel(xf86CrtcPtr crtc, uint32_t *argb, Bool premultiplied, + Bool apply_gamma) { - uint32_t alpha = argb >> 24; + uint32_t alpha = *argb >> 24; uint32_t rgb[3]; int i; - if (!alpha) - return 0; + if (premultiplied) { +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 18, 4, 0, 0) + if (alpha == 0 && (*argb & 0xffffff) != 0) + /* Doesn't look like premultiplied alpha */ + return FALSE; +#endif - if (crtc->scrn->depth != 24 && crtc->scrn->depth != 32) - return argb; + if (!apply_gamma) + return TRUE; + } - /* Un-premultiply alpha */ + if (!alpha) { + *argb = 0; + return TRUE; + } + + /* Extract RGB */ for (i = 0; i < 3; i++) - rgb[i] = ((argb >> (i * 8)) & 0xff) * 0xff / alpha; + rgb[i] = (*argb >> (i * 8)) & 0xff; + + if (premultiplied) { + /* Un-premultiply alpha */ + for (i = 0; i < 3; i++) + rgb[i] = rgb[i] * 0xff / alpha; + } + + if (apply_gamma) { + rgb[0] = crtc->gamma_blue[rgb[0]] >> 8; + rgb[1] = crtc->gamma_green[rgb[1]] >> 8; + rgb[2] = crtc->gamma_red[rgb[2]] >> 8; + } - /* Apply gamma correction and pre-multiply alpha */ - rgb[0] = (crtc->gamma_blue[rgb[0]] >> 8) * alpha / 0xff; - rgb[1] = (crtc->gamma_green[rgb[1]] >> 8) * alpha / 0xff; - rgb[2] = (crtc->gamma_red[rgb[2]] >> 8) * alpha / 0xff; + /* Premultiply alpha */ + for (i = 0; i < 3; i++) + rgb[i] = rgb[i] * alpha / 0xff; - return alpha << 24 | rgb[2] << 16 | rgb[1] << 8 | rgb[0]; + *argb = alpha << 24 | rgb[2] << 16 | rgb[1] << 8 | rgb[0]; + return TRUE; } static void @@ -1080,27 +1103,37 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) ScrnInfoPtr pScrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + Bool premultiplied = TRUE; + Bool apply_gamma = TRUE; + uint32_t argb; uint32_t *ptr; /* cursor should be mapped already */ ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr); + if (crtc->scrn->depth != 24 && crtc->scrn->depth != 32) + apply_gamma = FALSE; + #if XF86_CRTC_VERSION < 7 if (crtc->driverIsPerformingTransform) { uint32_t cursor_w = info->cursor_w, cursor_h = info->cursor_h; int dstx, dsty; int srcoffset; +retry_transform: for (dsty = 0; dsty < cursor_h; dsty++) { for (dstx = 0; dstx < cursor_w; dstx++) { srcoffset = drmmode_cursor_src_offset(crtc->rotation, cursor_w, cursor_h, dstx, dsty); - - ptr[dsty * info->cursor_w + dstx] = - cpu_to_le32(drmmode_cursor_gamma(crtc, - image[srcoffset])); + argb = image[srcoffset]; + if (!drmmode_cursor_pixel(crtc, &argb, premultiplied, + apply_gamma)) { + premultiplied = FALSE; + goto retry_transform; + } + ptr[dsty * info->cursor_w + dstx] = cpu_to_le32(argb); } } } else @@ -1109,8 +1142,16 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) uint32_t cursor_size = info->cursor_w * info->cursor_h; int i; - for (i = 0; i < cursor_size; i++) - ptr[i] = cpu_to_le32(drmmode_cursor_gamma(crtc, image[i])); +retry: + for (i = 0; i < cursor_size; i++) { + argb = image[i]; + if (!drmmode_cursor_pixel(crtc, &argb, premultiplied, + apply_gamma)) { + premultiplied = FALSE; + goto retry; + } + ptr[i] = cpu_to_le32(argb); + } } } -- cgit v1.2.3 From 99ac121770da53196124d80375a5c8edbcf827fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 20 Dec 2018 18:38:33 +0100 Subject: Skip gamma correction of cursor data if premultiplied R/G/B > alpha The un-premultiplied R/G/B values would overflow the gamma LUT, so just pass through the data unchanged, and leave it up to the HW how to interpret such weird premultiplied alpha pixels. Bugzilla: https://bugs.freedesktop.org/108355 (Ported from amdgpu commit 13c94a373b4858a2d2aa14c22b5f98d53c84c0d9) --- src/drmmode_display.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 9a9e092a..831394d4 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1050,8 +1050,8 @@ drmmode_cursor_src_offset(Rotation rotation, int width, int height, #endif static Bool -drmmode_cursor_pixel(xf86CrtcPtr crtc, uint32_t *argb, Bool premultiplied, - Bool apply_gamma) +drmmode_cursor_pixel(xf86CrtcPtr crtc, uint32_t *argb, Bool *premultiplied, + Bool *apply_gamma) { uint32_t alpha = *argb >> 24; uint32_t rgb[3]; @@ -1059,13 +1059,23 @@ drmmode_cursor_pixel(xf86CrtcPtr crtc, uint32_t *argb, Bool premultiplied, if (premultiplied) { #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 18, 4, 0, 0) - if (alpha == 0 && (*argb & 0xffffff) != 0) + if (alpha == 0 && (*argb & 0xffffff) != 0) { /* Doesn't look like premultiplied alpha */ + *premultiplied = FALSE; return FALSE; + } #endif - if (!apply_gamma) + if (!(*apply_gamma)) return TRUE; + + if (*argb > (alpha | alpha << 8 | alpha << 16 | alpha << 24)) { + /* Un-premultiplied R/G/B would overflow gamma LUT, + * don't apply gamma correction + */ + *apply_gamma = FALSE; + return FALSE; + } } if (!alpha) { @@ -1083,7 +1093,7 @@ drmmode_cursor_pixel(xf86CrtcPtr crtc, uint32_t *argb, Bool premultiplied, rgb[i] = rgb[i] * 0xff / alpha; } - if (apply_gamma) { + if (*apply_gamma) { rgb[0] = crtc->gamma_blue[rgb[0]] >> 8; rgb[1] = crtc->gamma_green[rgb[1]] >> 8; rgb[2] = crtc->gamma_red[rgb[2]] >> 8; @@ -1128,11 +1138,10 @@ retry_transform: cursor_h, dstx, dsty); argb = image[srcoffset]; - if (!drmmode_cursor_pixel(crtc, &argb, premultiplied, - apply_gamma)) { - premultiplied = FALSE; + if (!drmmode_cursor_pixel(crtc, &argb, &premultiplied, + &apply_gamma)) goto retry_transform; - } + ptr[dsty * info->cursor_w + dstx] = cpu_to_le32(argb); } } @@ -1145,11 +1154,10 @@ retry_transform: retry: for (i = 0; i < cursor_size; i++) { argb = image[i]; - if (!drmmode_cursor_pixel(crtc, &argb, premultiplied, - apply_gamma)) { - premultiplied = FALSE; + if (!drmmode_cursor_pixel(crtc, &argb, &premultiplied, + &apply_gamma)) goto retry; - } + ptr[i] = cpu_to_le32(argb); } } -- cgit v1.2.3 From 06957e3067b9eb38d30b32d98a07895399f4cb36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 20 Dec 2018 18:40:19 +0100 Subject: glamor: Can work at depth >= 15 with current xserver Git master (Ported from amdgpu commit 0734cdf544ffd3f2ac8749ad0e4bf43f8a5cea50) --- src/radeon_bo_helper.c | 2 ++ src/radeon_glamor.c | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c index da5a484f..8b3e5797 100644 --- a/src/radeon_bo_helper.c +++ b/src/radeon_bo_helper.c @@ -39,6 +39,8 @@ radeon_get_gbm_format(int depth, int bitsPerPixel) case 8: return GBM_FORMAT_R8; #endif + case 15: + return GBM_FORMAT_ARGB1555; case 16: return GBM_FORMAT_RGB565; case 32: diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index bffc89ec..f1098381 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -109,9 +109,14 @@ radeon_glamor_pre_init(ScrnInfoPtr scrn) "glamor may not work (well) with GPUs < RV515.\n"); } +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,99,0,0) if (scrn->depth < 24) { +#else + if (scrn->depth < 15) { +#endif xf86DrvMsg(scrn->scrnIndex, s ? X_ERROR : X_WARNING, - "glamor requires depth >= 24, disabling.\n"); + "Depth %d not supported with glamor, disabling\n", + scrn->depth); return FALSE; } -- cgit v1.2.3 From 189b6facb3988c00c96d970f8c13ed8d58fa3998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 20 Dec 2018 18:44:24 +0100 Subject: Use drm_abort_one in drm_queue_handler At this point, we've already established that e->handler is NULL, no need to check again in drm_queue_handle_one. This also makes it clearer what's happening. (Ported from amdgpu commit eda571222f5a6be47f8897e82d85199bb9d95251) --- src/radeon_drm_queue.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index ea78e8e2..ebc6a5b6 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -72,6 +72,19 @@ radeon_drm_queue_handle_one(struct radeon_drm_queue_entry *e) free(e); } +/* + * Abort one queued DRM entry, removing it + * from the list, calling the abort function and + * freeing the memory + */ +static void +radeon_drm_abort_one(struct radeon_drm_queue_entry *e) +{ + xorg_list_del(&e->list); + e->abort(e->crtc, e->data); + free(e); +} + static void radeon_drm_queue_handler(struct xorg_list *signalled, unsigned int frame, unsigned int sec, unsigned int usec, void *user_ptr) @@ -82,7 +95,7 @@ radeon_drm_queue_handler(struct xorg_list *signalled, unsigned int frame, xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { if (e->seq == seq) { if (!e->handler) { - radeon_drm_queue_handle_one(e); + radeon_drm_abort_one(e); break; } @@ -173,19 +186,6 @@ radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, return e->seq; } -/* - * Abort one queued DRM entry, removing it - * from the list, calling the abort function and - * freeing the memory - */ -static void -radeon_drm_abort_one(struct radeon_drm_queue_entry *e) -{ - xorg_list_del(&e->list); - e->abort(e->crtc, e->data); - free(e); -} - /* * Abort drm queue entries for a client * -- cgit v1.2.3 From f450632077843a95a6ef269febbfb64a605045ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 20 Dec 2018 18:48:19 +0100 Subject: Explicitly keep track of whether a DRM event is for a flip or not When an async flip is performed, and TearFree is enabled on the CRTC used for timing, we schedule a vblank event for completing the page flip. The DRM event queuing code treated this event like a vblank event, but it needs to be treated like a page flip event. (Ported from amdgpu commit e2c7369cae65069aa93eed1c0b678f975ce5c274) --- src/drmmode_display.c | 3 ++- src/radeon_dri2.c | 4 ++-- src/radeon_drm_queue.c | 39 +++++++++++---------------------------- src/radeon_drm_queue.h | 3 ++- src/radeon_kms.c | 10 ++++++---- src/radeon_present.c | 3 ++- 6 files changed, 25 insertions(+), 37 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 831394d4..134b0f72 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -3397,7 +3397,8 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, drm_queue_seq = radeon_drm_queue_alloc(crtc, client, id, flipdata, drmmode_flip_handler, - drmmode_flip_abort); + drmmode_flip_abort, + TRUE); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM queue event entry failed.\n"); diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 4d12fc09..922ed4fb 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -1076,7 +1076,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, 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); + radeon_dri2_frame_event_abort, FALSE); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM queue event entry failed.\n"); @@ -1215,7 +1215,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, 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); + radeon_dri2_frame_event_abort, FALSE); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM queue entry failed.\n"); diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index ebc6a5b6..acfea3da 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -48,6 +48,7 @@ struct radeon_drm_queue_entry { xf86CrtcPtr crtc; radeon_drm_handler_proc handler; radeon_drm_abort_proc abort; + Bool is_flip; unsigned int frame; }; @@ -86,8 +87,8 @@ radeon_drm_abort_one(struct radeon_drm_queue_entry *e) } static void -radeon_drm_queue_handler(struct xorg_list *signalled, unsigned int frame, - unsigned int sec, unsigned int usec, void *user_ptr) +radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, + unsigned int usec, void *user_ptr) { uintptr_t seq = (uintptr_t)user_ptr; struct radeon_drm_queue_entry *e, *tmp; @@ -102,34 +103,14 @@ radeon_drm_queue_handler(struct xorg_list *signalled, unsigned int frame, xorg_list_del(&e->list); e->usec = (uint64_t)sec * 1000000 + usec; e->frame = frame; - xorg_list_append(&e->list, signalled); + xorg_list_append(&e->list, e->is_flip ? + &radeon_drm_flip_signalled : + &radeon_drm_vblank_signalled); break; } } } -/* - * Signal a DRM page flip event - */ -static void -radeon_drm_page_flip_handler(int fd, unsigned int frame, unsigned int sec, - unsigned int usec, void *user_ptr) -{ - radeon_drm_queue_handler(&radeon_drm_flip_signalled, frame, sec, usec, - user_ptr); -} - -/* - * Signal a DRM vblank event - */ -static void -radeon_drm_vblank_handler(int fd, unsigned int frame, unsigned int sec, - unsigned int usec, void *user_ptr) -{ - radeon_drm_queue_handler(&radeon_drm_vblank_signalled, frame, sec, usec, - user_ptr); -} - /* * Handle deferred DRM vblank events * @@ -162,7 +143,8 @@ 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) + radeon_drm_abort_proc abort, + Bool is_flip) { struct radeon_drm_queue_entry *e; @@ -180,6 +162,7 @@ radeon_drm_queue_alloc(xf86CrtcPtr crtc, ClientPtr client, e->data = data; e->handler = handler; e->abort = abort; + e->is_flip = is_flip; xorg_list_append(&e->list, &radeon_drm_queue); @@ -306,8 +289,8 @@ radeon_drm_queue_init(ScrnInfoPtr scrn) drmmode_ptr drmmode = &info->drmmode; drmmode->event_context.version = 2; - drmmode->event_context.vblank_handler = radeon_drm_vblank_handler; - drmmode->event_context.page_flip_handler = radeon_drm_page_flip_handler; + drmmode->event_context.vblank_handler = radeon_drm_queue_handler; + drmmode->event_context.page_flip_handler = radeon_drm_queue_handler; if (radeon_drm_queue_refcnt++) return; diff --git a/src/radeon_drm_queue.h b/src/radeon_drm_queue.h index 334c4ca6..19d42e93 100644 --- a/src/radeon_drm_queue.h +++ b/src/radeon_drm_queue.h @@ -44,7 +44,8 @@ void radeon_drm_queue_handle_deferred(xf86CrtcPtr crtc); 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); + radeon_drm_abort_proc abort, + Bool is_flip); void radeon_drm_abort_client(ClientPtr client); void radeon_drm_abort_entry(uintptr_t seq); void radeon_drm_abort_id(uint64_t id); diff --git a/src/radeon_kms.c b/src/radeon_kms.c index cd5efd53..a7aade70 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -769,7 +769,8 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) RADEON_DRM_QUEUE_CLIENT_DEFAULT, RADEON_DRM_QUEUE_ID_DEFAULT, NULL, radeon_prime_scanout_update_handler, - radeon_prime_scanout_update_abort); + radeon_prime_scanout_update_abort, + FALSE); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "radeon_drm_queue_alloc failed for PRIME update\n"); @@ -817,7 +818,7 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) RADEON_DRM_QUEUE_ID_DEFAULT, NULL, radeon_scanout_flip_handler, - radeon_scanout_flip_abort); + radeon_scanout_flip_abort, TRUE); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM event queue entry failed for PRIME flip.\n"); @@ -1053,7 +1054,8 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) RADEON_DRM_QUEUE_ID_DEFAULT, drmmode_crtc, radeon_scanout_update_handler, - radeon_scanout_update_abort); + radeon_scanout_update_abort, + FALSE); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "radeon_drm_queue_alloc failed for scanout update\n"); @@ -1102,7 +1104,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, RADEON_DRM_QUEUE_ID_DEFAULT, NULL, radeon_scanout_flip_handler, - radeon_scanout_flip_abort); + radeon_scanout_flip_abort, TRUE); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Allocating DRM event queue entry failed.\n"); diff --git a/src/radeon_present.c b/src/radeon_present.c index d0a0c68c..0b55117e 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -157,7 +157,8 @@ radeon_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) RADEON_DRM_QUEUE_CLIENT_DEFAULT, event_id, event, radeon_present_vblank_handler, - radeon_present_vblank_abort); + radeon_present_vblank_abort, + FALSE); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { free(event); return BadAlloc; -- cgit v1.2.3 From 64942d2c49f9fa1afcc42c07943d076a40963e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 20 Dec 2018 19:00:08 +0100 Subject: Move deferred vblank events to separate drm_vblank_deferred list It was still possible for nested xorg_list_for_each_entry_safe loops to occur over the drm_vblank_signalled list, which could mess up that list. Moving deferred events to a separate list allows processing the drm_vblank_signalled list without xorg_list_for_each_entry_safe. Bugzilla: https://bugs.freedesktop.org/108600 (Ported from amdgpu commit 51ba6dddee40c3688d4c7b12eabeab516ed153b7) --- src/radeon_drm_queue.c | 57 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index acfea3da..d8a8243c 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -56,6 +56,7 @@ static int radeon_drm_queue_refcnt; static struct xorg_list radeon_drm_queue; static struct xorg_list radeon_drm_flip_signalled; static struct xorg_list radeon_drm_vblank_signalled; +static struct xorg_list radeon_drm_vblank_deferred; static uintptr_t radeon_drm_queue_seq; @@ -111,6 +112,31 @@ radeon_drm_queue_handler(int fd, unsigned int frame, unsigned int sec, } } +/* + * Handle signalled vblank events. If we're waiting for a flip event, + * put events for that CRTC in the vblank_deferred list. + */ +static void +radeon_drm_handle_vblank_signalled(void) +{ + drmmode_crtc_private_ptr drmmode_crtc; + struct radeon_drm_queue_entry *e; + + while (!xorg_list_is_empty(&radeon_drm_vblank_signalled)) { + e = xorg_list_first_entry(&radeon_drm_vblank_signalled, + struct radeon_drm_queue_entry, list); + drmmode_crtc = e->crtc->driver_private; + + if (drmmode_crtc->wait_flip_nesting_level == 0) { + radeon_drm_queue_handle_one(e); + continue; + } + + xorg_list_del(&e->list); + xorg_list_append(&e->list, &radeon_drm_vblank_deferred); + } +} + /* * Handle deferred DRM vblank events * @@ -127,12 +153,18 @@ radeon_drm_queue_handle_deferred(xf86CrtcPtr crtc) --drmmode_crtc->wait_flip_nesting_level > 0) return; - xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) { - drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private; + /* Put previously deferred vblank events for this CRTC back in the + * signalled queue + */ + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_deferred, list) { + if (e->crtc != crtc) + continue; - if (drmmode_crtc->wait_flip_nesting_level == 0) - radeon_drm_queue_handle_one(e); + xorg_list_del(&e->list); + xorg_list_append(&e->list, &radeon_drm_vblank_signalled); } + + radeon_drm_handle_vblank_signalled(); } /* @@ -205,6 +237,13 @@ radeon_drm_abort_entry(uintptr_t seq) } } + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_deferred, list) { + if (e->seq == seq) { + radeon_drm_abort_one(e); + return; + } + } + xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_queue, list) { if (e->seq == seq) { radeon_drm_abort_one(e); @@ -235,7 +274,7 @@ radeon_drm_abort_id(uint64_t id) int radeon_drm_handle_event(int fd, drmEventContext *event_context) { - struct radeon_drm_queue_entry *e, *tmp; + struct radeon_drm_queue_entry *e; int r; r = drmHandleEvent(fd, event_context); @@ -246,12 +285,7 @@ radeon_drm_handle_event(int fd, drmEventContext *event_context) radeon_drm_queue_handle_one(e); } - xorg_list_for_each_entry_safe(e, tmp, &radeon_drm_vblank_signalled, list) { - drmmode_crtc_private_ptr drmmode_crtc = e->crtc->driver_private; - - if (drmmode_crtc->wait_flip_nesting_level == 0) - radeon_drm_queue_handle_one(e); - } + radeon_drm_handle_vblank_signalled(); return r; } @@ -298,6 +332,7 @@ radeon_drm_queue_init(ScrnInfoPtr scrn) xorg_list_init(&radeon_drm_queue); xorg_list_init(&radeon_drm_flip_signalled); xorg_list_init(&radeon_drm_vblank_signalled); + xorg_list_init(&radeon_drm_vblank_deferred); } /* -- cgit v1.2.3 From 21d65e5b78c8889e363aee8596cd0b0f942fee46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 21 Dec 2018 12:38:04 +0100 Subject: Perform scanout buffer update immediately if drmmode_wait_vblank fails Otherwise the damaged screen contents may never be displayed in that case. (Ported from amdgpu commit 500fadb16285146e91f62fce3a0ce1360ca684ba) --- src/radeon_kms.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index a7aade70..796dac5f 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -752,6 +752,7 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) { ScreenPtr screen = dirty->slave_dst->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); xf86CrtcPtr xf86_crtc = radeon_prime_dirty_to_crtc(dirty); drmmode_crtc_private_ptr drmmode_crtc; uintptr_t drm_queue_seq; @@ -774,19 +775,23 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "radeon_drm_queue_alloc failed for PRIME update\n"); + radeon_prime_scanout_update_handler(xf86_crtc, 0, 0, NULL); return; } + drmmode_crtc->scanout_update_pending = drm_queue_seq; + if (!drmmode_wait_vblank(xf86_crtc, DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT, 1, drm_queue_seq, NULL, NULL)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "drmmode_wait_vblank failed for PRIME update: %s\n", strerror(errno)); - radeon_drm_abort_entry(drm_queue_seq); - return; + drmmode_crtc->drmmode->event_context.vblank_handler(pRADEONEnt->fd, + 0, 0, 0, + (void*)drm_queue_seq); + drmmode_crtc->wait_flip_nesting_level++; + radeon_drm_queue_handle_deferred(xf86_crtc); } - - drmmode_crtc->scanout_update_pending = drm_queue_seq; } static void @@ -1022,8 +1027,9 @@ static void radeon_scanout_update(xf86CrtcPtr xf86_crtc) { drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; + ScrnInfoPtr scrn = xf86_crtc->scrn; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); uintptr_t drm_queue_seq; - ScrnInfoPtr scrn; DamagePtr pDamage; RegionPtr pRegion; BoxRec extents; @@ -1048,7 +1054,6 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) return; } - scrn = xf86_crtc->scrn; drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, RADEON_DRM_QUEUE_ID_DEFAULT, @@ -1059,19 +1064,23 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "radeon_drm_queue_alloc failed for scanout update\n"); + radeon_scanout_update_handler(xf86_crtc, 0, 0, drmmode_crtc); return; } + drmmode_crtc->scanout_update_pending = drm_queue_seq; + if (!drmmode_wait_vblank(xf86_crtc, DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT, 1, drm_queue_seq, NULL, NULL)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "drmmode_wait_vblank failed for scanout update: %s\n", strerror(errno)); - radeon_drm_abort_entry(drm_queue_seq); - return; + drmmode_crtc->drmmode->event_context.vblank_handler(pRADEONEnt->fd, + 0, 0, 0, + (void*)drm_queue_seq); + drmmode_crtc->wait_flip_nesting_level++; + radeon_drm_queue_handle_deferred(xf86_crtc); } - - drmmode_crtc->scanout_update_pending = drm_queue_seq; } static void -- cgit v1.2.3 From ce7db51020d32f17e442338bfd305220feb51630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 21 Dec 2018 12:47:18 +0100 Subject: Cancel pending scanout update in drmmode_crtc_scanout_update drmmode_crtc_scanout_update does the equivalent of a scanout update, so no need to do it again. This might also avoid issues if there's a pending scanout update at this point. (Ported from amdgpu commit 4e7a24ac5a64e402146953ec5850d13c05742116) --- src/drmmode_display.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 134b0f72..34c88c8e 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -781,11 +781,17 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, *fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); *x = *y = 0; - radeon_scanout_do_update(crtc, scanout_id, - screen->GetWindowPixmap(screen->root), - extents); - RegionEmpty(DamageRegion(drmmode_crtc->scanout_damage)); - radeon_finish(scrn, drmmode_crtc->scanout[scanout_id].bo); + if (radeon_scanout_do_update(crtc, scanout_id, + screen->GetWindowPixmap(screen->root), + extents)) { + RegionEmpty(DamageRegion(drmmode_crtc->scanout_damage)); + radeon_glamor_finish(scrn); + + if (!drmmode_crtc->flip_pending) { + radeon_drm_abort_entry(drmmode_crtc-> + scanout_update_pending); + } + } } } -- cgit v1.2.3 From f66254c171f5a3b052a2a9e0339f17dfb5a60dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 21 Dec 2018 12:49:27 +0100 Subject: Automatically try re-enabling TearFree after a flip failed Specifically, after both the page flip and vblank ioctls failed, but then the vblank ioctl started working again. This can happen intermittently e.g. when hotplugging a DP display. Previously, TearFree would stay disabled in that case until a modeset was triggered somehow. Bugzilla: https://bugs.freedesktop.org/103791 (Ported from amdgpu commit bcfa6c258fdf41a9928f8a3c78fc528d0fafee25) --- src/drmmode_display.h | 7 +++++ src/radeon_kms.c | 75 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/src/drmmode_display.h b/src/drmmode_display.h index bfc13010..f5659664 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -71,6 +71,12 @@ struct drmmode_fb { uint32_t handle; }; +enum drmmode_scanout_status { + DRMMODE_SCANOUT_OK, + DRMMODE_SCANOUT_FLIP_FAILED = 1u << 0, + DRMMODE_SCANOUT_VBLANK_FAILED = 1u << 1, +}; + struct drmmode_scanout { struct radeon_buffer *bo; PixmapPtr pixmap; @@ -90,6 +96,7 @@ typedef struct { unsigned scanout_id; uintptr_t scanout_update_pending; Bool tear_free; + enum drmmode_scanout_status scanout_status; PixmapPtr prime_scanout_pixmap; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 796dac5f..dd9955da 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -783,15 +783,32 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) if (!drmmode_wait_vblank(xf86_crtc, DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT, 1, drm_queue_seq, NULL, NULL)) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "drmmode_wait_vblank failed for PRIME update: %s\n", - strerror(errno)); + if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_VBLANK_FAILED)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "drmmode_wait_vblank failed for PRIME update: %s\n", + strerror(errno)); + drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_VBLANK_FAILED; + } + drmmode_crtc->drmmode->event_context.vblank_handler(pRADEONEnt->fd, 0, 0, 0, (void*)drm_queue_seq); drmmode_crtc->wait_flip_nesting_level++; radeon_drm_queue_handle_deferred(xf86_crtc); + return; + } + + if (drmmode_crtc->scanout_status == + (DRMMODE_SCANOUT_FLIP_FAILED | DRMMODE_SCANOUT_VBLANK_FAILED)) { + /* The page flip and vblank ioctls failed before, but the vblank + * ioctl is working again, so we can try re-enabling TearFree + */ + xf86_crtc->funcs->set_mode_major(xf86_crtc, &xf86_crtc->mode, + xf86_crtc->rotation, + xf86_crtc->x, xf86_crtc->y); } + + drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_VBLANK_FAILED; } static void @@ -842,12 +859,22 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, drmmode_crtc->flip_pending->handle, 0, drm_queue_seq, 0) != 0) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", - __func__, strerror(errno)); + if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "flip queue failed in %s: %s, TearFree inactive\n", + __func__, strerror(errno)); + drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_FLIP_FAILED; + } + radeon_drm_abort_entry(drm_queue_seq); return; } + if (drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED) { + xf86DrvMsg(scrn->scrnIndex, X_INFO, "TearFree active again\n"); + drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_FLIP_FAILED; + } + drmmode_crtc->scanout_id = scanout_id; drmmode_crtc->scanout_update_pending = drm_queue_seq; } @@ -1072,15 +1099,32 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) if (!drmmode_wait_vblank(xf86_crtc, DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT, 1, drm_queue_seq, NULL, NULL)) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "drmmode_wait_vblank failed for scanout update: %s\n", - strerror(errno)); + if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_VBLANK_FAILED)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "drmmode_wait_vblank failed for scanout update: %s\n", + strerror(errno)); + drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_VBLANK_FAILED; + } + drmmode_crtc->drmmode->event_context.vblank_handler(pRADEONEnt->fd, 0, 0, 0, (void*)drm_queue_seq); drmmode_crtc->wait_flip_nesting_level++; radeon_drm_queue_handle_deferred(xf86_crtc); + return; + } + + if (drmmode_crtc->scanout_status == + (DRMMODE_SCANOUT_FLIP_FAILED | DRMMODE_SCANOUT_VBLANK_FAILED)) { + /* The page flip and vblank ioctls failed before, but the vblank + * ioctl is working again, so we can try re-enabling TearFree + */ + xf86_crtc->funcs->set_mode_major(xf86_crtc, &xf86_crtc->mode, + xf86_crtc->rotation, + xf86_crtc->x, xf86_crtc->y); } + + drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_VBLANK_FAILED; } static void @@ -1132,9 +1176,13 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, drmmode_crtc->flip_pending->handle, 0, drm_queue_seq, 0) != 0) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s, " - "TearFree inactive until next modeset\n", - __func__, strerror(errno)); + if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "flip queue failed in %s: %s, TearFree inactive\n", + __func__, strerror(errno)); + drmmode_crtc->scanout_status |= DRMMODE_SCANOUT_FLIP_FAILED; + } + radeon_drm_abort_entry(drm_queue_seq); RegionCopy(DamageRegion(drmmode_crtc->scanout_damage), &drmmode_crtc->scanout_last_region); @@ -1146,6 +1194,11 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, return; } + if (drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED) { + xf86DrvMsg(scrn->scrnIndex, X_INFO, "TearFree active again\n"); + drmmode_crtc->scanout_status &= ~DRMMODE_SCANOUT_FLIP_FAILED; + } + drmmode_crtc->scanout_id = scanout_id; drmmode_crtc->scanout_update_pending = drm_queue_seq; } -- cgit v1.2.3 From e14c3d2f86c7be2b5c3d06a47bf0abe954207d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 21 Dec 2018 17:38:51 +0100 Subject: Drop RADEONInfoRec::cursor_bo array Not needed or even useful for anything. (Ported from amdgpu commit e95044e45350870fa7e237860e89ade91ac03550) --- src/drmmode_display.c | 9 --------- src/drmmode_display.h | 1 - src/radeon.h | 1 - src/radeon_kms.c | 21 +++++++++++---------- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 34c88c8e..ef235bd2 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2967,15 +2967,6 @@ miPointerSpriteFuncRec drmmode_sprite_funcs = { }; -void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - xf86CrtcPtr crtc = xf86_config->crtc[id]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - - drmmode_crtc->cursor_bo = bo; -} - void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); diff --git a/src/drmmode_display.h b/src/drmmode_display.h index f5659664..d7ab9d7e 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -213,7 +213,6 @@ extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp); extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr); -extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo); void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y); extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw); diff --git a/src/radeon.h b/src/radeon.h index cde922c6..74454c30 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -572,7 +572,6 @@ typedef struct { struct radeon_cs_manager *csm; struct radeon_cs *cs; - struct radeon_bo *cursor_bo[32]; uint64_t vram_size; uint64_t gart_size; drmmode_rec drmmode; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index dd9955da..27a02109 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2760,21 +2760,20 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) cursor_size = info->cursor_w * info->cursor_h * 4; cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE); for (c = 0; c < xf86_config->num_crtc; c++) { - /* cursor objects */ - if (!info->cursor_bo[c]) { - info->cursor_bo[c] = radeon_bo_open(info->bufmgr, 0, - cursor_size, 0, - RADEON_GEM_DOMAIN_VRAM, 0); - if (!info->cursor_bo[c]) { + drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private; + + if (!drmmode_crtc->cursor_bo) { + drmmode_crtc->cursor_bo = radeon_bo_open(info->bufmgr, 0, + cursor_size, 0, + RADEON_GEM_DOMAIN_VRAM, 0); + if (!(drmmode_crtc->cursor_bo)) { ErrorF("Failed to allocate cursor buffer memory\n"); return FALSE; } - if (radeon_bo_map(info->cursor_bo[c], 1)) { + if (radeon_bo_map(drmmode_crtc->cursor_bo, 1)) { ErrorF("Failed to map cursor buffer memory\n"); } - - drmmode_set_cursor(pScrn, &info->drmmode, c, info->cursor_bo[c]); } } } @@ -2840,7 +2839,9 @@ void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size) int c; for (c = 0; c < xf86_config->num_crtc; c++) { - if (info->cursor_bo[c]) + drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private; + + if (drmmode_crtc->cursor_bo) new_fb_size += (64 * 4 * 64); } -- cgit v1.2.3 From 92df709786830d4e30a106dd49d8e0355c50c8f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 21 Dec 2018 17:54:36 +0100 Subject: Use drmIoctl in drmmode_show_cursor This should be functionally equivalent to what drmModeSetCursor(2) do behind the scenes, but allows for new tricks in following changes. (Ported from amdgpu commit b344e1559e936046ef02c777fc4f6bcefa3830bc) --- src/drmmode_display.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index ef235bd2..c2a59da7 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1202,8 +1202,16 @@ drmmode_show_cursor (xf86CrtcPtr crtc) RADEONInfoPtr info = RADEONPTR(pScrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - uint32_t handle = drmmode_crtc->cursor_bo->handle; static Bool use_set_cursor2 = TRUE; + struct drm_mode_cursor2 arg; + + memset(&arg, 0, sizeof(arg)); + + arg.handle = drmmode_crtc->cursor_bo->handle; + arg.flags = DRM_MODE_CURSOR_BO; + arg.crtc_id = drmmode_crtc->mode_crtc->crtc_id; + arg.width = info->cursor_w; + arg.height = info->cursor_h; if (use_set_cursor2) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); @@ -1240,18 +1248,17 @@ drmmode_show_cursor (xf86CrtcPtr crtc) } } - ret = - drmModeSetCursor2(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, - handle, info->cursor_w, info->cursor_h, - xhot, yhot); + arg.hot_x = xhot; + arg.hot_y = yhot; + + ret = drmIoctl(pRADEONEnt->fd, DRM_IOCTL_MODE_CURSOR2, &arg); if (ret == -EINVAL) use_set_cursor2 = FALSE; else return; } - drmModeSetCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, handle, - info->cursor_w, info->cursor_h); + drmIoctl(pRADEONEnt->fd, DRM_IOCTL_MODE_CURSOR, &arg); } /* Xorg expects a non-NULL return value from drmmode_crtc_shadow_allocate, and -- cgit v1.2.3 From 91e557f78ad261e76a1829f54722c2c0781742d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 21 Dec 2018 18:00:09 +0100 Subject: Update cursor position in drmmode_show_cursor if hotspot changed The cursor position is updated to be consistent with the new hotspot in the same ioctl call. (Ported from amdgpu commit b04697de5270e8e45744a7025c24df1f454a4cf0) --- src/drmmode_display.c | 75 +++++++++++++++++++++++++++++---------------------- src/drmmode_display.h | 5 ++++ 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index c2a59da7..bec309e5 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1017,6 +1017,9 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) } #endif + drmmode_crtc->cursor_x = x; + drmmode_crtc->cursor_y = y; + drmModeMoveCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); } @@ -1202,6 +1205,10 @@ drmmode_show_cursor (xf86CrtcPtr crtc) RADEONInfoPtr info = RADEONPTR(pScrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + CursorPtr cursor = xf86_config->cursor; + int xhot = cursor->bits->xhot; + int yhot = cursor->bits->yhot; static Bool use_set_cursor2 = TRUE; struct drm_mode_cursor2 arg; @@ -1213,41 +1220,45 @@ drmmode_show_cursor (xf86CrtcPtr crtc) arg.width = info->cursor_w; arg.height = info->cursor_h; + if (crtc->rotation != RR_Rotate_0 && + crtc->rotation != (RR_Rotate_180 | RR_Reflect_X | + RR_Reflect_Y)) { + int t; + + /* Reflect & rotate hotspot position */ + if (crtc->rotation & RR_Reflect_X) + xhot = info->cursor_w - xhot - 1; + if (crtc->rotation & RR_Reflect_Y) + yhot = info->cursor_h - yhot - 1; + + switch (crtc->rotation & 0xf) { + case RR_Rotate_90: + t = xhot; + xhot = yhot; + yhot = info->cursor_w - t - 1; + break; + case RR_Rotate_180: + xhot = info->cursor_w - xhot - 1; + yhot = info->cursor_h - yhot - 1; + break; + case RR_Rotate_270: + t = xhot; + xhot = info->cursor_h - yhot - 1; + yhot = t; + } + } + + if (xhot != drmmode_crtc->cursor_xhot || yhot != drmmode_crtc->cursor_yhot) { + arg.flags |= DRM_MODE_CURSOR_MOVE; + arg.x = drmmode_crtc->cursor_x += drmmode_crtc->cursor_xhot - xhot; + arg.y = drmmode_crtc->cursor_y += drmmode_crtc->cursor_yhot - yhot; + drmmode_crtc->cursor_xhot = xhot; + drmmode_crtc->cursor_yhot = yhot; + } + if (use_set_cursor2) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); - CursorPtr cursor = xf86_config->cursor; - int xhot = cursor->bits->xhot; - int yhot = cursor->bits->yhot; int ret; - if (crtc->rotation != RR_Rotate_0 && - crtc->rotation != (RR_Rotate_180 | RR_Reflect_X | - RR_Reflect_Y)) { - int t; - - /* Reflect & rotate hotspot position */ - if (crtc->rotation & RR_Reflect_X) - xhot = info->cursor_w - xhot - 1; - if (crtc->rotation & RR_Reflect_Y) - yhot = info->cursor_h - yhot - 1; - - switch (crtc->rotation & 0xf) { - case RR_Rotate_90: - t = xhot; - xhot = yhot; - yhot = info->cursor_w - t - 1; - break; - case RR_Rotate_180: - xhot = info->cursor_w - xhot - 1; - yhot = info->cursor_h - yhot - 1; - break; - case RR_Rotate_270: - t = xhot; - xhot = info->cursor_h - yhot - 1; - yhot = t; - } - } - arg.hot_x = xhot; arg.hot_y = yhot; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index d7ab9d7e..49893ab0 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -87,6 +87,11 @@ typedef struct { drmmode_ptr drmmode; drmModeCrtcPtr mode_crtc; int hw_id; + + int cursor_x; + int cursor_y; + int cursor_xhot; + int cursor_yhot; struct radeon_bo *cursor_bo; struct drmmode_scanout rotate; struct drmmode_scanout scanout[2]; -- cgit v1.2.3 From 803f872f7d4b2d80be434bb42ce64dfd295b122c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 21 Dec 2018 18:04:21 +0100 Subject: Use two HW cursor buffers per CRTC Switch to the other buffer when xf86_config->cursor changes. Avoids these issues possible when re-using the same buffer: * The HW may intermittently display a mix of the old and new cursor images. * If the hotspot changes, the HW may intermittently display the new cursor image at the location corresponding to the old image's hotspot. Bugzilla: https://bugs.freedesktop.org/108832 (Ported from amdgpu commit 0d60233d26ec70d4e1faa343b438e33829c6d5e4) --- src/drmmode_display.c | 18 +++++++++++++++--- src/drmmode_display.h | 5 ++++- src/radeon_kms.c | 34 ++++++++++++++++++---------------- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index bec309e5..d433e061 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1122,13 +1122,18 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) ScrnInfoPtr pScrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + unsigned id = drmmode_crtc->cursor_id; Bool premultiplied = TRUE; Bool apply_gamma = TRUE; uint32_t argb; uint32_t *ptr; + if (drmmode_crtc->cursor && + XF86_CRTC_CONFIG_PTR(pScrn)->cursor != drmmode_crtc->cursor) + id ^= 1; + /* cursor should be mapped already */ - ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr); + ptr = (uint32_t *)(drmmode_crtc->cursor_bo[id]->ptr); if (crtc->scrn->depth != 24 && crtc->scrn->depth != 32) apply_gamma = FALSE; @@ -1170,6 +1175,11 @@ retry: ptr[i] = cpu_to_le32(argb); } } + + if (id != drmmode_crtc->cursor_id) { + drmmode_crtc->cursor_id = id; + crtc->funcs->show_cursor(crtc); + } } #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,903,0) @@ -1195,7 +1205,7 @@ drmmode_hide_cursor (xf86CrtcPtr crtc) drmModeSetCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, 0, info->cursor_w, info->cursor_h); - + drmmode_crtc->cursor = NULL; } static void @@ -1212,9 +1222,11 @@ drmmode_show_cursor (xf86CrtcPtr crtc) static Bool use_set_cursor2 = TRUE; struct drm_mode_cursor2 arg; + drmmode_crtc->cursor = xf86_config->cursor; + memset(&arg, 0, sizeof(arg)); - arg.handle = drmmode_crtc->cursor_bo->handle; + arg.handle = drmmode_crtc->cursor_bo[drmmode_crtc->cursor_id]->handle; arg.flags = DRM_MODE_CURSOR_BO; arg.crtc_id = drmmode_crtc->mode_crtc->crtc_id; arg.width = info->cursor_w; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 49893ab0..2c2c3d57 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -88,11 +88,14 @@ typedef struct { drmModeCrtcPtr mode_crtc; int hw_id; + CursorPtr cursor; int cursor_x; int cursor_y; int cursor_xhot; int cursor_yhot; - struct radeon_bo *cursor_bo; + unsigned cursor_id; + struct radeon_bo *cursor_bo[2]; + struct drmmode_scanout rotate; struct drmmode_scanout scanout[2]; DamagePtr scanout_damage; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 27a02109..bb6885fb 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2755,27 +2755,29 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen) { int cursor_size; - int c; + int c, i; cursor_size = info->cursor_w * info->cursor_h * 4; cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE); for (c = 0; c < xf86_config->num_crtc; c++) { drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private; - if (!drmmode_crtc->cursor_bo) { - drmmode_crtc->cursor_bo = radeon_bo_open(info->bufmgr, 0, - cursor_size, 0, - RADEON_GEM_DOMAIN_VRAM, 0); - if (!(drmmode_crtc->cursor_bo)) { - ErrorF("Failed to allocate cursor buffer memory\n"); - return FALSE; - } - - if (radeon_bo_map(drmmode_crtc->cursor_bo, 1)) { - ErrorF("Failed to map cursor buffer memory\n"); - } - } - } + for (i = 0; i < 2; i++) { + if (!drmmode_crtc->cursor_bo[i]) { + drmmode_crtc->cursor_bo[i] = + radeon_bo_open(info->bufmgr, 0, cursor_size, 0, + RADEON_GEM_DOMAIN_VRAM, 0); + + if (!(drmmode_crtc->cursor_bo[i])) { + ErrorF("Failed to allocate cursor buffer memory\n"); + return FALSE; + } + + if (radeon_bo_map(drmmode_crtc->cursor_bo[i], 1)) + ErrorF("Failed to map cursor buffer memory\n"); + } + } + } } if (!info->front_buffer) { @@ -2841,7 +2843,7 @@ void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size) for (c = 0; c < xf86_config->num_crtc; c++) { drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private; - if (drmmode_crtc->cursor_bo) + if (drmmode_crtc->cursor_bo[0]) new_fb_size += (64 * 4 * 64); } -- cgit v1.2.3 From 38db1bbcfc019c92884c7819a6630c70e543f6b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 9 Jan 2019 11:33:18 +0100 Subject: Only call drmmode_uevent_init if RandR is enabled There's no point in listening for hotplug events if RandR is disabled, as there's no other mechanism for them to be propagated. We were already mostly ignoring them in that case. Inspired by https://gitlab.freedesktop.org/xorg/driver/xf86-video-intel/commit/1a489142c8e6a4828348cc9afbd0f430d3b1e2d8 (via https://bugs.freedesktop.org/109230#c11). Reviewed-by: Alex Deucher --- src/drmmode_display.c | 2 +- src/radeon_kms.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index d433e061..e04a17d5 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -3273,7 +3273,7 @@ restart_destroy: /* Check to see if a lessee has disappeared */ drmmode_validate_leases(scrn); - if (changed && dixPrivateKeyRegistered(rrPrivKey)) { + if (changed) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0) RRSetChanged(xf86ScrnToScreen(scrn)); #else diff --git a/src/radeon_kms.c b/src/radeon_kms.c index bb6885fb..67f42e0f 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -349,13 +349,13 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen) RROutputChanged(rrScrPriv->primaryOutput, FALSE); rrScrPriv->layoutChanged = TRUE; } + + drmmode_uevent_init(pScrn, &info->drmmode); } if (!drmmode_set_desired_modes(pScrn, &info->drmmode, pScreen->isGPU)) return FALSE; - drmmode_uevent_init(pScrn, &info->drmmode); - if (info->r600_shadow_fb) { pixmap = pScreen->GetScreenPixmap(pScreen); -- cgit v1.2.3 From b1c01698f577577e4a88bad0ae08fb5d998e7ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 9 Jan 2019 11:26:14 +0100 Subject: Only call drmmode_validate_leases if RandR is enabled It would crash if RandR is disabled, e.g. because Xinerama is enabled. Bugzilla: https://bugs.freedesktop.org/109230 Reviewed-by: Alex Deucher --- src/drmmode_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index e04a17d5..71f3539f 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -3100,7 +3100,8 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, } /* Validate leases on VT re-entry */ - drmmode_validate_leases(pScrn); + if (dixPrivateKeyRegistered(rrPrivKey)) + drmmode_validate_leases(pScrn); return TRUE; } -- cgit v1.2.3 From 77d7abf46446522e686c6b6f1e4857458589ef37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 Jan 2019 18:00:20 +0100 Subject: dri3: Flush if necessary in dri3_fd_from_pixmap To make sure the client can't use the shared pixmap storage for direct rendering first, which could produce garbage. Bugzilla: https://bugs.freedesktop.org/109235 (Ported from amdgpu commit d168532ee739f7e33a2798051e64ba445dd3859f) --- src/radeon_dri3.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c index 25078bae..73353bf5 100644 --- a/src/radeon_dri3.c +++ b/src/radeon_dri3.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -218,8 +219,34 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen, ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONInfoPtr info = RADEONPTR(scrn); - if (info->use_glamor) - return glamor_fd_from_pixmap(screen, pixmap, stride, size); + if (info->use_glamor) { + Bool need_flush = TRUE; + int ret = -1; +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,19,99,904,0) + struct gbm_bo *gbm_bo = glamor_gbm_bo_from_pixmap(screen, pixmap); + + if (gbm_bo) { + ret = gbm_bo_get_fd(gbm_bo); + gbm_bo_destroy(gbm_bo); + + if (ret >= 0) + need_flush = FALSE; + } +#endif + + if (ret < 0) + ret = glamor_fd_from_pixmap(screen, pixmap, stride, size); + + /* glamor might have needed to reallocate the pixmap storage and + * copy the pixmap contents to the new storage. The copy + * operation needs to be flushed to the kernel driver before the + * client starts using the pixmap storage for direct rendering. + */ + if (ret >= 0 && need_flush) + radeon_cs_flush_indirect(scrn); + + return ret; + } #endif bo = radeon_get_pixmap_bo(pixmap); -- cgit v1.2.3 From 6d1dfe2523e900517bd1e8743c87d6990a82c800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 Jan 2019 18:04:41 +0100 Subject: dri2: Flush in dri2_create_buffer2 after calling glamor_set_pixmap_bo To make sure the client can't use the shared pixmap storage for direct rendering first, which could produce garbage. Bugzilla: https://bugs.freedesktop.org/109235 (Ported from amdgpu commit ebd32b1c07208f8dbe853e089f5e4b7c6a7a658a) --- src/radeon_dri2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 922ed4fb..b5d6835c 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -252,6 +252,12 @@ radeon_dri2_create_buffer2(ScreenPtr pScreen, } else if (is_glamor_pixmap) { pixmap = radeon_glamor_set_pixmap_bo(drawable, pixmap); pixmap->refcnt++; + + /* The copy operation from radeon_glamor_set_pixmap_bo needs to + * be flushed to the kernel driver before the client starts + * using the pixmap storage for direct rendering. + */ + radeon_cs_flush_indirect(pScrn); } if (!radeon_get_flink_name(pRADEONEnt, pixmap, &buffers->name)) -- cgit v1.2.3 From 274703087f80342f51fa69c935bb9a1cb0c4ae47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 Jan 2019 18:06:50 +0100 Subject: glamor: Avoid glamor_create_pixmap for pixmaps backing windows If the compositing manager uses direct rendering (as is usually the case these days), the storage of a pixmap allocated by glamor_create_pixmap needs to be reallocated for sharing it with the compositing manager. Instead, allocate pixmap storage which can be shared directly. (Ported from amdgpu commit bf326f2ea19daa6c8da23d6788ff301ae70b8e69) --- src/radeon_glamor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index f1098381..3e676f2d 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -238,7 +238,7 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, if (info->shadow_primary) { if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) return fbCreatePixmap(screen, w, h, depth, usage); - } else { + } else if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) { pixmap = glamor_create_pixmap(screen, w, h, depth, usage); if (pixmap) return pixmap; -- cgit v1.2.3 From dcd3527299c1f6d6faa401c565fa884f4d8f3287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 Jan 2019 18:08:35 +0100 Subject: Don't allow TearFree scanout flips to complete in the same vblank period We were using a relative target of 0, meaning "complete the flip ASAP". This could result in the flip sometimes, but not always completing in the same vertical blank period where the corresponding drawing occurred, potentially causing judder artifacts with applications updating their window contents synchronized to the display refresh. A good way to test this is the vsynctester.com site in a windowed browser, where the judder results in the large "VSYNC" text intermittently appearing red or cyan instead of the expected gray. To avoid this, use a relative target MSC of 1, meaning that if a vertical blank period is in progress, the flip will only complete in the next one. Reported by Julian Tempel and Brandon Wright in https://bugs.freedesktop.org/106175 . (Ported from amdgpu commit a1b479c7d0066c481af920f297d6af9009dda11e) --- src/radeon_kms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 67f42e0f..8b965622 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -858,7 +858,7 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, drmmode_crtc->flip_pending->handle, - 0, drm_queue_seq, 0) != 0) { + 0, drm_queue_seq, 1) != 0) { if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s, TearFree inactive\n", @@ -1175,7 +1175,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, drmmode_crtc->flip_pending->handle, - 0, drm_queue_seq, 0) != 0) { + 0, drm_queue_seq, 1) != 0) { if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s, TearFree inactive\n", -- cgit v1.2.3 From 1bfdccf7639ee2f655dc659cafa63830ba28be85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 Jan 2019 18:11:10 +0100 Subject: Only update drmmode_crtc->flip_pending after actually submitting a flip And only clear it if it matches the framebuffer of the completed flip being processed. Fixes (WW) RADEON(0): flip queue failed: Device or resource busy (WW) RADEON(0): Page flip failed: Device or resource busy (EE) RADEON(0): present flip failed due to clobbering drmmode_crtc->flip_pending. Reproducer: Enable TearFree, run warzone2100 fullscreen, toggle Vertical sync on/off under Video Options. Discovered while investigating https://bugs.freedesktop.org/109364 . (Ported from amdgpu commit e72a02ba1d35743fefd939458b9d8cddce86e7f5) --- src/drmmode_display.c | 15 +++++++----- src/radeon_kms.c | 66 ++++++++++++++++++++++++++------------------------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 71f3539f..c5fccd2a 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2651,12 +2651,14 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *even flipdata->fe_usec = usec; } - if (drmmode_crtc->flip_pending == *fb) { - drmmode_fb_reference(pRADEONEnt->fd, - &drmmode_crtc->flip_pending, NULL); + if (*fb) { + if (drmmode_crtc->flip_pending == *fb) { + drmmode_fb_reference(pRADEONEnt->fd, + &drmmode_crtc->flip_pending, NULL); + } + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, *fb); + drmmode_fb_reference(pRADEONEnt->fd, fb, NULL); } - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, *fb); - drmmode_fb_reference(pRADEONEnt->fd, fb, NULL); if (--flipdata->flip_count == 0) { /* Deliver MSC & UST from reference/current CRTC to flip event @@ -3492,9 +3494,10 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, drmmode_crtc->ignore_damage = TRUE; } - next: drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, flipdata->fb[crtc_id]); + + next: drm_queue_seq = 0; } diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 8b965622..ff4f8dcf 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -526,10 +526,14 @@ radeon_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data) { RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + struct drmmode_fb *fb = event_data; drmmode_crtc->scanout_update_pending = 0; - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, - NULL); + + if (drmmode_crtc->flip_pending == fb) { + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, + NULL); + } } static void @@ -538,9 +542,9 @@ radeon_scanout_flip_handler(xf86CrtcPtr crtc, uint32_t msc, uint64_t usec, { RADEONEntPtr pRADEONEnt = RADEONEntPriv(crtc->scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + struct drmmode_fb *fb = event_data; - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, - drmmode_crtc->flip_pending); + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->fb, fb); radeon_scanout_flip_abort(crtc, event_data); } @@ -821,24 +825,31 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) drmmode_crtc_private_ptr drmmode_crtc; uintptr_t drm_queue_seq; unsigned scanout_id; + struct drmmode_fb *fb; if (!crtc || !crtc->enabled) return; drmmode_crtc = crtc->driver_private; + scanout_id = drmmode_crtc->scanout_id ^ 1; if (drmmode_crtc->scanout_update_pending || - !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap || + !drmmode_crtc->scanout[scanout_id].pixmap || drmmode_crtc->dpms_mode != DPMSModeOn) return; - scanout_id = drmmode_crtc->scanout_id ^ 1; if (!radeon_prime_scanout_do_update(crtc, scanout_id)) return; + fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); + if (!fb) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "Failed to get FB for PRIME flip.\n"); + return; + } + drm_queue_seq = radeon_drm_queue_alloc(crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, - RADEON_DRM_QUEUE_ID_DEFAULT, - NULL, + RADEON_DRM_QUEUE_ID_DEFAULT, fb, radeon_scanout_flip_handler, radeon_scanout_flip_abort, TRUE); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { @@ -847,18 +858,9 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) return; } - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, - radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap)); - if (!drmmode_crtc->flip_pending) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "Failed to get FB for PRIME flip.\n"); - radeon_drm_abort_entry(drm_queue_seq); - return; - } - if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, - drmmode_crtc->flip_pending->handle, - 0, drm_queue_seq, 1) != 0) { + fb->handle, 0, drm_queue_seq, 1) + != 0) { if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s, TearFree inactive\n", @@ -877,6 +879,7 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) drmmode_crtc->scanout_id = scanout_id; drmmode_crtc->scanout_update_pending = drm_queue_seq; + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, fb); } static void @@ -1137,6 +1140,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); uintptr_t drm_queue_seq; unsigned scanout_id; + struct drmmode_fb *fb; if (drmmode_crtc->scanout_update_pending || drmmode_crtc->flip_pending || @@ -1152,10 +1156,16 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, radeon_cs_flush_indirect(scrn); RegionEmpty(region); + fb = radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap); + if (!fb) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "Failed to get FB for scanout flip.\n"); + return; + } + drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc, RADEON_DRM_QUEUE_CLIENT_DEFAULT, - RADEON_DRM_QUEUE_ID_DEFAULT, - NULL, + RADEON_DRM_QUEUE_ID_DEFAULT, fb, radeon_scanout_flip_handler, radeon_scanout_flip_abort, TRUE); if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { @@ -1164,18 +1174,9 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, return; } - drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, - radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap)); - if (!drmmode_crtc->flip_pending) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "Failed to get FB for scanout flip.\n"); - radeon_drm_abort_entry(drm_queue_seq); - return; - } - if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, - drmmode_crtc->flip_pending->handle, - 0, drm_queue_seq, 1) != 0) { + fb->handle, 0, drm_queue_seq, 1) + != 0) { if (!(drmmode_crtc->scanout_status & DRMMODE_SCANOUT_FLIP_FAILED)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s, TearFree inactive\n", @@ -1201,6 +1202,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, drmmode_crtc->scanout_id = scanout_id; drmmode_crtc->scanout_update_pending = drm_queue_seq; + drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending, fb); } static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) -- cgit v1.2.3 From 227123de3d862e691131708b7f55260bee17f2b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 Jan 2019 18:24:41 +0100 Subject: Call drmHandleEvent again if it was interrupted by a signal drmHandleEvent can be interrupted by a signal in read(), in which case it doesn't process any events but returns -1, which drm_handle_event propagated to its callers. This could cause the following failure cascade: 1. drm_wait_pending_flip stopped waiting for a pending flip. 2. Its caller cleared drmmode_crtc->flip_pending before the flip completed. 3. Another flip was attempted but got an unexpected EBUSY error because the previous flip was still pending. 4. TearFree was disabled due to the error. The solution is to call drmHandleEvent if it was interrupted by a signal. We can do that in drm_handle_event, because when that is called, either it is known that there are events ready to be processed, or the caller has to wait for events to arrive anyway. Bugzilla: https://bugs.freedesktop.org/109364 (Ported from amdgpu commit 3ff2cc225f6bc08364ee007fa54e9d0150adaf11) --- src/radeon_drm_queue.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index d8a8243c..2e2b8404 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -30,6 +30,8 @@ #include "config.h" #endif +#include + #include #include #include @@ -277,7 +279,20 @@ radeon_drm_handle_event(int fd, drmEventContext *event_context) struct radeon_drm_queue_entry *e; int r; - r = drmHandleEvent(fd, event_context); + /* Retry drmHandleEvent if it was interrupted by a signal in read() */ + do { + r = drmHandleEvent(fd, event_context); + } while (r < 0 && (errno == EINTR || errno == EAGAIN)); + + if (r < 0) { + static Bool printed; + + if (!printed) { + ErrorF("%s: drmHandleEvent returned %d, errno=%d (%s)\n", + __func__, r, errno, strerror(errno)); + printed = TRUE; + } + } while (!xorg_list_is_empty(&radeon_drm_flip_signalled)) { e = xorg_list_first_entry(&radeon_drm_flip_signalled, -- cgit v1.2.3 From 15697ee242c30b9ea6775624e8282e0171a113a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 Jan 2019 18:27:10 +0100 Subject: Keep waiting for a pending flip if drm_handle_event returns 0 drm_wait_pending_flip stopped waiting if drm_handle_event returned 0, but that might have processed only some unrelated DRM events. As long as the flip is pending, we have to keep waiting for its completion event. Noticed while working on the previous fix. (Ported from amdgpu commit 9045fb310f88780e250e60b80431ca153330e61b) --- src/radeon_drm_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/radeon_drm_queue.c b/src/radeon_drm_queue.c index 2e2b8404..fc043605 100644 --- a/src/radeon_drm_queue.c +++ b/src/radeon_drm_queue.c @@ -325,7 +325,7 @@ void radeon_drm_wait_pending_flip(xf86CrtcPtr crtc) while (drmmode_crtc->flip_pending && radeon_drm_handle_event(pRADEONEnt->fd, - &drmmode_crtc->drmmode->event_context) > 0); + &drmmode_crtc->drmmode->event_context) >= 0); } /* -- cgit v1.2.3 From 705020b6247eaa062edc9c88e6ad52f8c5468051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 1 Mar 2019 18:23:30 +0100 Subject: present: Check that flip and screen pixmap pitches match If they don't, flipping will result in corrupted display. Test case: * Run Xorg at 1920x1080 with no window manager * glxgears -geometry 2048x1080 The Present extension code in xserver 1.21 will check for this. (Ported from amdgpu commit a636f42b496b0604ca00a144690ece61d1a88a27) Reviewed-by: Alex Deucher --- src/radeon_present.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/radeon_present.c b/src/radeon_present.c index 0b55117e..38a9a6b7 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -256,7 +256,7 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, ScrnInfoPtr scrn = xf86_crtc->scrn; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); RADEONInfoPtr info = RADEONPTR(scrn); - PixmapPtr screen_pixmap; + PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); int num_crtcs_on; int i; @@ -272,10 +272,14 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, if (info->drmmode.dri2_flipping) return FALSE; +#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1, 20, 99, 1, 0) + if (pixmap->devKind != screen_pixmap->devKind) + return FALSE; +#endif + /* The kernel driver doesn't handle flipping between BOs with different * tiling parameters correctly yet */ - screen_pixmap = screen->GetScreenPixmap(screen); if (radeon_present_get_pixmap_tiling_flags(info, pixmap) != radeon_present_get_pixmap_tiling_flags(info, screen_pixmap)) return FALSE; -- cgit v1.2.3 From c301b8af25d2c2cd49035a4395ebe6c3612df366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 1 Mar 2019 18:28:11 +0100 Subject: dri2: Call drm_queue_handle_deferred in dri2_deferred_event drm_queue_handler just puts the event on the signalled list; without calling drm_queue_handle_deferred, actual processing of the event may be delayed indefinitely, e.g. until another event arrives from the kernel. This could result in DRI2 clients hanging during DPMS off. Fixes: ba83a866af5a "Add radeon_drm_handle_event wrapper for drmHandleEvent" (Ported from amdgpu commit 09be74a3d1dd9604336d9a27f98d132b262dcbaf) Reviewed-by: Alex Deucher --- src/radeon_dri2.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index b5d6835c..a9f14e8d 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -979,12 +979,18 @@ 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_seq) + + if (event_info->drm_queue_seq) { drmmode_crtc->drmmode->event_context. vblank_handler(pRADEONEnt->fd, 0, 0, 0, (void*)event_info->drm_queue_seq); - else + drmmode_crtc->wait_flip_nesting_level++; + radeon_drm_queue_handle_deferred(crtc); + + } else { radeon_dri2_frame_event_handler(crtc, 0, 0, data); + } + return 0; } /* @@ -995,13 +1001,18 @@ 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_seq) + + if (event_info->drm_queue_seq) { drmmode_crtc->drmmode->event_context. vblank_handler(pRADEONEnt->fd, frame, drm_now / 1000000, drm_now % 1000000, (void*)event_info->drm_queue_seq); - else + drmmode_crtc->wait_flip_nesting_level++; + radeon_drm_queue_handle_deferred(crtc); + } else { radeon_dri2_frame_event_handler(crtc, frame, drm_now, data); + } + return 0; } -- cgit v1.2.3 From 0d132d99e0b750896a78f47d73a8639680495d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 6 Mar 2019 17:48:03 +0100 Subject: Bump version for 19.0.0 release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 84f25cfd..0763a8ed 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [18.1.99], + [19.0.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) -- cgit v1.2.3 From f6cd4a67d7de5d3ff1a6e58a8c83749fc8ffc310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 8 Mar 2019 11:48:10 +0100 Subject: Revert "glamor: Avoid glamor_create_pixmap for pixmaps backing windows" This reverts commit 274703087f80342f51fa69c935bb9a1cb0c4ae47. Reports of visual corruption were bisected to this, e.g. https://bugs.archlinux.org/task/61941 . I can reproduce this with Turks, but not with Bonaire. I assume it's a Mesa/glamor bug, but let's revert for now. Acked-by: Alex Deucher --- src/radeon_glamor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index 3e676f2d..f1098381 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -238,7 +238,7 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, if (info->shadow_primary) { if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) return fbCreatePixmap(screen, w, h, depth, usage); - } else if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) { + } else { pixmap = glamor_create_pixmap(screen, w, h, depth, usage); if (pixmap) return pixmap; -- cgit v1.2.3 From 79bc0e054f37026377d54cac6cd8127d4aa9baca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 14 Mar 2019 11:10:51 +0100 Subject: Use radeon_finish in drmmode_crtc_scanout_update radeon_glamor_finish only works if we're using glamor, otherwise it'll crash. Fixes: ce7db51020d3 "Cancel pending scanout update in drmmode_crtc_scanout_update" Bug: https://bugs.debian.org/924540 Reviewed-by: Alex Deucher --- src/drmmode_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index c5fccd2a..002513f1 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -785,7 +785,7 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, screen->GetWindowPixmap(screen->root), extents)) { RegionEmpty(DamageRegion(drmmode_crtc->scanout_damage)); - radeon_glamor_finish(scrn); + radeon_finish(scrn, drmmode_crtc->scanout[scanout_id].bo); if (!drmmode_crtc->flip_pending) { radeon_drm_abort_entry(drmmode_crtc-> -- cgit v1.2.3 From 4407c78bd86da4460ee07a15a365e07d99e0dd27 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 14 Mar 2019 11:17:32 +0100 Subject: modesetting: add tile property support This adds tiling support to the driver, it retrieves the tile info from the kernel and translates it into the server format and exposes the property. (Ported from xserver commits 8fb8bbb3062f1a06621ab7030a9e89d5e8367b35 and 6abdb54a11dac4e8854ff94ecdcb90a14321ab31) (Ported from amdgpu commit 6ee857726166f495abcd68e4ff60e3a09593d079) Reviewed-by: Alex Deucher --- src/drmmode_display.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/drmmode_display.h | 3 +++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 002513f1..0e9e2474 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1576,6 +1576,51 @@ drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) return MODE_OK; } +static void +drmmode_output_attach_tile(xf86OutputPtr output) +{ +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1, 17, 99, 901, 0) + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + RADEONEntPtr pRADEONEnt = RADEONEntPriv(output->scrn); + struct xf86CrtcTileInfo tile_info, *set = NULL; + int i; + + if (!koutput) { + xf86OutputSetTile(output, NULL); + return; + } + + /* look for a TILE property */ + for (i = 0; i < koutput->count_props; i++) { + drmModePropertyPtr props; + props = drmModeGetProperty(pRADEONEnt->fd, koutput->props[i]); + if (!props) + continue; + + if (!(props->flags & DRM_MODE_PROP_BLOB)) { + drmModeFreeProperty(props); + continue; + } + + if (!strcmp(props->name, "TILE")) { + drmModeFreePropertyBlob(drmmode_output->tile_blob); + drmmode_output->tile_blob = + drmModeGetPropertyBlob(pRADEONEnt->fd, + koutput->prop_values[i]); + } + drmModeFreeProperty(props); + } + if (drmmode_output->tile_blob) { + if (xf86OutputParseKMSTile(drmmode_output->tile_blob->data, + drmmode_output->tile_blob->length, + &tile_info) == TRUE) + set = &tile_info; + } + xf86OutputSetTile(output, set); +#endif +} + static int koutput_get_prop_idx(int fd, drmModeConnectorPtr koutput, int type, const char *name) @@ -1648,6 +1693,8 @@ drmmode_output_get_modes(xf86OutputPtr output) } xf86OutputSetEDID(output, mon); + drmmode_output_attach_tile(output); + /* modes should already be available */ for (i = 0; i < koutput->count_modes; i++) { Mode = xnfalloc(sizeof(DisplayModeRec)); @@ -1665,8 +1712,11 @@ drmmode_output_destroy(xf86OutputPtr output) drmmode_output_private_ptr drmmode_output = output->driver_private; int i; - if (drmmode_output->edid_blob) - drmModeFreePropertyBlob(drmmode_output->edid_blob); + drmModeFreePropertyBlob(drmmode_output->edid_blob); +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1, 17, 99, 901, 0) + drmModeFreePropertyBlob(drmmode_output->tile_blob); +#endif + for (i = 0; i < drmmode_output->num_props; i++) { drmModeFreeProperty(drmmode_output->props[i].mode_prop); free(drmmode_output->props[i].atoms); diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 2c2c3d57..96eaef0a 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -142,6 +142,9 @@ typedef struct { drmModeConnectorPtr mode_output; drmModeEncoderPtr *mode_encoders; drmModePropertyBlobPtr edid_blob; +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1, 17, 99, 901, 0) + drmModePropertyBlobPtr tile_blob; +#endif int dpms_enum_id; int num_props; drmmode_prop_ptr props; -- cgit v1.2.3 From 36703f66c3b06875651606a6280d5dc9d9dad51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 19 Mar 2019 18:01:02 +0100 Subject: Bump version for 19.0.1 release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0763a8ed..49e82fc8 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [19.0.0], + [19.0.1], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) -- cgit v1.2.3 From d1d8e3c8d0a0a0394d395eba171460501745209b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 24 Apr 2019 12:25:39 +0200 Subject: Retry get_fb_ptr in get_fb If get_fb_ptr returns NULL, try again after pixmap_get_handle, it should work then. Fixes spurious Present page flipping failures using "normal" pixmaps which aren't shared with direct rendering clients, e.g. with a compositor using the RENDER extension. Bugzilla: https://bugs.freedesktop.org/110417 (Ported from amdgpu commit bf61e6d7ac1a5754b1026d7f80acf25ef622c491) Reviewed-by: Alex Deucher --- src/radeon.h | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index 74454c30..008a59f3 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -877,21 +877,22 @@ static inline struct drmmode_fb* radeon_pixmap_get_fb(PixmapPtr pix) { struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pix); - - if (!fb_ptr) - return NULL; - - if (!*fb_ptr) { - uint32_t handle; - - if (radeon_get_pixmap_handle(pix, &handle)) { - ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - - *fb_ptr = radeon_fb_create(scrn, pRADEONEnt->fd, pix->drawable.width, - pix->drawable.height, pix->devKind, - handle); - } + uint32_t handle; + + if (fb_ptr && *fb_ptr) + return *fb_ptr; + + if (radeon_get_pixmap_handle(pix, &handle)) { + ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); + + if (!fb_ptr) + fb_ptr = radeon_pixmap_get_fb_ptr(pix); + + *fb_ptr = radeon_fb_create(scrn, pRADEONEnt->fd, + pix->drawable.width, + pix->drawable.height, pix->devKind, + handle); } return *fb_ptr; -- cgit v1.2.3 From f758908db4e71406e5d437d32e43aabd38a63504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 9 May 2019 12:35:37 +0200 Subject: dri3: Always flush glamor before sharing pixmap storage with clients Even if glamor_gbm_bo_from_pixmap / glamor_fd_from_pixmap themselves don't trigger any drawing, there could already be unflushed drawing to the pixmap whose storage we share with a client. (Ported from amdgpu commit 4b17533fcb30842caf0035ba593b7d986520cc85) Acked-by: Alex Deucher --- src/radeon_dri3.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/src/radeon_dri3.c b/src/radeon_dri3.c index 73353bf5..f8f91c4b 100644 --- a/src/radeon_dri3.c +++ b/src/radeon_dri3.c @@ -220,29 +220,13 @@ static int radeon_dri3_fd_from_pixmap(ScreenPtr screen, RADEONInfoPtr info = RADEONPTR(scrn); if (info->use_glamor) { - Bool need_flush = TRUE; - int ret = -1; -#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,19,99,904,0) - struct gbm_bo *gbm_bo = glamor_gbm_bo_from_pixmap(screen, pixmap); + int ret = glamor_fd_from_pixmap(screen, pixmap, stride, size); - if (gbm_bo) { - ret = gbm_bo_get_fd(gbm_bo); - gbm_bo_destroy(gbm_bo); - - if (ret >= 0) - need_flush = FALSE; - } -#endif - - if (ret < 0) - ret = glamor_fd_from_pixmap(screen, pixmap, stride, size); - - /* glamor might have needed to reallocate the pixmap storage and - * copy the pixmap contents to the new storage. The copy - * operation needs to be flushed to the kernel driver before the - * client starts using the pixmap storage for direct rendering. + /* Any pending drawing operations need to be flushed to the + * kernel driver before the client starts using the pixmap + * storage for direct rendering. */ - if (ret >= 0 && need_flush) + if (ret >= 0) radeon_cs_flush_indirect(scrn); return ret; -- cgit v1.2.3 From d5f5bc5846ef06c3ecf9e5acf1ca357574f06f5a Mon Sep 17 00:00:00 2001 From: Flora Cui Date: Fri, 14 Jun 2019 11:20:12 +0200 Subject: dri2: reply to client for WaitMSC request in any case otherwise client would wait for reply forever and desktop appears hang. Signed-off-by: Flora Cui (Ported from amdgpu commit fb06fb814700a47464abd756e1111dcc76d0d776) Reviewed-by: Alex Deucher --- src/radeon_dri2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index a9f14e8d..3c04e6fe 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -1156,6 +1156,9 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, out_complete: if (wait_info) radeon_dri2_deferred_event(NULL, 0, wait_info); + else + DRI2WaitMSCComplete(client, draw, 0, 0, 0); + return TRUE; } -- cgit v1.2.3 From 2a3f2d2089f603c99be54c98d7033155e771ce7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 14 Jun 2019 11:21:40 +0200 Subject: dri2: Re-use previous CRTC when possible if pick_best_crtc returns NULL This way, the MSC will continue ticking at the rate of (the last mode which was enabled for) that CRTC, instead of the client running unthrottled. (Ported from amdgpu commit 3109f088fdbd89c2ee8078625d4f073852492656) Reviewed-by: Alex Deucher --- src/radeon_dri2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 3c04e6fe..c59d799f 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -517,10 +517,12 @@ xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled) pDraw->x, pDraw->x + pDraw->width, pDraw->y, pDraw->y + pDraw->height); - if (crtc && pDraw->type == DRAWABLE_WINDOW) { + if (pDraw->type == DRAWABLE_WINDOW) { struct dri2_window_priv *priv = get_dri2_window_priv((WindowPtr)pDraw); - if (priv->crtc && priv->crtc != crtc) { + if (!crtc) { + crtc = priv->crtc; + } else if (priv->crtc && priv->crtc != crtc) { CARD64 ust, mscold, mscnew; if (radeon_dri2_get_crtc_msc(priv->crtc, &ust, &mscold) && -- cgit v1.2.3 From fee737e82837dc8282a832fc9391ed959c4c3737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 14 Jun 2019 11:23:34 +0200 Subject: Remove dri2_drawable_crtc parameter consider_disabled All callers were passing TRUE. (Ported from amdgpu commit ea19a5207054bb159fc7fb6d88e0ceb10c3da010) Reviewed-by: Alex Deucher --- src/radeon_dri2.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index c59d799f..66a223d8 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -509,11 +509,11 @@ static Bool radeon_dri2_get_crtc_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc) } static -xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled) +xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - xf86CrtcPtr crtc = radeon_pick_best_crtc(pScrn, consider_disabled, + xf86CrtcPtr crtc = radeon_pick_best_crtc(pScrn, TRUE, pDraw->x, pDraw->x + pDraw->width, pDraw->y, pDraw->y + pDraw->height); @@ -928,7 +928,7 @@ CARD32 radeon_dri2_extrapolate_msc_delay(xf86CrtcPtr crtc, CARD64 *target_msc, */ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) { - xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE); + xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw); /* Drawable not displayed, make up a value */ if (!crtc) { @@ -1043,7 +1043,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, ScrnInfoPtr scrn = xf86ScreenToScrn(screen); DRI2FrameEventPtr wait_info = NULL; uintptr_t drm_queue_seq = 0; - xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE); + xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw); uint32_t msc_delta; uint32_t seq; CARD64 current_msc; @@ -1192,7 +1192,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, { ScreenPtr screen = draw->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE); + xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw); uint32_t msc_delta; drmVBlankSeqType type; uint32_t seq; -- cgit v1.2.3 From 33803c85f761d343aa7300311b8e9489b1a89495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 25 Jun 2019 17:46:23 +0200 Subject: present: Check that we can get a KMS FB for flipping This can legitimately fail if the pixmap's storage is shared from another device, e.g. when using PRIME render offloading. (Ported from amdgpu commit 7d3fef72e0c871e1677e9e544f4cae5e238b5c52) --- src/radeon.h | 1 + src/radeon_present.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/radeon.h b/src/radeon.h index 008a59f3..2c913466 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -309,6 +309,7 @@ struct radeon_pixmap { struct radeon_buffer *bo; struct drmmode_fb *fb; + Bool fb_failed; uint32_t tiling_flags; diff --git a/src/radeon_present.c b/src/radeon_present.c index 38a9a6b7..494655c9 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -254,6 +254,7 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, xf86CrtcPtr xf86_crtc = crtc->devPrivate; ScreenPtr screen = window->drawable.pScreen; ScrnInfoPtr scrn = xf86_crtc->scrn; + struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); RADEONInfoPtr info = RADEONPTR(scrn); PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); @@ -277,6 +278,23 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, return FALSE; #endif + if (priv && priv->fb_failed) + return FALSE; + + if (!radeon_pixmap_get_fb(pixmap)) { + if (!priv) + priv = radeon_get_pixmap_private(pixmap); + + if (priv && !priv->fb_failed) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "Cannot get FB for Present flip (may be " + "normal if using PRIME render offloading)\n"); + priv->fb_failed = TRUE; + } + + return FALSE; + } + /* The kernel driver doesn't handle flipping between BOs with different * tiling parameters correctly yet */ -- cgit v1.2.3 From c7ed12cb2ea76999351d7cb87877224bdc0664f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 18 Jul 2019 18:14:48 +0200 Subject: Don't disable page flipping completely with SW cursor Even with SW cursor, page flipping can be used while no X cursor is visible. Occurred to me in the context of xorg/xserver#828. (Ported from amdgpu commit 87f41ace4920fd2069794211683659eb25b025a6) --- src/radeon_kms.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index ff4f8dcf..777fc14e 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -1917,19 +1917,15 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) if (!pScrn->is_gpu) { if (info->dri2.pKernelDRMVersion->version_minor >= 8) { - Bool sw_cursor = xf86ReturnOptValBool(info->Options, - OPTION_SW_CURSOR, FALSE); - info->allowPageFlip = xf86ReturnOptValBool(info->Options, OPTION_PAGE_FLIP, TRUE); - if (sw_cursor || info->shadow_primary) { + if (info->shadow_primary) { xf86DrvMsg(pScrn->scrnIndex, info->allowPageFlip ? X_WARNING : X_DEFAULT, "KMS Pageflipping: disabled%s\n", info->allowPageFlip ? - (sw_cursor ? " because of SWcursor" : - " because of ShadowPrimary") : ""); + " because of ShadowPrimary" : ""); info->allowPageFlip = FALSE; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, -- cgit v1.2.3 From 2cbbd8648cdd27db8076565943b932ef81337053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 20 Sep 2019 18:47:02 +0200 Subject: Don't set up black scanout buffer if LeaveVT is called from CloseScreen Avoids a crash described in https://gitlab.freedesktop.org/xorg/driver/xf86-video-amdgpu/merge_requests/43#note_223718 (Ported from amdgpu commit 5b8bc9fc505c551dcd9b0ed5ab835a49fa4f9fda) Reviewed-by: Alex Deucher --- src/radeon_kms.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 777fc14e..107c1ce7 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2629,6 +2629,12 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn) unsigned w = 0, h = 0; int i; + /* If we're called from CloseScreen, trying to clear the black + * scanout BO will likely crash and burn + */ + if (!pScreen->GCperDepth[0]) + goto hide_cursors; + /* Compute maximum scanout dimensions of active CRTCs */ for (i = 0; i < xf86_config->num_crtc; i++) { crtc = xf86_config->crtc[i]; @@ -2701,8 +2707,10 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn) pScrn->displayWidth * info->pixel_bytes * pScrn->virtualY); } - TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen); + if (pScreen->GCperDepth[0]) + TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen); + hide_cursors: xf86_hide_cursors (pScrn); radeon_drop_drm_master(pScrn); -- cgit v1.2.3 From 2faaecc69b127248718e759c6c98c84d56dd1b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 20 Sep 2019 17:24:19 +0200 Subject: Don't unreference FBs of pixmaps from different screens in LeaveVT FindClientResourcesByType finds pixmaps from all screens, but trying to process ones from other screens here makes no sense and likely results in a crash or memory corruption. Fixes: 06a465484101 ("Make all active CRTCs scan out an all-black framebuffer in LeaveVT") --- src/radeon_kms.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 107c1ce7..b3db7c41 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -2602,16 +2602,25 @@ CARD32 cleanup_black_fb(OsTimerPtr timer, CARD32 now, pointer data) } static void -pixmap_unref_fb(void *value, XID id, void *cdata) +pixmap_unref_fb(PixmapPtr pixmap) { - PixmapPtr pixmap = value; - RADEONEntPtr pRADEONEnt = cdata; + ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pixmap); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); if (fb_ptr) drmmode_fb_reference(pRADEONEnt->fd, fb_ptr, NULL); } +static void +client_pixmap_unref_fb(void *value, XID id, void *pScreen) +{ + PixmapPtr pixmap = value; + + if (pixmap->drawable.pScreen == pScreen) + pixmap_unref_fb(pixmap); +} + void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -2673,11 +2682,9 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn) if (pScrn->is_gpu) { if (drmmode_crtc->scanout[0].pixmap) - pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap, - None, pRADEONEnt); + pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap); if (drmmode_crtc->scanout[1].pixmap) - pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap, - None, pRADEONEnt); + pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap); } else { drmmode_crtc_scanout_free(crtc); } @@ -2697,11 +2704,11 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn) (!clients[i] || clients[i]->clientState != ClientStateRunning)) continue; - FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb, - pRADEONEnt); + FindClientResourcesByType(clients[i], RT_PIXMAP, + client_pixmap_unref_fb, pScreen); } - pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt); + pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen)); } else { memset(info->front_buffer->bo.radeon->ptr, 0, pScrn->displayWidth * info->pixel_bytes * pScrn->virtualY); -- cgit v1.2.3 From b9bd8097e1d2c088b081f1b81799ea3892406214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 15 Oct 2019 17:54:12 +0200 Subject: Bump version for 19.1.0 release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 49e82fc8..a504695b 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-ati], - [19.0.1], + [19.1.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/Radeon], [xf86-video-ati]) -- cgit v1.2.3 From f223035f4ffcff2a9296d1e907a5193f8e8845a3 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 4 Feb 2020 16:38:06 -0500 Subject: Fix link failure with gcc 10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without the 'extern' this looks like a definition not just a declaration, in every file that includes the header. gcc 10 is stricter about this kind of multiple definition. Reviewed-by: Michel Dänzer --- src/drmmode_display.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 96eaef0a..8cd8a0a6 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -262,7 +262,7 @@ Bool drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type, uint64_t *ust, uint32_t *result_seq); -miPointerSpriteFuncRec drmmode_sprite_funcs; +extern miPointerSpriteFuncRec drmmode_sprite_funcs; #endif -- cgit v1.2.3 From 4d84cf438e7f1bebf0053035ef0292e9fed257d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 29 Nov 2019 16:37:32 +0100 Subject: Handle NULL fb_ptr in pixmap_get_fb This can happen when HW acceleration is disabled. Fixes https://gitlab.freedesktop.org/xorg/driver/xf86-video-ati/issues/188 --- src/radeon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/radeon.h b/src/radeon.h index 2c913466..8e964805 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -896,7 +896,7 @@ radeon_pixmap_get_fb(PixmapPtr pix) handle); } - return *fb_ptr; + return fb_ptr ? *fb_ptr : NULL; } -- cgit v1.2.3 From c0eb5dbd9c1db6b6d5b1574bcd8c584170d7ab54 Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Wed, 27 Nov 2019 20:50:58 +0400 Subject: Don't crash X server if GPU acceleration is not available Commit d1d8e3c8d0a0a0394d395eba171460501745209b causes X server to fail on startup when GPU acceleration is not working (or is disabled). The reason is that `radeon_get_pixmap_bo` function gets called too early (before EXA has been initialized) and fails with an assert: #0 __GI_raise (sig=) at ../sysdeps/unix/sysv/linux/raise.c:50 #1 0x76ab1c6c in __GI_abort () at abort.c:79 #2 0x76ac0b64 in __assert_fail_base (fmt=0x76bfbce4 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x7658c80c "key->initialized", file=, line=121, function=0x7658d040 <__PRETTY_FUNCTION__.10607> "dixGetPrivateAddr") at assert.c:92 #3 0x76ac0c0c in __GI___assert_fail (assertion=0x7658c80c "key->initialized", file=0x7658c9d0 "../include/privates.h", line=121, function=0x7658d040 <__PRETTY_FUNCTION__.10607> "dixGetPrivateAddr") at assert.c:101 #4 0x76579e6c in dixGetPrivateAddr (key=, key=, privates=) at ../include/privates.h:121 #5 0x7657a954 in dixGetPrivateAddr (key=, key=, privates=) at exa.c:70 #6 dixGetPrivate (key=, privates=) at ../include/privates.h:136 #7 exaGetPixmapDriverPrivate (pPix=) at exa.c:68 #8 0x7623d460 in radeon_get_pixmap_bo (pPix=0x71c1b8) at radeon.h:804 #9 radeon_get_pixmap_handle (pixmap=0x71c1b8, handle=0x7fa22328) at radeon_bo_helper.c:357 #10 0x76244458 in radeon_pixmap_get_fb (pix=0x71c1b8) at radeon.h:886 #11 drmmode_set_mode_major (crtc=0x691860, mode=0x69191c, rotation=, x=, y=) at drmmode_display.c:918 #12 0x762467e8 in drmmode_set_desired_modes (pScrn=0x67c678, drmmode=, set_hw=1) at drmmode_display.c:3128 #13 0x0047bfa4 in MapWindow (client=0x669ec8, pWin=0x7206c0) at window.c:2722 #14 MapWindow (pWin=0x7206c0, client=0x669ec8) at window.c:2665 #15 0x00449650 in dix_main (argc=3, argv=0x7fa22604, envp=) at main.c:247 #16 0x76ab2198 in __libc_start_main (main=0x42db10
, argc=3, argv=0x7fa22604, init=, fini=0x606434 <__libc_csu_fini>, rtld_fini=0x77229930 <_dl_fini>, stack_end=0x7fa225e0) at libc-start.c:308 #17 0x0042db80 in __start () at ../sysdeps/mips/start.S:110 Don't call `exaGetPixmapDriverPrivate` if the acceleration (EXA) is not enabled [yet] to avoid the problem. Closes: https://gitlab.freedesktop.org/xorg/driver/xf86-video-ati/issues/188 Closes: https://bugzilla.altlinux.org/show_bug.cgi?id=37539 --- src/radeon.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index 8e964805..e4a2ba66 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -790,8 +790,8 @@ static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_buffer *bo static inline struct radeon_buffer *radeon_get_pixmap_bo(PixmapPtr pPix) { -#ifdef USE_GLAMOR RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen)); +#ifdef USE_GLAMOR if (info->use_glamor) { struct radeon_pixmap *priv; @@ -799,7 +799,7 @@ static inline struct radeon_buffer *radeon_get_pixmap_bo(PixmapPtr pPix) return priv ? priv->bo : NULL; } else #endif - { + if (info->accelOn) { struct radeon_exa_pixmap_priv *driver_priv; driver_priv = exaGetPixmapDriverPrivate(pPix); return driver_priv ? driver_priv->bo : NULL; -- cgit v1.2.3 From 3845392426e9798c1fb2a6fc5e97bf5dfd5c443d Mon Sep 17 00:00:00 2001 From: Niclas Zeising Date: Tue, 14 Apr 2020 17:01:57 +0200 Subject: Fix return value check of drmIoctl() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the drmModeSetCursor2() call was replaced with bare drmIoctl() call in 92df7097, a bug was introduced. With the use of drmModeSetCursor2(), the return value from drmIoctl() (which calls ioctl()) were mangled, if they were negative, they were replaced by -errno by a wrapper function in xf86drMode.c in libdrm. After replacing drmModeSetCursor2() with the call to drmIoctl(), this mangling no longer happens, and we need to explicitly check if the call to drmIoctl() fails, which is indicated by returning -1, and then why it failed, by checking errno. If the error indicated by errno is EINVAL, then we can't use the DRM_IOCTL_MODE_CURSOR2 ioctl(), and need to fall back to the DRM_IOCTL_MODE_CURSOR ioctl(). This bug can manifest itself by an invisible hw cursor on systems where the DRM_IOCTL_MODE_CURSOR2 is not implemented by the graphics driver. Credit also to Alexey Dokuchaev for help with developing the fix and testing. This fixes #190 Signed-off-by: Niclas Zeising Reviewed-by: Michel Dänzer --- src/drmmode_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 0e9e2474..72f96a0c 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -1275,7 +1275,7 @@ drmmode_show_cursor (xf86CrtcPtr crtc) arg.hot_y = yhot; ret = drmIoctl(pRADEONEnt->fd, DRM_IOCTL_MODE_CURSOR2, &arg); - if (ret == -EINVAL) + if (ret == -1 && errno == EINVAL) use_set_cursor2 = FALSE; else return; -- cgit v1.2.3 From 8da3e4561ef82bb78c9a17b8cd8bf139b9cfd680 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 13 Jul 2020 09:11:28 +1000 Subject: ati: cleanup terminology to use primary/secondary The X server changed some API/ABIs here. Based on amdgpu patch by Michel --- man/radeon.man | 2 +- src/compat-api.h | 6 +++++ src/drmmode_display.c | 4 +-- src/evergreen_state.h | 2 +- src/r600_state.h | 2 +- src/radeon.h | 10 +++---- src/radeon_exa.c | 2 +- src/radeon_glamor.c | 2 +- src/radeon_kms.c | 74 +++++++++++++++++++++++++-------------------------- 9 files changed, 55 insertions(+), 49 deletions(-) diff --git a/man/radeon.man b/man/radeon.man index dcebf537..247dcdb7 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -290,7 +290,7 @@ on. If this option is set, the default value of the property is 'on' or 'off' accordingly. If this option isn't set, the default value of the property is .B auto, which means that TearFree is on for rotated outputs, outputs with RandR -transforms applied and for RandR 1.4 slave outputs, otherwise off. +transforms applied and for RandR 1.4 secondary outputs, otherwise off. .TP .BI "Option \*qAccelMethod\*q \*q" "string" \*q Chooses between available acceleration architectures. Valid values are diff --git a/src/compat-api.h b/src/compat-api.h index f4e7524f..def6d3e4 100644 --- a/src/compat-api.h +++ b/src/compat-api.h @@ -34,4 +34,10 @@ #define BLOCKHANDLER_ARGS pScreen, pTimeout, pReadmask #endif +#if ABI_VIDEODRV_VERSION < SET_ABI_VERSION(25, 2) +#define current_primary current_master +#define primary_pixmap master_pixmap +#define secondary_dst slave_dst +#endif + #endif diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 72f96a0c..3099a729 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -720,7 +720,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { if (radeon_dirty_src_equals(dirty, drmmode_crtc->prime_scanout_pixmap)) { - dirty->slave_dst = + dirty->secondary_dst = drmmode_crtc->scanout[scanout_id].pixmap; break; } @@ -1356,7 +1356,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { if (radeon_dirty_src_equals(dirty, drmmode_crtc->prime_scanout_pixmap)) { - PixmapStopDirtyTracking(dirty->src, dirty->slave_dst); + PixmapStopDirtyTracking(dirty->src, dirty->secondary_dst); break; } } diff --git a/src/evergreen_state.h b/src/evergreen_state.h index 7e54e1c7..34ba87b6 100644 --- a/src/evergreen_state.h +++ b/src/evergreen_state.h @@ -350,7 +350,7 @@ extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, int *new_pitch); extern void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv); extern Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix); -extern Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **handle_p); +extern Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr secondary, void **handle_p); extern Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *handle); #endif diff --git a/src/r600_state.h b/src/r600_state.h index 34345996..567c3ca2 100644 --- a/src/r600_state.h +++ b/src/r600_state.h @@ -321,6 +321,6 @@ extern void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, int *new_pitch); extern void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv); extern Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix); -extern Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **handle_p); +extern Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr secondary, void **handle_p); extern Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *handle); #endif diff --git a/src/radeon.h b/src/radeon.h index e4a2ba66..68d7756a 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -182,18 +182,18 @@ typedef enum { static inline ScreenPtr -radeon_master_screen(ScreenPtr screen) +radeon_primary_screen(ScreenPtr screen) { - if (screen->current_master) - return screen->current_master; + if (screen->current_primary) + return screen->current_primary; return screen; } static inline ScreenPtr -radeon_dirty_master(PixmapDirtyUpdatePtr dirty) +radeon_dirty_primary(PixmapDirtyUpdatePtr dirty) { - return radeon_master_screen(dirty->slave_dst->drawable.pScreen); + return radeon_primary_screen(dirty->secondary_dst->drawable.pScreen); } static inline DrawablePtr diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 268155ed..320ff992 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -282,7 +282,7 @@ void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv) free(driverPriv); } -Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **fd_handle) +Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr seconndary, void **fd_handle) { struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(ppix); diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c index f1098381..ccf99941 100644 --- a/src/radeon_glamor.c +++ b/src/radeon_glamor.c @@ -366,7 +366,7 @@ radeon_glamor_set_pixmap_bo(DrawablePtr drawable, PixmapPtr pixmap) static Bool -radeon_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, +radeon_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr secondary, void **handle_p) { ScreenPtr screen = pixmap->drawable.pScreen; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index b3db7c41..62962d61 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -559,8 +559,8 @@ dirty_region(PixmapDirtyUpdatePtr dirty) if (dirty->rotation != RR_Rotate_0) { dstregion = transform_region(damageregion, &dirty->f_inverse, - dirty->slave_dst->drawable.width, - dirty->slave_dst->drawable.height); + dirty->secondary_dst->drawable.width, + dirty->secondary_dst->drawable.height); } else #endif { @@ -568,7 +568,7 @@ dirty_region(PixmapDirtyUpdatePtr dirty) dstregion = RegionDuplicate(damageregion); RegionTranslate(dstregion, -dirty->x, -dirty->y); - PixmapRegionInit(&pixregion, dirty->slave_dst); + PixmapRegionInit(&pixregion, dirty->secondary_dst); RegionIntersect(dstregion, dstregion, &pixregion); RegionUninit(&pixregion); } @@ -585,8 +585,8 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region) if (RegionNil(region)) goto out; - if (dirty->slave_dst->master_pixmap) - DamageRegionAppend(&dirty->slave_dst->drawable, region); + if (dirty->secondary_dst->primary_pixmap) + DamageRegionAppend(&dirty->secondary_dst->drawable, region); #ifdef HAS_DIRTYTRACKING_ROTATION PixmapSyncDirtyHelper(dirty); @@ -595,8 +595,8 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region) #endif radeon_cs_flush_indirect(src_scrn); - if (dirty->slave_dst->master_pixmap) - DamageRegionProcessPending(&dirty->slave_dst->drawable); + if (dirty->secondary_dst->primary_pixmap) + DamageRegionProcessPending(&dirty->secondary_dst->drawable); out: DamageEmpty(dirty->damage); @@ -613,12 +613,12 @@ radeon_prime_scanout_update_abort(xf86CrtcPtr crtc, void *event_data) void radeon_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) { - ScreenPtr master_screen = radeon_dirty_master(dirty); + ScreenPtr primary_screen = radeon_dirty_primary(dirty); PixmapDirtyUpdatePtr ent; RegionPtr region; - xorg_list_for_each_entry(ent, &master_screen->pixmap_dirty_list, ent) { - if (!radeon_dirty_src_equals(dirty, ent->slave_dst)) + xorg_list_for_each_entry(ent, &primary_screen->pixmap_dirty_list, ent) { + if (!radeon_dirty_src_equals(dirty, ent->secondary_dst)) continue; region = dirty_region(ent); @@ -631,45 +631,45 @@ radeon_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) #if HAS_SYNC_SHARED_PIXMAP static Bool -master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) +primary_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) { - ScreenPtr master_screen = radeon_dirty_master(dirty); + ScreenPtr primary_screen = radeon_dirty_primary(dirty); - return !!master_screen->SyncSharedPixmap; + return !!primary_screen->SyncSharedPixmap; } static Bool -slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) +secondary_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) { - ScreenPtr slave_screen = dirty->slave_dst->drawable.pScreen; + ScreenPtr secondary_screen = dirty->secondary_dst->drawable.pScreen; - return !!slave_screen->SyncSharedPixmap; + return !!secondary_screen->SyncSharedPixmap; } static void call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) { - ScreenPtr master_screen = radeon_dirty_master(dirty); + ScreenPtr primary_screen = radeon_dirty_primary(dirty); - master_screen->SyncSharedPixmap(dirty); + primary_screen->SyncSharedPixmap(dirty); } #else /* !HAS_SYNC_SHARED_PIXMAP */ static Bool -master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) +primary_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) { - ScrnInfoPtr master_scrn = xf86ScreenToScrn(radeon_dirty_master(dirty)); + ScrnInfoPtr primary_scrn = xf86ScreenToScrn(radeon_dirty_primary(dirty)); - return master_scrn->driverName == scrn->driverName; + return primary_scrn->driverName == scrn->driverName; } static Bool -slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) +secondary_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty) { - ScrnInfoPtr slave_scrn = xf86ScreenToScrn(dirty->slave_dst->drawable.pScreen); + ScrnInfoPtr secondary_scrn = xf86ScreenToScrn(dirty->secondary_dst->drawable.pScreen); - return slave_scrn->driverName == scrn->driverName; + return secondary_scrn->driverName == scrn->driverName; } static void @@ -684,12 +684,12 @@ call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) static xf86CrtcPtr radeon_prime_dirty_to_crtc(PixmapDirtyUpdatePtr dirty) { - ScreenPtr screen = dirty->slave_dst->drawable.pScreen; + ScreenPtr screen = dirty->secondary_dst->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int c; - /* Find the CRTC which is scanning out from this slave pixmap */ + /* Find the CRTC which is scanning out from this secondary pixmap */ for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr xf86_crtc = xf86_config->crtc[c]; drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; @@ -714,7 +714,7 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id) if (radeon_dirty_src_equals(dirty, drmmode_crtc->prime_scanout_pixmap)) { RegionPtr region; - if (master_has_sync_shared_pixmap(scrn, dirty)) + if (primary_has_sync_shared_pixmap(scrn, dirty)) call_sync_shared_pixmap(dirty); region = dirty_region(dirty); @@ -727,7 +727,7 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id) radeon_cs_flush_indirect(scrn); RegionCopy(&drmmode_crtc->scanout_last_region, region); RegionTranslate(region, -crtc->x, -crtc->y); - dirty->slave_dst = drmmode_crtc->scanout[scanout_id].pixmap; + dirty->secondary_dst = drmmode_crtc->scanout[scanout_id].pixmap; } redisplay_dirty(dirty, region); @@ -754,7 +754,7 @@ radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t u static void radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) { - ScreenPtr screen = dirty->slave_dst->drawable.pScreen; + ScreenPtr screen = dirty->secondary_dst->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); xf86CrtcPtr xf86_crtc = radeon_prime_dirty_to_crtc(dirty); @@ -818,7 +818,7 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) static void radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent) { - ScreenPtr screen = ent->slave_dst->drawable.pScreen; + ScreenPtr screen = ent->secondary_dst->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); xf86CrtcPtr crtc = radeon_prime_dirty_to_crtc(ent); @@ -893,11 +893,11 @@ radeon_dirty_update(ScrnInfoPtr scrn) if (screen->isGPU) { PixmapDirtyUpdatePtr region_ent = ent; - if (master_has_sync_shared_pixmap(scrn, ent)) { - ScreenPtr master_screen = radeon_dirty_master(ent); + if (primary_has_sync_shared_pixmap(scrn, ent)) { + ScreenPtr primary_screen = radeon_dirty_primary(ent); - xorg_list_for_each_entry(region_ent, &master_screen->pixmap_dirty_list, ent) { - if (radeon_dirty_src_equals(ent, region_ent->slave_dst)) + xorg_list_for_each_entry(region_ent, &primary_screen->pixmap_dirty_list, ent) { + if (radeon_dirty_src_equals(ent, region_ent->secondary_dst)) break; } } @@ -921,7 +921,7 @@ radeon_dirty_update(ScrnInfoPtr scrn) RegionDestroy(region); } else { - if (slave_has_sync_shared_pixmap(scrn, ent)) + if (secondary_has_sync_shared_pixmap(scrn, ent)) continue; region = dirty_region(ent); @@ -1216,7 +1216,7 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); pScreen->BlockHandler = RADEONBlockHandler_KMS; - if (!xf86ScreenToScrn(radeon_master_screen(pScreen))->vtSema) + if (!xf86ScreenToScrn(radeon_primary_screen(pScreen))->vtSema) return; if (!pScreen->isGPU) @@ -2584,7 +2584,7 @@ CARD32 cleanup_black_fb(OsTimerPtr timer, CARD32 now, pointer data) xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int c; - if (xf86ScreenToScrn(radeon_master_screen(screen))->vtSema) + if (xf86ScreenToScrn(radeon_primary_screen(screen))->vtSema) return 0; /* Unreference the all-black FB created by RADEONLeaveVT_KMS. After -- cgit v1.2.3 From 3c7c84ed49564907a148ae99b03200e0be350060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 26 Mar 2021 17:42:10 +0100 Subject: Guard local variable priv only used with glamor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes compile errors with glamor disabled: ../../src/radeon_present.c: In function ‘radeon_present_check_flip’: ../../src/radeon_present.c:281:21: error: invalid use of undefined type ‘struct radeon_pixmap’ 281 | if (priv && priv->fb_failed) | ^~ ../../src/radeon_present.c:288:19: error: invalid use of undefined type ‘struct radeon_pixmap’ 288 | if (priv && !priv->fb_failed) { | ^~ ../../src/radeon_present.c:292:10: error: invalid use of undefined type ‘struct radeon_pixmap’ 292 | priv->fb_failed = TRUE; | ^~ --- src/radeon_present.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/radeon_present.c b/src/radeon_present.c index 494655c9..d010aa19 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -254,7 +254,9 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, xf86CrtcPtr xf86_crtc = crtc->devPrivate; ScreenPtr screen = window->drawable.pScreen; ScrnInfoPtr scrn = xf86_crtc->scrn; +#ifdef USE_GLAMOR struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap); +#endif xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); RADEONInfoPtr info = RADEONPTR(scrn); PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); @@ -278,10 +280,13 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, return FALSE; #endif +#ifdef USE_GLAMOR if (priv && priv->fb_failed) return FALSE; +#endif if (!radeon_pixmap_get_fb(pixmap)) { +#ifdef USE_GLAMOR if (!priv) priv = radeon_get_pixmap_private(pixmap); @@ -291,6 +296,7 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, "normal if using PRIME render offloading)\n"); priv->fb_failed = TRUE; } +#endif return FALSE; } -- cgit v1.2.3 From 77d9ab03ca20e683be4c40ccc879e201b538f7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 26 Mar 2021 17:37:53 +0100 Subject: Guard local variable info only used with glamor Fixes compiler warning with glamor disabled: radeon_dri2.c: In function 'radeon_dri2_exchange_buffers': radeon_dri2.c:732:19: error: unused variable 'info' [-Werror=unused-variable] RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen)); ^~~~ --- src/radeon_dri2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 66a223d8..17983779 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -728,8 +728,9 @@ radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPt { struct dri2_buffer_priv *front_priv = front->driverPrivate; struct dri2_buffer_priv *back_priv = back->driverPrivate; - ScreenPtr screen = draw->pScreen; - RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen)); +#ifdef USE_GLAMOR + RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(draw->pScreen)); +#endif RegionRec region; int tmp; -- cgit v1.2.3 From ecced3b3c6af501c4c90265f8404b6898f3cf037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 26 Mar 2021 17:16:32 +0100 Subject: Add GitLab CI pipeline Based on xf86-video-amdgpu, but applying experience gained in the meantime in other projects and taking advantage of new features available with current versions of GitLab. --- .gitlab-ci.yml | 80 ++++++++++++++++++++++++++++++++++++++++++++ .gitlab-ci/debian-install.sh | 74 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 .gitlab-ci.yml create mode 100644 .gitlab-ci/debian-install.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..f7891323 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,80 @@ +# FDO_DISTRIBUTION_TAG is the tag of the docker image used for the build +# jobs. If the image doesn't exist yet, the docker-image stage generates it +# or copies it from upstream (this is all handled by the templates). +# +# In order to generate a new image, one should generally change the tag. +# While removing the image from the registry would also work, that's not +# recommended except for ephemeral images during development. +# +variables: + FDO_DISTRIBUTION_VERSION: buster-slim + FDO_DISTRIBUTION_EXEC: 'bash .gitlab-ci/debian-install.sh' + FDO_DISTRIBUTION_TAG: "2021-05-10" + FDO_UPSTREAM_REPO: xorg/driver/xf86-video-ati + +include: + - project: 'freedesktop/ci-templates' + ref: 290b79e0e78eab67a83766f4e9691be554fc4afd + file: '/templates/debian.yml' + +stages: + - docker-image + - build + + +container-build: + extends: + - .fdo.container-build@debian + stage: docker-image + variables: + + +# The default build instructions +.default_build: + extends: + - .fdo.distribution-image@debian + stage: build + script: + - ./autogen.sh + - make -j${FDO_CI_CONCURRENT:-4} check V=1 + variables: + CFLAGS: "-pipe -g -O2 -Werror" + ACLOCAL_PATH: /usr/local/xserver-$XSERVER_VERSION/share/aclocal + PKG_CONFIG_PATH: /usr/local/xserver-$XSERVER_VERSION/lib/pkgconfig + +build-distcheck: + extends: + - .default_build + script: + - ./autogen.sh + - make -j${FDO_CI_CONCURRENT:-4} check V=1 + - make install V=1 + - make -j${FDO_CI_CONCURRENT:-4} distcheck + variables: + XSERVER_VERSION: "1.20" + +build-gcc: + extends: + - .default_build + parallel: + matrix: + - XSERVER_VERSION: ["1.16", "1.17", "1.18", "1.19"] + +build-clang: + extends: + - .default_build + parallel: + matrix: + - XSERVER_VERSION: ["1.20", "1.18", "1.19"] + variables: + CC: clang + +build-noglamor: + extends: + - .default_build + script: + - ./autogen.sh --disable-glamor + - make -j${FDO_CI_CONCURRENT:-4} check V=1 + parallel: + matrix: + - XSERVER_VERSION: ["1.13", "1.14", "1.15"] diff --git a/.gitlab-ci/debian-install.sh b/.gitlab-ci/debian-install.sh new file mode 100644 index 00000000..4e528588 --- /dev/null +++ b/.gitlab-ci/debian-install.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +set -e +set -o xtrace + +echo 'deb-src https://deb.debian.org/debian buster main' >/etc/apt/sources.list.d/deb-src.list +apt-get update + + +# Ephemeral packages (installed for this script and removed again at the end) +EPHEMERAL=" + ca-certificates + git + " + +# libXfont/xserver build dependencies +apt-get install -y --no-remove \ + autoconf \ + automake \ + build-essential \ + libtool \ + pkg-config \ + $EPHEMERAL + +echo 'APT::Get::Build-Dep-Automatic "true";' >>/etc/apt/apt.conf +apt-get build-dep -y xorg-server + + +git clone https://gitlab.freedesktop.org/xorg/lib/libXfont.git +cd libXfont +git checkout libXfont-1.5-branch +./autogen.sh +make install-pkgconfigDATA +cd .. +rm -rf libXfont + + +git clone https://gitlab.freedesktop.org/xorg/xserver.git +cd xserver + +for VERSION in 1.13 1.14 1.15; do + git checkout server-${VERSION}-branch + ./autogen.sh --prefix=/usr/local/xserver-$VERSION --enable-dri2 + make -C include install-nodist_sdkHEADERS + make install-headers install-aclocalDATA install-pkgconfigDATA clean +done + +for VERSION in 1.16 1.17 1.18 1.19 1.20; do + git checkout server-${VERSION}-branch + ./autogen.sh --prefix=/usr/local/xserver-$VERSION --enable-dri2 --enable-dri3 --enable-glamor + make -C include install-nodist_sdkHEADERS + make install-headers install-aclocalDATA install-pkgconfigDATA clean +done + +cd .. +rm -rf xserver + + +# xf86-video-ati build dependencies +apt-get install -y --no-remove \ + clang \ + libdrm-dev \ + libgbm-dev \ + libgl1-mesa-dev \ + libpciaccess-dev \ + libpixman-1-dev \ + libudev-dev \ + xutils-dev \ + x11proto-dev + + +# Remove unneeded packages +apt-get purge -y $EPHEMERAL +apt-get autoremove -y --purge -- cgit v1.2.3 From 5eba006e4129e8015b822f9e1d2f1e613e252cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 2 Feb 2021 12:45:54 +0100 Subject: Only include dri.h with older versions of xserver Not needed anymore with current versions. --- src/drmmode_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 3099a729..a58f24dd 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -45,7 +45,9 @@ #include "radeon_glamor.h" #include "radeon_reg.h" +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,19,99,1,0) #include +#endif #include "drmmode_display.h" -- cgit v1.2.3