[PATCH] glamor: Initial PRIME pixmap sharing hooks.

Michel Dänzer michel at daenzer.net
Fri Mar 22 02:59:13 PDT 2013


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

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57200

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---

Christoph / linedot, please test if this patch still works for you.

 src/radeon_bo_helper.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/radeon_bo_helper.h |  7 ++++++
 src/radeon_exa.c       | 63 ++++++-----------------------------------------
 src/radeon_glamor.c    | 58 +++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 135 insertions(+), 59 deletions(-)

diff --git a/src/radeon_bo_helper.c b/src/radeon_bo_helper.c
index 593c690..c5f5ce2 100644
--- a/src/radeon_bo_helper.c
+++ b/src/radeon_bo_helper.c
@@ -26,6 +26,9 @@
 
 #include "radeon.h"
 
+#ifdef RADEON_PIXMAP_SHARING
+#include "radeon_bo_gem.h"
+#endif
 
 static const unsigned MicroBlockTable[5][3][2] = {
     /*linear  tiled   square-tiled */
@@ -181,3 +184,66 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
     *new_pitch = pitch;
     return bo;
 }
+
+#ifdef RADEON_PIXMAP_SHARING
+
+Bool radeon_share_pixmap_backing(struct radeon_bo *bo, void **handle_p)
+{
+    int handle;
+
+    if (radeon_gem_prime_share_bo(bo, &handle) != 0)
+	return FALSE;
+
+    *handle_p = (void *)(long)handle;
+    return TRUE;
+}
+
+Bool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
+				      struct radeon_surface *surface)
+{
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    struct radeon_bo *bo;
+    int ihandle = (int)(long)fd_handle;
+    uint32_t size = ppix->devKind * ppix->drawable.height;
+
+    bo = radeon_gem_bo_open_prime(info->bufmgr, ihandle, size);
+    if (!bo)
+        return FALSE;
+
+    memset(surface, 0, sizeof(struct radeon_surface));
+
+    if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
+
+	surface->npix_x = ppix->drawable.width;
+	surface->npix_y = ppix->drawable.height;
+	surface->npix_z = 1;
+	surface->blk_w = 1;
+	surface->blk_h = 1;
+	surface->blk_d = 1;
+	surface->array_size = 1;
+	surface->bpe = ppix->drawable.bitsPerPixel / 8;
+	surface->nsamples = 1;
+	surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
+	surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
+	if (radeon_surface_best(info->surf_man, surface)) {
+	    return FALSE;
+	}
+	if (radeon_surface_init(info->surf_man, surface)) {
+	    return FALSE;
+	}
+	/* we have to post hack the surface to reflect the actual size
+	   of the shared pixmap */
+	surface->level[0].pitch_bytes = ppix->devKind;
+	surface->level[0].nblk_x = ppix->devKind / surface->bpe;
+    }
+    radeon_set_pixmap_bo(ppix, bo);
+
+    close(ihandle);
+    /* we have a reference from the alloc and one from set pixmap bo,
+       drop one */
+    radeon_bo_unref(bo);
+    return TRUE;
+}
+
+#endif /* RADEON_PIXMAP_SHARING */
diff --git a/src/radeon_bo_helper.h b/src/radeon_bo_helper.h
index 0f6fffb..9c3d73f 100644
--- a/src/radeon_bo_helper.h
+++ b/src/radeon_bo_helper.h
@@ -28,4 +28,11 @@ radeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
 		       int usage_hint, int bitsPerPixel, int *new_pitch,
 		       struct radeon_surface *new_surface, uint32_t *new_tiling);
 
+extern Bool
+radeon_share_pixmap_backing(struct radeon_bo *bo, void **handle_p);
+
+extern Bool
+radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
+				 struct radeon_surface *surface);
+
 #endif /* RADEON_BO_HELPER_H */
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 22e2cef..fcafb68 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -41,7 +41,6 @@
 #include "radeon_probe.h"
 #include "radeon_version.h"
 #include "radeon_exa_shared.h"
-#include "radeon_bo_gem.h"
 #include "xf86.h"
 
 
@@ -315,72 +314,24 @@ void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv)
 #ifdef RADEON_PIXMAP_SHARING
 Bool RADEONEXASharePixmapBacking(PixmapPtr ppix, ScreenPtr slave, void **fd_handle)
 {
-    struct radeon_exa_pixmap_priv *driver_priv;
-    int ret;
-    int handle;
+    struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(ppix);
 
-    driver_priv = exaGetPixmapDriverPrivate(ppix);
-
-    ret = radeon_gem_prime_share_bo(driver_priv->bo, &handle);
-    if (ret)
+    if (!radeon_share_pixmap_backing(driver_priv->bo, fd_handle))
 	return FALSE;
 
     driver_priv->shared = TRUE;
-    *fd_handle = (void *)(long)handle;
     return TRUE;
 }
 
 Bool RADEONEXASetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle)
 {
-    ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    struct radeon_exa_pixmap_priv *driver_priv;
-    struct radeon_bo *bo;
-    int ihandle = (int)(long)fd_handle;
-    uint32_t size = ppix->devKind * ppix->drawable.height;
-    struct radeon_surface surface;
-
-    driver_priv = exaGetPixmapDriverPrivate(ppix);
-
-    bo = radeon_gem_bo_open_prime(info->bufmgr, ihandle, size);
-    if (!bo)
-        return FALSE;
-
-    memset(&surface, 0, sizeof(struct radeon_surface));
-	
-    if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
-
-	surface.npix_x = ppix->drawable.width;
-	surface.npix_y = ppix->drawable.height;
-	surface.npix_z = 1;
-	surface.blk_w = 1;
-	surface.blk_h = 1;
-	surface.blk_d = 1;
-	surface.array_size = 1;
-	surface.bpe = ppix->drawable.bitsPerPixel / 8;
-	surface.nsamples = 1;
-	surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
-	surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
-	if (radeon_surface_best(info->surf_man, &surface)) {
-	    return FALSE;
-	}
-	if (radeon_surface_init(info->surf_man, &surface)) {
-	    return FALSE;
-	}
-	/* we have to post hack the surface to reflect the actual size
-	   of the shared pixmap */
-	surface.level[0].pitch_bytes = ppix->devKind;
-	surface.level[0].nblk_x = ppix->devKind / surface.bpe;
-    }
-    driver_priv->surface = surface;
+    struct radeon_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(ppix);
+
+    if (!radeon_set_shared_pixmap_backing(ppix, fd_handle, &driver_priv->surface))
+	return FALSE;
+
     driver_priv->shared = TRUE;
     driver_priv->tiling_flags = 0;
-    radeon_set_pixmap_bo(ppix, bo);
-
-    close(ihandle);
-    /* we have a reference from the alloc and one from set pixmap bo,
-       drop one */
-    radeon_bo_unref(bo);
     return TRUE;
 }
 #endif
diff --git a/src/radeon_glamor.c b/src/radeon_glamor.c
index ef7d95c..faee5ee 100644
--- a/src/radeon_glamor.c
+++ b/src/radeon_glamor.c
@@ -161,7 +161,7 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	struct radeon_pixmap *priv;
 	PixmapPtr pixmap, new_pixmap = NULL;
 
-	if (!(usage & RADEON_CREATE_PIXMAP_DRI2)) {
+	if (!(usage & (CREATE_PIXMAP_USAGE_SHARED | RADEON_CREATE_PIXMAP_DRI2))) {
 		pixmap = glamor_create_pixmap(screen, w, h, depth, usage);
 		if (pixmap)
 			return pixmap;
@@ -204,13 +204,13 @@ radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	return pixmap;
 
 fallback_glamor:
-	if (usage & RADEON_CREATE_PIXMAP_DRI2) {
+	if (usage & (CREATE_PIXMAP_USAGE_SHARED | RADEON_CREATE_PIXMAP_DRI2)) {
 	/* XXX need further work to handle the DRI2 failure case.
 	 * Glamor don't know how to handle a BO only pixmap. Put
 	 * a warning indicator here.
 	 */
 		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-			   "Failed to create textured DRI2 pixmap.");
+			   "Failed to create textured DRI2/PRIME pixmap.");
 		return pixmap;
 	}
 	/* Create textured pixmap failed means glamor failed to
@@ -244,6 +244,54 @@ static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap)
 	return TRUE;
 }
 
+#ifdef RADEON_PIXMAP_SHARING
+
+static Bool
+radeon_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave,
+				   void **handle_p)
+{
+	struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
+
+	if (!priv)
+		return FALSE;
+
+	return radeon_share_pixmap_backing(priv->bo, handle_p);
+}
+
+static Bool
+radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle)
+{
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+	struct radeon_surface surface;
+	struct radeon_pixmap *priv;
+
+	if (!radeon_set_shared_pixmap_backing(pixmap, handle, &surface))
+		return FALSE;
+
+	priv = radeon_get_pixmap_private(pixmap);
+	priv->stride = pixmap->devKind;
+	priv->surface = surface;
+	priv->tiling_flags = 0;
+
+	if (!radeon_glamor_create_textured_pixmap(pixmap)) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Failed to get PRIME drawable for glamor pixmap.\n");
+		return FALSE;
+	}
+
+	screen->ModifyPixmapHeader(pixmap,
+				   pixmap->drawable.width,
+				   pixmap->drawable.height,
+				   0, 0,
+				   priv->stride,
+				   NULL);
+
+	return TRUE;
+}
+
+#endif /* RADEON_PIXMAP_SHARING */
+
 Bool
 radeon_glamor_init(ScreenPtr screen)
 {
@@ -271,6 +319,10 @@ radeon_glamor_init(ScreenPtr screen)
 
 	screen->CreatePixmap = radeon_glamor_create_pixmap;
 	screen->DestroyPixmap = radeon_glamor_destroy_pixmap;
+#ifdef RADEON_PIXMAP_SHARING
+	screen->SharePixmapBacking = radeon_glamor_share_pixmap_backing;
+	screen->SetSharedPixmapBacking = radeon_glamor_set_shared_pixmap_backing;
+#endif
 
 	xf86DrvMsg(scrn->scrnIndex, X_INFO,
 		   "Use GLAMOR acceleration.\n");
-- 
1.8.2.rc3



More information about the xorg-driver-ati mailing list