[Glamor] [PATCH] Allow to create textured pixmaps from gbm_bo without using gem names
davyaxel at free.fr
davyaxel at free.fr
Sat Nov 23 05:19:20 PST 2013
On 23/11/2013, zhigang gong wrote :
> At the time I developed glamor, the extension of creating egl image from gl texture was
> not implemented in mesa. Now mesa already supported it, and we can provide these new
> APIs to DDR driver. Just as you said, we may need a new API in libglamor.so to query a
> pixmap's type and texture unit id, then we don't need to access the pixmap's private data
> structure.
> The new API you implemented will give DDR a chance to support DRI more efficiently.
> Currently, when the client want to create a dri2 buffer on a textured only pixmap, it will
> trigger a glamor_fixup function to create a new textured_drm pixmap and then copy the
> old buffer to this new buffer. Now we can avoid this extra copy with this new API at that
> case.
> Thanks,
> Zhigang Gong.
The other dri3 helper could look like that:
PixmapPtr glamor_egl_get_pixmap_from_fd (ScreenPtr screen,
int fd,
int width,
int height,
int stride,
int depth,
int bpp)
{
PixmapPtr pixmap;
struct glamor_egl_screen_private *glamor_egl;
EGLImageKHR image;
struct gbm_bo* bo;
EGLint attribs[] = {
EGL_WIDTH, 0,
EGL_HEIGHT, 0,
EGL_LINUX_DRM_FOURCC_EXT, 0,
EGL_DMA_BUF_PLANE0_FD_EXT, 0,
EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
EGL_NONE
};
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
glamor_egl = glamor_egl_get_screen_private(scrn);
/* we have no way to choose between RGB or others. Favor RGB */
switch(bpp){
case 16:
if (depth == 16)
attribs[5] = DRM_FORMAT_RGB565;
break;
case 24:
if (depth == 24)
attribs[5] = DRM_FORMAT_RGB888;
break;
case 32:
if (depth == 24)
attribs [5] = DRM_FORMAT_XRGB8888;
else if (depth == 32)
attribs [5] = DRM_FORMAT_ARGB8888;
}
if (attribs[5] == 0 || width==0 || height == 0)
goto failure;
pixmap = fbCreatePixmap(screen, 0, 0, depth, 0);
attribs[1] = width;
attribs[3] = height;
attribs[7] = fd;
attribs[11] = stride;
screen->ModifyPixmapHeader (pixmap, width, height, 0, 0,
stride, NULL);
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)
goto destroy_pixmap;
/* images imported with EGL_LINUX_DMA_BUF_EXT have
restrictions about their use, since they can potentially
be of YUV format. Convert to gbm_bo, which accepts
only non YUV formats, and then do not share the same
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)
goto destroy_pixmap;
if(!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo))
goto destroy_bo;
gbm_bo_destroy(bo);
return pixmap;
destroy_bo:
gbm_bo_destroy(bo);
destroy_pixmap:
fbDestroyPixmap(pixmap);
failure:
return NULL;
}
For the dri2 use case you mention,
It'll probably need a glamor_egl_get_name_from_pixmap.
Axel Davy
> On Fri, Nov 22, 2013 at 6:45 AM, <davyaxel at free.fr> wrote:
>
> Hi,
>
> I've got pixmap->fd working with this experimental function (on intel):
>
> Bool glamor_egl_get_fd_from_pixmap(PixmapPtr pixmap, int* fd)
> {
> struct glamor_pixmap_private * priv = glamor_get_pixmap_private(pixmap);
> ScreenPtr screen = pixmap->drawable.pScreen;
> ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> struct glamor_egl_screen_private *glamor_egl;
> EGLImageKHR image;
> GLuint texture;
> Bool ret = FALSE;
> struct gbm_bo* bo;
> EGLint attribs[] = {
> EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
> EGL_GL_TEXTURE_LEVEL_KHR, 0,
> EGL_NONE
> };
>
> glamor_egl = glamor_egl_get_screen_private(scrn);
> switch (priv->type)
> {
> case GLAMOR_TEXTURE_DRM:
> case GLAMOR_TEXTURE_ONLY:
> glamor_egl_make_current(screen);
> image = glamor_egl->egl_create_image_khr(glamor_egl->display,
> glamor_egl->context,
> EGL_GL_TEXTURE_2D_KHR,
> priv->base.fbo->tex, attribs);
> if (image == EGL_NO_IMAGE_KHR)
> goto leave;
> bo = gbm_bo_import(glamor_egl->gbm,GBM_BO_IMPORT_EGL_IMAGE,image,0);
> glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
> ret = glamor_get_fd_from_bo(glamor_egl->fd,bo,fd);
> if(ret)
> {
> glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
> pixmap->devKind = gbm_bo_get_stride(bo);
> }
> gbm_bo_destroy(bo);
> break;
> default: return 0;
> }
> leave:
> glamor_egl_restore_context(screen);
> return ret;
> }
>
> 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;
> }
>
>
> Of course there are some missing checks, etc.
> And it needs glamor_egl.c has access to the glamor_pixmap_private to get the texture.
> I think it would be better to have a function glamor_get_pixmap_texture_number that glamor_egl would have access to.
>
> Feel free to add comments
>
> Axel Davy
> _______________________________________________
> Glamor mailing list
> Glamor at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/glamor
>
More information about the Glamor
mailing list