xf86-video-ati: Branch 'master'

Michel Dänzer daenzer at kemper.freedesktop.org
Tue Aug 2 07:37:13 UTC 2016


 src/radeon.h     |    2 +
 src/radeon_kms.c |   79 ++++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 66 insertions(+), 15 deletions(-)

New commits:
commit 9a1afbf61fbb2827c86bd86d295fa0848980d60b
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Mon Jul 11 12:22:09 2016 +0900

    Use EventCallback to avoid flushing every time in the FlushCallback
    
    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 at amd.com>

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 122b932..da11358 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;
 


More information about the xorg-commit mailing list