uxa,sna: Prevent bo exchange when pinned for non-DRI2 clients
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 22 Nov 2013 13:34:35 +0000 (13:34 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 22 Nov 2013 13:37:00 +0000 (13:37 +0000)
With the advent of DRI3 (and previously with Prime and Glamor) we have
external clients who rely on the pixmap<->bo mapping being invariant.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
src/sna/sna.h
src/sna/sna_accel.c
src/sna/sna_dri.c
src/uxa/intel.h
src/uxa/intel_dri.c
src/uxa/intel_uxa.c

index 6474d11..b3e38a3 100644 (file)
@@ -142,10 +142,11 @@ struct sna_pixmap {
 
 #define SOURCE_BIAS 4
        uint16_t source_count;
-       uint8_t pinned :3;
+       uint8_t pinned :4;
 #define PIN_SCANOUT 0x1
-#define PIN_DRI 0x2
-#define PIN_PRIME 0x4
+#define PIN_DRI2 0x2
+#define PIN_DRI3 0x4
+#define PIN_PRIME 0x8
        uint8_t create :4;
        uint8_t mapped :2;
 #define MAPPED_NONE 0
index 7238cbe..a68e5fb 100644 (file)
@@ -1040,7 +1040,7 @@ sna_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle)
                     pixmap->drawable.width, pixmap->drawable.height,
                     pixmap->drawable.serialNumber));
 
-               if (priv->pinned & ~(PIN_DRI | PIN_PRIME)) {
+               if (priv->pinned) {
                        DBG(("%s: can't convert pinned bo\n", __FUNCTION__));
                        return FALSE;
                }
index 5e6d3a7..a218be3 100644 (file)
@@ -248,7 +248,7 @@ sna_dri_create_buffer(DrawablePtr draw,
                        assert(private->pixmap == pixmap);
                        assert(sna_pixmap(pixmap)->flush);
                        assert(sna_pixmap(pixmap)->gpu_bo == private->bo);
-                       assert(sna_pixmap(pixmap)->pinned & PIN_DRI);
+                       assert(sna_pixmap(pixmap)->pinned & PIN_DRI2);
                        assert(kgem_bo_flink(&sna->kgem, private->bo) == buffer->name);
                        assert(8*private->bo->pitch >= pixmap->drawable.width * pixmap->drawable.bitsPerPixel);
                        assert(private->bo->pitch * pixmap->drawable.height <= kgem_bo_size(private->bo));
@@ -378,10 +378,10 @@ sna_dri_create_buffer(DrawablePtr draw,
 
                priv = sna_pixmap(pixmap);
                assert(priv->flush == false);
-               assert((priv->pinned & PIN_DRI) == 0);
+               assert((priv->pinned & PIN_DRI2) == 0);
 
                /* Don't allow this named buffer to be replaced */
-               priv->pinned |= PIN_DRI;
+               priv->pinned |= PIN_DRI2;
 
                /* We need to submit any modifications to and reads from this
                 * buffer before we send any reply to the Client.
@@ -424,7 +424,7 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
                assert(sna_pixmap_get_buffer(pixmap) == buffer);
                assert(priv->gpu_bo == private->bo);
                assert(priv->gpu_bo->flush);
-               assert(priv->pinned & PIN_DRI);
+               assert(priv->pinned & PIN_DRI2);
                assert(priv->flush);
 
                /* Undo the DRI markings on this pixmap */
@@ -436,7 +436,7 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
                list_del(&priv->flush_list);
 
                priv->gpu_bo->flush = false;
-               priv->pinned &= ~PIN_DRI;
+               priv->pinned &= ~PIN_DRI2;
 
                priv->flush = false;
                sna_accel_watch_flush(sna, -1);
@@ -496,7 +496,7 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo)
        assert(pixmap->drawable.height * bo->pitch <= kgem_bo_size(bo));
        assert(bo->proxy == NULL);
        assert(bo->flush);
-       assert(priv->pinned & PIN_DRI);
+       assert(priv->pinned & PIN_DRI2);
        assert((priv->pinned & PIN_PRIME) == 0);
        assert(priv->flush);
 
@@ -1214,6 +1214,12 @@ can_flip(struct sna * sna,
                return false;
        }
 
+       if (sna_pixmap(pixmap)->pinned & ~(PIN_DRI2 | PIN_SCANOUT)) {
+               DBG(("%s -- no, pinned: front %x\n",
+                    __FUNCTION__, get_private(front)->pinned));
+               return false;
+       }
+
        return true;
 }
 
index 131f18c..ded975f 100644 (file)
@@ -97,10 +97,12 @@ struct intel_pixmap {
        int8_t busy :2;
        uint8_t dirty :1;
        uint8_t offscreen :1;
-       uint8_t pinned :3;
+       uint8_t pinned :5;
 #define PIN_SCANOUT 0x1
-#define PIN_DRI 0x2
-#define PIN_GLAMOR 0x4
+#define PIN_DRI2 0x2
+#define PIN_DRI3 0x4
+#define PIN_PRIME 0x8
+#define PIN_GLAMOR 0x10
 };
 
 #if HAS_DEVPRIVATEKEYREC
index acedd0b..1a9bad0 100644 (file)
@@ -91,7 +91,7 @@ static uint32_t pixmap_flink(PixmapPtr pixmap)
        if (dri_bo_flink(priv->bo, &name) != 0)
                return 0;
 
-       priv->pinned |= PIN_DRI;
+       priv->pinned |= PIN_DRI2;
        return name;
 }
 
@@ -984,6 +984,9 @@ can_exchange(DrawablePtr drawable, DRI2BufferPtr front, DRI2BufferPtr back)
        if (front_intel->tiling != back_intel->tiling)
                return FALSE;
 
+       if (front_intel->pinned & ~(PIN_SCANOUT | PIN_DRI2))
+               return FALSE;
+
        return TRUE;
 }
 
index 6fb1333..d4ba7fc 100644 (file)
@@ -1195,7 +1195,7 @@ intel_uxa_share_pixmap_backing(PixmapPtr ppix, ScreenPtr slave, void **fd_handle
        drm_intel_bo_get_tiling(bo, &tiling, &swizzle);
 
        if (tiling == I915_TILING_X) {
-               if (priv->pinned & ~PIN_DRI)
+               if (priv->pinned)
                        return FALSE;
 
                tiling = I915_TILING_NONE;
@@ -1219,7 +1219,7 @@ intel_uxa_share_pixmap_backing(PixmapPtr ppix, ScreenPtr slave, void **fd_handle
        }
        drm_intel_bo_get_tiling(bo, &tiling, &swizzle);
        drm_intel_bo_gem_export_to_prime(bo, &handle);
-       priv->pinned |= PIN_DRI;
+       priv->pinned |= PIN_PRIME;
 
        *fd_handle = (void *)(long)handle;
        return TRUE;