[Glamor] [PATCH] Add DRI3 support to glamor

zhigang gong zhigang.gong at gmail.com
Wed Dec 4 07:19:10 PST 2013


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?
> > 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?

Thanks,
Zhigang Gong.
>
> >  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


More information about the Glamor mailing list