summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@gmail.com>2016-02-09 16:42:33 +1000
committerDave Airlie <airlied@gmail.com>2016-02-09 16:49:36 +1000
commitbbc826578f17eb6bbf404162892483972de8cbfb (patch)
tree895ca64b90c2486559ded1709489094489e710e4
parentb0c7318ecc3e3817f8cf3519d229640a1ff73712 (diff)
pixmap: add wait shared pixmapprime-fixes
With modesetting/glamor/reverse prime setups, we don't have a decent sync mechanism between master and slave drivers. The drivers each have their own driver pixmap/bo for their side of the shared pixmap so nothing is available to synchronise these. Ideally we'd have cross driver sync objects, but those particular pigs can't fly yet. In lieu of this glFinish is pretty close to the best thing we have, it might be possible to use a glSyncObject to make this a bit lighter, but for now lets try this. This just causes glFinish to be called so the first driver has written all its changes to the shared pixmap before the second driver does things to its side of the shared pixmap. This fixes a wierd lag, if you run X across two GPUs, and then run xsetroot -solid and various values, the slave screens end up a slot behind. Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--dix/pixmap.c13
-rw-r--r--glamor/glamor.c9
-rw-r--r--glamor/glamor.h1
-rw-r--r--hw/xfree86/drivers/modesetting/driver.c11
-rw-r--r--include/pixmap.h3
-rw-r--r--include/scrnintstr.h4
6 files changed, 41 insertions, 0 deletions
diff --git a/dix/pixmap.c b/dix/pixmap.c
index 11d83fe00..a696c92e4 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -392,3 +392,16 @@ Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty)
pScreen->SourceValidate = SourceValidate;
return TRUE;
}
+
+void WaitSharedPixmap(PixmapPtr pSharedPix)
+{
+ ScreenPtr mscreen;
+ if (!pSharedPix->master_pixmap)
+ return;
+
+ mscreen = pSharedPix->master_pixmap->drawable.pScreen;
+ if (!mscreen->WaitSharedPixmap)
+ return;
+
+ mscreen->WaitSharedPixmap(pSharedPix->master_pixmap);
+}
diff --git a/glamor/glamor.c b/glamor/glamor.c
index e9c1d9ed3..f356ab1d2 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -808,3 +808,12 @@ glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
}
return -1;
}
+
+void
+glamor_finish(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ glamor_make_current(glamor_priv);
+ glFinish();
+}
diff --git a/glamor/glamor.h b/glamor/glamor.h
index a73e9eff0..e27033a84 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -336,6 +336,7 @@ extern _X_EXPORT void glamor_destroy_gc(GCPtr gc);
extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
+extern _X_EXPORT void glamor_finish(ScreenPtr screen);
#define HAS_GLAMOR_TEXT 1
#ifdef GLAMOR_FOR_XORG
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 8f60eae57..f5ef17387 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -570,6 +570,7 @@ redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
RegionRec pixregion;
+ WaitSharedPixmap(dirty->slave_dst);
PixmapRegionInit(&pixregion, dirty->slave_dst);
DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
PixmapSyncDirtyHelper(dirty);
@@ -1098,6 +1099,15 @@ SetMaster(ScrnInfoPtr pScrn)
return ret == 0;
}
+static void
+msWaitSharedPixmap(PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+#ifdef GLAMOR_HAS_GBM
+ glamor_finish(pScreen);
+#endif
+}
+
static Bool
ScreenInit(ScreenPtr pScreen, int argc, char **argv)
{
@@ -1217,6 +1227,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
pScreen->SetSharedPixmapBacking = msSetSharedPixmapBacking;
pScreen->StartPixmapTracking = PixmapStartDirtyTracking;
pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
+ pScreen->WaitSharedPixmap = msWaitSharedPixmap;
if (!xf86CrtcScreenInit(pScreen))
return FALSE;
diff --git a/include/pixmap.h b/include/pixmap.h
index c6a773649..c1fc033c0 100644
--- a/include/pixmap.h
+++ b/include/pixmap.h
@@ -130,4 +130,7 @@ PixmapStopDirtyTracking(PixmapPtr src, PixmapPtr slave_dst);
extern _X_EXPORT Bool
PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty);
+extern _X_EXPORT void
+WaitSharedPixmap(PixmapPtr pSharedPix);
+
#endif /* PIXMAP_H */
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 2e617c466..e8087357f 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -358,6 +358,8 @@ typedef WindowPtr (*XYToWindowProcPtr)(ScreenPtr pScreen,
typedef int (*NameWindowPixmapProcPtr)(WindowPtr, PixmapPtr, CARD32);
+typedef void (*WaitSharedPixmapProcPtr)(PixmapPtr);
+
/* Wrapping Screen procedures
There are a few modules in the X server which dynamically add and
@@ -610,6 +612,8 @@ typedef struct _Screen {
ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap;
XYToWindowProcPtr XYToWindow;
+
+ WaitSharedPixmapProcPtr WaitSharedPixmap;
} ScreenRec;
static inline RegionPtr