xf86-video-ati: Branch 'master' - 2 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Aug 3 16:31:09 UTC 2018


 src/drmmode_display.c |   47 ++++++++++++++++++++++++++---------------------
 src/drmmode_display.h |    2 +-
 src/radeon_dri3.c     |    1 +
 3 files changed, 28 insertions(+), 22 deletions(-)

New commits:
commit 740f0850f1e40403c8dd727e074eae36caeb1f63
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Aug 2 18:49:48 2018 +0200

    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 <alexander.deucher at amd.com>

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 {
commit ef2a6b818fa47ad571bb0bc105aa8193d51a2190
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Aug 2 18:48:04 2018 +0200

    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 <alexander.deucher at amd.com>

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;
 			}
 


More information about the xorg-commit mailing list