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 <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5831>
diff --git a/src/compiler/glsl/gl_nir_link_uniforms.c b/src/compiler/glsl/gl_nir_link_uniforms.c
index 656b42b..ce51374 100644
--- a/src/compiler/glsl/gl_nir_link_uniforms.c
+++ b/src/compiler/glsl/gl_nir_link_uniforms.c
@@ -1727,54 +1727,57 @@
}
}
- 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);