From 210c71b856d17fc7168c70d99dad25d996b1ae0d Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 17 Dec 2023 09:56:42 +0100 Subject: [PATCH] egl: Split out a function This makes no sense by itself, but we want to create the EGLImage at DmabufTexture construction so that we can actually reject dmabufs that we can't create EGLImages for. This will make it possible to bail when the stride limitation for AMD GPUs hits. --- gdk/gdkdisplay.c | 1 + gdk/gdkdmabufegl.c | 87 ++++++++++++++++++++++++++++++++++++++- gdk/gdkdmabufeglprivate.h | 18 ++++++++ gdk/gdkdmabufprivate.h | 3 -- gdk/gdkglcontext.c | 83 +++++-------------------------------- 5 files changed, 114 insertions(+), 78 deletions(-) create mode 100644 gdk/gdkdmabufeglprivate.h diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index 4037574139..212e710721 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -31,6 +31,7 @@ #include "gdkclipboardprivate.h" #include "gdkdeviceprivate.h" #include "gdkdisplaymanagerprivate.h" +#include "gdkdmabufeglprivate.h" #include "gdkdmabufformatsbuilderprivate.h" #include "gdkdmabufformatsprivate.h" #include "gdkdmabuftextureprivate.h" diff --git a/gdk/gdkdmabufegl.c b/gdk/gdkdmabufegl.c index 0a33996c23..b6a486cd32 100644 --- a/gdk/gdkdmabufegl.c +++ b/gdk/gdkdmabufegl.c @@ -19,7 +19,7 @@ #include "config.h" #if defined(HAVE_DMABUF) && defined (HAVE_EGL) -#include "gdkdmabufprivate.h" +#include "gdkdmabufeglprivate.h" #include "gdkdmabufformatsbuilderprivate.h" #include "gdkdebugprivate.h" @@ -31,7 +31,6 @@ #include "gdktexturedownloader.h" #include -#include /* A dmabuf downloader implementation that downloads buffers via * gsk_renderer_render_texture + GL texture download. @@ -259,4 +258,88 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display, return NULL; } +EGLImage +gdk_dmabuf_egl_create_image (GdkDisplay *display, + int width, + int height, + const GdkDmabuf *dmabuf, + int target) +{ + EGLDisplay egl_display = gdk_display_get_egl_display (display); + EGLint attribs[64]; + int i; + EGLImage image; + + g_return_val_if_fail (width > 0, 0); + g_return_val_if_fail (height > 0, 0); + g_return_val_if_fail (1 <= dmabuf->n_planes && dmabuf->n_planes <= 4, 0); + g_return_val_if_fail (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES, 0); + + if (egl_display == EGL_NO_DISPLAY || !display->have_egl_dma_buf_import) + { + GDK_DISPLAY_DEBUG (display, DMABUF, + "Can't import dmabufs into GL, missing EGL or EGL_EXT_image_dma_buf_import_modifiers"); + return EGL_NO_IMAGE; + } + + GDK_DISPLAY_DEBUG (display, DMABUF, + "Importing dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %u) into GL", + (char *) &dmabuf->fourcc, dmabuf->modifier, dmabuf->n_planes); + + i = 0; + attribs[i++] = EGL_IMAGE_PRESERVED_KHR; + attribs[i++] = EGL_TRUE; + attribs[i++] = EGL_WIDTH; + attribs[i++] = width; + attribs[i++] = EGL_HEIGHT; + attribs[i++] = height; + attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT; + attribs[i++] = dmabuf->fourcc; + attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT; + attribs[i++] = EGL_ITU_REC601_EXT; + attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT; + attribs[i++] = EGL_YUV_FULL_RANGE_EXT; + +#define ADD_PLANE(plane) \ + { \ + if (dmabuf->modifier != DRM_FORMAT_MOD_INVALID) \ + { \ + attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_MODIFIER_LO_EXT; \ + attribs[i++] = dmabuf->modifier & 0xFFFFFFFF; \ + attribs[i++] = EGL_DMA_BUF_PLANE## plane ## _MODIFIER_HI_EXT; \ + attribs[i++] = dmabuf->modifier >> 32; \ + } \ + attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_FD_EXT; \ + attribs[i++] = dmabuf->planes[plane].fd; \ + attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_PITCH_EXT; \ + attribs[i++] = dmabuf->planes[plane].stride; \ + attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_OFFSET_EXT; \ + attribs[i++] = dmabuf->planes[plane].offset; \ + } + + ADD_PLANE (0); + + if (dmabuf->n_planes > 1) ADD_PLANE (1); + if (dmabuf->n_planes > 2) ADD_PLANE (2); + if (dmabuf->n_planes > 3) ADD_PLANE (3); + + attribs[i++] = EGL_NONE; + + image = eglCreateImageKHR (egl_display, + EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, + (EGLClientBuffer)NULL, + attribs); + + if (image == EGL_NO_IMAGE) + { + GDK_DISPLAY_DEBUG (display, DMABUF, + "Creating EGLImage for dmabuf failed: %#x", + eglGetError ()); + return 0; + } + + return image; +} + #endif /* HAVE_DMABUF && HAVE_EGL */ diff --git a/gdk/gdkdmabufeglprivate.h b/gdk/gdkdmabufeglprivate.h new file mode 100644 index 0000000000..4ff1a0f614 --- /dev/null +++ b/gdk/gdkdmabufeglprivate.h @@ -0,0 +1,18 @@ +#pragma once + +#if defined(HAVE_DMABUF) && defined (HAVE_EGL) + +#include "gdkdmabufprivate.h" +#include "gdkdmabufdownloaderprivate.h" + +#include + +GdkDmabufDownloader * gdk_dmabuf_get_egl_downloader (GdkDisplay *display, + GdkDmabufFormatsBuilder *builder); +EGLImage gdk_dmabuf_egl_create_image (GdkDisplay *display, + int width, + int height, + const GdkDmabuf *dmabuf, + int target); + +#endif /* HAVE_DMABUF && HAVE_EGL */ diff --git a/gdk/gdkdmabufprivate.h b/gdk/gdkdmabufprivate.h index 939a6c3692..cd12e07ac1 100644 --- a/gdk/gdkdmabufprivate.h +++ b/gdk/gdkdmabufprivate.h @@ -40,9 +40,6 @@ struct _GdkDmabufDownloader #ifdef HAVE_DMABUF -const GdkDmabufDownloader * gdk_dmabuf_get_egl_downloader (GdkDisplay *display, - GdkDmabufFormatsBuilder *builder); - GdkDmabufFormats * gdk_dmabuf_get_mmap_formats (void) G_GNUC_CONST; void gdk_dmabuf_download_mmap (GdkTexture *texture, GdkMemoryFormat format, diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index e67bee79b6..1a405442b2 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -78,7 +78,7 @@ #include "gdkdebugprivate.h" #include "gdkdisplayprivate.h" -#include +#include "gdkdmabufeglprivate.h" #include "gdkmemoryformatprivate.h" #include "gdkmemorytextureprivate.h" #include "gdkprofilerprivate.h" @@ -87,6 +87,8 @@ #include "gdkprivate.h" +#include + #ifdef GDK_WINDOWING_WIN32 # include "gdk/win32/gdkwin32.h" #endif @@ -2159,81 +2161,16 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self, { #if defined(HAVE_EGL) && defined(HAVE_DMABUF) GdkDisplay *display = gdk_gl_context_get_display (self); - EGLDisplay egl_display = gdk_display_get_egl_display (display); - EGLint attribs[64]; - int i; EGLImage image; guint texture_id; - g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), 0); - g_return_val_if_fail (width > 0, 0); - g_return_val_if_fail (height > 0, 0); - g_return_val_if_fail (1 <= dmabuf->n_planes && dmabuf->n_planes <= 4, 0); - g_return_val_if_fail (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES, 0); - - if (egl_display == EGL_NO_DISPLAY || !display->have_egl_dma_buf_import) - { - GDK_DISPLAY_DEBUG (display, DMABUF, - "Can't import dmabufs into GL, missing EGL or EGL_EXT_image_dma_buf_import_modifiers"); - return 0; - } - - GDK_DISPLAY_DEBUG (display, DMABUF, - "Importing dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %u) into GL", - (char *) &dmabuf->fourcc, dmabuf->modifier, dmabuf->n_planes); - - i = 0; - attribs[i++] = EGL_IMAGE_PRESERVED_KHR; - attribs[i++] = EGL_TRUE; - attribs[i++] = EGL_WIDTH; - attribs[i++] = width; - attribs[i++] = EGL_HEIGHT; - attribs[i++] = height; - attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT; - attribs[i++] = dmabuf->fourcc; - attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT; - attribs[i++] = EGL_ITU_REC601_EXT; - attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT; - attribs[i++] = EGL_YUV_FULL_RANGE_EXT; - -#define ADD_PLANE(plane) \ - { \ - if (dmabuf->modifier != DRM_FORMAT_MOD_INVALID) \ - { \ - attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_MODIFIER_LO_EXT; \ - attribs[i++] = dmabuf->modifier & 0xFFFFFFFF; \ - attribs[i++] = EGL_DMA_BUF_PLANE## plane ## _MODIFIER_HI_EXT; \ - attribs[i++] = dmabuf->modifier >> 32; \ - } \ - attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_FD_EXT; \ - attribs[i++] = dmabuf->planes[plane].fd; \ - attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_PITCH_EXT; \ - attribs[i++] = dmabuf->planes[plane].stride; \ - attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_OFFSET_EXT; \ - attribs[i++] = dmabuf->planes[plane].offset; \ - } - - ADD_PLANE (0); - - if (dmabuf->n_planes > 1) ADD_PLANE (1); - if (dmabuf->n_planes > 2) ADD_PLANE (2); - if (dmabuf->n_planes > 3) ADD_PLANE (3); - - attribs[i++] = EGL_NONE; - - image = eglCreateImageKHR (egl_display, - EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, - (EGLClientBuffer)NULL, - attribs); - + image = gdk_dmabuf_egl_create_image (display, + width, + height, + dmabuf, + target); if (image == EGL_NO_IMAGE) - { - GDK_DISPLAY_DEBUG (display, DMABUF, - "Creating EGLImage for dmabuf failed: %#x", - eglGetError ()); - return 0; - } + return 0; glGenTextures (1, &texture_id); glBindTexture (target, texture_id); @@ -2241,7 +2178,7 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self, glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - eglDestroyImageKHR (egl_display, image); + eglDestroyImageKHR (gdk_display_get_egl_display (display), image); return texture_id; #else