unsigned shader_shadow_samplers;
nir_variable *current_var;
+ int offset;
+ bool var_is_in_block;
struct type_tree_entry *current_type;
};
glsl_type_is_struct_or_ifc(glsl_get_array_element(type))))) {
int location_count = 0;
struct type_tree_entry *old_type = state->current_type;
+ unsigned int struct_base_offset = state->offset;
state->current_type = old_type->children;
for (unsigned i = 0; i < glsl_get_length(type); i++) {
const struct glsl_type *field_type;
- if (glsl_type_is_struct_or_ifc(type))
+ if (glsl_type_is_struct_or_ifc(type)) {
field_type = glsl_get_struct_field(type, i);
- else
+ /* Use the offset inside the struct only for variables backed by
+ * a buffer object. For variables not backed by a buffer object,
+ * offset is -1.
+ */
+ if (state->var_is_in_block) {
+ state->offset =
+ struct_base_offset + glsl_get_struct_field_offset(type, i);
+ }
+ } else {
field_type = glsl_get_array_element(type);
+ }
int entries = nir_link_uniform(ctx, prog, stage_program, stage,
field_type, type, i, location,
uniform->matrix_stride = -1;
uniform->row_major = false;
- if (nir_variable_is_in_block(state->current_var)) {
+ if (state->var_is_in_block) {
uniform->array_stride = glsl_type_is_array(type) ?
glsl_get_explicit_stride(type) : 0;
}
}
- if (parent_type)
- uniform->offset = glsl_get_struct_field_offset(parent_type, index_in_parent);
- else
- uniform->offset = 0;
+ uniform->offset = state->var_is_in_block ? state->offset : -1;
int buffer_block_index = -1;
/* If the uniform is inside a uniform block determine its block index by
* comparing the bindings, we can not use names.
*/
- if (nir_variable_is_in_block(state->current_var)) {
+ if (state->var_is_in_block) {
struct gl_uniform_block *blocks = nir_variable_is_in_ssbo(state->current_var) ?
prog->data->ShaderStorageBlocks : prog->data->UniformBlocks;
}
}
assert(buffer_block_index >= 0);
+
+ /* Compute the next offset. */
+ state->offset += glsl_get_explicit_size(type, true);
}
uniform->block_index = buffer_block_index;
var->data.location = prog->data->NumUniformStorage;
state.current_var = var;
+ state.offset = 0;
+ state.var_is_in_block = nir_variable_is_in_block(var);
/*
* From ARB_program_interface spec, issue (16):
* arrays of instance as a single block.
*/
const struct glsl_type *type = var->type;
- if (nir_variable_is_in_block(var) &&
- glsl_type_is_array(type)) {
+ if (state.var_is_in_block && glsl_type_is_array(type)) {
type = glsl_without_array(type);
}