Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Tobi_Peter:yuga:testing
mutter
3304.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 3304.patch of Package mutter
From 190f1c7be3a64f56195487ce21fc38433f00cc50 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt <daniel.van.vugt@canonical.com> Date: Wed, 20 Sep 2023 19:31:35 +0800 Subject: [PATCH 1/7] onscreen/native: Try gbm_surface_create_with_modifiers* first Nvidia only supports gbm_surface_create_with_modifiers, but we should try all the forms in order of preference. --- src/backends/native/meta-onscreen-native.c | 28 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index d27995aee3..f89e898943 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -2106,6 +2106,7 @@ init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_nat MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; MetaGpuKms *gpu_kms; uint32_t format; + const uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; render_device = renderer_gpu_data->render_device; egl_display = meta_render_device_get_egl_display (render_device); @@ -2117,10 +2118,29 @@ init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_nat render_device_gbm = META_RENDER_DEVICE_GBM (render_device); gbm_device = meta_render_device_gbm_get_gbm_device (render_device_gbm); - gbm_surface = gbm_surface_create (gbm_device, - width, height, - format, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + + gbm_surface = gbm_surface_create_with_modifiers2 (gbm_device, + width, height, + format, + NULL, 0, + flags); + + if (!gbm_surface) + { + gbm_surface = gbm_surface_create_with_modifiers (gbm_device, + width, height, + format, + NULL, 0); + } + + if (!gbm_surface) + { + gbm_surface = gbm_surface_create (gbm_device, + width, height, + format, + flags); + } + if (!gbm_surface) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, -- GitLab From 4f762f46884caa439d1053739c283a008d84f370 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt <daniel.van.vugt@canonical.com> Date: Tue, 3 Oct 2023 17:38:47 +0800 Subject: [PATCH 2/7] egl: Add function: meta_egl_query_string --- src/backends/meta-egl.c | 8 ++++++++ src/backends/meta-egl.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c index ac19828c4c..c468c6f970 100644 --- a/src/backends/meta-egl.c +++ b/src/backends/meta-egl.c @@ -238,6 +238,14 @@ meta_egl_has_extensions (MetaEgl *egl, return has_extensions; } +const char * +meta_egl_query_string (MetaEgl *egl, + EGLDisplay display, + EGLint name) +{ + return eglQueryString (display, name); +} + gboolean meta_egl_initialize (MetaEgl *egl, EGLDisplay display, diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h index 4ed54a5399..55976bfdb1 100644 --- a/src/backends/meta-egl.h +++ b/src/backends/meta-egl.h @@ -47,6 +47,10 @@ gboolean meta_egl_has_extensions (MetaEgl *egl, const char *first_extension, ...); +const char * meta_egl_query_string (MetaEgl *egl, + EGLDisplay display, + EGLint name); + gboolean meta_egl_initialize (MetaEgl *egl, EGLDisplay display, GError **error); -- GitLab From 54f64d4074a2703f3703c6ce3104d49aeb9bec40 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt <daniel.van.vugt@canonical.com> Date: Tue, 3 Oct 2023 17:39:49 +0800 Subject: [PATCH 3/7] renderer/native: Flag when explicit sync between GPUs is required --- src/backends/native/meta-renderer-native-private.h | 1 + src/backends/native/meta-renderer-native.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/backends/native/meta-renderer-native-private.h b/src/backends/native/meta-renderer-native-private.h index 66b987a5c0..1a4ee2c810 100644 --- a/src/backends/native/meta-renderer-native-private.h +++ b/src/backends/native/meta-renderer-native-private.h @@ -60,6 +60,7 @@ typedef struct _MetaRendererNativeGpuData struct { MetaSharedFramebufferCopyMode copy_mode; gboolean has_EGL_EXT_image_dma_buf_import_modifiers; + gboolean needs_explicit_sync; /* For GPU blit mode */ EGLContext egl_context; diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 0811be7bb2..d9cb9fb441 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -1761,6 +1761,7 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data, CoglContext *cogl_context; CoglDisplay *cogl_display; const char **missing_gl_extensions; + const char *egl_vendor; egl_display = meta_render_device_get_egl_display (render_device); if (egl_display == EGL_NO_DISPLAY) @@ -1827,6 +1828,11 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data, meta_egl_has_extensions (egl, egl_display, NULL, "EGL_EXT_image_dma_buf_import_modifiers", NULL); + + egl_vendor = meta_egl_query_string (egl, egl_display, EGL_VENDOR); + if (!g_strcmp0 (egl_vendor, "NVIDIA")) + renderer_gpu_data->secondary.needs_explicit_sync = TRUE; + ret = TRUE; out: maybe_restore_cogl_egl_api (renderer_native); -- GitLab From f34880e117ced677446ab86356d847421e8f3182 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt <daniel.van.vugt@canonical.com> Date: Fri, 29 Sep 2023 18:38:26 +0800 Subject: [PATCH 4/7] onscreen/native: Finish primary GPU rendering before copying to secondary As mentioned in the OES_EGL_image_external spec, there is no implicit sync between the EGLImage producer and consumer. And in this code path we don't have meta_drm_buffer_gbm_new_lock_front on the primary GPU to do it for us either. So synchronization has to be done manually or else the secondary GPU is likely to get an unfinished image. This problem has only been observed when the secondary GPU is using the Nvidia proprietary driver. --- src/backends/native/meta-onscreen-native.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index f89e898943..dcb0e731ca 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -619,6 +619,9 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen, COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferSecondaryGpu, "copy_shared_framebuffer_gpu()"); + if (renderer_gpu_data->secondary.needs_explicit_sync) + cogl_framebuffer_finish (COGL_FRAMEBUFFER (onscreen)); + render_device = renderer_gpu_data->render_device; egl_display = meta_render_device_get_egl_display (render_device); -- GitLab From 8d0563daf5da775aaffeefebbe46ffab54e2f7a0 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt <daniel.van.vugt@canonical.com> Date: Fri, 29 Sep 2023 17:19:16 +0800 Subject: [PATCH 5/7] renderer/native-gles3: Remember to set the glViewport This is a critical part of any OpenGL program. Mesa allowed us to get away without it and provided a sane default of the full buffer, but Nvidia seems to default to an empty/zero viewport so would refuse to paint any pixels. In the OpenGL ES 2.0 spec this is ambiguous: > In the initial state, w and h are set to the width and height, > respectively, of the window into which the GL is to do its rendering. because the first "window" used is EGL_NO_SURFACE in init_secondary_gpu_data_gpu. It has no width or height. In the OpenGL ES 3.0 spec the ambiguity is somewhat resolved: > If the default framebuffer is bound but no default framebuffer is > associated with the GL context (see chapter 4), then w and h are > initially set to zero. but not entirely resolved because neither spec says whether EGL_NO_SURFACE should be treated as zero dimensions (Nvidia) or ignored and not counted as the first "window" (Mesa). --- src/backends/native/meta-renderer-native-gles3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backends/native/meta-renderer-native-gles3.c b/src/backends/native/meta-renderer-native-gles3.c index cf27ba8d46..b1c4a0de91 100644 --- a/src/backends/native/meta-renderer-native-gles3.c +++ b/src/backends/native/meta-renderer-native-gles3.c @@ -54,6 +54,8 @@ paint_egl_image (MetaGles3 *gles3, meta_gles3_clear_error (gles3); + GLBAS (gles3, glViewport, (0, 0, width, height)); + GLBAS (gles3, glGenFramebuffers, (1, &framebuffer)); GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer)); -- GitLab From 1849b91094674b56f6328a0f1ee5e7deb6f72f70 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt <daniel.van.vugt@canonical.com> Date: Thu, 21 Sep 2023 18:35:24 +0800 Subject: [PATCH 6/7] renderer/native-gles3: Use GL_OES_EGL_image_external, not GL_OES_EGL_image Although MetaRendererNative checks for the GL_OES_EGL_image_external extension, paint_egl_image was implemented to use GL_OES_EGL_image. That was a problem because: 1. Nvidia only knows how to import buffers from Mesa using GL_OES_EGL_image_external. 2. GL_OES_EGL_image_external doesn't support GL_TEXTURE_2D. 3. glFramebufferTexture2D doesn't support GL_TEXTURE_EXTERNAL_OES. So we're left with only one option to use GL_OES_EGL_image_external and GL_TEXTURE_EXTERNAL_OES. This means we can't use glFramebufferTexture2D anymore, which means we can't use glBlitFramebuffer anymore. We're resigned to implementing a traditional shader. As a bonus, this makes us OpenGL ES 2.0 compliant because we've removed the code that required ES 3.0 (GL_READ_FRAMEBUFFER and glBlitFramebuffer). Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6221, https://gitlab.gnome.org/GNOME/mutter/-/issues/2247, https://launchpad.net/bugs/1970291 --- .../native/meta-renderer-native-gles3.c | 149 +++++++++++++++--- 1 file changed, 128 insertions(+), 21 deletions(-) diff --git a/src/backends/native/meta-renderer-native-gles3.c b/src/backends/native/meta-renderer-native-gles3.c index b1c4a0de91..333f977967 100644 --- a/src/backends/native/meta-renderer-native-gles3.c +++ b/src/backends/native/meta-renderer-native-gles3.c @@ -3,6 +3,7 @@ /* * Copyright (C) 2017 Red Hat * Copyright (c) 2018 DisplayLink (UK) Ltd. + * Copyright (c) 2023 Canonical Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -43,6 +44,120 @@ #error "Somehow included OpenGL headers when we shouldn't have" #endif +static GQuark shader_program_quark = 0; + +static GLuint +load_shader (const char *src, + GLenum type) +{ + GLuint shader = glCreateShader (type); + + if (shader) + { + GLint compiled; + + glShaderSource (shader, 1, &src, NULL); + glCompileShader (shader); + glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) + { + GLchar log[1024]; + + glGetShaderInfoLog (shader, sizeof (log) - 1, NULL, log); + log[sizeof (log) - 1] = '\0'; + g_warning ("load_shader compile failed: %s", log); + glDeleteShader (shader); + shader = 0; + } + } + + return shader; +} + +static void +ensure_shader_program (MetaGles3 *gles3) +{ + static const char vertex_shader_source[] = + "#version 100\n" + "attribute vec2 position;\n" + "attribute vec2 texcoord;\n" + "varying vec2 v_texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position, 0.0, 1.0);\n" + " v_texcoord = texcoord;\n" + "}\n"; + + static const char fragment_shader_source[] = + "#version 100\n" + "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "uniform samplerExternalOES s_texture;\n" + "varying vec2 v_texcoord;\n" + "\n" + " void main()\n" + "{\n" + " gl_FragColor = texture2D(s_texture, v_texcoord);\n" + "}\n"; + + static const GLfloat box[] = + { /* position texcoord */ + -1.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 1.0f, + }; + GLint linked; + GLuint vertex_shader, fragment_shader; + GLint position_attrib, texcoord_attrib; + GLuint shader_program; + + if (!shader_program_quark) + shader_program_quark = g_quark_from_static_string ("shader program"); + + if (g_object_get_qdata (G_OBJECT (gles3), shader_program_quark)) + return; + + shader_program = glCreateProgram (); + g_return_if_fail (shader_program); + g_object_set_qdata_full (G_OBJECT (gles3), + shader_program_quark, + GUINT_TO_POINTER (shader_program), + NULL); + + vertex_shader = load_shader (vertex_shader_source, GL_VERTEX_SHADER); + g_return_if_fail (vertex_shader); + fragment_shader = load_shader (fragment_shader_source, GL_FRAGMENT_SHADER); + g_return_if_fail (fragment_shader); + + GLBAS (gles3, glAttachShader, (shader_program, vertex_shader)); + GLBAS (gles3, glAttachShader, (shader_program, fragment_shader)); + GLBAS (gles3, glLinkProgram, (shader_program)); + GLBAS (gles3, glGetProgramiv, (shader_program, GL_LINK_STATUS, &linked)); + if (!linked) + { + GLchar log[1024]; + + glGetProgramInfoLog (shader_program, sizeof (log) - 1, NULL, log); + log[sizeof (log) - 1] = '\0'; + g_warning ("Link failed: %s", log); + return; + } + + GLBAS (gles3, glUseProgram, (shader_program)); + + position_attrib = glGetAttribLocation (shader_program, "position"); + GLBAS (gles3, glEnableVertexAttribArray, (position_attrib)); + GLBAS (gles3, glVertexAttribPointer, + (position_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (GLfloat), box)); + + texcoord_attrib = glGetAttribLocation (shader_program, "texcoord"); + GLBAS (gles3, glEnableVertexAttribArray, (texcoord_attrib)); + GLBAS (gles3, glVertexAttribPointer, + (texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (GLfloat), box + 2)); +} + static void paint_egl_image (MetaGles3 *gles3, EGLImageKHR egl_image, @@ -50,41 +165,33 @@ paint_egl_image (MetaGles3 *gles3, int height) { GLuint texture; - GLuint framebuffer; meta_gles3_clear_error (gles3); + ensure_shader_program (gles3); GLBAS (gles3, glViewport, (0, 0, width, height)); - GLBAS (gles3, glGenFramebuffers, (1, &framebuffer)); - GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer)); - GLBAS (gles3, glActiveTexture, (GL_TEXTURE0)); GLBAS (gles3, glGenTextures, (1, &texture)); - GLBAS (gles3, glBindTexture, (GL_TEXTURE_2D, texture)); - GLEXT (gles3, glEGLImageTargetTexture2DOES, (GL_TEXTURE_2D, egl_image)); - GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GLBAS (gles3, glBindTexture, (GL_TEXTURE_EXTERNAL_OES, texture)); + GLEXT (gles3, glEGLImageTargetTexture2DOES, (GL_TEXTURE_EXTERNAL_OES, + egl_image)); + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, + GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, + GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE)); - GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, + GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_R_OES, + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, + GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - GLBAS (gles3, glFramebufferTexture2D, (GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, texture, 0)); - - GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer)); - GLBAS (gles3, glBlitFramebuffer, (0, height, width, 0, - 0, 0, width, height, - GL_COLOR_BUFFER_BIT, - GL_NEAREST)); + GLBAS (gles3, glDrawArrays, (GL_TRIANGLE_FAN, 0, 4)); GLBAS (gles3, glDeleteTextures, (1, &texture)); - GLBAS (gles3, glDeleteFramebuffers, (1, &framebuffer)); } gboolean -- GitLab From 46c8f479de314ce84fd039ea2e966cfd77903134 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt <daniel.van.vugt@canonical.com> Date: Tue, 24 Oct 2023 16:26:57 +0800 Subject: [PATCH 7/7] onscreen/native: Don't refuse primary GPU copy support based on egl_surface Because that egl_surface is only used for secondary GPU copying, which isn't relevant to primary GPU copies. This is a partial revert of 41bfabad96 which is no longer required since the previous commits have enabled secondary GPU copy support for nvidia-drm. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2551 --- src/backends/native/meta-onscreen-native.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index dcb0e731ca..8cecd8932a 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -728,8 +728,7 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferPrimaryGpu, "copy_shared_framebuffer_primary_gpu()"); - if (!secondary_gpu_state || - secondary_gpu_state->egl_surface == EGL_NO_SURFACE) + if (!secondary_gpu_state) return NULL; primary_gpu = meta_renderer_native_get_primary_gpu (renderer_native); -- GitLab
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor