diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-09-06 11:38:08 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-09-06 11:43:48 +0100 |
commit | 9bdf46d6c1a29b7b9e3d35e39a2e789334c0e1be (patch) | |
tree | 9acecde0baef2d52b5639604194fde0e1b6e041b /src/sna | |
parent | 39c4be2b0be66ed83bf059d3007f4143325e340d (diff) |
sna/prime: Distinguish forms of pinned pixmap
So that we can allow prime to replace the backing bo of currently
exported pixmaps through DRI2.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/sna.h | 9 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 60 | ||||
-rw-r--r-- | src/sna/sna_display.c | 4 | ||||
-rw-r--r-- | src/sna/sna_dri.c | 4 | ||||
-rw-r--r-- | src/sna/sna_glyphs.c | 2 |
5 files changed, 53 insertions, 26 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index b8760616..44e7f6e4 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -123,7 +123,10 @@ struct sna_pixmap { #define SOURCE_BIAS 4 uint16_t source_count; - uint8_t pinned :1; + uint8_t pinned :3; +#define PIN_SCANOUT 0x1 +#define PIN_DRI 0x2 +#define PIN_PRIME 0x4 uint8_t mapped :1; uint8_t shm :1; uint8_t clear :1; @@ -542,7 +545,7 @@ static inline struct kgem_bo *sna_pixmap_get_bo(PixmapPtr pixmap) return sna_pixmap(pixmap)->gpu_bo; } -static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap) +static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap, unsigned flags) { struct sna_pixmap *priv; @@ -550,7 +553,7 @@ static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap) if (!priv) return NULL; - priv->pinned = 1; + priv->pinned |= flags; return priv->gpu_bo; } diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index bb0bc147..678f687d 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -937,39 +937,63 @@ sna_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle) if (priv == NULL) return FALSE; + assert(!priv->shm); assert(priv->gpu_bo); assert(priv->stride); /* XXX negotiate format and stride restrictions */ - if (priv->gpu_bo->tiling && - !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) { - DBG(("%s: failed to change tiling for export\n", __FUNCTION__)); - return FALSE; - } - - /* nvidia requires a minimum pitch alignment of 256 */ - if (priv->gpu_bo->pitch & 255) { + if (priv->gpu_bo->tiling != I915_TILING_NONE || + priv->gpu_bo->pitch & 255) { struct kgem_bo *bo; + BoxRec box; - if (priv->pinned) { - DBG(("%s: failed to change pitch for export, pinned!\n", __FUNCTION__)); + DBG(("%s: removing tiling %d, and aligning pitch for %dx%d pixmap=%ld\n", + __FUNCTION__, priv->gpu_bo->tiling, + pixmap->drawable.width, pixmap->drawable.height, + pixmap->drawable.serialNumber)); + + if (priv->pinned & ~(PIN_DRI | PIN_PRIME)) { + DBG(("%s: can't convert pinned bo\n", __FUNCTION__)); return FALSE; } - bo = kgem_replace_bo(&sna->kgem, priv->gpu_bo, - pixmap->drawable.width, - pixmap->drawable.height, - ALIGN(priv->gpu_bo->pitch, 256), - pixmap->drawable.bitsPerPixel); + assert_pixmap_damage(pixmap); + + bo = kgem_create_2d(&sna->kgem, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->drawable.bitsPerPixel, + I915_TILING_NONE, + CREATE_GTT_MAP | CREATE_PRIME); if (bo == NULL) { - DBG(("%s: failed to change pitch for export\n", __FUNCTION__)); + DBG(("%s: allocation failed\n", __FUNCTION__)); + return FALSE; + } + + box.x1 = box.y1 = 0; + box.x2 = pixmap->drawable.width; + box.y2 = pixmap->drawable.height; + + assert(!wedged(sna)); /* XXX */ + if (!sna->render.copy_boxes(sna, GXcopy, + pixmap, priv->gpu_bo, 0, 0, + pixmap, bo, 0, 0, + &box, 1, 0)) { + DBG(("%s: copy failed\n", __FUNCTION__)); + kgem_bo_destroy(&sna->kgem, bo); return FALSE; } kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = bo; + + if (priv->mapped) { + pixmap->devPrivate.ptr = NULL; + priv->mapped = false; + } } assert(priv->gpu_bo->tiling == I915_TILING_NONE); + assert((priv->gpu_bo->pitch & 255) == 0); /* And export the bo->pitch via pixmap->devKind */ pixmap->devPrivate.ptr = kgem_bo_map__async(&sna->kgem, priv->gpu_bo); @@ -983,7 +1007,7 @@ sna_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle) if (fd == -1) return FALSE; - priv->pinned = true; + priv->pinned |= PIN_PRIME; *fd_handle = (void *)(intptr_t)fd; return TRUE; @@ -1022,7 +1046,7 @@ sna_set_shared_pixmap_backing(PixmapPtr pixmap, void *fd_handle) priv->stride = pixmap->devKind; priv->gpu_bo = bo; - priv->pinned = true; + priv->pinned |= PIN_DRI; close((intptr_t)fd_handle); return TRUE; diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 59e128bc..5d906539 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -967,7 +967,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc) if (!sna_crtc_enable_shadow(sna, sna_crtc)) return NULL; - bo = sna_pixmap_pin(sna_crtc->scanout_pixmap); + bo = sna_pixmap_pin(sna_crtc->scanout_pixmap, PIN_SCANOUT); if (bo == NULL) return NULL; @@ -1009,7 +1009,7 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc) } else { DBG(("%s: attaching to framebuffer\n", __FUNCTION__)); sna_crtc_disable_shadow(sna, sna_crtc); - bo = sna_pixmap_pin(sna->front); + bo = sna_pixmap_pin(sna->front, PIN_SCANOUT); if (bo == NULL) return NULL; diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index e28ea4a5..63292469 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -188,7 +188,7 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna, sna_accel_watch_flush(sna, 1); /* Don't allow this named buffer to be replaced */ - priv->pinned = 1; + priv->pinned |= PIN_DRI; return priv->gpu_bo; } @@ -368,7 +368,7 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer) pixmap == sna->front)); list_del(&priv->list); sna_accel_watch_flush(sna, -1); - priv->pinned = pixmap == sna->front; + priv->pinned &= ~PIN_DRI; } sna_pixmap_set_buffer(pixmap, NULL); diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c index f7331a57..7a96fab8 100644 --- a/src/sna/sna_glyphs.c +++ b/src/sna/sna_glyphs.c @@ -219,7 +219,7 @@ bool sna_glyphs_create(struct sna *sna) priv = sna_pixmap(pixmap); if (priv != NULL) { /* Prevent the cache from ever being paged out */ - priv->pinned = true; + priv->pinned = PIN_SCANOUT; component_alpha = NeedsComponent(pPictFormat->format); picture = CreatePicture(0, &pixmap->drawable, pPictFormat, |