From 6911bfb466ce6defd800377618d4cf8cb4a0904b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 28 Dec 2023 21:08:39 +0200 Subject: [PATCH] Don't add both location and binding to the same uniform It's unclear from the GLSL spec if this is allowed or not, but Intel driver refuses to compile such shaders and it causes weird behaviour on AMD too. --- source/glsl/finalize.cpp | 33 +++++++++---- tests/glsl/arithmetic_assignment.glsl | 6 +-- tests/glsl/constructors.glsl | 2 +- tests/glsl/function_overloading.glsl | 2 +- tests/glsl/parentheses.glsl | 2 +- tests/glsl/uniform_location_allocation.glsl | 52 +++++++++++++-------- 6 files changed, 63 insertions(+), 34 deletions(-) diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index e26b7b26..afe0f7fa 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -214,8 +214,11 @@ void LocationAllocator::visit(VariableDeclaration &var) if(!var.name.compare(0, 3, "gl_")) return; + bool has_location = false; + bool needs_location = false; if(!var.interface.empty() && !var.block_declaration) { + needs_location = true; int location = get_layout_value(var.layout.get(), "location"); if(location<0 && var.linked_declaration && var.linked_declaration->layout) @@ -227,31 +230,43 @@ void LocationAllocator::visit(VariableDeclaration &var) if(location>=0) { + has_location = true; unsigned size = LocationCounter().apply(var); for(unsigned i=0; iblock_name, var.layout)) - unbound_blocks.push_back(&var); + if(!has_layout_qualifier(var.layout.get(), "push_constant")) + { + needs_binding = true; + has_binding = visit_uniform(var.block_declaration->block_name, var.layout); + } } - else + else if(dynamic_cast(get_ultimate_base_type(var.type_declaration))) { - const TypeDeclaration *base_type = get_ultimate_base_type(var.type_declaration); - if(dynamic_cast(base_type) && !visit_uniform(var.name, var.layout)) - unbound_textures.push_back(&var); + needs_binding = true; + is_texture = true; + has_binding = visit_uniform(var.name, var.layout); } } + + if(needs_binding && !has_location) + { + if(!has_binding) + (is_texture ? unbound_textures : unbound_blocks).push_back(&var); + } + else if(needs_location && !has_location) + unplaced_variables.push_back(&var); } diff --git a/tests/glsl/arithmetic_assignment.glsl b/tests/glsl/arithmetic_assignment.glsl index d0898fbe..1f7bfcf5 100644 --- a/tests/glsl/arithmetic_assignment.glsl +++ b/tests/glsl/arithmetic_assignment.glsl @@ -44,9 +44,9 @@ void main() */ /* Expected output: fragment -layout(location=4, binding=71) uniform sampler2D tex; -layout(location=5) uniform vec3 tint; -layout(location=6) uniform vec3 ambient; +layout(binding=71) uniform sampler2D tex; +layout(location=4) uniform vec3 tint; +layout(location=5) uniform vec3 ambient; layout(location=0) out vec4 frag_color; layout(location=1) in vec2 _vs_out_texcoord; layout(location=0) in float light; diff --git a/tests/glsl/constructors.glsl b/tests/glsl/constructors.glsl index 151ee5ef..2977c4a2 100644 --- a/tests/glsl/constructors.glsl +++ b/tests/glsl/constructors.glsl @@ -50,7 +50,7 @@ void main() */ /* Expected output: fragment -layout(location=9, binding=25) uniform sampler2D normalmap; +layout(binding=25) uniform sampler2D normalmap; layout(location=0) out vec4 frag_color; layout(location=1) in vec2 _vs_out_texcoord; layout(location=0) in vec3 tbn_light_dir; diff --git a/tests/glsl/function_overloading.glsl b/tests/glsl/function_overloading.glsl index 411776b6..3ffa8cc9 100644 --- a/tests/glsl/function_overloading.glsl +++ b/tests/glsl/function_overloading.glsl @@ -45,7 +45,7 @@ void main() */ /* Expected output: fragment -layout(location=4, binding=71) uniform sampler2D tex; +layout(binding=71) uniform sampler2D tex; layout(location=0) out vec4 frag_color; layout(location=0) in vec2 _vs_out_texcoord; void main() diff --git a/tests/glsl/parentheses.glsl b/tests/glsl/parentheses.glsl index 7eb6512b..ebf21712 100644 --- a/tests/glsl/parentheses.glsl +++ b/tests/glsl/parentheses.glsl @@ -61,7 +61,7 @@ struct LightParams }; layout(location=5) uniform LightParams light; layout(location=9) uniform vec3 material_color; -layout(location=10, binding=83) uniform sampler2D occlusion_map; +layout(binding=83) uniform sampler2D occlusion_map; layout(location=0) out vec4 frag_color; layout(location=1) in vec2 _vs_out_texcoord; layout(location=0) in vec3 _vs_out_normal; diff --git a/tests/glsl/uniform_location_allocation.glsl b/tests/glsl/uniform_location_allocation.glsl index 65321047..8323144d 100644 --- a/tests/glsl/uniform_location_allocation.glsl +++ b/tests/glsl/uniform_location_allocation.glsl @@ -1,46 +1,60 @@ #pragma MSP stage(vertex) -uniform mat4 mvp; -uniform sampler2D heightmap; -layout(location=0) in vec2 position; -layout(location=1) in vec2 texcoord; +uniform mat4 model; +uniform mat4 viewproj; +uniform vec4 light_pos; +layout(location=0) in vec3 position; +layout(location=1) in vec3 normal; void main() { - gl_Position = mvp*vec4(position, texture(heightmap, texcoord).r, 1.0); - passthrough; + vec4 world_pos = model*vec4(position, 1.0); + out vec3 world_normal = mat3(model)*normal; + out vec3 light_dir = light_pos.xyz-world_pos.xyz*light_pos.w; + gl_Position = viewproj*world_pos; } #pragma MSP stage(fragment) -layout(location=0) uniform sampler2D heightmap; +layout(location=2) uniform vec4 light_pos; uniform vec4 color; out vec4 frag_color; void main() { - frag_color = color*vec4(texture(heightmap, texcoord).rrr, 1.0); + float intensity = max(dot(normalize(light_dir), normalize(world_normal)), 0.0); + if(light_pos.w>0) + intensity *= 1.0/(0.1+length(light_dir)); + frag_color = color*vec4(vec3(intensity), 1.0); } // Target API: OpenGL /* Expected output: vertex -layout(location=1) uniform mat4 mvp; -layout(location=0, binding=16) uniform sampler2D heightmap; -layout(location=0) in vec2 position; -layout(location=1) in vec2 texcoord; -layout(location=0) out vec2 _vs_out_texcoord; +layout(location=3) uniform mat4 model; +layout(location=7) uniform mat4 viewproj; +layout(location=2) uniform vec4 light_pos; +layout(location=0) in vec3 position; +layout(location=1) in vec3 normal; +layout(location=0) out vec3 world_normal; +layout(location=1) out vec3 light_dir; void main() { - gl_Position = mvp*vec4(position, texture(heightmap, texcoord).r, 1.0); - _vs_out_texcoord = texcoord; + vec4 world_pos = model*vec4(position, 1.0); + world_normal = mat3(model[0].xyz, model[1].xyz, model[2].xyz)*normal; + light_dir = light_pos.xyz-world_pos.xyz*light_pos.w; + gl_Position = viewproj*world_pos; gl_Position.z = gl_Position.z*2.0-gl_Position.w; } */ /* Expected output: fragment -layout(location=0, binding=16) uniform sampler2D heightmap; -layout(location=5) uniform vec4 color; +layout(location=2) uniform vec4 light_pos; +layout(location=11) uniform vec4 color; layout(location=0) out vec4 frag_color; -layout(location=0) in vec2 _vs_out_texcoord; +layout(location=1) in vec3 light_dir; +layout(location=0) in vec3 world_normal; void main() { - frag_color = color*vec4(texture(heightmap, _vs_out_texcoord).rrr, 1.0); + float intensity = max(dot(normalize(light_dir), normalize(world_normal)), 0.0); + if(light_pos.w>0.0) + intensity *= 1.0/(0.1+length(light_dir)); + frag_color = color*vec4(vec3(intensity), 1.0); } */ -- 2.45.2