Files
fml13v01-buildroot/package/mesa3d/0048-gbm-add-pbuffer-support.patch
T
2022-08-16 17:38:05 +08:00

230 lines
7.8 KiB
Diff

From 4d19dc5cc9be4f3f25ed8befbfcda70c047065d3 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Fri, 21 Aug 2020 12:13:28 +0100
Subject: [PATCH 48/67] gbm: add pbuffer support
The EGL backend GLX provider for XWayland may get the EGL configs it
uses to generate the GLX ones from GBM. That platform doesn't support
pbuffers. When the client tries to match GLX configs with the DRI ones,
a mismatch in the pbuffer attributes will result in the GLX config
being rejected.
Although support for creating pbuffers has been added, this isn't
required when using the EGL backend GLX provider, as indirect GLX
isn't supported.
---
src/egl/drivers/dri2/egl_dri2.h | 3 +
src/egl/drivers/dri2/platform_drm.c | 110 +++++++++++++++++++++++++---
2 files changed, 103 insertions(+), 10 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 13b808bff80..141df1b1732 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -471,6 +471,9 @@ struct dri2_egl_surface
/* surfaceless and device */
__DRIimage *front;
unsigned int visual;
+#ifdef HAVE_DRM_PLATFORM
+ struct gbm_bo *front_bo;
+#endif
#ifdef HAVE_WAYLAND_PLATFORM
void *swrast_front;
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 2b329437f88..258e8b6593e 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -41,6 +41,38 @@
#include "egl_dri2.h"
#include "loader.h"
+static bool
+dri2_drm_alloc_front_image(struct dri2_egl_surface *dri2_surf)
+{
+ if (!dri2_surf->front_bo) {
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
+
+ dri2_surf->front_bo = gbm_bo_create(&dri2_dpy->gbm_dri->base,
+ surf->base.v0.width,
+ surf->base.v0.height,
+ surf->base.v0.format,
+ surf->base.v0.flags);
+ if (!dri2_surf->front_bo) {
+ _eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void
+dri2_drm_free_front_image(struct dri2_egl_surface *dri2_surf)
+{
+ if (dri2_surf->front_bo) {
+ gbm_bo_destroy(dri2_surf->front_bo);
+ dri2_surf->front_bo = NULL;
+ }
+}
+
static struct gbm_bo *
lock_front_buffer(struct gbm_surface *_surf)
{
@@ -138,8 +170,8 @@ dri2_drm_config_is_compatible(struct dri2_egl_display *dri2_dpy,
}
static _EGLSurface *
-dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
- void *native_surface, const EGLint *attrib_list)
+dri2_drm_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
+ void *native_surface, const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
@@ -154,11 +186,25 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
- if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf,
+ if (!dri2_init_surface(&dri2_surf->base, disp, type, conf,
attrib_list, false, native_surface))
goto cleanup_surf;
- config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+ if (type == EGL_PBUFFER_BIT) {
+ struct gbm_device *gbm = disp->PlatformDisplay;
+ _EGLSurface *surf = &dri2_surf->base;
+
+ assert(!surface);
+
+ surface = gbm_surface_create(gbm, surf->Width, surf->Height,
+ conf->NativeVisualID, GBM_BO_USE_RENDERING);
+ if (!surface) {
+ _eglError(EGL_BAD_ALLOC, "Failed to allocate pbuffer GBM surface");
+ goto cleanup_surf;
+ }
+ }
+
+ config = dri2_get_dri_config(dri2_conf, type,
dri2_surf->base.GLColorspace);
if (!config) {
@@ -183,11 +229,22 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
return &dri2_surf->base;
cleanup_surf:
+ if (type == EGL_PBUFFER_BIT && surface != NULL)
+ gbm_surface_destroy(surface);
+
free(dri2_surf);
return NULL;
}
+static _EGLSurface *
+dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
+ void *native_surface, const EGLint *attrib_list)
+{
+ return dri2_drm_create_surface(disp, EGL_WINDOW_BIT, conf,
+ native_surface, attrib_list);
+}
+
static _EGLSurface *
dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
void *native_window, const EGLint *attrib_list)
@@ -202,6 +259,14 @@ dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
+static _EGLSurface *
+dri2_drm_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
+ const EGLint *attrib_list)
+{
+ return dri2_drm_create_surface(disp, EGL_PBUFFER_BIT, conf,
+ NULL, attrib_list);
+}
+
static EGLBoolean
dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
{
@@ -217,6 +282,11 @@ dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dri2_egl_surface_free_local_buffers(dri2_surf);
+ dri2_drm_free_front_image(dri2_surf);
+
+ if (surf->Type == EGL_PBUFFER_BIT)
+ gbm_surface_destroy(&dri2_surf->gbm_surf->base);
+
dri2_fini_surface(surf);
free(surf);
@@ -402,12 +472,27 @@ dri2_drm_image_get_buffers(__DRIdrawable *driDrawable,
struct dri2_egl_surface *dri2_surf = loaderPrivate;
struct gbm_dri_bo *bo;
- if (get_back_bo(dri2_surf) < 0)
- return 0;
+ buffers->image_mask = 0;
+ buffers->front = NULL;
+ buffers->back = NULL;
- bo = gbm_dri_bo(dri2_surf->back->bo);
- buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
- buffers->back = bo->image;
+ if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
+ if (!dri2_drm_alloc_front_image(dri2_surf))
+ return 0;
+
+ bo = gbm_dri_bo(dri2_surf->front_bo);
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
+ buffers->front = bo->image;
+ }
+
+ if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
+ if (get_back_bo(dri2_surf) < 0)
+ return 0;
+
+ bo = gbm_dri_bo(dri2_surf->back->bo);
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
+ buffers->back = bo->image;
+ }
return 1;
}
@@ -425,6 +510,9 @@ dri2_drm_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ if (dri2_surf->base.Type != EGL_WINDOW_BIT)
+ return EGL_TRUE;
+
if (!dri2_dpy->flush) {
dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
return EGL_TRUE;
@@ -648,7 +736,8 @@ drm_add_configs_for_visuals(_EGLDisplay *disp)
};
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
- config_count + 1, EGL_WINDOW_BIT, attr_list, NULL, NULL);
+ config_count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ attr_list, NULL, NULL);
if (dri2_conf) {
if (dri2_conf->base.ConfigID == config_count + 1)
config_count++;
@@ -672,6 +761,7 @@ static const struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
.authenticate = dri2_drm_authenticate,
.create_window_surface = dri2_drm_create_window_surface,
.create_pixmap_surface = dri2_drm_create_pixmap_surface,
+ .create_pbuffer_surface = dri2_drm_create_pbuffer_surface,
.destroy_surface = dri2_drm_destroy_surface,
.create_image = dri2_drm_create_image_khr,
.swap_buffers = dri2_drm_swap_buffers,
--
2.25.1