[PATCH] glamor: Initial PRIME pixmap sharing hooks.

Alex Deucher alexdeucher at gmail.com
Fri Mar 22 06:25:47 PDT 2013


On Fri, Mar 22, 2013 at 5:59 AM, Michel Dänzer <michel at daenzer.net> wrote:
> 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>

Reviewed-by: Alex Deucher <alexander.deucher 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
>
> _______________________________________________
> xorg-driver-ati mailing list
> xorg-driver-ati at lists.x.org
> http://lists.x.org/mailman/listinfo/xorg-driver-ati


More information about the xorg-driver-ati mailing list