From: Michel Dänzer <[email protected]> We only need to flush for XDamageNotify events.
Significantly reduces compositing slowdown due to flushing overhead, in particular with glamor. (Ported from radeon commit 9a1afbf61fbb2827c86bd86d295fa0848980d60b) Signed-off-by: Michel Dänzer <[email protected]> --- src/amdgpu_drv.h | 2 ++ src/amdgpu_glamor.c | 3 ++- src/amdgpu_kms.c | 77 ++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 66 insertions(+), 16 deletions(-) diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h index 60aa0be..d2b3a6b 100644 --- a/src/amdgpu_drv.h +++ b/src/amdgpu_drv.h @@ -209,6 +209,8 @@ typedef struct { /* accel */ PixmapPtr fbcon_pixmap; + int callback_event_type; + uint_fast32_t callback_needs_flush; uint_fast32_t gpu_flushed; uint_fast32_t gpu_synced; Bool use_glamor; diff --git a/src/amdgpu_glamor.c b/src/amdgpu_glamor.c index 62831d0..d29b096 100644 --- a/src/amdgpu_glamor.c +++ b/src/amdgpu_glamor.c @@ -460,8 +460,9 @@ void amdgpu_glamor_flush(ScrnInfoPtr pScrn) if (info->use_glamor) { glamor_block_handler(pScrn->pScreen); - info->gpu_flushed++; } + + info->gpu_flushed++; } void amdgpu_glamor_finish(ScrnInfoPtr pScrn) diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c index 9f023cf..b1f6bd7 100644 --- a/src/amdgpu_kms.c +++ b/src/amdgpu_kms.c @@ -50,6 +50,8 @@ #include <X11/extensions/dpms.h> #endif +#include <X11/extensions/damageproto.h> + #include "amdgpu_chipinfo_gen.h" #include "amdgpu_bo_helper.h" #include "amdgpu_pixmap.h" @@ -163,8 +165,51 @@ amdgpuUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) shadowUpdatePacked(pScreen, pBuf); } +static Bool +callback_needs_flush(AMDGPUInfoPtr info) +{ + return (int)(info->callback_needs_flush - info->gpu_flushed) > 0; +} + +static void +amdgpu_event_callback(CallbackListPtr *list, + pointer user_data, pointer call_data) +{ + EventInfoRec *eventinfo = call_data; + ScrnInfoPtr pScrn = user_data; + AMDGPUInfoPtr info = AMDGPUPTR(pScrn); + int i; + + if (callback_needs_flush(info)) + return; + + /* Don't let gpu_flushed get too far ahead of callback_needs_flush, + * in order to prevent false positives in callback_needs_flush() + */ + info->callback_needs_flush = info->gpu_flushed; + + for (i = 0; i < eventinfo->count; i++) { + if (eventinfo->events[i].u.u.type == info->callback_event_type) { + info->callback_needs_flush++; + return; + } + } +} + +static void +amdgpu_flush_callback(CallbackListPtr *list, + pointer user_data, pointer call_data) +{ + ScrnInfoPtr pScrn = user_data; + AMDGPUInfoPtr info = AMDGPUPTR(pScrn); + + if (pScrn->vtSema && callback_needs_flush(info)) + amdgpu_glamor_flush(pScrn); +} + static Bool AMDGPUCreateScreenResources_KMS(ScreenPtr pScreen) { + ExtensionEntry *damage_ext = CheckExtension("DAMAGE"); ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); AMDGPUInfoPtr info = AMDGPUPTR(pScrn); PixmapPtr pixmap; @@ -217,6 +262,19 @@ static Bool AMDGPUCreateScreenResources_KMS(ScreenPtr pScreen) if (info->use_glamor) amdgpu_glamor_create_screen_resources(pScreen); + info->callback_event_type = -1; + if (damage_ext) { + info->callback_event_type = damage_ext->eventBase + XDamageNotify; + + if (!AddCallback(&FlushCallback, amdgpu_flush_callback, pScrn)) + return FALSE; + + if (!AddCallback(&EventCallback, amdgpu_event_callback, pScrn)) { + DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn); + return FALSE; + } + } + return TRUE; } @@ -542,17 +600,6 @@ static void AMDGPUBlockHandler_oneshot(BLOCKHANDLER_ARGS_DECL) drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE); } -static void -amdgpu_flush_callback(CallbackListPtr * list, - pointer user_data, pointer call_data) -{ - ScrnInfoPtr pScrn = user_data; - - if (pScrn->vtSema) { - amdgpu_glamor_flush(pScrn); - } -} - /* This is called by AMDGPUPreInit to set up the default visual */ static Bool AMDGPUPreInitVisual(ScrnInfoPtr pScrn) { @@ -1108,7 +1155,10 @@ static Bool AMDGPUCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL) drmmode_uevent_fini(pScrn, &info->drmmode); amdgpu_drm_queue_close(pScrn); - DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn); + if (info->callback_event_type != -1) { + DeleteCallback(&EventCallback, amdgpu_event_callback, pScrn); + DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn); + } amdgpu_sync_close(pScreen); amdgpu_drop_drm_master(pScrn); @@ -1347,9 +1397,6 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL) info->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = AMDGPUBlockHandler_oneshot; - if (!AddCallback(&FlushCallback, amdgpu_flush_callback, pScrn)) - return FALSE; - info->CreateScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = AMDGPUCreateScreenResources_KMS; -- 2.9.3 _______________________________________________ amd-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/amd-gfx
