[Glamor] [PATCH] Add DRI3 support to glamor

Zhigang Gong zhigang.gong at linux.intel.com
Wed Dec 4 17:10:39 PST 2013


On Wed, Dec 04, 2013 at 08:42:37PM +0100, davyaxel at free.fr wrote:
> On 04/12/2013, zhigang gong wrote :
> > On Tue, Dec 03, 2013 at 06:43:33PM +0100, davyaxel at free.fr wrote:
> >> On 03/12/2013, zhigang gong wrote :
> >>>
> >>>
> >>> On Sat, Nov 30, 2013 at 7:53 PM, Axel Davy <axel.davy at ens.fr> wrote:
> >>>
> >>>     This implements some DRI3 helpers to help the DDXs using
> >>>     glamor to support DRI3.
> >>>
> >>>     Signed-off-by: Axel Davy <axel.davy at ens.fr>
> >>>     ---
> >>>      src/glamor.c      |  79 +++++++++++++++++++-
> >>>      src/glamor.h      |  69 ++++++++++++++++-
> >>>      src/glamor_egl.c  | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>>      src/glamor_fbo.c  |  36 ++++++---
> >>>      src/glamor_priv.h |   1 +
> >>>      5 files changed, 389 insertions(+), 14 deletions(-)
> >>>
> >>>     diff --git a/src/glamor.c b/src/glamor.c
> >>>     index e8e68be..7b749aa 100644
> >>>     --- a/src/glamor.c
> >>>     +++ b/src/glamor.c
> >>>     @@ -209,7 +209,12 @@ glamor_destroy_textured_pixmap(PixmapPtr pixmap)
> >>>      Bool
> >>>      glamor_destroy_pixmap(PixmapPtr pixmap)
> >>>      {
> >>>     -       glamor_destroy_textured_pixmap(pixmap);
> >>>     +       glamor_screen_private
> >>>     +         *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
> >>>     +       if (glamor_priv->dri3_enabled)
> >>>     +               glamor_egl_destroy_textured_pixmap(pixmap);
> >>>     +       else
> >>>     +               glamor_destroy_textured_pixmap(pixmap);
> >>>
> >>> We don't need to change the logic of glamor_destroy_pixmap(), it's DDX's responsibility to call glamor_egl_destroy_textured_pixmap if it is
> >>> using glamor_egl module. You can check the related code in intel ddx driver as below: (it always call glamor_egl_destroy_textured_pixmap)
> >> The point is that the DDX can avoid creating textured pixmaps itself at all, since Glamor would create them automatically when needed (when we use the dri3 helpers).
> >> So the DDX can avoid intercepting pixmap destruction. That's why when dri3 is enabled, I made glamor_destroy_pixmap destroys textured pixmaps.
> > I understand your point here and agree with you that now the DDX don't
> > need to allocate buffer object itself at all.
> > But I don't think you need to change the glamor_destroy_pixmap, here.
> > The original desgin purpose is to:
> > 1. If the DDX is using egl module, then the DDX need to call
> > glamor_egl_destroy_textured_pixmap to destroy a pixmap.
> > 2. If the DDX is using glx module which was embedded in the Xephyr
> > (never upstreamed), then the DDX need to call glamor_destroy_pixmap.
> >
> > Then you just need to call glamor_egl_destroy_textured_pixmap rather
> > than glamor_destroy_pixmap in the DDX driver. Then everything should
> > be ok. Right?
> My point is that the DDX shouldn't need to redirect screen->DestroyPixmap anymore.
> When DRI3 is enabled, the DDX can avoid storing private information with the pixmaps,
> since it can get fd and names from the pixmap (and the stride, width, etc is in pixmap).
> 
> Glamor redirects screen->DestroyPixmap to call glamor_destroy_pixmap.
> Since it would be tricky to change the redirection after that (when we know Dri3 is enabled),
> I proposed this change to glamor_destroy_pixmap, which conceptually, will do a similar thing
> to what the DDX would have to do if we don't do this change.
> 
> Another way of achieving the same result would be to add another redirection of screen->DestroyPixmap,
> to a function that would just clean the glamor_egl part, but I prefer to avoid this solution.
I agree that your solution does make the DDX simpler. The only concern is that this way, we make the libglamor.so
bind to glamor_egl module more tightly. Any way, considering that the only use scenario of glamor in
the real world is using egl context , I agree to go with your way. And we may merge the libglamor.so into glamor egl
module in the future which could make the DDX even simpler than now.

Thanks,
Zhigang Gong.

> >
> >>> void
> >>> intel_glamor_destroy_pixmap(PixmapPtr pixmap)
> >>> {
> >>>         ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
> >>>         intel_screen_private * intel;
> >>>         intel = intel_get_screen_private(scrn);
> >>>         if (intel->uxa_flags & UXA_USE_GLAMOR)
> >>>                 glamor_egl_destroy_textured_pixmap(pixmap);
> >>> }
> >>>
> >>>             return fbDestroyPixmap(pixmap);
> >>>      }
> >>>
> >>>     @@ -552,3 +557,75 @@ glamor_fini(ScreenPtr screen)
> >>>      {
> >>>             /* Do nothing currently. */
> >>>      }
> >>>     +
> >>>     +void glamor_egl_dri3_capabilities(ScreenPtr screen)
> >>>     +{
> >>>
> >>> This function is in glamor domain not the glamor_egl
> >>> domain. We may not use glamor_egl prefix. The second is that it is to set one
> >>> flag rather then query the capabilities. How about to change to:
> >>> glamor_enable_dri3(ScreenPtr screen) ?
> >> Ok, I'll do this change
> >>>
> >>>
> >>>     +       glamor_screen_private *glamor_priv =
> >>>     +           glamor_get_screen_private(screen);
> >>>     +       glamor_priv->dri3_enabled = TRUE;
> >>>     +}
> >>>     +
> >>>     +Bool glamor_is_dri3_support_enabled(ScreenPtr screen)
> >>>     +{
> >>>     +       glamor_screen_private *glamor_priv =
> >>>     +           glamor_get_screen_private(screen);
> >>>     +       return glamor_priv->dri3_enabled;
> >>>     +}
> >>>     +
> >>>     +int
> >>>     +glamor_dri3_fd_from_pixmap (ScreenPtr screen,
> >>>
> >>> As we can get screen from pixmap, we may reduce the first parameter. Right?
> >> The point is that the helpers exactly have the right arguments of the dri3 functions needed by X.
> > Ok, that's reasonable.
> >>>
> >>>     +                            PixmapPtr pixmap,
> >>>     +                            CARD16 *stride,
> >>>     +                            CARD32 *size)
> >>>     +{
> >>>     +       glamor_pixmap_private *pixmap_priv;
> >>>     +       glamor_screen_private *glamor_priv =
> >>>     +           glamor_get_screen_private(pixmap->drawable.pScreen);
> >>>     +
> >>>     +       pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
> >>>     +                                       glamor_pixmap_private_key);
> >>>     +       if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
> >>>     +               return -1;
> >>>     +       switch (pixmap_priv->type)
> >>>     +       {
> >>>     +               case GLAMOR_TEXTURE_DRM:
> >>>     +               case GLAMOR_TEXTURE_ONLY:
> >>>     +                       glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0);
> >>>     +                       return glamor_egl_dri3_fd_name_from_tex(screen,
> >>>     +                                                               pixmap,
> >>>     +                                                               pixmap_priv->base.fbo->tex,
> >>>     +                                                               FALSE,
> >>>     +                                                               stride,
> >>>     +                                                               size);
> >>>     +               default: break;
> >>>     +       }
> >>>     +       return -1;
> >>>     +}
> >>>     +
> >>>     +int
> >>>     +glamor_dri3_name_from_pixmap (ScreenPtr screen,
> >>>
> >>> Similar comments as  glamor_dri3_fd_from_pixma's. Don't need screen parameter.
> >>>
> >>>     +                              PixmapPtr pixmap)
> >>>     +{
> >>>     +       glamor_pixmap_private *pixmap_priv;
> >>>     +       glamor_screen_private *glamor_priv =
> >>>     +           glamor_get_screen_private(pixmap->drawable.pScreen);
> >>>     +
> >>>     +       pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
> >>>     +                                       glamor_pixmap_private_key);
> >>>
> >>>  pixmap_priv = glamor_get_pixmap_private(pixmap);
> >>>  should be clearer. There are some other similar code which should use glamor_get_pixmap_private(pixmap) although I only highlighted this one.
> >>>
> >>>     +       if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
> >>>     +               return -1;
> >>>     +       switch (pixmap_priv->type)
> >>>     +       {
> >>>     +               case GLAMOR_TEXTURE_DRM:
> >>>     +               case GLAMOR_TEXTURE_ONLY:
> >>>     +                       glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0);
> >>>     +                       return glamor_egl_dri3_fd_name_from_tex(screen,
> >>>     +                                                               pixmap,
> >>>     +                                                               pixmap_priv->base.fbo->tex,
> >>>     +                                                               TRUE,
> >>>     +                                                               NULL,
> >>>     +                                                               NULL);
> >>>     +               default: break;
> >>>     +       }
> >>>     +       return -1;
> >>>     +}
> >>>     diff --git a/src/glamor.h b/src/glamor.h
> >>>     index 927892f..e36fc80 100644
> >>>     --- a/src/glamor.h
> >>>     +++ b/src/glamor.h
> >>>     @@ -164,6 +164,72 @@ extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr bac
> >>>
> >>>      extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back);
> >>>
> >>>     +/* The DDX is not supposed to call these three functions */
> >>>     +extern _X_EXPORT void glamor_egl_dri3_capabilities(ScreenPtr screen);
> >>>     +extern _X_EXPORT unsigned int glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h);
> >>>     +extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr, unsigned int, Bool, CARD16*, CARD32*);
> >>>     +
> >>>     +/* @glamor_is_dri3_support_enabled: Returns if DRI3 support is enabled.
> >>>     + *
> >>>     + * @screen: Current screen pointer.
> >>>     + *
> >>>     + * To have DRI3 support enabled, glamor and glamor_egl need to be initialized,
> >>>     + * and glamor_egl_init_textured_pixmap need to be called. glamor also
> >>>     + * has to be compiled with gbm support.
> >>>     + * The EGL layer need to have the following extensions working:
> >>>     + * .EGL_KHR_gl_texture_2D_image
> >>>     + * .EGL_EXT_image_dma_buf_import
> >>>     + * If DRI3 support is not enabled, the following helpers will return an error.
> >>>     + * */
> >>>     +extern _X_EXPORT Bool glamor_is_dri3_support_enabled(ScreenPtr screen);
> >>>     +
> >>>     +/* @glamor_dri3_fd_from_pixmap: DRI3 helper to get a dma-buf fd from a pixmap.
> >>>     + *
> >>>     + * @screen: Current screen pointer.
> >>>     + * @pixmap: The pixmap from which we want the fd.
> >>>     + * @stride, @size: Pointers to fill the stride and size of the
> >>>     + *                buffer associated to the fd.
> >>>     + *
> >>>     + * the pixmap and the buffer associated by the fd will share the same
> >>>     + * content.
> >>>     + * Returns the fd on success, -1 on error.
> >>>     + * */
> >>>     +extern _X_EXPORT int glamor_dri3_fd_from_pixmap (ScreenPtr screen,
> >>>     +                                                PixmapPtr pixmap,
> >>>     +                                                CARD16 *stride,
> >>>     +                                                CARD32 *size);
> >>>     +
> >>>     +/* @glamor_dri3_name_from_pixmap: helper to get an gem name from a pixmap.
> >>>     + *
> >>>     + * @screen: Current screen pointer.
> >>>     + * @pixmap: The pixmap from which we want the gem name.
> >>>     + *
> >>>     + * the pixmap and the buffer associated by the gem name will share the same
> >>>     + * content. This function can be used by the DDX to support DRI2, but needs
> >>>     + * glamor DRI3 support to be activated.
> >>>     + * Returns the name on success, -1 on error.
> >>>     + * */
> >>>     +extern _X_EXPORT int glamor_dri3_name_from_pixmap (ScreenPtr screen, PixmapPtr pixmap);
> >>>     +
> >>>     +/* @glamor_egl_dri3_pixmap_from_fd: DRI3 helper to get a pixmap from a dma-buf fd.
> >>>     + *
> >>>     + * @screen: Current screen pointer.
> >>>     + * @fd: The dma-buf fd to import.
> >>>     + * @width: The width of the buffer.
> >>>     + * @height: The height of the buffer.
> >>>     + * @stride: The stride of the buffer.
> >>>     + * @depth: The depth of the buffer.
> >>>     + * @bpp: The number of bpp of the buffer.
> >>>     + *
> >>>     + * Returns a valid pixmap if the import succeeded, else NULL.
> >>>     + * */
> >>>     +extern _X_EXPORT PixmapPtr glamor_egl_dri3_pixmap_from_fd (ScreenPtr screen,
> >>>     +                                                          int fd,
> >>>     +                                                          CARD16 width,
> >>>     +                                                          CARD16 height,
> >>>     +                                                          CARD16 stride,
> >>>     +                                                          CARD8 depth,
> >>>     +                                                          CARD8 bpp);
> >>>
> >>>      #ifdef GLAMOR_FOR_XORG
> >>>
> >>>     @@ -243,9 +309,10 @@ extern _X_EXPORT Bool
> >>>             glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
> >>>                                                           void *bo);
> >>>
> >>>     -extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
> >>>      #endif
> >>>
> >>>     +extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
> >>>     +
> >>>      extern _X_EXPORT int glamor_create_gc(GCPtr gc);
> >>>
> >>>      extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable);
> >>>     diff --git a/src/glamor_egl.c b/src/glamor_egl.c
> >>>     index 13b7f44..0baa98a 100644
> >>>     --- a/src/glamor_egl.c
> >>>     +++ b/src/glamor_egl.c
> >>>     @@ -45,6 +45,7 @@
> >>>
> >>>      #ifdef GLAMOR_HAS_GBM
> >>>      #include <gbm.h>
> >>>     +#include <drm_fourcc.h>
> >>>      #endif
> >>>
> >>>      #if GLAMOR_GLES2
> >>>     @@ -95,6 +96,7 @@ struct glamor_egl_screen_private {
> >>>             void *glamor_context;
> >>>             void *current_context;
> >>>             int gl_context_depth;
> >>>     +       int dri3_capable;
> >>>
> >>>             PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
> >>>             PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr;
> >>>     @@ -218,6 +220,40 @@ glamor_create_texture_from_image(struct glamor_egl_screen_private
> >>>             return TRUE;
> >>>      }
> >>>
> >>>     +unsigned int
> >>>     +glamor_egl_create_argb8888_based_texture(ScreenPtr screen,
> >>>     +                                        int w,
> >>>     +                                        int h)
> >>>     +{
> >>>     +       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> >>>     +       struct glamor_egl_screen_private *glamor_egl;
> >>>     +       EGLImageKHR image;
> >>>     +       GLuint texture;
> >>>     +#ifdef GLAMOR_HAS_GBM
> >>>     +       struct gbm_bo *bo;
> >>>     +       glamor_egl = glamor_egl_get_screen_private(scrn);
> >>>     +       bo = gbm_bo_create (glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888,
> >>>     +                                     GBM_BO_USE_RENDERING |
> >>>     +                                     GBM_BO_USE_SCANOUT);
> >>>     +       if (!bo)
> >>>     +               return 0;
> >>>     +
> >>>     +       image = glamor_egl->egl_create_image_khr(glamor_egl->display,
> >>>     +                                                EGL_NO_CONTEXT,
> >>>     +                                                EGL_NATIVE_PIXMAP_KHR,
> >>>     +                                                bo, NULL);
> >>>     +       gbm_bo_destroy(bo);
> >>>     +       if (image == EGL_NO_IMAGE_KHR)
> >>>     +               return 0;
> >>>     +       glamor_create_texture_from_image(glamor_egl, image, &texture);
> >>>     +       glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
> >>>     +
> >>>     +       return texture;
> >>>     +#else
> >>>     +       return 0; /* this path should never happen */
> >>>     +#endif
> >>>     +}
> >>>     +
> >>>      Bool
> >>>      glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
> >>>      {
> >>>     @@ -349,6 +385,178 @@ done:
> >>>             return ret;
> >>>      }
> >>>
> >>>     +#ifdef GLAMOR_HAS_GBM
> >>>     +int glamor_get_fd_from_bo (int gbm_fd, struct gbm_bo *bo, int *fd);
> >>>     +void glamor_get_name_from_bo (int gbm_fd, struct gbm_bo *bo, int *name);
> >>>     +int
> >>>     +glamor_get_fd_from_bo (int gbm_fd, struct gbm_bo *bo, int *fd)
> >>>     +{
> >>>     +       union gbm_bo_handle handle;
> >>>     +       struct drm_prime_handle args;
> >>>     +
> >>>     +       handle = gbm_bo_get_handle(bo);
> >>>     +       args.handle = handle.u32;
> >>>     +       args.flags = DRM_CLOEXEC;
> >>>     +       if (ioctl (gbm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
> >>>     +               return FALSE;
> >>>     +       *fd = args.fd;
> >>>     +       return TRUE;
> >>>     +}
> >>>     +
> >>>     +void
> >>>     +glamor_get_name_from_bo (int gbm_fd, struct gbm_bo *bo, int *name)
> >>>     +{
> >>>     +       union gbm_bo_handle handle;
> >>>     +
> >>>     +       handle = gbm_bo_get_handle(bo);
> >>>     +       if (!glamor_get_flink_name(gbm_fd, handle.u32, name))
> >>>     +               *name = -1;
> >>>     +}
> >>>     +#endif
> >>>     +
> >>>     +int glamor_egl_dri3_fd_name_from_tex (ScreenPtr screen,
> >>>     +                                     PixmapPtr pixmap,
> >>>     +                                     unsigned int tex,
> >>>     +                                     Bool want_name,
> >>>     +                                     CARD16 *stride,
> >>>     +                                     CARD32 *size)
> >>>
> >>>  How about to change the parameter "Bool want_name" to
> >>>  int *name,
> >>>  and change the return value to Bool type.
> >>>  If the name/stride/size is not NULL, we need to get name/stride/size to the caller.
> >>>  If everything is ok, return TRUE, otherwise, return FALSE.
> >> I was thinking my approach was more efficient, but I can do that if you want.
> > I saw your new patch, using two APIs is acceptable. Thanks.
> >>>
> >>>
> >>>     +{
> >>>     +#ifdef GLAMOR_HAS_GBM
> >>>     +       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> >>>     +       struct glamor_egl_screen_private *glamor_egl;
> >>>     +       EGLImageKHR image;
> >>>     +       struct gbm_bo* bo;
> >>>     +       int fd = -1;
> >>>     +
> >>>     +       EGLint attribs[] = {
> >>>     +               EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
> >>>     +               EGL_GL_TEXTURE_LEVEL_KHR, 0,
> >>>     +               EGL_NONE
> >>>     +       };
> >>>     +
> >>>     +       glamor_egl = glamor_egl_get_screen_private(scrn);
> >>>     +
> >>>     +       glamor_egl_make_current(screen);
> >>>     +
> >>>     +       image = dixLookupPrivate(&pixmap->devPrivates,
> >>>     +                                glamor_egl_pixmap_private_key);
> >>>     +
> >>>     +       if (image == EGL_NO_IMAGE_KHR || image == NULL)
> >>>     +       {
> >>>     +               image = glamor_egl->egl_create_image_khr(glamor_egl->display,
> >>>     +                                                        glamor_egl->context,
> >>>     +                                                        EGL_GL_TEXTURE_2D_KHR,
> >>>     +                                                        tex, attribs);
> >>>     +               if (image == EGL_NO_IMAGE_KHR)
> >>>     +                       goto failure;
> >>>     +
> >>>     +               dixSetPrivate(&pixmap->devPrivates,
> >>>     +                             glamor_egl_pixmap_private_key,
> >>>     +                             image);
> >>>     +               glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
> >>>     +       }
> >>>     +
> >>>     +       bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
> >>>     +       if (!bo)
> >>>     +               goto failure;
> >>>     +
> >>>     +       pixmap->devKind = gbm_bo_get_stride(bo);
> >>>
> >>>  Why do you set the devKind here? This function doesn't allocate new buffer object for the pixmap.
> >>>  It just get name/fd for a given texture, so the devKind should remain no change here right?
> >> The previous devKind is wrong.
> >> When creating a textured pixmap with the radeon DDX and wlglamor, we have to get the stride of the buffer,
> >> and set the devKind to the stride.
> >> Since here Glamor creates the textured pixmap, and not the DDX, and that we have the gbm_bo, why not
> >> set the correct devKind at this moment?
> >> The devKind isn't used so much overall, so there is no essential need to set it before.
> >> But at this point, we know the pixmap might be used for dri2 or XWayland,
> >> and since dri2 or XWayland can use the devKind to get the stride, it is better to set it correctly.
> > That make sense.
> >
> > The last comment is that I found there are some whitespace errors with
> > your new patch, as below:
> > /home/gongzg/glamor/.git/rebase-apply/patch:50: trailing whitespace.
> >         glamor_screen_private
> > /home/gongzg/glamor/.git/rebase-apply/patch:78: trailing whitespace.
> > int
> > /home/gongzg/glamor/.git/rebase-apply/patch:107: trailing whitespace.
> > int
> > /home/gongzg/glamor/.git/rebase-apply/patch:146: trailing whitespace.
> >  *
> > /home/gongzg/glamor/.git/rebase-apply/patch:148: trailing whitespace.
> >  *
> > warning: squelched 15 whitespace errors
> > warning: 20 lines add whitespace errors.
> >
> > Could you fix them in next version of patch?
> Ok
> >
> >
> > Thanks,
> > Zhigang Gong.
> Thanks,
> Axel Davy
> >
> >>
> >>>  Thanks,
> >>>  Zhigang Gong.
> >> Thanks for the comments,
> >> Axel Davy
> >>>
> >>>     +
> >>>     +       if (want_name)
> >>>     +       {
> >>>     +               if (glamor_egl->has_gem)
> >>>     +                       glamor_get_name_from_bo(glamor_egl->fd, bo, &fd);
> >>>     +       }
> >>>     +       else
> >>>     +       {
> >>>     +               if (glamor_get_fd_from_bo(glamor_egl->fd, bo, &fd))
> >>>     +               {
> >>>     +                       *stride = pixmap->devKind;
> >>>     +                       *size = pixmap->devKind * gbm_bo_get_height(bo);
> >>>     +               }
> >>>     +       }
> >>>     +
> >>>     +       gbm_bo_destroy(bo);
> >>>     +failure:
> >>>     +       glamor_egl_restore_context(screen);
> >>>     +       return fd;
> >>>     +#else
> >>>     +       return -1;
> >>>     +#endif
> >>>     +}
> >>>     +
> >>>     +PixmapPtr glamor_egl_dri3_pixmap_from_fd (ScreenPtr screen,
> >>>     +                                         int fd,
> >>>     +                                         CARD16 width,
> >>>     +                                         CARD16 height,
> >>>     +                                         CARD16 stride,
> >>>     +                                         CARD8 depth,
> >>>     +                                         CARD8 bpp)
> >>>     +{
> >>>     +#ifdef GLAMOR_HAS_GBM
> >>>     +       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> >>>     +       struct glamor_egl_screen_private *glamor_egl;
> >>>     +       struct gbm_bo* bo;
> >>>     +       EGLImageKHR image;
> >>>     +       PixmapPtr pixmap;
> >>>     +       Bool ret = FALSE;
> >>>     +       EGLint attribs[] = {
> >>>     +               EGL_WIDTH, 0,
> >>>     +               EGL_HEIGHT, 0,
> >>>     +               EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
> >>>     +               EGL_DMA_BUF_PLANE0_FD_EXT, 0,
> >>>     +               EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
> >>>     +               EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
> >>>     +               EGL_NONE
> >>>     +       };
> >>>     +
> >>>     +       glamor_egl = glamor_egl_get_screen_private(scrn);
> >>>     +
> >>>     +       if (!glamor_egl->dri3_capable)
> >>>     +               return NULL;
> >>>     +
> >>>     +       if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0)
> >>>     +               return NULL;
> >>>     +
> >>>     +       attribs[1] = width;
> >>>     +       attribs[3] = height;
> >>>     +       attribs[7] = fd;
> >>>     +       attribs[11] = stride;
> >>>     +       image = glamor_egl->egl_create_image_khr(glamor_egl->display,
> >>>     +                                                EGL_NO_CONTEXT,
> >>>     +                                                EGL_LINUX_DMA_BUF_EXT,
> >>>     +                                                NULL, attribs);
> >>>     +
> >>>     +       if (image == EGL_NO_IMAGE_KHR)
> >>>     +               return NULL;
> >>>     +
> >>>     +       /* EGL_EXT_image_dma_buf_import can impose restrictions on the
> >>>     +        * usage of the image. Use gbm_bo to bypass the limitations. */
> >>>     +
> >>>     +       bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
> >>>     +       glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
> >>>     +
> >>>     +       if (!bo)
> >>>     +               return NULL;
> >>>     +
> >>>     +       pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
> >>>     +       screen->ModifyPixmapHeader (pixmap, width, height, 0, 0, stride, NULL);
> >>>     +
> >>>     +       ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo);
> >>>     +       gbm_bo_destroy(bo);
> >>>     +
> >>>     +       if (ret)
> >>>     +               return pixmap;
> >>>     +       else
> >>>     +       {
> >>>     +               screen->DestroyPixmap(pixmap);
> >>>     +               return NULL;
> >>>     +       }
> >>>     +#else
> >>>     +       return NULL;
> >>>     +#endif
> >>>     +}
> >>>     +
> >>>      static void
> >>>      _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
> >>>      {
> >>>     @@ -558,6 +766,11 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
> >>>             GLAMOR_CHECK_EGL_EXTENSIONS(KHR_surfaceless_context, KHR_surfaceless_opengl);
> >>>      #endif
> >>>
> >>>     +#ifdef GLAMOR_HAS_GBM
> >>>     +       if (glamor_egl_has_extension(glamor_egl, "EGL_KHR_gl_texture_2D_image") &&
> >>>     +           glamor_egl_has_extension(glamor_egl, "EGL_EXT_image_dma_buf_import") )
> >>>     +           glamor_egl->dri3_capable = TRUE;
> >>>     +#endif
> >>>             glamor_egl->egl_create_image_khr = (PFNEGLCREATEIMAGEKHRPROC)
> >>>                 eglGetProcAddress("eglCreateImageKHR");
> >>>
> >>>     @@ -609,6 +822,9 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
> >>>      Bool
> >>>      glamor_egl_init_textured_pixmap(ScreenPtr screen)
> >>>      {
> >>>     +       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> >>>     +       struct glamor_egl_screen_private *glamor_egl =
> >>>     +           glamor_egl_get_screen_private(scrn);
> >>>             if (!dixRegisterPrivateKey
> >>>                 (glamor_egl_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
> >>>                     LogMessage(X_WARNING,
> >>>     @@ -616,6 +832,8 @@ glamor_egl_init_textured_pixmap(ScreenPtr screen)
> >>>                                screen->myNum);
> >>>                     return FALSE;
> >>>             }
> >>>     +       if (glamor_egl->dri3_capable)
> >>>     +               glamor_egl_dri3_capabilities(screen);
> >>>             return TRUE;
> >>>      }
> >>>
> >>>     diff --git a/src/glamor_fbo.c b/src/glamor_fbo.c
> >>>     index 4838a27..2327e86 100644
> >>>     --- a/src/glamor_fbo.c
> >>>     +++ b/src/glamor_fbo.c
> >>>     @@ -328,18 +328,30 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
> >>>                        int w, int h, GLenum format)
> >>>      {
> >>>             glamor_gl_dispatch *dispatch;
> >>>     -       unsigned int tex;
> >>>     -
> >>>     -       dispatch = glamor_get_dispatch(glamor_priv);
> >>>     -       dispatch->glGenTextures(1, &tex);
> >>>     -       dispatch->glBindTexture(GL_TEXTURE_2D, tex);
> >>>     -       dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
> >>>     -                                 GL_NEAREST);
> >>>     -       dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
> >>>     -                                 GL_NEAREST);
> >>>     -       dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format,
> >>>     -                              GL_UNSIGNED_BYTE, NULL);
> >>>     -       glamor_put_dispatch(glamor_priv);
> >>>     +       unsigned int tex = 0;
> >>>     +
> >>>     +       /* With dri3, we want to allocate ARGB8888 pixmaps only.
> >>>     +        * Depending on the implementation, GL_RGBA might not
> >>>     +        * give us ARGB8888. We ask glamor_egl to use get
> >>>     +        * an ARGB8888 based texture for us. */
> >>>     +       if (glamor_priv->dri3_enabled && format == GL_RGBA)
> >>>     +       {
> >>>     +               tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen,
> >>>     +                                                               w, h);
> >>>     +       }
> >>>
> >>>     +       if (!tex)
> >>>     +       {
> >>>     +               dispatch = glamor_get_dispatch(glamor_priv);
> >>>     +               dispatch->glGenTextures(1, &tex);
> >>>     +               dispatch->glBindTexture(GL_TEXTURE_2D, tex);
> >>>     +               dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
> >>>     +                                         GL_NEAREST);
> >>>     +               dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
> >>>     +                                         GL_NEAREST);
> >>>     +               dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
> >>>     +                                      format, GL_UNSIGNED_BYTE, NULL);
> >>>     +               glamor_put_dispatch(glamor_priv);
> >>>     +       }
> >>>             return tex;
> >>>      }
> >>>
> >>>     diff --git a/src/glamor_priv.h b/src/glamor_priv.h
> >>>     index b6a1075..7b8f762 100644
> >>>     --- a/src/glamor_priv.h
> >>>     +++ b/src/glamor_priv.h
> >>>     @@ -305,6 +305,7 @@ typedef struct glamor_screen_private {
> >>>             int state;
> >>>             unsigned int render_idle_cnt;
> >>>             ScreenPtr screen;
> >>>     +       int dri3_enabled;
> >>>
> >>>             /* xv */
> >>>             GLint xv_prog;
> >>>     --
> >>>     1.8.1.2
> >>>
> >>>     _______________________________________________
> >>>     Glamor mailing list
> >>>     Glamor at lists.freedesktop.org
> >>>     http://lists.freedesktop.org/mailman/listinfo/glamor
> >>>
> >>> _______________________________________________
> >>> Glamor mailing list
> >>> Glamor at lists.freedesktop.org
> >>> http://lists.freedesktop.org/mailman/listinfo/glamor
> >
> _______________________________________________
> Glamor mailing list
> Glamor at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/glamor


More information about the Glamor mailing list