From 78a7127b96b58eb6b409f7cade92a5114738c7cf Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 3 Nov 2023 07:01:52 +0100 Subject: [PATCH] gpu: Handle missing support nor nonuniform texture accesses We compile custom shaders for Vulkan 1.0 that don't require the extension. We also ensure that our accesses are uniform by only executing one shader at a time. --- gsk/gpu/gskgpushaderop.c | 5 +++- gsk/gpu/gskvulkandevice.c | 17 +++++++++++-- gsk/gpu/shaders/common-vulkan.glsl | 39 +++++++++++++++++++++--------- gsk/gpu/shaders/meson.build | 22 ++++++++++++++--- 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/gsk/gpu/gskgpushaderop.c b/gsk/gpu/gskgpushaderop.c index 000e69354f..0a61a9bf94 100644 --- a/gsk/gpu/gskgpushaderop.c +++ b/gsk/gpu/gskgpushaderop.c @@ -40,11 +40,14 @@ gsk_gpu_shader_op_vk_command_n (GskGpuOp *op, GskGpuOp *next; gsize i, n; - if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_MERGE)) + if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_MERGE) && + gsk_vulkan_device_has_feature (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), + GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING)) n = MAX_MERGE_OPS; else n = 1; i = 1; + for (next = op->next; next && i < n; next = next->next) { GskGpuShaderOp *next_shader = (GskGpuShaderOp *) next; diff --git a/gsk/gpu/gskvulkandevice.c b/gsk/gpu/gskvulkandevice.c index 87913fba55..df9e36b18d 100644 --- a/gsk/gpu/gskvulkandevice.c +++ b/gsk/gpu/gskvulkandevice.c @@ -856,6 +856,7 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self, PipelineCacheKey cache_key; VkPipeline pipeline; GdkDisplay *display; + const char *version_string; char *vertex_shader_name, *fragment_shader_name; cache_key = (PipelineCacheKey) { @@ -868,8 +869,20 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self, return pipeline; display = gsk_gpu_device_get_display (GSK_GPU_DEVICE (self)); - vertex_shader_name = g_strconcat ("/org/gtk/libgsk/shaders/vulkan/", op_class->shader_name, ".vert.spv", NULL); - fragment_shader_name = g_strconcat ("/org/gtk/libgsk/shaders/vulkan/", op_class->shader_name, ".frag.spv", NULL); + if (gsk_vulkan_device_has_feature (self, GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING)) + version_string = ".1.2"; + else + version_string = ".1.0"; + vertex_shader_name = g_strconcat ("/org/gtk/libgsk/shaders/vulkan/", + op_class->shader_name, + version_string, + ".vert.spv", + NULL); + fragment_shader_name = g_strconcat ("/org/gtk/libgsk/shaders/vulkan/", + op_class->shader_name, + version_string, + ".frag.spv", + NULL); GSK_VK_CHECK (vkCreateGraphicsPipelines, display->vk_device, display->vk_pipeline_cache, diff --git a/gsk/gpu/shaders/common-vulkan.glsl b/gsk/gpu/shaders/common-vulkan.glsl index 86f5b92dec..abfcef82f9 100644 --- a/gsk/gpu/shaders/common-vulkan.glsl +++ b/gsk/gpu/shaders/common-vulkan.glsl @@ -1,4 +1,6 @@ +#ifdef HAVE_NONUNIFORM #extension GL_EXT_nonuniform_qualifier : enable +#endif #include "enums.glsl" @@ -62,12 +64,13 @@ gsk_texture (uint id, return texture (immutable_textures[6], pos); else if (GSK_N_IMMUTABLE_SAMPLERS > 7 && id == 7) return texture (immutable_textures[7], pos); - else - return vec4 (1.0, 0.0, 0.8, 1.0); } else { id >>= 1; +#ifdef HAVE_NONUNIFORM + return texture (textures[nonuniformEXT (id)], pos); +#else if (id == 0) return texture (textures[0], pos); else if (GSK_N_SAMPLERS > 1 && id == 1) @@ -84,9 +87,11 @@ gsk_texture (uint id, return texture (textures[6], pos); else if (GSK_N_SAMPLERS > 7 && id == 7) return texture (textures[7], pos); - else - return texture (textures[nonuniformEXT (id)], pos); + else if (GSK_N_SAMPLERS > 8) + return texture (textures[id], pos); +#endif } + return vec4 (1.0, 0.0, 0.8, 1.0); } ivec2 @@ -112,12 +117,13 @@ gsk_texture_size (uint id, return textureSize (immutable_textures[6], lod); else if (GSK_N_IMMUTABLE_SAMPLERS > 7 && id == 7) return textureSize (immutable_textures[7], lod); - else - return ivec2 (1, 1); } else { id >>= 1; +#ifdef HAVE_NONUNIFORM + return textureSize (textures[nonuniformEXT (id)], lod); +#else if (id == 0) return textureSize (textures[0], lod); else if (GSK_N_SAMPLERS > 1 && id == 1) @@ -134,9 +140,11 @@ gsk_texture_size (uint id, return textureSize (textures[6], lod); else if (GSK_N_SAMPLERS > 7 && id == 7) return textureSize (textures[7], lod); - else - return textureSize (textures[nonuniformEXT (id)], lod); + else if (GSK_N_SAMPLERS > 8) + return textureSize (textures[id], lod); +#endif } + return ivec2 (1, 1); } vec4 @@ -163,12 +171,13 @@ gsk_texel_fetch (uint id, return texelFetch (immutable_textures[6], pos, lod); else if (GSK_N_IMMUTABLE_SAMPLERS > 7 && id == 7) return texelFetch (immutable_textures[7], pos, lod); - else - return vec4 (1.0, 0.0, 0.8, 1.0); } else { id >>= 1; +#ifdef HAVE_NONUNIFORM + return texelFetch (textures[nonuniformEXT (id)], pos, lod); +#else if (id == 0) return texelFetch (textures[0], pos, lod); else if (GSK_N_SAMPLERS > 1 && id == 1) @@ -185,12 +194,18 @@ gsk_texel_fetch (uint id, return texelFetch (textures[6], pos, lod); else if (GSK_N_SAMPLERS > 7 && id == 7) return texelFetch (textures[7], pos, lod); - else - return texelFetch (textures[nonuniformEXT (id)], pos, lod); + else if (GSK_N_SAMPLERS > 8) + return texelFetch (textures[id], pos, lod); +#endif } + return vec4 (1.0, 0.0, 0.8, 1.0); } +#ifdef HAVE_NONUNIFORM #define gsk_get_buffer(id) buffers[nonuniformEXT (id)] +#else +#define gsk_get_buffer(id) buffers[id] +#endif #define gsk_get_float(id) gsk_get_buffer(id >> 22).floats[id & 0x3FFFFF] #define gsk_get_int(id) (floatBitsToInt(gsk_get_float(id))) #define gsk_get_uint(id) (floatBitsToUint(gsk_get_float(id))) diff --git a/gsk/gpu/shaders/meson.build b/gsk/gpu/shaders/meson.build index 85164792ed..b2eb7c75e4 100644 --- a/gsk/gpu/shaders/meson.build +++ b/gsk/gpu/shaders/meson.build @@ -56,18 +56,32 @@ foreach shader: gsk_private_gpu_shaders if (have_vulkan) glslc_options = [ - [ fs.name (fs.replace_suffix (shader, '')) + '.vert.spv', + [ fs.name (fs.replace_suffix (shader, '')) + '.1.2.vert.spv', [ '--target-env=vulkan1.2', '-fshader-stage=vertex', '-DGSK_VERTEX_SHADER=1', + '-DHAVE_NONUNIFORM=1' + ] + ], + [ fs.name (fs.replace_suffix (shader, '')) + '.1.2.frag.spv', + [ '--target-env=vulkan1.2', + '-fshader-stage=fragment', + '-DGSK_FRAGMENT_SHADER=1', + '-DHAVE_NONUNIFORM=1' + ] + ], + [ fs.name (fs.replace_suffix (shader, '')) + '.1.0.vert.spv', + [ '--target-env=vulkan1.0', + '-fshader-stage=vertex', + '-DGSK_VERTEX_SHADER=1', ] ], - [ fs.name (fs.replace_suffix (shader, '')) + '.frag.spv', - [ '--target-env=vulkan1.2', + [ fs.name (fs.replace_suffix (shader, '')) + '.1.0.frag.spv', + [ '--target-env=vulkan1.0', '-fshader-stage=fragment', '-DGSK_FRAGMENT_SHADER=1', ] - ] + ], ] foreach option: glslc_options target = custom_target(option.get(0),