mirror of
https://github.com/X11Libre/xserver.git
synced 2026-10-26 01:59:57 +00:00
[PR #3877] glamor/glamor_egl: Add a fallback path to glamor_gbm_bo_from_pixmap_internal
nvidia's gbm backend has issues dealing with importing a gbm bo directly from an EGLImage This exports the image as dmabufs and imports a bo from dmabufs This is needed for DRI3 export on nvidia Fixes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/14047 v2: Don't pass usage flags Reviewed-by: James Jones <jajones@nvidia.com> Signed-off-by: stefan11111 <stefan11111github@gmail.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2321> (cherry picked from commitb522485155) (cherry picked from commit9f36f7bd50) PR: https://github.com/X11Libre/xserver/pull/3877 (cherry picked from commit74b69ba1b3) (cherry picked from commit d5f91a42c49e0a251c91f0cbe214a964805d61aa)
This commit is contained in:
parent
c0e0e3568c
commit
3715cb527e
1 changed files with 139 additions and 195 deletions
|
|
@ -26,7 +26,8 @@
|
||||||
* Zhigang Gong <zhigang.gong@linux.intel.com>
|
* Zhigang Gong <zhigang.gong@linux.intel.com>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <dix-config.h>
|
|
||||||
|
#include "dix-config.h"
|
||||||
|
|
||||||
#define GLAMOR_FOR_XORG
|
#define GLAMOR_FOR_XORG
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -41,11 +42,10 @@
|
||||||
#include <gbm.h>
|
#include <gbm.h>
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
|
|
||||||
#include "dix/screen_hooks_priv.h"
|
|
||||||
#include "glamor/glamor_priv.h"
|
|
||||||
#include "os/bug_priv.h"
|
|
||||||
|
|
||||||
#include "glamor_egl.h"
|
#include "glamor_egl.h"
|
||||||
|
|
||||||
|
#include "glamor.h"
|
||||||
|
#include "glamor_priv.h"
|
||||||
#include "glamor_glx_provider.h"
|
#include "glamor_glx_provider.h"
|
||||||
#include "dri3.h"
|
#include "dri3.h"
|
||||||
|
|
||||||
|
|
@ -53,12 +53,19 @@ struct glamor_egl_screen_private {
|
||||||
EGLDisplay display;
|
EGLDisplay display;
|
||||||
EGLContext context;
|
EGLContext context;
|
||||||
char *device_path;
|
char *device_path;
|
||||||
|
|
||||||
|
CreateScreenResourcesProcPtr CreateScreenResources;
|
||||||
|
CloseScreenProcPtr CloseScreen;
|
||||||
|
#ifdef EGL_MESA_image_dma_buf_export
|
||||||
|
int has_image_dma_buf_export;
|
||||||
|
#endif
|
||||||
|
int fd;
|
||||||
|
struct gbm_device *gbm;
|
||||||
|
int dmabuf_capable;
|
||||||
char *glvnd_vendor; /* GLVND vendor if forced from options or NULL otherwise */
|
char *glvnd_vendor; /* GLVND vendor if forced from options or NULL otherwise */
|
||||||
|
|
||||||
struct gbm_device *gbm;
|
CloseScreenProcPtr saved_close_screen;
|
||||||
int fd;
|
DestroyPixmapProcPtr saved_destroy_pixmap;
|
||||||
int dmabuf_capable;
|
|
||||||
|
|
||||||
xf86FreeScreenProc *saved_free_screen;
|
xf86FreeScreenProc *saved_free_screen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -141,6 +148,22 @@ glamor_egl_get_gbm_device(ScreenPtr screen)
|
||||||
return glamor_egl->gbm;
|
return glamor_egl->gbm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
|
||||||
|
{
|
||||||
|
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||||
|
PixmapPtr screen_pixmap;
|
||||||
|
|
||||||
|
screen_pixmap = screen->GetScreenPixmap(screen);
|
||||||
|
|
||||||
|
if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) {
|
||||||
|
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
|
||||||
|
"Failed to create textured screen.");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image,
|
glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image,
|
||||||
Bool used_modifiers)
|
Bool used_modifiers)
|
||||||
|
|
@ -149,8 +172,6 @@ glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image,
|
||||||
glamor_get_pixmap_private(pixmap);
|
glamor_get_pixmap_private(pixmap);
|
||||||
EGLImageKHR old;
|
EGLImageKHR old;
|
||||||
|
|
||||||
BUG_RETURN(!pixmap_priv);
|
|
||||||
|
|
||||||
old = pixmap_priv->image;
|
old = pixmap_priv->image;
|
||||||
if (old) {
|
if (old) {
|
||||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
|
|
@ -213,106 +234,12 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
|
||||||
Bool ret = FALSE;
|
Bool ret = FALSE;
|
||||||
|
|
||||||
glamor_egl = glamor_egl_get_screen_private(scrn);
|
glamor_egl = glamor_egl_get_screen_private(scrn);
|
||||||
#ifdef GBM_BO_FD_FOR_PLANE
|
|
||||||
uint64_t modifier = gbm_bo_get_modifier(bo);
|
|
||||||
const int num_planes = gbm_bo_get_plane_count(bo);
|
|
||||||
int fds[GBM_MAX_PLANES];
|
|
||||||
int plane;
|
|
||||||
int attr_num = 0;
|
|
||||||
EGLint img_attrs[64] = {0};
|
|
||||||
enum PlaneAttrs {
|
|
||||||
PLANE_FD,
|
|
||||||
PLANE_OFFSET,
|
|
||||||
PLANE_PITCH,
|
|
||||||
PLANE_MODIFIER_LO,
|
|
||||||
PLANE_MODIFIER_HI,
|
|
||||||
NUM_PLANE_ATTRS
|
|
||||||
};
|
|
||||||
static const EGLint planeAttrs[][NUM_PLANE_ATTRS] = {
|
|
||||||
{
|
|
||||||
EGL_DMA_BUF_PLANE0_FD_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE0_OFFSET_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE0_PITCH_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
EGL_DMA_BUF_PLANE1_FD_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE1_OFFSET_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE1_PITCH_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
EGL_DMA_BUF_PLANE2_FD_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE2_OFFSET_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE2_PITCH_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
EGL_DMA_BUF_PLANE3_FD_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE3_OFFSET_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE3_PITCH_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT,
|
|
||||||
EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (plane = 0; plane < num_planes; plane++) fds[plane] = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
#ifdef GBM_BO_FD_FOR_PLANE
|
image = eglCreateImageKHR(glamor_egl->display,
|
||||||
if (glamor_egl->dmabuf_capable) {
|
EGL_NO_CONTEXT,
|
||||||
#define ADD_ATTR(attrs, num, attr) \
|
EGL_NATIVE_PIXMAP_KHR, bo, NULL);
|
||||||
do { \
|
|
||||||
assert(((num) + 1) < (sizeof(attrs) / sizeof((attrs)[0]))); \
|
|
||||||
(attrs)[(num)++] = (attr); \
|
|
||||||
} while (0)
|
|
||||||
ADD_ATTR(img_attrs, attr_num, EGL_WIDTH);
|
|
||||||
ADD_ATTR(img_attrs, attr_num, gbm_bo_get_width(bo));
|
|
||||||
ADD_ATTR(img_attrs, attr_num, EGL_HEIGHT);
|
|
||||||
ADD_ATTR(img_attrs, attr_num, gbm_bo_get_height(bo));
|
|
||||||
ADD_ATTR(img_attrs, attr_num, EGL_LINUX_DRM_FOURCC_EXT);
|
|
||||||
ADD_ATTR(img_attrs, attr_num, gbm_bo_get_format(bo));
|
|
||||||
|
|
||||||
for (plane = 0; plane < num_planes; plane++) {
|
|
||||||
fds[plane] = gbm_bo_get_fd_for_plane(bo, plane);
|
|
||||||
ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_FD]);
|
|
||||||
ADD_ATTR(img_attrs, attr_num, fds[plane]);
|
|
||||||
ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_OFFSET]);
|
|
||||||
ADD_ATTR(img_attrs, attr_num, gbm_bo_get_offset(bo, plane));
|
|
||||||
ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_PITCH]);
|
|
||||||
ADD_ATTR(img_attrs, attr_num, gbm_bo_get_stride_for_plane(bo, plane));
|
|
||||||
ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_MODIFIER_LO]);
|
|
||||||
ADD_ATTR(img_attrs, attr_num, (uint32_t)(modifier & 0xFFFFFFFFULL));
|
|
||||||
ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_MODIFIER_HI]);
|
|
||||||
ADD_ATTR(img_attrs, attr_num, (uint32_t)(modifier >> 32ULL));
|
|
||||||
}
|
|
||||||
ADD_ATTR(img_attrs, attr_num, EGL_NONE);
|
|
||||||
#undef ADD_ATTR
|
|
||||||
|
|
||||||
image = eglCreateImageKHR(glamor_egl->display,
|
|
||||||
EGL_NO_CONTEXT,
|
|
||||||
EGL_LINUX_DMA_BUF_EXT,
|
|
||||||
NULL,
|
|
||||||
img_attrs);
|
|
||||||
|
|
||||||
for (plane = 0; plane < num_planes; plane++) {
|
|
||||||
close(fds[plane]);
|
|
||||||
fds[plane] = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
image = eglCreateImageKHR(glamor_egl->display,
|
|
||||||
EGL_NO_CONTEXT,
|
|
||||||
EGL_NATIVE_PIXMAP_KHR, bo, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image == EGL_NO_IMAGE_KHR) {
|
if (image == EGL_NO_IMAGE_KHR) {
|
||||||
glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
|
glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -354,8 +281,6 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap, Bool modifiers_ok)
|
||||||
PixmapPtr exported;
|
PixmapPtr exported;
|
||||||
GCPtr scratch_gc;
|
GCPtr scratch_gc;
|
||||||
|
|
||||||
BUG_RETURN_VAL(!pixmap_priv, FALSE);
|
|
||||||
|
|
||||||
if (pixmap_priv->image &&
|
if (pixmap_priv->image &&
|
||||||
(modifiers_ok || !pixmap_priv->used_modifiers))
|
(modifiers_ok || !pixmap_priv->used_modifiers))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
@ -391,30 +316,8 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap, Bool modifiers_ok)
|
||||||
|
|
||||||
glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
|
glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
|
||||||
|
|
||||||
if (num_modifiers > 0) {
|
bo = gbm_bo_create_with_modifiers(glamor_egl->gbm, width, height,
|
||||||
#ifdef GBM_BO_WITH_MODIFIERS2
|
format, modifiers, num_modifiers);
|
||||||
/* TODO: Is scanout ever used? If so, where? */
|
|
||||||
bo = gbm_bo_create_with_modifiers2(glamor_egl->gbm, width, height,
|
|
||||||
format, modifiers, num_modifiers,
|
|
||||||
GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
|
|
||||||
if (!bo) {
|
|
||||||
/* something failed, try again without GBM_BO_USE_SCANOUT */
|
|
||||||
/* maybe scanout does work, but modifiers aren't supported */
|
|
||||||
/* we handle this case on the fallback path */
|
|
||||||
bo = gbm_bo_create_with_modifiers2(glamor_egl->gbm, width, height,
|
|
||||||
format, modifiers, num_modifiers,
|
|
||||||
GBM_BO_USE_RENDERING);
|
|
||||||
#if 0
|
|
||||||
if (bo) {
|
|
||||||
/* TODO: scanout failed, but regular buffer succeeded, maybe log something? */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
bo = gbm_bo_create_with_modifiers(glamor_egl->gbm, width, height,
|
|
||||||
format, modifiers, num_modifiers);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (bo)
|
if (bo)
|
||||||
used_modifiers = TRUE;
|
used_modifiers = TRUE;
|
||||||
free(modifiers);
|
free(modifiers);
|
||||||
|
|
@ -423,27 +326,12 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap, Bool modifiers_ok)
|
||||||
|
|
||||||
if (!bo)
|
if (!bo)
|
||||||
{
|
{
|
||||||
/* TODO: Is scanout ever used? If so, where? */
|
|
||||||
bo = gbm_bo_create(glamor_egl->gbm, width, height, format,
|
bo = gbm_bo_create(glamor_egl->gbm, width, height, format,
|
||||||
#ifdef GLAMOR_HAS_GBM_LINEAR
|
#ifdef GLAMOR_HAS_GBM_LINEAR
|
||||||
(pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
|
(pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
|
||||||
GBM_BO_USE_LINEAR : 0) |
|
GBM_BO_USE_LINEAR : 0) |
|
||||||
#endif
|
#endif
|
||||||
GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
|
GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
|
||||||
if (!bo) {
|
|
||||||
/* something failed, try again without GBM_BO_USE_SCANOUT */
|
|
||||||
bo = gbm_bo_create(glamor_egl->gbm, width, height, format,
|
|
||||||
#ifdef GLAMOR_HAS_GBM_LINEAR
|
|
||||||
(pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
|
|
||||||
GBM_BO_USE_LINEAR : 0) |
|
|
||||||
GBM_BO_USE_RENDERING);
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
if (bo) {
|
|
||||||
/* TODO: scanout failed, but regular buffer succeeded, maybe log something? */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bo) {
|
if (!bo) {
|
||||||
|
|
@ -461,7 +349,7 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap, Bool modifiers_ok)
|
||||||
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
|
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
|
||||||
"Failed to make %dx%dx%dbpp pixmap from GBM bo\n",
|
"Failed to make %dx%dx%dbpp pixmap from GBM bo\n",
|
||||||
width, height, pixmap->drawable.bitsPerPixel);
|
width, height, pixmap->drawable.bitsPerPixel);
|
||||||
dixDestroyPixmap(exported, 0);
|
screen->DestroyPixmap(exported);
|
||||||
gbm_bo_destroy(bo);
|
gbm_bo_destroy(bo);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -482,7 +370,7 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap, Bool modifiers_ok)
|
||||||
/* Swap the devKind into the original pixmap, reflecting the bo's stride */
|
/* Swap the devKind into the original pixmap, reflecting the bo's stride */
|
||||||
screen->ModifyPixmapHeader(pixmap, 0, 0, 0, 0, exported->devKind, NULL);
|
screen->ModifyPixmapHeader(pixmap, 0, 0, 0, 0, exported->devKind, NULL);
|
||||||
|
|
||||||
dixDestroyPixmap(exported, 0);
|
screen->DestroyPixmap(exported);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -494,14 +382,58 @@ glamor_gbm_bo_from_pixmap_internal(ScreenPtr screen, PixmapPtr pixmap)
|
||||||
glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
|
glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
|
||||||
struct glamor_pixmap_private *pixmap_priv =
|
struct glamor_pixmap_private *pixmap_priv =
|
||||||
glamor_get_pixmap_private(pixmap);
|
glamor_get_pixmap_private(pixmap);
|
||||||
|
struct gbm_bo* ret = NULL;
|
||||||
BUG_RETURN_VAL(!pixmap_priv, NULL);
|
#ifdef EGL_MESA_image_dma_buf_export
|
||||||
|
int fourcc = 0;
|
||||||
|
int num_planes = 0;
|
||||||
|
struct gbm_import_fd_modifier_data fd_modifier_data;
|
||||||
|
EGLuint64KHR modifiers[GBM_MAX_PLANES] = {0};
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!pixmap_priv->image)
|
if (!pixmap_priv->image)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE,
|
ret = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE,
|
||||||
pixmap_priv->image, GBM_BO_USE_RENDERING);
|
pixmap_priv->image, 0);
|
||||||
|
|
||||||
|
#ifdef EGL_MESA_image_dma_buf_export
|
||||||
|
if (ret || !glamor_egl->has_image_dma_buf_export) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef GBM_MAX_PLANES
|
||||||
|
#define GBM_MAX_PLANES 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!eglExportDMABUFImageQueryMESA(glamor_egl->display, pixmap_priv->image, &fourcc, &num_planes, modifiers) || (num_planes > GBM_MAX_PLANES)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_modifier_data = (struct gbm_import_fd_modifier_data) {
|
||||||
|
.width = pixmap->drawable.width,
|
||||||
|
.height = pixmap->drawable.height,
|
||||||
|
.format = fourcc, /* GBM and DRM formats are the same */
|
||||||
|
.num_fds = num_planes,
|
||||||
|
.modifier = modifiers[0],
|
||||||
|
.fds = {-1, -1, -1, -1},
|
||||||
|
.strides = {0},
|
||||||
|
.offsets = {0},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (eglExportDMABUFImageMESA(glamor_egl->display, pixmap_priv->image,
|
||||||
|
fd_modifier_data.fds,
|
||||||
|
fd_modifier_data.strides,
|
||||||
|
fd_modifier_data.offsets)) {
|
||||||
|
ret = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD_MODIFIER,
|
||||||
|
&fd_modifier_data, 0);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < num_planes; i++) {
|
||||||
|
if (fd_modifier_data.fds[i] >= 0) {
|
||||||
|
close(fd_modifier_data.fds[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gbm_bo *
|
struct gbm_bo *
|
||||||
|
|
@ -518,7 +450,7 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
|
||||||
uint32_t *strides, uint32_t *offsets,
|
uint32_t *strides, uint32_t *offsets,
|
||||||
uint64_t *modifier)
|
uint64_t *modifier)
|
||||||
{
|
{
|
||||||
#ifdef GLAMOR_HAS_GBM
|
#ifdef HAVE_GBM
|
||||||
struct gbm_bo *bo;
|
struct gbm_bo *bo;
|
||||||
int num_fds;
|
int num_fds;
|
||||||
#ifdef GBM_BO_WITH_MODIFIERS
|
#ifdef GBM_BO_WITH_MODIFIERS
|
||||||
|
|
@ -586,7 +518,7 @@ int
|
||||||
glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
|
glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
|
||||||
CARD16 *stride, CARD32 *size)
|
CARD16 *stride, CARD32 *size)
|
||||||
{
|
{
|
||||||
#ifdef GLAMOR_HAS_GBM
|
#ifdef HAVE_GBM
|
||||||
struct gbm_bo *bo;
|
struct gbm_bo *bo;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
|
@ -686,8 +618,7 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
|
||||||
import_data.width = width;
|
import_data.width = width;
|
||||||
import_data.height = height;
|
import_data.height = height;
|
||||||
import_data.stride = stride;
|
import_data.stride = stride;
|
||||||
bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD, &import_data,
|
bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD, &import_data, 0);
|
||||||
GBM_BO_USE_RENDERING);
|
|
||||||
if (!bo)
|
if (!bo)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
@ -733,8 +664,7 @@ glamor_pixmap_from_fds(ScreenPtr screen,
|
||||||
import_data.strides[i] = strides[i];
|
import_data.strides[i] = strides[i];
|
||||||
import_data.offsets[i] = offsets[i];
|
import_data.offsets[i] = offsets[i];
|
||||||
}
|
}
|
||||||
bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD_MODIFIER, &import_data,
|
bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD_MODIFIER, &import_data, 0);
|
||||||
GBM_BO_USE_RENDERING);
|
|
||||||
if (bo) {
|
if (bo) {
|
||||||
screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL);
|
screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, strides[0], NULL);
|
||||||
ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo, TRUE);
|
ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo, TRUE);
|
||||||
|
|
@ -751,7 +681,7 @@ glamor_pixmap_from_fds(ScreenPtr screen,
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (ret == FALSE) {
|
if (ret == FALSE) {
|
||||||
dixDestroyPixmap(pixmap, 0);
|
screen->DestroyPixmap(pixmap);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return pixmap;
|
return pixmap;
|
||||||
|
|
@ -773,7 +703,7 @@ glamor_pixmap_from_fd(ScreenPtr screen,
|
||||||
stride, depth, bpp);
|
stride, depth, bpp);
|
||||||
|
|
||||||
if (ret == FALSE) {
|
if (ret == FALSE) {
|
||||||
dixDestroyPixmap(pixmap, 0);
|
screen->DestroyPixmap(pixmap);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return pixmap;
|
return pixmap;
|
||||||
|
|
@ -786,12 +716,10 @@ glamor_get_formats(ScreenPtr screen,
|
||||||
#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF
|
#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF
|
||||||
struct glamor_egl_screen_private *glamor_egl;
|
struct glamor_egl_screen_private *glamor_egl;
|
||||||
EGLint num;
|
EGLint num;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Explicitly zero the count and formats as the caller may ignore the return value */
|
/* Explicitly zero the count as the caller may ignore the return value */
|
||||||
*num_formats = 0;
|
*num_formats = 0;
|
||||||
*formats = NULL;
|
|
||||||
#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF
|
|
||||||
glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
|
glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
|
||||||
|
|
||||||
if (!glamor_egl->dmabuf_capable)
|
if (!glamor_egl->dmabuf_capable)
|
||||||
|
|
@ -810,13 +738,15 @@ glamor_get_formats(ScreenPtr screen,
|
||||||
if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, num,
|
if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, num,
|
||||||
(EGLint *) *formats, &num)) {
|
(EGLint *) *formats, &num)) {
|
||||||
free(*formats);
|
free(*formats);
|
||||||
*formats = NULL;
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*num_formats = num;
|
*num_formats = num;
|
||||||
#endif
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
#else
|
||||||
|
*num_formats = 0;
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
|
|
@ -826,12 +756,10 @@ glamor_get_modifiers(ScreenPtr screen, uint32_t format,
|
||||||
#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF
|
#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF
|
||||||
struct glamor_egl_screen_private *glamor_egl;
|
struct glamor_egl_screen_private *glamor_egl;
|
||||||
EGLint num;
|
EGLint num;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Explicitly zero the count and modifiers as the caller may ignore the return value */
|
/* Explicitly zero the count as the caller may ignore the return value */
|
||||||
*num_modifiers = 0;
|
*num_modifiers = 0;
|
||||||
*modifiers = NULL;
|
|
||||||
#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF
|
|
||||||
glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
|
glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
|
||||||
|
|
||||||
if (!glamor_egl->dmabuf_capable)
|
if (!glamor_egl->dmabuf_capable)
|
||||||
|
|
@ -856,8 +784,11 @@ glamor_get_modifiers(ScreenPtr screen, uint32_t format,
|
||||||
}
|
}
|
||||||
|
|
||||||
*num_modifiers = num;
|
*num_modifiers = num;
|
||||||
#endif
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
#else
|
||||||
|
*num_modifiers = 0;
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
|
@ -875,20 +806,30 @@ glamor_egl_get_driver_name(ScreenPtr screen)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void glamor_egl_pixmap_destroy(CallbackListPtr *pcbl, ScreenPtr pScreen, PixmapPtr pixmap)
|
|
||||||
|
static Bool
|
||||||
|
glamor_egl_destroy_pixmap(PixmapPtr pixmap)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||||
struct glamor_egl_screen_private *glamor_egl =
|
struct glamor_egl_screen_private *glamor_egl =
|
||||||
glamor_egl_get_screen_private(scrn);
|
glamor_egl_get_screen_private(scrn);
|
||||||
|
Bool ret;
|
||||||
|
|
||||||
struct glamor_pixmap_private *pixmap_priv =
|
if (pixmap->refcnt == 1) {
|
||||||
glamor_get_pixmap_private(pixmap);
|
struct glamor_pixmap_private *pixmap_priv =
|
||||||
|
glamor_get_pixmap_private(pixmap);
|
||||||
|
|
||||||
BUG_RETURN(!pixmap_priv);
|
if (pixmap_priv->image)
|
||||||
|
eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
|
||||||
|
}
|
||||||
|
|
||||||
if (pixmap_priv->image)
|
screen->DestroyPixmap = glamor_egl->saved_destroy_pixmap;
|
||||||
eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
|
ret = screen->DestroyPixmap(pixmap);
|
||||||
|
glamor_egl->saved_destroy_pixmap = screen->DestroyPixmap;
|
||||||
|
screen->DestroyPixmap = glamor_egl_destroy_pixmap;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -905,10 +846,8 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
|
||||||
|
|
||||||
temp_img = back_priv->image;
|
temp_img = back_priv->image;
|
||||||
temp_mod = back_priv->used_modifiers;
|
temp_mod = back_priv->used_modifiers;
|
||||||
BUG_RETURN(!back_priv);
|
|
||||||
back_priv->image = front_priv->image;
|
back_priv->image = front_priv->image;
|
||||||
back_priv->used_modifiers = front_priv->used_modifiers;
|
back_priv->used_modifiers = front_priv->used_modifiers;
|
||||||
BUG_RETURN(!front_priv);
|
|
||||||
front_priv->image = temp_img;
|
front_priv->image = temp_img;
|
||||||
front_priv->used_modifiers = temp_mod;
|
front_priv->used_modifiers = temp_mod;
|
||||||
|
|
||||||
|
|
@ -916,7 +855,8 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
|
||||||
glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
|
glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void glamor_egl_close_screen(CallbackListPtr *pcbl, ScreenPtr screen, void *unused)
|
static Bool
|
||||||
|
glamor_egl_close_screen(ScreenPtr screen)
|
||||||
{
|
{
|
||||||
ScrnInfoPtr scrn;
|
ScrnInfoPtr scrn;
|
||||||
struct glamor_egl_screen_private *glamor_egl;
|
struct glamor_egl_screen_private *glamor_egl;
|
||||||
|
|
@ -926,15 +866,14 @@ static void glamor_egl_close_screen(CallbackListPtr *pcbl, ScreenPtr screen, voi
|
||||||
scrn = xf86ScreenToScrn(screen);
|
scrn = xf86ScreenToScrn(screen);
|
||||||
glamor_egl = glamor_egl_get_screen_private(scrn);
|
glamor_egl = glamor_egl_get_screen_private(scrn);
|
||||||
screen_pixmap = screen->GetScreenPixmap(screen);
|
screen_pixmap = screen->GetScreenPixmap(screen);
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
|
pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
|
||||||
BUG_RETURN(!pixmap_priv);
|
|
||||||
|
|
||||||
eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
|
eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
|
||||||
pixmap_priv->image = NULL;
|
pixmap_priv->image = NULL;
|
||||||
|
|
||||||
dixScreenUnhookClose(screen, glamor_egl_close_screen);
|
screen->CloseScreen = glamor_egl->saved_close_screen;
|
||||||
dixScreenUnhookPixmapDestroy(screen, glamor_egl_pixmap_destroy);
|
|
||||||
|
return screen->CloseScreen(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DRI3
|
#ifdef DRI3
|
||||||
|
|
@ -1014,8 +953,11 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
|
||||||
#endif
|
#endif
|
||||||
const char *gbm_backend_name;
|
const char *gbm_backend_name;
|
||||||
|
|
||||||
dixScreenHookClose(screen, glamor_egl_close_screen);
|
glamor_egl->saved_close_screen = screen->CloseScreen;
|
||||||
dixScreenHookPixmapDestroy(screen, glamor_egl_pixmap_destroy);
|
screen->CloseScreen = glamor_egl_close_screen;
|
||||||
|
|
||||||
|
glamor_egl->saved_destroy_pixmap = screen->DestroyPixmap;
|
||||||
|
screen->DestroyPixmap = glamor_egl_destroy_pixmap;
|
||||||
|
|
||||||
glamor_ctx->ctx = glamor_egl->context;
|
glamor_ctx->ctx = glamor_egl->context;
|
||||||
glamor_ctx->display = glamor_egl->display;
|
glamor_ctx->display = glamor_egl->display;
|
||||||
|
|
@ -1059,6 +1001,7 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
|
||||||
#ifdef GLXEXT
|
#ifdef GLXEXT
|
||||||
if (!vendor_initialized) {
|
if (!vendor_initialized) {
|
||||||
GlxPushProvider(&glamor_provider);
|
GlxPushProvider(&glamor_provider);
|
||||||
|
xorgGlxCreateVendor();
|
||||||
vendor_initialized = TRUE;
|
vendor_initialized = TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1154,7 +1097,7 @@ glamor_egl_try_gles_api(ScrnInfoPtr scrn)
|
||||||
{
|
{
|
||||||
struct glamor_egl_screen_private *glamor_egl =
|
struct glamor_egl_screen_private *glamor_egl =
|
||||||
glamor_egl_get_screen_private(scrn);
|
glamor_egl_get_screen_private(scrn);
|
||||||
|
|
||||||
static const EGLint config_attribs[] = {
|
static const EGLint config_attribs[] = {
|
||||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
|
|
@ -1216,12 +1159,9 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
|
||||||
memcpy(options, GlamorEGLOptions, sizeof(GlamorEGLOptions));
|
memcpy(options, GlamorEGLOptions, sizeof(GlamorEGLOptions));
|
||||||
xf86ProcessOptions(scrn->scrnIndex, scrn->options, options);
|
xf86ProcessOptions(scrn->scrnIndex, scrn->options, options);
|
||||||
glvnd_vendor = xf86GetOptValString(options, GLAMOREGLOPT_VENDOR_LIBRARY);
|
glvnd_vendor = xf86GetOptValString(options, GLAMOREGLOPT_VENDOR_LIBRARY);
|
||||||
if (glvnd_vendor) {
|
if (glvnd_vendor)
|
||||||
glamor_egl->glvnd_vendor = strdup(glvnd_vendor);
|
glamor_egl->glvnd_vendor = XNFstrdup(glvnd_vendor);
|
||||||
if (!glamor_egl->glvnd_vendor) {
|
|
||||||
xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Couldn't set gl vendor to: %s\n", glvnd_vendor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
api = xf86GetOptValString(options, GLAMOREGLOPT_RENDERING_API);
|
api = xf86GetOptValString(options, GLAMOREGLOPT_RENDERING_API);
|
||||||
if (api && !strncasecmp(api, "es", 2))
|
if (api && !strncasecmp(api, "es", 2))
|
||||||
force_es = TRUE;
|
force_es = TRUE;
|
||||||
|
|
@ -1250,6 +1190,10 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EGL_MESA_image_dma_buf_export
|
||||||
|
glamor_egl->has_image_dma_buf_export = epoxy_has_egl_extension(glamor_egl->display, "EGL_MESA_image_dma_buf_export");
|
||||||
|
#endif
|
||||||
|
|
||||||
#define GLAMOR_CHECK_EGL_EXTENSION(EXT) \
|
#define GLAMOR_CHECK_EGL_EXTENSION(EXT) \
|
||||||
if (!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT)) { \
|
if (!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT)) { \
|
||||||
ErrorF("EGL_" #EXT " required.\n"); \
|
ErrorF("EGL_" #EXT " required.\n"); \
|
||||||
|
|
@ -1331,7 +1275,7 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
|
||||||
glamor_egl->dmabuf_capable = TRUE;
|
glamor_egl->dmabuf_capable = TRUE;
|
||||||
else if (strstr((const char *)renderer, "zink"))
|
else if (strstr((const char *)renderer, "zink"))
|
||||||
glamor_egl->dmabuf_capable = TRUE;
|
glamor_egl->dmabuf_capable = TRUE;
|
||||||
else if (strstr((const char *)renderer, "NVIDIA"))
|
else if (strstr((const char *)renderer, "radeonsi"))
|
||||||
glamor_egl->dmabuf_capable = TRUE;
|
glamor_egl->dmabuf_capable = TRUE;
|
||||||
else
|
else
|
||||||
glamor_egl->dmabuf_capable = FALSE;
|
glamor_egl->dmabuf_capable = FALSE;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue