Yes, it works for me. For people testing this with kwin: There might be a little issue that the window content is initially black, but after disabling and enabling compositing it displays normally. When possible, resizing the window a little bit also works.
On 22.03.2013 10:59, Michel Dänzer wrote: > From: Michel Dänzer <[email protected]> > > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57200 > > Signed-off-by: Michel Dänzer <[email protected]> > --- > > 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"); > _______________________________________________ xorg-driver-ati mailing list [email protected] http://lists.x.org/mailman/listinfo/xorg-driver-ati
