- U_01-* ... U_20-* : Include patches that haven't made it into the 7.7.1 release. This means almost all commits between xf86-video-ati-7.7.0 and 12d30eeb9711bd2b1609d6bbb74c4a1760596f72. Fixes (bsc#990066). OBS-URL: https://build.opensuse.org/request/show/438260 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xf86-video-ati?expand=0&rev=51
171 lines
5.1 KiB
Diff
171 lines
5.1 KiB
Diff
From: Michel Dänzer <michel.daenzer@amd.com>
|
|
Date: Mon Jul 11 12:22:09 2016 +0900
|
|
Subject: [PATCH 10/20]Use EventCallback to avoid flushing every time in the FlushCallback
|
|
Patch-mainline: Upstream
|
|
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
|
Git-commit: 9a1afbf61fbb2827c86bd86d295fa0848980d60b
|
|
References: bsc#990066
|
|
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
|
|
|
We only need to flush for XDamageNotify events.
|
|
|
|
Significantly reduces compositing slowdown due to flushing overhead, in
|
|
particular with glamor.
|
|
|
|
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
|
---
|
|
src/radeon.h | 2 ++
|
|
src/radeon_kms.c | 79 +++++++++++++++++++++++++++++++++++++++++++++-----------
|
|
2 files changed, 66 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/src/radeon.h b/src/radeon.h
|
|
index 37d5fb6..25ff61c 100644
|
|
--- a/src/radeon.h
|
|
+++ b/src/radeon.h
|
|
@@ -473,6 +473,8 @@ typedef struct {
|
|
Bool RenderAccel; /* Render */
|
|
Bool allowColorTiling;
|
|
Bool allowColorTiling2D;
|
|
+ int callback_event_type;
|
|
+ uint_fast32_t callback_needs_flush;
|
|
uint_fast32_t gpu_flushed;
|
|
uint_fast32_t gpu_synced;
|
|
struct radeon_accel_state *accel_state;
|
|
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
|
index a618513..f778d30 100644
|
|
--- a/src/radeon_kms.c
|
|
+++ b/src/radeon_kms.c
|
|
@@ -51,6 +51,8 @@
|
|
#include <X11/extensions/dpms.h>
|
|
#endif
|
|
|
|
+#include <X11/extensions/damageproto.h>
|
|
+
|
|
#include "radeon_chipinfo_gen.h"
|
|
|
|
#include "radeon_bo_gem.h"
|
|
@@ -91,10 +93,11 @@ void radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
|
|
struct radeon_accel_state *accel_state;
|
|
int ret;
|
|
|
|
+ info->gpu_flushed++;
|
|
+
|
|
#ifdef USE_GLAMOR
|
|
if (info->use_glamor) {
|
|
glamor_block_handler(pScrn->pScreen);
|
|
- info->gpu_flushed++;
|
|
return;
|
|
}
|
|
#endif
|
|
@@ -237,8 +240,51 @@ radeonUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
|
|
shadowUpdatePacked(pScreen, pBuf);
|
|
}
|
|
|
|
+static Bool
|
|
+callback_needs_flush(RADEONInfoPtr info)
|
|
+{
|
|
+ return (int)(info->callback_needs_flush - info->gpu_flushed) > 0;
|
|
+}
|
|
+
|
|
+static void
|
|
+radeon_event_callback(CallbackListPtr *list,
|
|
+ pointer user_data, pointer call_data)
|
|
+{
|
|
+ EventInfoRec *eventinfo = call_data;
|
|
+ ScrnInfoPtr pScrn = user_data;
|
|
+ RADEONInfoPtr info = RADEONPTR(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
|
|
+radeon_flush_callback(CallbackListPtr *list,
|
|
+ pointer user_data, pointer call_data)
|
|
+{
|
|
+ ScrnInfoPtr pScrn = user_data;
|
|
+ RADEONInfoPtr info = RADEONPTR(pScrn);
|
|
+
|
|
+ if (pScrn->vtSema && callback_needs_flush(info))
|
|
+ radeon_cs_flush_indirect(pScrn);
|
|
+}
|
|
+
|
|
static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
|
{
|
|
+ ExtensionEntry *damage_ext = CheckExtension("DAMAGE");
|
|
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
|
|
RADEONInfoPtr info = RADEONPTR(pScrn);
|
|
PixmapPtr pixmap;
|
|
@@ -294,6 +340,19 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
|
if (info->use_glamor)
|
|
radeon_glamor_create_screen_resources(pScreen);
|
|
|
|
+ info->callback_event_type = -1;
|
|
+ if (damage_ext) {
|
|
+ info->callback_event_type = damage_ext->eventBase + XDamageNotify;
|
|
+
|
|
+ if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn))
|
|
+ return FALSE;
|
|
+
|
|
+ if (!AddCallback(&EventCallback, radeon_event_callback, pScrn)) {
|
|
+ DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
|
|
+ return FALSE;
|
|
+ }
|
|
+ }
|
|
+
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -641,16 +700,6 @@ static void RADEONBlockHandler_oneshot(BLOCKHANDLER_ARGS_DECL)
|
|
drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE);
|
|
}
|
|
|
|
-static void
|
|
-radeon_flush_callback(CallbackListPtr *list,
|
|
- pointer user_data, pointer call_data)
|
|
-{
|
|
- ScrnInfoPtr pScrn = user_data;
|
|
-
|
|
- if (pScrn->vtSema)
|
|
- radeon_cs_flush_indirect(pScrn);
|
|
-}
|
|
-
|
|
static Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn)
|
|
{
|
|
RADEONInfoPtr info = RADEONPTR(pScrn);
|
|
@@ -1564,7 +1613,10 @@ static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
|
|
radeon_drm_queue_close(pScrn);
|
|
radeon_cs_flush_indirect(pScrn);
|
|
|
|
- DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
|
|
+ if (info->callback_event_type != -1) {
|
|
+ DeleteCallback(&EventCallback, radeon_event_callback, pScrn);
|
|
+ DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
|
|
+ }
|
|
|
|
if (info->accel_state->exa) {
|
|
exaDriverFini(pScreen);
|
|
@@ -1838,9 +1890,6 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
|
|
info->BlockHandler = pScreen->BlockHandler;
|
|
pScreen->BlockHandler = RADEONBlockHandler_oneshot;
|
|
|
|
- if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn))
|
|
- return FALSE;
|
|
-
|
|
info->CreateScreenResources = pScreen->CreateScreenResources;
|
|
pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
|
|
|