From 03cd6520634014d6bea2d32df6ba0b734ecdd44c Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 07:50:52 +0100 Subject: [PATCH] gpu: Disable the ubershader when shaders aren't nonuniform If shaders don't support nonuniform indexing, we emulate it via if/else ladders (or switch ladders) which get inlined by the GLSL compiles and massively blow up the code. And that makes compilation of the shaders take minutes and results in shader code that isn't necessarily faster. So we disable it on GL entirely and on Vulkan if the required features aren't available. As it's only an optimization and does not fall back to Cairo anymore, this should be fine. --- gdk/gdkdisplay.c | 11 +++++++++++ gdk/gdkdisplayprivate.h | 2 ++ gsk/gpu/gsknglrenderer.c | 7 +++++++ gsk/gpu/gskvulkanrenderer.c | 9 +++++++++ 4 files changed, 29 insertions(+) diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index b4b95c8ec7..00182bfba2 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -1307,6 +1307,17 @@ gdk_display_create_vulkan_context (GdkDisplay *self, NULL); } +gboolean +gdk_display_has_vulkan_feature (GdkDisplay *self, + GdkVulkanFeatures feature) +{ +#ifdef GDK_RENDERING_VULKAN + return !!(self->vulkan_features & feature); +#else + return FALSE; +#endif +} + static void gdk_display_init_gl (GdkDisplay *self) { diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h index d50320af37..a655ed33b3 100644 --- a/gdk/gdkdisplayprivate.h +++ b/gdk/gdkdisplayprivate.h @@ -233,6 +233,8 @@ void _gdk_display_unpause_events (GdkDisplay *display void gdk_display_init_dmabuf (GdkDisplay *self); +gboolean gdk_display_has_vulkan_feature (GdkDisplay *self, + GdkVulkanFeatures feature); GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self, GError **error); diff --git a/gsk/gpu/gsknglrenderer.c b/gsk/gpu/gsknglrenderer.c index cbac62cd60..8aeca40633 100644 --- a/gsk/gpu/gsknglrenderer.c +++ b/gsk/gpu/gsknglrenderer.c @@ -54,6 +54,13 @@ gsk_ngl_renderer_create_context (GskGpuRenderer *renderer, gdk_gl_context_make_current (context); *supported = -1; + + /* Shader compilation takes too long when texture() and get_float() calls + * use if/else ladders to avoid non-uniform indexing. + * And that is always true with GL. + */ + *supported &= ~GSK_GPU_OPTIMIZE_UBER; + if (!gdk_gl_context_check_version (context, "4.2", "9.9") && !epoxy_has_gl_extension ("GL_EXT_base_instance") && !epoxy_has_gl_extension ("GL_ARB_base_instance")) diff --git a/gsk/gpu/gskvulkanrenderer.c b/gsk/gpu/gskvulkanrenderer.c index 05e74fedfa..7ba5fdbd11 100644 --- a/gsk/gpu/gskvulkanrenderer.c +++ b/gsk/gpu/gskvulkanrenderer.c @@ -98,6 +98,15 @@ gsk_vulkan_renderer_create_context (GskGpuRenderer *renderer, *supported = -1; + /* Shader compilation takes too long when texture() and get_float() calls + * use if/else ladders to avoid non-uniform indexing. + * This is true when we use the Vulkan 1.0 shaders, but works with the Vulkan 1.2 + * shaders. + */ + if (!gdk_display_has_vulkan_feature (display, GDK_VULKAN_FEATURE_DYNAMIC_INDEXING) || + !gdk_display_has_vulkan_feature (display, GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING)) + *supported &= ~GSK_GPU_OPTIMIZE_UBER; + return GDK_DRAW_CONTEXT (context); }