All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH xf86-video-ati 1/4] Factor out transform_region helper
@ 2016-09-02 10:03 Michel Dänzer
       [not found] ` <20160902100331.7545-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Michel Dänzer @ 2016-09-02 10:03 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Michel Dänzer <michel.daenzer@amd.com>

While we're at it, fix leaking the memory allocated for xRectangles.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
---
 src/radeon_kms.c | 73 +++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 43 insertions(+), 30 deletions(-)

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 711e84a..7173b77 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -382,6 +382,45 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
 }
 
 #ifdef RADEON_PIXMAP_SHARING
+
+static RegionPtr
+transform_region(RegionPtr region, struct pict_f_transform *transform,
+		 int w, int h)
+{
+	BoxPtr boxes = RegionRects(region);
+	int nboxes = RegionNumRects(region);
+	xRectanglePtr rects = malloc(nboxes * sizeof(*rects));
+	RegionPtr transformed;
+	int nrects = 0;
+	BoxRec box;
+	int i;
+
+	for (i = 0; i < nboxes; i++) {
+		box.x1 = boxes[i].x1;
+		box.x2 = boxes[i].x2;
+		box.y1 = boxes[i].y1;
+		box.y2 = boxes[i].y2;
+		pixman_f_transform_bounds(transform, &box);
+
+		box.x1 = max(box.x1, 0);
+		box.y1 = max(box.y1, 0);
+		box.x2 = min(box.x2, w);
+		box.y2 = min(box.y2, h);
+		if (box.x1 >= box.x2 || box.y1 >= box.y2)
+			continue;
+
+		rects[nrects].x = box.x1;
+		rects[nrects].y = box.y1;
+		rects[nrects].width = box.x2 - box.x1;
+		rects[nrects].height = box.y2 - box.y1;
+		nrects++;
+	}
+
+	transformed = RegionFromRects(nrects, rects, CT_UNSORTED);
+	free(rects);
+	return transformed;
+}
+
 static RegionPtr
 dirty_region(PixmapDirtyUpdatePtr dirty)
 {
@@ -390,36 +429,10 @@ dirty_region(PixmapDirtyUpdatePtr dirty)
 
 #ifdef HAS_DIRTYTRACKING_ROTATION
 	if (dirty->rotation != RR_Rotate_0) {
-		BoxPtr boxes = RegionRects(damageregion);
-		int nboxes = RegionNumRects(damageregion);
-		xRectanglePtr rects = malloc(nboxes * sizeof(*rects));
-		int dst_w = dirty->slave_dst->drawable.width;
-		int dst_h = dirty->slave_dst->drawable.height;
-		int nrects = 0;
-		BoxRec box;
-		int i;
-
-		for (i = 0; i < nboxes; i++) {
-			box.x1 = boxes[i].x1;
-			box.x2 = boxes[i].x2;
-			box.y1 = boxes[i].y1;
-			box.y2 = boxes[i].y2;
-			pixman_f_transform_bounds(&dirty->f_inverse, &box);
-
-			box.x1 = max(box.x1, 0);
-			box.y1 = max(box.y1, 0);
-			box.x2 = min(box.x2, dst_w);
-			box.y2 = min(box.y2, dst_h);
-			if (box.x1 >= box.x2 || box.y1 >= box.y2)
-				continue;
-
-			rects[nrects].x = box.x1;
-			rects[nrects].y = box.y1;
-			rects[nrects].width = box.x2 - box.x1;
-			rects[nrects].height = box.y2 - box.y1;
-			nrects++;
-		}
-		dstregion = RegionFromRects(nrects, rects, CT_UNSORTED);
+		dstregion = transform_region(damageregion,
+					     &dirty->f_inverse,
+					     dirty->slave_dst->drawable.width,
+					     dirty->slave_dst->drawable.height);
 	} else
 #endif
 	{
-- 
2.9.3

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH xf86-video-ati 2/4] Move up radeon_scanout_extents_intersect
       [not found] ` <20160902100331.7545-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
@ 2016-09-02 10:03   ` Michel Dänzer
  2016-09-02 10:03   ` [PATCH xf86-video-ati 3/4] Synchronize scanout pixmaps for TearFree Michel Dänzer
  2016-09-02 10:03   ` [PATCH xf86-video-ati 4/4] Make TearFree effective with PRIME slave scanout Michel Dänzer
  2 siblings, 0 replies; 5+ messages in thread
From: Michel Dänzer @ 2016-09-02 10:03 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Michel Dänzer <michel.daenzer@amd.com>

Will be needed higher up by the following changes. No functional change.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
---
 src/radeon_kms.c | 42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 7173b77..568c49e 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -381,6 +381,27 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
     return TRUE;
 }
 
+static Bool
+radeon_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents, int w,
+				 int h)
+{
+    extents->x1 = max(extents->x1 - xf86_crtc->x, 0);
+    extents->y1 = max(extents->y1 - xf86_crtc->y, 0);
+
+    switch (xf86_crtc->rotation & 0xf) {
+    case RR_Rotate_90:
+    case RR_Rotate_270:
+	extents->x2 = min(extents->x2 - xf86_crtc->x, h);
+	extents->y2 = min(extents->y2 - xf86_crtc->y, w);
+	break;
+    default:
+	extents->x2 = min(extents->x2 - xf86_crtc->x, w);
+	extents->y2 = min(extents->y2 - xf86_crtc->y, h);
+    }
+
+    return (extents->x1 < extents->x2 && extents->y1 < extents->y2);
+}
+
 #ifdef RADEON_PIXMAP_SHARING
 
 static RegionPtr
@@ -636,27 +657,6 @@ radeon_dirty_update(ScrnInfoPtr scrn)
 #endif
 
 static Bool
-radeon_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents, int w,
-				 int h)
-{
-    extents->x1 = max(extents->x1 - xf86_crtc->x, 0);
-    extents->y1 = max(extents->y1 - xf86_crtc->y, 0);
-
-    switch (xf86_crtc->rotation & 0xf) {
-    case RR_Rotate_90:
-    case RR_Rotate_270:
-	extents->x2 = min(extents->x2 - xf86_crtc->x, h);
-	extents->y2 = min(extents->y2 - xf86_crtc->y, w);
-	break;
-    default:
-	extents->x2 = min(extents->x2 - xf86_crtc->x, w);
-	extents->y2 = min(extents->y2 - xf86_crtc->y, h);
-    }
-
-    return (extents->x1 < extents->x2 && extents->y1 < extents->y2);
-}
-
-static Bool
 radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
 {
     drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
-- 
2.9.3

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH xf86-video-ati 3/4] Synchronize scanout pixmaps for TearFree
       [not found] ` <20160902100331.7545-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
  2016-09-02 10:03   ` [PATCH xf86-video-ati 2/4] Move up radeon_scanout_extents_intersect Michel Dänzer
@ 2016-09-02 10:03   ` Michel Dänzer
  2016-09-02 10:03   ` [PATCH xf86-video-ati 4/4] Make TearFree effective with PRIME slave scanout Michel Dänzer
  2 siblings, 0 replies; 5+ messages in thread
From: Michel Dänzer @ 2016-09-02 10:03 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Michel Dänzer <michel.daenzer@amd.com>

Copy the damaged areas which are still valid in the other scanout pixmap
from there, then only copy the remaining damaged area from the screen
pixmap.

This is slightly more efficient, and will be significantly more efficient
with the following change.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
---
 src/drmmode_display.c | 95 +++++++++++++++++++++++++--------------------------
 src/drmmode_display.h |  3 +-
 src/radeon_kms.c      | 92 ++++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 124 insertions(+), 66 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 2afeeb0..2b80c21 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -523,10 +523,20 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
 		radeon_bo_unref(scanout->bo);
 		scanout->bo = NULL;
 	}
+}
 
-	if (scanout->damage) {
-		DamageDestroy(scanout->damage);
-		scanout->damage = NULL;
+static void
+drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc)
+{
+	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
+				     &drmmode_crtc->scanout[0]);
+	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
+				     &drmmode_crtc->scanout[1]);
+
+	if (drmmode_crtc->scanout_damage) {
+		DamageDestroy(drmmode_crtc->scanout_damage);
+		drmmode_crtc->scanout_damage = NULL;
+		RegionUninit(&drmmode_crtc->scanout_last_region);
 	}
 }
 
@@ -536,15 +546,8 @@ drmmode_scanout_free(ScrnInfoPtr scrn)
 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 	int c;
 
-	for (c = 0; c < xf86_config->num_crtc; c++) {
-		drmmode_crtc_private_ptr drmmode_crtc =
-			xf86_config->crtc[c]->driver_private;
-
-		drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
-					     &drmmode_crtc->scanout[0]);
-		drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
-					     &drmmode_crtc->scanout[1]);
-	}
+	for (c = 0; c < xf86_config->num_crtc; c++)
+		drmmode_crtc_scanout_free(xf86_config->crtc[c]->driver_private);
 }
 
 static void *
@@ -797,8 +800,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 			fb_id = drmmode_crtc->rotate.fb_id;
 			x = y = 0;
 
-			drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[0]);
-			drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]);
+			drmmode_crtc_scanout_free(drmmode_crtc);
 		} else if (
 #ifdef RADEON_PIXMAP_SHARING
 			!pScreen->isGPU &&
@@ -813,42 +815,40 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 							    &drmmode_crtc->scanout[i],
 							    mode->HDisplay,
 							    mode->VDisplay);
-
-				if (drmmode_crtc->scanout[i].pixmap) {
-					RegionPtr pRegion;
-					BoxPtr pBox;
-
-					if (!drmmode_crtc->scanout[i].damage) {
-						drmmode_crtc->scanout[i].damage =
-							DamageCreate(radeon_screen_damage_report,
-								     NULL, DamageReportRawRegion,
-								     TRUE, pScreen, NULL);
-						DamageRegister(&pScreen->GetScreenPixmap(pScreen)->drawable,
-							       drmmode_crtc->scanout[i].damage);
-					}
-
-					pRegion = DamageRegion(drmmode_crtc->scanout[i].damage);
-					RegionUninit(pRegion);
-					pRegion->data = NULL;
-					pBox = RegionExtents(pRegion);
-					pBox->x1 = min(pBox->x1, x);
-					pBox->y1 = min(pBox->y1, y);
-
-					switch (crtc->rotation & 0xf) {
-					case RR_Rotate_90:
-					case RR_Rotate_270:
-						pBox->x2 = max(pBox->x2, x + mode->VDisplay);
-						pBox->y2 = max(pBox->y2, y + mode->HDisplay);
-						break;
-					default:
-						pBox->x2 = max(pBox->x2, x + mode->HDisplay);
-						pBox->y2 = max(pBox->y2, y + mode->VDisplay);
-					}
-				}
 			}
 
 			if (drmmode_crtc->scanout[0].pixmap &&
 			    (!info->tear_free || drmmode_crtc->scanout[1].pixmap)) {
+				RegionPtr pRegion;
+				BoxPtr pBox;
+
+				if (!drmmode_crtc->scanout_damage) {
+					drmmode_crtc->scanout_damage =
+						DamageCreate(radeon_screen_damage_report,
+							     NULL, DamageReportRawRegion,
+							     TRUE, pScreen, NULL);
+					DamageRegister(&pScreen->GetScreenPixmap(pScreen)->drawable,
+						       drmmode_crtc->scanout_damage);
+				}
+
+				pRegion = DamageRegion(drmmode_crtc->scanout_damage);
+				RegionUninit(pRegion);
+				pRegion->data = NULL;
+				pBox = RegionExtents(pRegion);
+				pBox->x1 = min(pBox->x1, x);
+				pBox->y1 = min(pBox->y1, y);
+
+				switch (crtc->rotation & 0xf) {
+				case RR_Rotate_90:
+				case RR_Rotate_270:
+					pBox->x2 = max(pBox->x2, x + mode->VDisplay);
+					pBox->y2 = max(pBox->y2, y + mode->HDisplay);
+					break;
+				default:
+					pBox->x2 = max(pBox->x2, x + mode->HDisplay);
+					pBox->y2 = max(pBox->y2, y + mode->VDisplay);
+				}
+
 				drmmode_crtc->scanout_id = 0;
 				fb_id = drmmode_crtc->scanout[0].fb_id;
 				x = y = 0;
@@ -1125,8 +1125,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 		if (crtc->randr_crtc->scanout_pixmap)
 			PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap,
 						drmmode_crtc->scanout[0].pixmap);
-		drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
-					     &drmmode_crtc->scanout[0]);
+		drmmode_crtc_scanout_free(drmmode_crtc);
 		return TRUE;
 	}
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 53c7926..5df9773 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -73,7 +73,6 @@ typedef struct {
 struct drmmode_scanout {
     struct radeon_bo *bo;
     PixmapPtr pixmap;
-    DamagePtr damage;
     unsigned fb_id;
     int width, height;
 };
@@ -85,6 +84,8 @@ typedef struct {
     struct radeon_bo *cursor_bo;
     struct drmmode_scanout rotate;
     struct drmmode_scanout scanout[2];
+    DamagePtr scanout_damage;
+    RegionRec scanout_last_region;
     unsigned scanout_id;
     Bool scanout_update_pending;
     int dpms_mode;
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 568c49e..bcaa024 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -402,8 +402,6 @@ radeon_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents, int w,
     return (extents->x1 < extents->x2 && extents->y1 < extents->y2);
 }
 
-#ifdef RADEON_PIXMAP_SHARING
-
 static RegionPtr
 transform_region(RegionPtr region, struct pict_f_transform *transform,
 		 int w, int h)
@@ -442,6 +440,70 @@ transform_region(RegionPtr region, struct pict_f_transform *transform,
 	return transformed;
 }
 
+static void
+radeon_sync_scanout_pixmaps(xf86CrtcPtr xf86_crtc, RegionPtr new_region,
+			    int scanout_id)
+{
+    drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
+    DrawablePtr dst = &drmmode_crtc->scanout[scanout_id].pixmap->drawable;
+    DrawablePtr src = &drmmode_crtc->scanout[scanout_id ^ 1].pixmap->drawable;
+    RegionPtr last_region = &drmmode_crtc->scanout_last_region;
+    ScrnInfoPtr scrn = xf86_crtc->scrn;
+    ScreenPtr pScreen = scrn->pScreen;
+    RADEONInfoPtr info = RADEONPTR(scrn);
+    RegionRec remaining;
+    RegionPtr sync_region = NULL;
+    BoxRec extents;
+    Bool force;
+    GCPtr gc;
+
+    if (RegionNil(last_region))
+	return;
+
+    RegionNull(&remaining);
+    RegionSubtract(&remaining, last_region, new_region);
+    if (RegionNil(&remaining))
+	goto uninit;
+
+    extents = *RegionExtents(&remaining);
+    if (!radeon_scanout_extents_intersect(xf86_crtc, &extents, dst->width,
+					  dst->height))
+	goto uninit;
+
+#if XF86_CRTC_VERSION >= 4
+    if (xf86_crtc->driverIsPerformingTransform) {
+	sync_region = transform_region(&remaining,
+				       &xf86_crtc->f_framebuffer_to_crtc,
+				       dst->width, dst->height);
+    } else
+#endif /* XF86_CRTC_VERSION >= 4 */
+    {
+	sync_region = RegionDuplicate(&remaining);
+	RegionTranslate(sync_region, -xf86_crtc->x, -xf86_crtc->y);
+    }
+
+    force = info->accel_state->force;
+    info->accel_state->force = TRUE;
+
+    gc = GetScratchGC(dst->depth, pScreen);
+    if (gc) {
+	ValidateGC(dst, gc);
+	gc->funcs->ChangeClip(gc, CT_REGION, sync_region, 0);
+	sync_region = NULL;
+	gc->ops->CopyArea(src, dst, gc, 0, 0, dst->width, dst->height, 0, 0);
+	FreeScratchGC(gc);
+    }
+
+    info->accel_state->force = force;
+
+ uninit:
+    if (sync_region)
+	RegionDestroy(sync_region);
+    RegionUninit(&remaining);
+}
+
+#ifdef RADEON_PIXMAP_SHARING
+
 static RegionPtr
 dirty_region(PixmapDirtyUpdatePtr dirty)
 {
@@ -660,13 +722,12 @@ static Bool
 radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
 {
     drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
-    ScrnInfoPtr scrn;
-    DamagePtr pDamage;
-    RegionPtr pRegion;
+    RegionPtr pRegion = DamageRegion(drmmode_crtc->scanout_damage);
+    ScrnInfoPtr scrn = xf86_crtc->scrn;
+    ScreenPtr pScreen = scrn->pScreen;
+    RADEONInfoPtr info = RADEONPTR(scrn);
     DrawablePtr pDraw;
-    ScreenPtr pScreen;
     BoxRec extents;
-    RADEONInfoPtr info;
     Bool force;
 
     if (!xf86_crtc->enabled ||
@@ -674,24 +735,21 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
 	!drmmode_crtc->scanout[scanout_id].pixmap)
 	return FALSE;
 
-    pDamage = drmmode_crtc->scanout[scanout_id].damage;
-    if (!pDamage)
-	return FALSE;
-
-    pRegion = DamageRegion(pDamage);
     if (!RegionNotEmpty(pRegion))
 	return FALSE;
 
     pDraw = &drmmode_crtc->scanout[scanout_id].pixmap->drawable;
-    pScreen = pDraw->pScreen;
     extents = *RegionExtents(pRegion);
-    RegionEmpty(pRegion);
     if (!radeon_scanout_extents_intersect(xf86_crtc, &extents, pDraw->width,
 					  pDraw->height))
 	return FALSE;
 
-    scrn = xf86_crtc->scrn;
-    info = RADEONPTR(scrn);
+    if (info->tear_free) {
+	radeon_sync_scanout_pixmaps(xf86_crtc, pRegion, scanout_id);
+	RegionCopy(&drmmode_crtc->scanout_last_region, pRegion);
+    }
+    RegionEmpty(pRegion);
+
     force = info->accel_state->force;
     info->accel_state->force = TRUE;
 
@@ -807,7 +865,7 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc)
 	drmmode_crtc->pending_dpms_mode != DPMSModeOn)
 	return;
 
-    pDamage = drmmode_crtc->scanout[0].damage;
+    pDamage = drmmode_crtc->scanout_damage;
     if (!pDamage)
 	return;
 
-- 
2.9.3

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH xf86-video-ati 4/4] Make TearFree effective with PRIME slave scanout
       [not found] ` <20160902100331.7545-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
  2016-09-02 10:03   ` [PATCH xf86-video-ati 2/4] Move up radeon_scanout_extents_intersect Michel Dänzer
  2016-09-02 10:03   ` [PATCH xf86-video-ati 3/4] Synchronize scanout pixmaps for TearFree Michel Dänzer
@ 2016-09-02 10:03   ` Michel Dänzer
       [not found]     ` <20160902100331.7545-4-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
  2 siblings, 1 reply; 5+ messages in thread
From: Michel Dänzer @ 2016-09-02 10:03 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Michel Dänzer <michel.daenzer@amd.com>

TearFree can now prevent tearing with any possible display
configuration.

Note that with PRIME slave scanout, there may still be inter-GPU tearing
if the primary GPU uses a different driver.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
---
 src/drmmode_display.c |  33 ++++++++++++---
 src/drmmode_display.h |   1 +
 src/radeon_kms.c      | 110 ++++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 131 insertions(+), 13 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 2b80c21..34f7735 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -528,10 +528,19 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
 static void
 drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc)
 {
-	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
-				     &drmmode_crtc->scanout[0]);
-	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
-				     &drmmode_crtc->scanout[1]);
+	if (drmmode_crtc->flip_pending) {
+		drmmode_crtc->scanout_destroy[0] = drmmode_crtc->scanout[0];
+		drmmode_crtc->scanout[0].pixmap = NULL;
+		drmmode_crtc->scanout[0].bo = NULL;
+		drmmode_crtc->scanout_destroy[1] = drmmode_crtc->scanout[1];
+		drmmode_crtc->scanout[1].pixmap = NULL;
+		drmmode_crtc->scanout[1].bo = NULL;
+	} else {
+		drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
+					     &drmmode_crtc->scanout[0]);
+		drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
+					     &drmmode_crtc->scanout[1]);
+	}
 
 	if (drmmode_crtc->scanout_damage) {
 		DamageDestroy(drmmode_crtc->scanout_damage);
@@ -1120,11 +1129,12 @@ static Bool
 drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
 
 	if (!ppix) {
 		if (crtc->randr_crtc->scanout_pixmap)
 			PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap,
-						drmmode_crtc->scanout[0].pixmap);
+						drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap);
 		drmmode_crtc_scanout_free(drmmode_crtc);
 		return TRUE;
 	}
@@ -1134,6 +1144,14 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 					 ppix->drawable.height))
 		return FALSE;
 
+	if (info->tear_free &&
+	    !drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
+					 ppix->drawable.width,
+					 ppix->drawable.height)) {
+		drmmode_crtc_scanout_free(drmmode_crtc);
+		return FALSE;
+	}
+
 #ifdef HAS_DIRTYTRACKING_ROTATION
 	PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[0].pixmap,
 				 0, 0, 0, 0, RR_Rotate_0);
@@ -2200,6 +2218,11 @@ drmmode_clear_pending_flip(xf86CrtcPtr crtc)
 
 		drmmode_crtc_dpms(crtc, drmmode_crtc->pending_dpms_mode);
 	}
+
+	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
+				     &drmmode_crtc->scanout_destroy[0]);
+	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
+				     &drmmode_crtc->scanout_destroy[1]);
 }
 
 static void
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 5df9773..7602eb8 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -84,6 +84,7 @@ typedef struct {
     struct radeon_bo *cursor_bo;
     struct drmmode_scanout rotate;
     struct drmmode_scanout scanout[2];
+    struct drmmode_scanout scanout_destroy[2];
     DamagePtr scanout_damage;
     RegionRec scanout_last_region;
     unsigned scanout_id;
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index bcaa024..3418716 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -597,31 +597,55 @@ slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
     return slave_scrn->driverName == scrn->driverName;
 }
 
-void
-radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
-				    void *event_data)
+static Bool
+radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
 {
     ScrnInfoPtr scrn = crtc->scrn;
     ScreenPtr screen = scrn->pScreen;
+    RADEONInfoPtr info = RADEONPTR(scrn);
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
     PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
     PixmapDirtyUpdatePtr dirty;
+    Bool ret = FALSE;
 
     xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
-	if (dirty->src == scanoutpix &&
-	    dirty->slave_dst == drmmode_crtc->scanout[0].pixmap) {
+	if (dirty->src == scanoutpix) {
 	    RegionPtr region;
 
 	    if (master_has_sync_shared_pixmap(scrn, dirty))
 		radeon_sync_shared_pixmap(dirty);
 
 	    region = dirty_region(dirty);
+	    if (RegionNil(region))
+		goto destroy;
+
+	    if (info->tear_free) {
+		RegionTranslate(region, crtc->x, crtc->y);
+		radeon_sync_scanout_pixmaps(crtc, region, 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;
+	    }
+
 	    redisplay_dirty(dirty, region);
+	    ret = TRUE;
+	destroy:
 	    RegionDestroy(region);
 	    break;
 	}
     }
 
+    return ret;
+}
+
+void
+radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
+				    void *event_data)
+{
+    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+    radeon_prime_scanout_do_update(crtc, 0);
     drmmode_crtc->scanout_update_pending = FALSE;
 }
 
@@ -679,8 +703,74 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
 }
 
 static void
+radeon_prime_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data)
+{
+    drmmode_crtc_private_ptr drmmode_crtc = event_data;
+
+    drmmode_crtc->scanout_update_pending = FALSE;
+    drmmode_clear_pending_flip(crtc);
+}
+
+static void
+radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
+{
+    ScreenPtr screen = ent->slave_dst->drawable.pScreen;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CrtcPtr crtc = NULL;
+    drmmode_crtc_private_ptr drmmode_crtc = NULL;
+    uintptr_t drm_queue_seq;
+    unsigned scanout_id;
+    int c;
+
+    /* Find the CRTC which is scanning out from this slave pixmap */
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	crtc = xf86_config->crtc[c];
+	drmmode_crtc = crtc->driver_private;
+	scanout_id = drmmode_crtc->scanout_id;
+	if (drmmode_crtc->scanout[scanout_id].pixmap == ent->slave_dst)
+	    break;
+    }
+
+    if (c == xf86_config->num_crtc ||
+	!crtc->enabled ||
+	drmmode_crtc->scanout_update_pending ||
+	!drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap ||
+	drmmode_crtc->pending_dpms_mode != DPMSModeOn)
+	return;
+
+    scanout_id = drmmode_crtc->scanout_id ^ 1;
+    if (!radeon_prime_scanout_do_update(crtc, scanout_id))
+	return;
+
+    drm_queue_seq = radeon_drm_queue_alloc(crtc,
+					   RADEON_DRM_QUEUE_CLIENT_DEFAULT,
+					   RADEON_DRM_QUEUE_ID_DEFAULT,
+					   drmmode_crtc, NULL,
+					   radeon_prime_scanout_flip_abort);
+    if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+		   "Allocating DRM event queue entry failed for PRIME flip.\n");
+	return;
+    }
+
+    if (drmModePageFlip(drmmode_crtc->drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+			drmmode_crtc->scanout[scanout_id].fb_id,
+			DRM_MODE_PAGE_FLIP_EVENT, (void*)drm_queue_seq)) {
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n",
+		   __func__, strerror(errno));
+	return;
+    }
+
+    drmmode_crtc->scanout_id = scanout_id;
+    drmmode_crtc->scanout_update_pending = TRUE;
+    drmmode_crtc->flip_pending = TRUE;
+}
+
+static void
 radeon_dirty_update(ScrnInfoPtr scrn)
 {
+	RADEONInfoPtr info = RADEONPTR(scrn);
 	ScreenPtr screen = scrn->pScreen;
 	PixmapDirtyUpdatePtr ent;
 	RegionPtr region;
@@ -700,10 +790,14 @@ radeon_dirty_update(ScrnInfoPtr scrn)
 
 			region = dirty_region(region_ent);
 
-			if (RegionNotEmpty(region))
-				radeon_prime_scanout_update(ent);
-			else
+			if (RegionNotEmpty(region)) {
+				if (info->tear_free)
+					radeon_prime_scanout_flip(ent);
+				else
+					radeon_prime_scanout_update(ent);
+			} else {
 				DamageEmpty(region_ent->damage);
+			}
 
 			RegionDestroy(region);
 		} else {
-- 
2.9.3

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* RE: [PATCH xf86-video-ati 4/4] Make TearFree effective with PRIME slave scanout
       [not found]     ` <20160902100331.7545-4-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
@ 2016-09-02 13:47       ` Deucher, Alexander
  0 siblings, 0 replies; 5+ messages in thread
From: Deucher, Alexander @ 2016-09-02 13:47 UTC (permalink / raw)
  To: 'Michel Dänzer', amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
> Of Michel Dänzer
> Sent: Friday, September 02, 2016 6:04 AM
> To: amd-gfx@lists.freedesktop.org
> Subject: [PATCH xf86-video-ati 4/4] Make TearFree effective with PRIME
> slave scanout
> 
> From: Michel Dänzer <michel.daenzer@amd.com>
> 
> TearFree can now prevent tearing with any possible display
> configuration.
> 
> Note that with PRIME slave scanout, there may still be inter-GPU tearing
> if the primary GPU uses a different driver.
> 
> Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>

For the series:
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  src/drmmode_display.c |  33 ++++++++++++---
>  src/drmmode_display.h |   1 +
>  src/radeon_kms.c      | 110
> ++++++++++++++++++++++++++++++++++++++++++++++----
>  3 files changed, 131 insertions(+), 13 deletions(-)
> 
> diff --git a/src/drmmode_display.c b/src/drmmode_display.c
> index 2b80c21..34f7735 100644
> --- a/src/drmmode_display.c
> +++ b/src/drmmode_display.c
> @@ -528,10 +528,19 @@ drmmode_crtc_scanout_destroy(drmmode_ptr
> drmmode,
>  static void
>  drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc)
>  {
> -	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
> -				     &drmmode_crtc->scanout[0]);
> -	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
> -				     &drmmode_crtc->scanout[1]);
> +	if (drmmode_crtc->flip_pending) {
> +		drmmode_crtc->scanout_destroy[0] = drmmode_crtc-
> >scanout[0];
> +		drmmode_crtc->scanout[0].pixmap = NULL;
> +		drmmode_crtc->scanout[0].bo = NULL;
> +		drmmode_crtc->scanout_destroy[1] = drmmode_crtc-
> >scanout[1];
> +		drmmode_crtc->scanout[1].pixmap = NULL;
> +		drmmode_crtc->scanout[1].bo = NULL;
> +	} else {
> +		drmmode_crtc_scanout_destroy(drmmode_crtc-
> >drmmode,
> +					     &drmmode_crtc->scanout[0]);
> +		drmmode_crtc_scanout_destroy(drmmode_crtc-
> >drmmode,
> +					     &drmmode_crtc->scanout[1]);
> +	}
> 
>  	if (drmmode_crtc->scanout_damage) {
>  		DamageDestroy(drmmode_crtc->scanout_damage);
> @@ -1120,11 +1129,12 @@ static Bool
>  drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
>  {
>  	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
> +	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
> 
>  	if (!ppix) {
>  		if (crtc->randr_crtc->scanout_pixmap)
>  			PixmapStopDirtyTracking(crtc->randr_crtc-
> >scanout_pixmap,
> -						drmmode_crtc-
> >scanout[0].pixmap);
> +						drmmode_crtc-
> >scanout[drmmode_crtc->scanout_id].pixmap);
>  		drmmode_crtc_scanout_free(drmmode_crtc);
>  		return TRUE;
>  	}
> @@ -1134,6 +1144,14 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc,
> PixmapPtr ppix)
>  					 ppix->drawable.height))
>  		return FALSE;
> 
> +	if (info->tear_free &&
> +	    !drmmode_crtc_scanout_create(crtc, &drmmode_crtc-
> >scanout[1],
> +					 ppix->drawable.width,
> +					 ppix->drawable.height)) {
> +		drmmode_crtc_scanout_free(drmmode_crtc);
> +		return FALSE;
> +	}
> +
>  #ifdef HAS_DIRTYTRACKING_ROTATION
>  	PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[0].pixmap,
>  				 0, 0, 0, 0, RR_Rotate_0);
> @@ -2200,6 +2218,11 @@ drmmode_clear_pending_flip(xf86CrtcPtr crtc)
> 
>  		drmmode_crtc_dpms(crtc, drmmode_crtc-
> >pending_dpms_mode);
>  	}
> +
> +	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
> +				     &drmmode_crtc->scanout_destroy[0]);
> +	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
> +				     &drmmode_crtc->scanout_destroy[1]);
>  }
> 
>  static void
> diff --git a/src/drmmode_display.h b/src/drmmode_display.h
> index 5df9773..7602eb8 100644
> --- a/src/drmmode_display.h
> +++ b/src/drmmode_display.h
> @@ -84,6 +84,7 @@ typedef struct {
>      struct radeon_bo *cursor_bo;
>      struct drmmode_scanout rotate;
>      struct drmmode_scanout scanout[2];
> +    struct drmmode_scanout scanout_destroy[2];
>      DamagePtr scanout_damage;
>      RegionRec scanout_last_region;
>      unsigned scanout_id;
> diff --git a/src/radeon_kms.c b/src/radeon_kms.c
> index bcaa024..3418716 100644
> --- a/src/radeon_kms.c
> +++ b/src/radeon_kms.c
> @@ -597,31 +597,55 @@ slave_has_sync_shared_pixmap(ScrnInfoPtr scrn,
> PixmapDirtyUpdatePtr dirty)
>      return slave_scrn->driverName == scrn->driverName;
>  }
> 
> -void
> -radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame,
> uint64_t usec,
> -				    void *event_data)
> +static Bool
> +radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
>  {
>      ScrnInfoPtr scrn = crtc->scrn;
>      ScreenPtr screen = scrn->pScreen;
> +    RADEONInfoPtr info = RADEONPTR(scrn);
>      drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
>      PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
>      PixmapDirtyUpdatePtr dirty;
> +    Bool ret = FALSE;
> 
>      xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
> -	if (dirty->src == scanoutpix &&
> -	    dirty->slave_dst == drmmode_crtc->scanout[0].pixmap) {
> +	if (dirty->src == scanoutpix) {
>  	    RegionPtr region;
> 
>  	    if (master_has_sync_shared_pixmap(scrn, dirty))
>  		radeon_sync_shared_pixmap(dirty);
> 
>  	    region = dirty_region(dirty);
> +	    if (RegionNil(region))
> +		goto destroy;
> +
> +	    if (info->tear_free) {
> +		RegionTranslate(region, crtc->x, crtc->y);
> +		radeon_sync_scanout_pixmaps(crtc, region, 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;
> +	    }
> +
>  	    redisplay_dirty(dirty, region);
> +	    ret = TRUE;
> +	destroy:
>  	    RegionDestroy(region);
>  	    break;
>  	}
>      }
> 
> +    return ret;
> +}
> +
> +void
> +radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame,
> uint64_t usec,
> +				    void *event_data)
> +{
> +    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
> +
> +    radeon_prime_scanout_do_update(crtc, 0);
>      drmmode_crtc->scanout_update_pending = FALSE;
>  }
> 
> @@ -679,8 +703,74 @@
> radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
>  }
> 
>  static void
> +radeon_prime_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data)
> +{
> +    drmmode_crtc_private_ptr drmmode_crtc = event_data;
> +
> +    drmmode_crtc->scanout_update_pending = FALSE;
> +    drmmode_clear_pending_flip(crtc);
> +}
> +
> +static void
> +radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
> +{
> +    ScreenPtr screen = ent->slave_dst->drawable.pScreen;
> +    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> +    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
> +    xf86CrtcPtr crtc = NULL;
> +    drmmode_crtc_private_ptr drmmode_crtc = NULL;
> +    uintptr_t drm_queue_seq;
> +    unsigned scanout_id;
> +    int c;
> +
> +    /* Find the CRTC which is scanning out from this slave pixmap */
> +    for (c = 0; c < xf86_config->num_crtc; c++) {
> +	crtc = xf86_config->crtc[c];
> +	drmmode_crtc = crtc->driver_private;
> +	scanout_id = drmmode_crtc->scanout_id;
> +	if (drmmode_crtc->scanout[scanout_id].pixmap == ent->slave_dst)
> +	    break;
> +    }
> +
> +    if (c == xf86_config->num_crtc ||
> +	!crtc->enabled ||
> +	drmmode_crtc->scanout_update_pending ||
> +	!drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap ||
> +	drmmode_crtc->pending_dpms_mode != DPMSModeOn)
> +	return;
> +
> +    scanout_id = drmmode_crtc->scanout_id ^ 1;
> +    if (!radeon_prime_scanout_do_update(crtc, scanout_id))
> +	return;
> +
> +    drm_queue_seq = radeon_drm_queue_alloc(crtc,
> +
> RADEON_DRM_QUEUE_CLIENT_DEFAULT,
> +
> RADEON_DRM_QUEUE_ID_DEFAULT,
> +					   drmmode_crtc, NULL,
> +					   radeon_prime_scanout_flip_abort);
> +    if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) {
> +	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
> +		   "Allocating DRM event queue entry failed for PRIME
> flip.\n");
> +	return;
> +    }
> +
> +    if (drmModePageFlip(drmmode_crtc->drmmode->fd, drmmode_crtc-
> >mode_crtc->crtc_id,
> +			drmmode_crtc->scanout[scanout_id].fb_id,
> +			DRM_MODE_PAGE_FLIP_EVENT,
> (void*)drm_queue_seq)) {
> +	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s:
> %s\n",
> +		   __func__, strerror(errno));
> +	return;
> +    }
> +
> +    drmmode_crtc->scanout_id = scanout_id;
> +    drmmode_crtc->scanout_update_pending = TRUE;
> +    drmmode_crtc->flip_pending = TRUE;
> +}
> +
> +static void
>  radeon_dirty_update(ScrnInfoPtr scrn)
>  {
> +	RADEONInfoPtr info = RADEONPTR(scrn);
>  	ScreenPtr screen = scrn->pScreen;
>  	PixmapDirtyUpdatePtr ent;
>  	RegionPtr region;
> @@ -700,10 +790,14 @@ radeon_dirty_update(ScrnInfoPtr scrn)
> 
>  			region = dirty_region(region_ent);
> 
> -			if (RegionNotEmpty(region))
> -				radeon_prime_scanout_update(ent);
> -			else
> +			if (RegionNotEmpty(region)) {
> +				if (info->tear_free)
> +					radeon_prime_scanout_flip(ent);
> +				else
> +
> 	radeon_prime_scanout_update(ent);
> +			} else {
>  				DamageEmpty(region_ent->damage);
> +			}
> 
>  			RegionDestroy(region);
>  		} else {
> --
> 2.9.3
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-09-02 13:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-02 10:03 [PATCH xf86-video-ati 1/4] Factor out transform_region helper Michel Dänzer
     [not found] ` <20160902100331.7545-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
2016-09-02 10:03   ` [PATCH xf86-video-ati 2/4] Move up radeon_scanout_extents_intersect Michel Dänzer
2016-09-02 10:03   ` [PATCH xf86-video-ati 3/4] Synchronize scanout pixmaps for TearFree Michel Dänzer
2016-09-02 10:03   ` [PATCH xf86-video-ati 4/4] Make TearFree effective with PRIME slave scanout Michel Dänzer
     [not found]     ` <20160902100331.7545-4-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
2016-09-02 13:47       ` Deucher, Alexander

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.