From 16430b10f19fb13fed3d855c712e160425986d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Thu, 7 Aug 2025 09:40:57 +0200 Subject: [PATCH] EEVEE: World Sun Shadow no longer works in 4.5 On some drivers, the GLSL compiler doesn't reflect the omitted `local_size_*` of a compute shader inside `gl_WorkGroupSize`. This lead to the 2D size computation of 1D workgroups to become 0 which was bypassing the parallel reduction algorithms. Ensuring `local_size_*` are always set fixes the issue. For clarity, also fix the 1D shaders to not use `gl_WorkGroupSize.y`. This also fix a copy paste error in the Metal backend. This issue affected AMD drivers on Windows. Rel #142046 Candidate for backporting to 4.5 LTS. Pull Request: https://projects.blender.org/blender/blender/pulls/144056 --- .../eevee_lightprobe_sphere_irradiance_comp.glsl | 2 +- .../eevee_lightprobe_sphere_sunlight_comp.glsl | 2 +- source/blender/gpu/intern/gpu_shader_create_info.hh | 4 ++-- source/blender/gpu/metal/mtl_shader_generator.mm | 10 ++-------- source/blender/gpu/opengl/gl_shader.cc | 11 ++++------- source/blender/gpu/vulkan/vk_shader.cc | 11 ++++------- .../blender/python/gpu/gpu_py_shader_create_info.cc | 6 +++--- 7 files changed, 17 insertions(+), 29 deletions(-) diff --git a/source/blender/draw/engines/eevee/shaders/eevee_lightprobe_sphere_irradiance_comp.glsl b/source/blender/draw/engines/eevee/shaders/eevee_lightprobe_sphere_irradiance_comp.glsl index c691fe73a8c..6b70da3510f 100644 --- a/source/blender/draw/engines/eevee/shaders/eevee_lightprobe_sphere_irradiance_comp.glsl +++ b/source/blender/draw/engines/eevee/shaders/eevee_lightprobe_sphere_irradiance_comp.glsl @@ -48,7 +48,7 @@ void main() local_sh_coefs[local_index][3] = sh.L1.Mp1; /* Parallel sum. */ - constexpr uint group_size = gl_WorkGroupSize.x * gl_WorkGroupSize.y; + constexpr uint group_size = gl_WorkGroupSize.x; uint stride = group_size / 2; for (int i = 0; i < 10; i++) { barrier(); diff --git a/source/blender/draw/engines/eevee/shaders/eevee_lightprobe_sphere_sunlight_comp.glsl b/source/blender/draw/engines/eevee/shaders/eevee_lightprobe_sphere_sunlight_comp.glsl index f76f7c2f43d..47188632eb6 100644 --- a/source/blender/draw/engines/eevee/shaders/eevee_lightprobe_sphere_sunlight_comp.glsl +++ b/source/blender/draw/engines/eevee/shaders/eevee_lightprobe_sphere_sunlight_comp.glsl @@ -42,7 +42,7 @@ void main() local_direction[local_index] = sun.direction; /* Parallel sum. */ - constexpr uint group_size = gl_WorkGroupSize.x * gl_WorkGroupSize.y; + constexpr uint group_size = gl_WorkGroupSize.x; uint stride = group_size / 2; for (int i = 0; i < 10; i++) { barrier(); diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh index 5e162576447..ff3ba88d981 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.hh +++ b/source/blender/gpu/intern/gpu_shader_create_info.hh @@ -119,7 +119,7 @@ # define FLAT(type, name) .flat(Type::type##_t, #name) # define NO_PERSPECTIVE(type, name) .no_perspective(Type::type##_t, #name) -/* LOCAL_GROUP_SIZE(int size_x, int size_y = -1, int size_z = -1) */ +/* LOCAL_GROUP_SIZE(int size_x, int size_y = 1, int size_z = 1) */ # define LOCAL_GROUP_SIZE(...) .local_group_size(__VA_ARGS__) # define VERTEX_IN(slot, type, name) .vertex_in(slot, Type::type##_t, #name) @@ -992,7 +992,7 @@ struct ShaderCreateInfo { return *(Self *)this; } - Self &local_group_size(int local_size_x = -1, int local_size_y = -1, int local_size_z = -1) + Self &local_group_size(int local_size_x, int local_size_y = 1, int local_size_z = 1) { compute_layout_.local_size_x = local_size_x; compute_layout_.local_size_y = local_size_y; diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index 9fa2dbcfb8d..185e797dc41 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -924,15 +924,9 @@ bool MTLShader::generate_msl_from_glsl_compute(const shader::ShaderCreateInfo *i ss_compute << "#define MTL_USE_WORKGROUP_SIZE 1" << std::endl; ss_compute << "#define MTL_WORKGROUP_SIZE_X " << info->compute_layout_.local_size_x << std::endl; - ss_compute << "#define MTL_WORKGROUP_SIZE_Y " - << ((info->compute_layout_.local_size_y != -1) ? - info->compute_layout_.local_size_y : - 1) + ss_compute << "#define MTL_WORKGROUP_SIZE_Y " << info->compute_layout_.local_size_y << std::endl; - ss_compute << "#define MTL_WORKGROUP_SIZE_Z " - << ((info->compute_layout_.local_size_y != -1) ? - info->compute_layout_.local_size_y : - 1) + ss_compute << "#define MTL_WORKGROUP_SIZE_Z " << info->compute_layout_.local_size_z << std::endl; } diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index b9c31015720..16ecbe10c96 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -964,13 +964,10 @@ std::string GLShader::compute_layout_declare(const ShaderCreateInfo &info) const { std::stringstream ss; ss << "\n/* Compute Layout. */\n"; - ss << "layout(local_size_x = " << info.compute_layout_.local_size_x; - if (info.compute_layout_.local_size_y != -1) { - ss << ", local_size_y = " << info.compute_layout_.local_size_y; - } - if (info.compute_layout_.local_size_z != -1) { - ss << ", local_size_z = " << info.compute_layout_.local_size_z; - } + ss << "layout("; + ss << " local_size_x = " << info.compute_layout_.local_size_x; + ss << ", local_size_y = " << info.compute_layout_.local_size_y; + ss << ", local_size_z = " << info.compute_layout_.local_size_z; ss << ") in;\n"; ss << "\n"; return ss.str(); diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc index ad2ef3993f5..ee20564dcc4 100644 --- a/source/blender/gpu/vulkan/vk_shader.cc +++ b/source/blender/gpu/vulkan/vk_shader.cc @@ -1215,13 +1215,10 @@ std::string VKShader::compute_layout_declare(const shader::ShaderCreateInfo &inf { std::stringstream ss; ss << "\n/* Compute Layout. */\n"; - ss << "layout(local_size_x = " << info.compute_layout_.local_size_x; - if (info.compute_layout_.local_size_y != -1) { - ss << ", local_size_y = " << info.compute_layout_.local_size_y; - } - if (info.compute_layout_.local_size_z != -1) { - ss << ", local_size_z = " << info.compute_layout_.local_size_z; - } + ss << "layout("; + ss << " local_size_x = " << info.compute_layout_.local_size_x; + ss << ", local_size_y = " << info.compute_layout_.local_size_y; + ss << ", local_size_z = " << info.compute_layout_.local_size_z; ss << ") in;\n"; ss << "\n"; return ss.str(); diff --git a/source/blender/python/gpu/gpu_py_shader_create_info.cc b/source/blender/python/gpu/gpu_py_shader_create_info.cc index e0c97770e37..0aa632fcf8d 100644 --- a/source/blender/python/gpu/gpu_py_shader_create_info.cc +++ b/source/blender/python/gpu/gpu_py_shader_create_info.cc @@ -1220,15 +1220,15 @@ static PyObject *pygpu_shader_info_define(BPyGPUShaderCreateInfo *self, PyObject PyDoc_STRVAR( /* Wrap. */ pygpu_shader_info_local_group_size_doc, - ".. method:: local_group_size(x, y=-1, z=-1)\n" + ".. method:: local_group_size(x, y=1, z=1)\n" "\n" " Specify the local group size for compute shaders.\n" "\n" " :arg x: The local group size in the x dimension.\n" " :type x: int\n" - " :arg y: The local group size in the y dimension. Optional. Defaults to -1.\n" + " :arg y: The local group size in the y dimension. Optional. Defaults to 1.\n" " :type y: int\n" - " :arg z: The local group size in the z dimension. Optional. Defaults to -1.\n" + " :arg z: The local group size in the z dimension. Optional. Defaults to 1.\n" " :type z: int\n"); static PyObject *pygpu_shader_info_local_group_size(BPyGPUShaderCreateInfo *self, PyObject *args) {