diff -urN a/src/radeon_glamor.c b/src/radeon_glamor.c --- a/src/radeon_glamor.c 2013-03-13 23:02:55.145637300 +0100 +++ b/src/radeon_glamor.c 2013-03-15 18:47:45.326019917 +0100 @@ -34,6 +34,7 @@ #include "radeon.h" #include "radeon_bo_helper.h" +#include "radeon_bo_gem.h" #if HAS_DEVPRIVATEKEYREC DevPrivateKeyRec glamor_pixmap_index; @@ -164,8 +165,20 @@ if (!(usage & RADEON_CREATE_PIXMAP_DRI2)) { pixmap = glamor_create_pixmap(screen, w, h, depth, usage); - if (pixmap) - return pixmap; + if (pixmap){ + if(usage & CREATE_PIXMAP_USAGE_SHARED) { + // alloc priv, else NULL in radeon_glamor_set_pixmap_backing + priv = calloc(1, sizeof(struct radeon_pixmap)); + if(!priv) { + glamor_destroy_pixmap(pixmap); + pixmap = NULL; + } + else { + radeon_set_pixmap_private(pixmap, priv); + return pixmap; + } + } + } } if (w > 32767 || h > 32767) @@ -245,6 +258,80 @@ return TRUE; } +#ifdef RADEON_PIXMAP_SHARING +Bool radeon_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle) +{ + struct radeon_pixmap *priv; + int ret; + int handle; + priv = radeon_get_pixmap_private(pixmap); + if(!priv) + return FALSE; + + ret = radeon_gem_prime_share_bo(priv->bo, &handle); + if(ret) + return FALSE; + + *fd_handle = (void*)(long)handle; + return TRUE; +} + +Bool radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void* fd_handle) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); + RADEONInfoPtr info = RADEONPTR(scrn); + struct radeon_bo *bo; + struct radeon_pixmap *priv; + struct radeon_surface surface; + int ihandle = (int)(long)fd_handle; + uint32_t size = pixmap->devKind * pixmap->drawable.height; + + priv = radeon_get_pixmap_private(pixmap); + if(!priv) + return FALSE; + + 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 = pixmap->drawable.width; + surface.npix_y = pixmap->drawable.height; + surface.npix_z = 1; + surface.blk_w = 1; + surface.blk_h = 1; + surface.blk_d = 1; + surface.array_size = 1; + surface.bpe = pixmap->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 = pixmap->devKind; + surface.level[0].nblk_x = pixmap->devKind / surface.bpe; + } + priv->surface = surface; + priv->tiling_flags = 0; + radeon_set_pixmap_bo(pixmap, 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 Bool radeon_glamor_init(ScreenPtr screen) { @@ -272,6 +359,8 @@ screen->CreatePixmap = radeon_glamor_create_pixmap; screen->DestroyPixmap = radeon_glamor_destroy_pixmap; + screen->SharePixmapBacking = radeon_glamor_share_pixmap_backing; + screen->SetSharedPixmapBacking = radeon_glamor_set_shared_pixmap_backing; xf86DrvMsg(scrn->scrnIndex, X_INFO, "Use GLAMOR acceleration.\n"); diff -urN a/src/radeon_glamor.h b/src/radeon_glamor.h --- a/src/radeon_glamor.h 2013-03-13 23:02:55.141637299 +0100 +++ b/src/radeon_glamor.h 2013-03-15 20:17:58.299542636 +0100 @@ -41,6 +41,9 @@ Bool radeon_glamor_create_textured_pixmap(PixmapPtr pixmap); void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst); +Bool radeon_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle); +Bool radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void* fd_handle); + Bool radeon_glamor_pixmap_is_offscreen(PixmapPtr pixmap); struct radeon_pixmap { @@ -84,6 +87,9 @@ static inline void radeon_glamor_exchange_buffers(PixmapPtr src, PixmapPtr dst) {} +static inline Bool radeon_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle) {return FALSE; } +static inline Bool radeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void* fd_handle) { return FALSE; } + static inline Bool radeon_glamor_pixmap_is_offscreen(PixmapPtr pixmap) { return FALSE; } static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap) { return NULL; }