const struct glsl_type *current_ifc_type;
int offset;
bool var_is_in_block;
+ bool set_top_level_array;
int top_level_array_size;
int top_level_array_stride;
struct gl_program *stage_program,
gl_shader_stage stage,
const struct glsl_type *type,
- const struct glsl_type *parent_type,
unsigned index_in_parent,
int location,
struct nir_link_uniforms_state *state,
{
struct gl_uniform_storage *uniform = NULL;
- if (parent_type == state->current_var->type &&
+ if (state->set_top_level_array &&
nir_variable_is_in_ssbo(state->current_var)) {
/* Type is the top level SSBO member */
if (glsl_type_is_array(type) &&
state->top_level_array_size = 1;
state->top_level_array_stride = 0;
}
+
+ state->set_top_level_array = false;
}
/* gl_uniform_storage can cope with one level of array, so if the type is a
state->current_type = old_type->children;
- for (unsigned i = 0; i < glsl_get_length(type); i++) {
+ /* Shader storage block unsized arrays: add subscript [0] to variable
+ * names.
+ */
+ unsigned length = glsl_get_length(type);
+ if (glsl_type_is_unsized_array(type))
+ length = 1;
+
+ for (unsigned i = 0; i < length; i++) {
const struct glsl_type *field_type;
size_t new_length = name_length;
type == state->current_ifc_type) {
state->offset = glsl_get_struct_field_offset(type, i);
}
+
+ if (glsl_type_is_interface(type))
+ state->set_top_level_array = true;
}
/* Append '.field' to the current variable name. */
}
int entries = nir_link_uniform(ctx, prog, stage_program, stage,
- field_type, type, i, location,
+ field_type, i, location,
state, name, new_length);
if (entries == -1)
return -1;
state.current_ifc_type = NULL;
state.offset = 0;
state.var_is_in_block = nir_variable_is_in_block(var);
+ state.set_top_level_array = false;
state.top_level_array_size = 0;
state.top_level_array_stride = 0;
state.current_ifc_type = type;
name = ralloc_strdup(NULL, glsl_get_type_name(type));
} else {
+ state.set_top_level_array = true;
name = ralloc_strdup(NULL, var->name);
}
location = -1;
int res = nir_link_uniform(ctx, prog, sh->Program, shader_type, type,
- NULL, 0,
- location,
+ 0, location,
&state,
!prog->data->spirv ? &name : NULL,
!prog->data->spirv ? strlen(name) : 0);