From 0ee29c4ea3b05e9361635a2ef6e7b92c160d68cf Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 22 Nov 2013 13:34:35 +0000 Subject: uxa,sna: Prevent bo exchange when pinned for non-DRI2 clients 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 --- src/sna/sna.h | 7 ++++--- src/sna/sna_accel.c | 2 +- src/sna/sna_dri.c | 18 ++++++++++++------ src/uxa/intel.h | 8 +++++--- src/uxa/intel_dri.c | 5 ++++- src/uxa/intel_uxa.c | 4 ++-- 6 files changed, 28 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/sna/sna.h b/src/sna/sna.h index 6474d11c..b3e38a3c 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -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 diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 7238cbe6..a68e5fb7 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -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; } diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index 5e6d3a75..a218be32 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -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; } diff --git a/src/uxa/intel.h b/src/uxa/intel.h index 131f18ca..ded975ff 100644 --- a/src/uxa/intel.h +++ b/src/uxa/intel.h @@ -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 diff --git a/src/uxa/intel_dri.c b/src/uxa/intel_dri.c index acedd0b7..1a9bad0b 100644 --- a/src/uxa/intel_dri.c +++ b/src/uxa/intel_dri.c @@ -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; } diff --git a/src/uxa/intel_uxa.c b/src/uxa/intel_uxa.c index 6fb1333f..d4ba7fcc 100644 --- a/src/uxa/intel_uxa.c +++ b/src/uxa/intel_uxa.c @@ -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; -- cgit v1.2.3