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>
This commit is contained in:
parent
ef0babab38
commit
47c358233d
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue