From 47c358233d45747def3b796c37ae92df86860141 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 9 Jul 2020 15:36:54 -0400 Subject: [PATCH] glsl: fix up location setting for variables pointing to a UBO's base while linking uniforms, we might get a variable which is the only reference to the ubo (i.e., offset 0), as determined by its type being the UBO's interface_type, at which point we can assign the previously-gotten block index to this variable's location Reviewed-by: Erik Faye-Lund Part-of: --- src/compiler/glsl/gl_nir_link_uniforms.c | 91 ++++++++++++------------ 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/src/compiler/glsl/gl_nir_link_uniforms.c b/src/compiler/glsl/gl_nir_link_uniforms.c index 656b42b601b..ce51374c654 100644 --- a/src/compiler/glsl/gl_nir_link_uniforms.c +++ b/src/compiler/glsl/gl_nir_link_uniforms.c @@ -1727,54 +1727,57 @@ gl_nir_link_uniforms(struct gl_context *ctx, } } - if (!prog->data->spirv && state.var_is_in_block && - glsl_without_array(state.current_var->type) != state.current_var->interface_type) { + if (!prog->data->spirv && state.var_is_in_block) { + if (glsl_without_array(state.current_var->type) != state.current_var->interface_type) { + /* this is nested at some offset inside the block */ + bool found = false; + char sentinel = '\0'; - bool found = false; - char sentinel = '\0'; - - if (glsl_type_is_struct(state.current_var->type)) { - sentinel = '.'; - } else if (glsl_type_is_array(state.current_var->type) && - (glsl_type_is_array(glsl_get_array_element(state.current_var->type)) - || glsl_type_is_struct(glsl_without_array(state.current_var->type)))) { - sentinel = '['; - } - - const unsigned l = strlen(state.current_var->name); - for (unsigned i = 0; i < num_blocks; i++) { - for (unsigned j = 0; j < blocks[i].NumUniforms; j++) { - if (sentinel) { - const char *begin = blocks[i].Uniforms[j].Name; - const char *end = strchr(begin, sentinel); - - if (end == NULL) - continue; - - if ((ptrdiff_t) l != (end - begin)) - continue; - found = strncmp(state.current_var->name, begin, l) == 0; - } else { - found = strcmp(state.current_var->name, blocks[i].Uniforms[j].Name) == 0; - } - - if (found) { - location = j; - - struct hash_entry *entry = - _mesa_hash_table_search(state.referenced_uniforms[shader_type], var->name); - if (entry) - blocks[i].stageref |= 1U << shader_type; - - break; - } + if (glsl_type_is_struct(state.current_var->type)) { + sentinel = '.'; + } else if (glsl_type_is_array(state.current_var->type) && + (glsl_type_is_array(glsl_get_array_element(state.current_var->type)) + || glsl_type_is_struct(glsl_without_array(state.current_var->type)))) { + sentinel = '['; } - if (found) - break; - } - assert(found); + const unsigned l = strlen(state.current_var->name); + for (unsigned i = 0; i < num_blocks; i++) { + for (unsigned j = 0; j < blocks[i].NumUniforms; j++) { + if (sentinel) { + const char *begin = blocks[i].Uniforms[j].Name; + const char *end = strchr(begin, sentinel); + if (end == NULL) + continue; + + if ((ptrdiff_t) l != (end - begin)) + continue; + found = strncmp(state.current_var->name, begin, l) == 0; + } else { + found = strcmp(state.current_var->name, blocks[i].Uniforms[j].Name) == 0; + } + + if (found) { + location = j; + + struct hash_entry *entry = + _mesa_hash_table_search(state.referenced_uniforms[shader_type], var->name); + if (entry) + blocks[i].stageref |= 1U << shader_type; + + break; + } + } + + if (found) + break; + } + assert(found); + } else + /* this is the base block offset */ + location = buffer_block_index; + assert(buffer_block_index >= 0); const struct gl_uniform_block *const block = &blocks[buffer_block_index]; assert(location != -1);