diff options
Diffstat (limited to 'glamor/glamor_egl.c')
-rw-r--r-- | glamor/glamor_egl.c | 121 |
1 files changed, 100 insertions, 21 deletions
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 53a74b8da..5708170a9 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -56,6 +56,7 @@ struct glamor_egl_screen_private { CloseScreenProcPtr CloseScreen; int fd; struct gbm_device *gbm; + int dmabuf_capable; CloseScreenProcPtr saved_close_screen; DestroyPixmapProcPtr saved_destroy_pixmap; @@ -329,10 +330,49 @@ glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap) } int -glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, - PixmapPtr pixmap, - unsigned int tex, - Bool want_name, CARD16 *stride, CARD32 *size) +glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, + uint32_t *strides, uint32_t *offsets, + uint64_t *modifier) +{ +#ifdef GLAMOR_HAS_GBM + struct gbm_bo *bo; +#ifdef GBM_BO_WITH_MODIFIERS + int num_fds, i; +#endif + + if (!glamor_make_pixmap_exportable(pixmap)) + return 0; + + bo = glamor_gbm_bo_from_pixmap(screen, pixmap); + if (!bo) + return 0; + +#ifdef GBM_BO_WITH_MODIFIERS + num_fds = gbm_bo_get_plane_count(bo); + for (i = 0; i < num_fds; i++) { + fds[i] = gbm_bo_get_fd(bo); + strides[i] = gbm_bo_get_stride_for_plane(bo, i); + offsets[i] = gbm_bo_get_offset(bo, i); + } + *modifier = gbm_bo_get_modifier(bo); +#else + fds[0] = gbm_bo_get_fd(bo); + strides[0] = gbm_bo_get_stride(bo); + offsets[0] = 0; + *modifier = 0; +#endif + + gbm_bo_destroy(bo); + return 1; +#else + return 0; +#endif +} + +int +glamor_egl_fd_name_from_pixmap(ScreenPtr screen, + PixmapPtr pixmap, + CARD16 *stride, CARD32 *size) { struct glamor_egl_screen_private *glamor_egl; struct gbm_bo *bo; @@ -346,12 +386,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, pixmap->devKind = gbm_bo_get_stride(bo); - if (want_name) { - glamor_get_name_from_bo(glamor_egl->fd, bo, &fd); - } - else { - fd = gbm_bo_get_fd(bo); - } + glamor_get_name_from_bo(glamor_egl->fd, bo, &fd); *stride = pixmap->devKind; *size = pixmap->devKind * gbm_bo_get_height(bo); @@ -396,19 +431,55 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap, } _X_EXPORT PixmapPtr -glamor_pixmap_from_fd(ScreenPtr screen, - int fd, - CARD16 width, - CARD16 height, - CARD16 stride, CARD8 depth, CARD8 bpp) +glamor_pixmap_from_fds(ScreenPtr screen, + CARD8 num_fds, int *fds, + CARD16 width, CARD16 height, + CARD32 *strides, CARD32 *offsets, + CARD8 depth, CARD8 bpp, + uint64_t modifier) { PixmapPtr pixmap; - Bool ret; + struct glamor_egl_screen_private *glamor_egl; + Bool ret = FALSE; + int i; + + glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0); - ret = glamor_back_pixmap_from_fd(pixmap, fd, width, height, - stride, depth, bpp); + +#ifdef GBM_BO_WITH_MODIFIERS + if (glamor_egl->dmabuf_capable) { + struct gbm_import_fd_modifier_data import_data = { 0 }; + struct gbm_bo *bo; + + import_data.width = width; + import_data.height = height; + import_data.num_fds = num_fds; + import_data.modifier = modifier; + for (i = 0; i < num_fds; i++) { + import_data.fds[i] = fds[i]; + import_data.strides[i] = strides[i]; + import_data.offsets[i] = offsets[i]; + } + import_data.format = GBM_FORMAT_ARGB8888; + bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD_MODIFIER, &import_data, 0); + if (bo) { + screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL); + ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo); + gbm_bo_destroy(bo); + } + } else +#endif + { + if (num_fds == 1) { + ret = glamor_back_pixmap_from_fd(pixmap, fds[0], width, height, + strides[0], depth, bpp); + } + } + if (ret == FALSE) { + for (i = 0; i < num_fds; i++) + close(fds[i]); screen->DestroyPixmap(pixmap); return NULL; } @@ -532,10 +603,10 @@ glamor_dri3_open_client(ClientPtr client, } static dri3_screen_info_rec glamor_dri3_info = { - .version = 1, + .version = 2, .open_client = glamor_dri3_open_client, - .pixmap_from_fd = glamor_pixmap_from_fd, - .fd_from_pixmap = glamor_fd_from_pixmap, + .pixmap_from_fds = glamor_pixmap_from_fds, + .fds_from_pixmap = glamor_egl_fds_from_pixmap, }; #endif /* DRI3 */ @@ -733,6 +804,14 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) xf86DrvMsg(scrn->scrnIndex, X_INFO, "glamor X acceleration enabled on %s\n", glGetString(GL_RENDERER)); +#ifdef GBM_BO_WITH_MODIFIERS + if (epoxy_has_egl_extension(glamor_egl->display, + "EGL_EXT_image_dma_buf_import") && + epoxy_has_egl_extension(glamor_egl->display, + "EGL_EXT_image_dma_buf_import_modifiers")) + glamor_egl->dmabuf_capable = TRUE; +#endif + glamor_egl->saved_free_screen = scrn->FreeScreen; scrn->FreeScreen = glamor_egl_free_screen; return TRUE; |