From f408a13dd3089483c78803e961ba8a4df8b4cbba Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Wed, 21 Oct 2015 09:46:48 +0200 Subject: [PATCH] glsl: fix shader storage block member rules when adding program resources Commit f24e5e did not take into account arrays of named shader storage blocks. Fixes 20 dEQP-GLES31.functional.ssbo.* tests: dEQP-GLES31.functional.ssbo.layout.single_struct_array.per_block_buffer.shared_instance_array dEQP-GLES31.functional.ssbo.layout.single_struct_array.per_block_buffer.packed_instance_array dEQP-GLES31.functional.ssbo.layout.single_struct_array.per_block_buffer.std140_instance_array dEQP-GLES31.functional.ssbo.layout.single_struct_array.per_block_buffer.std430_instance_array dEQP-GLES31.functional.ssbo.layout.single_struct_array.single_buffer.shared_instance_array dEQP-GLES31.functional.ssbo.layout.single_struct_array.single_buffer.packed_instance_array dEQP-GLES31.functional.ssbo.layout.single_struct_array.single_buffer.std140_instance_array dEQP-GLES31.functional.ssbo.layout.single_struct_array.single_buffer.std430_instance_array dEQP-GLES31.functional.ssbo.layout.single_nested_struct_array.per_block_buffer.shared_instance_array dEQP-GLES31.functional.ssbo.layout.single_nested_struct_array.per_block_buffer.packed_instance_array dEQP-GLES31.functional.ssbo.layout.single_nested_struct_array.per_block_buffer.std140_instance_array dEQP-GLES31.functional.ssbo.layout.single_nested_struct_array.per_block_buffer.std430_instance_array dEQP-GLES31.functional.ssbo.layout.single_nested_struct_array.single_buffer.shared_instance_array dEQP-GLES31.functional.ssbo.layout.single_nested_struct_array.single_buffer.packed_instance_array dEQP-GLES31.functional.ssbo.layout.single_nested_struct_array.single_buffer.std140_instance_array dEQP-GLES31.functional.ssbo.layout.single_nested_struct_array.single_buffer.std430_instance_array dEQP-GLES31.functional.ssbo.layout.random.all_per_block_buffers.2 dEQP-GLES31.functional.ssbo.layout.random.all_per_block_buffers.29 dEQP-GLES31.functional.ssbo.layout.random.all_per_block_buffers.33 dEQP-GLES31.functional.ssbo.layout.random.all_shared_buffer.3 V2: - Rename some variables (Timothy) Signed-off-by: Samuel Iglesias Gonsalvez Reviewed-by: Timothy Arceri --- src/glsl/linker.cpp | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 07ea0e0c7e5..424b92a1783 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -3137,7 +3137,8 @@ should_add_buffer_variable(struct gl_shader_program *shProg, GLenum type, const char *name) { bool found_interface = false; - const char *block_name = NULL; + unsigned block_name_len = 0; + const char *block_name_dot = strchr(name, '.'); /* These rules only apply to buffer variables. So we return * true for the rest of types. @@ -3146,8 +3147,28 @@ should_add_buffer_variable(struct gl_shader_program *shProg, return true; for (unsigned i = 0; i < shProg->NumBufferInterfaceBlocks; i++) { - block_name = shProg->BufferInterfaceBlocks[i].Name; - if (strncmp(block_name, name, strlen(block_name)) == 0) { + const char *block_name = shProg->BufferInterfaceBlocks[i].Name; + block_name_len = strlen(block_name); + + const char *block_square_bracket = strchr(block_name, '['); + if (block_square_bracket) { + /* The block is part of an array of named interfaces, + * for the name comparison we ignore the "[x]" part. + */ + block_name_len -= strlen(block_square_bracket); + } + + if (block_name_dot) { + /* Check if the variable name starts with the interface + * name. The interface name (if present) should have the + * length than the interface block name we are comparing to. + */ + unsigned len = strlen(name) - strlen(block_name_dot); + if (len != block_name_len) + continue; + } + + if (strncmp(block_name, name, block_name_len) == 0) { found_interface = true; break; } @@ -3157,7 +3178,7 @@ should_add_buffer_variable(struct gl_shader_program *shProg, * including the dot that follows it. */ if (found_interface) - name = name + strlen(block_name) + 1; + name = name + block_name_len + 1; /* From: ARB_program_interface_query extension: * @@ -3166,14 +3187,14 @@ should_add_buffer_variable(struct gl_shader_program *shProg, * of its type. For arrays of aggregate types, the enumeration rules are * applied recursively for the single enumerated array element. */ - const char *first_dot = strchr(name, '.'); + const char *struct_first_dot = strchr(name, '.'); const char *first_square_bracket = strchr(name, '['); /* The buffer variable is on top level and it is not an array */ if (!first_square_bracket) { return true; /* The shader storage block member is a struct, then generate the entry */ - } else if (first_dot && first_dot < first_square_bracket) { + } else if (struct_first_dot && struct_first_dot < first_square_bracket) { return true; } else { /* Shader storage block member is an array, only generate an entry for the -- 2.11.0