From 664e4a610dc8c0f2adc50de645a07cf4e2b622fd Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Wed, 21 Aug 2019 11:08:48 -0700 Subject: [PATCH] glsl/nir: Fill in the Parameters in NIR linker The parameter lists were not being created nor filled since i965 doesn't use them. In Gallium they are used for uniform handling, so add a way to fill them. The gl_uniform_storage struct got two new fields that let us go - from a Parameter to the matching UniformStorage and, - from the variable to the *first* UniformStorage without relying on names -- since they are optional for ARB_gl_spirv. Later patches will make use of them. v2: Do not fill parameters for i965. (Timothy) Use uint32_t for the new attributes. (Marek) v3: Serialize the new fields. (Timothy) Reviewed-by: Timothy Arceri --- src/compiler/glsl/gl_nir_link_uniforms.c | 69 +++++++++++++++++++++++- src/compiler/glsl/gl_nir_linker.h | 3 +- src/compiler/glsl/serialize.cpp | 6 +++ src/mesa/drivers/dri/i965/brw_link.cpp | 2 +- src/mesa/program/prog_parameter.h | 11 ++++ 5 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/compiler/glsl/gl_nir_link_uniforms.c b/src/compiler/glsl/gl_nir_link_uniforms.c index 6323d2940db..7aebe0dd7e2 100644 --- a/src/compiler/glsl/gl_nir_link_uniforms.c +++ b/src/compiler/glsl/gl_nir_link_uniforms.c @@ -249,6 +249,7 @@ struct nir_link_uniforms_state { unsigned num_shader_uniform_components; unsigned shader_samplers_used; unsigned shader_shadow_samplers; + struct gl_program_parameter_list *params; /* per-variable */ nir_variable *current_var; @@ -256,6 +257,7 @@ struct nir_link_uniforms_state { bool var_is_in_block; int top_level_array_size; int top_level_array_stride; + int main_uniform_storage_index; struct type_tree_entry *current_type; }; @@ -342,6 +344,59 @@ get_next_index(struct nir_link_uniforms_state *state, return index; } +static void +add_parameter(struct gl_uniform_storage *uniform, + struct gl_context *ctx, + struct gl_shader_program *prog, + const struct glsl_type *type, + struct nir_link_uniforms_state *state) +{ + if (!state->params || uniform->is_shader_storage || glsl_contains_opaque(type)) + return; + + unsigned num_params = glsl_get_aoa_size(type); + num_params = MAX2(num_params, 1); + num_params *= glsl_get_matrix_columns(glsl_without_array(type)); + + bool is_dual_slot = glsl_type_is_dual_slot(glsl_without_array(type)); + if (is_dual_slot) + num_params *= 2; + + struct gl_program_parameter_list *params = state->params; + int base_index = params->NumParameters; + _mesa_reserve_parameter_storage(params, num_params); + + if (ctx->Const.PackedDriverUniformStorage) { + for (unsigned i = 0; i < num_params; i++) { + unsigned dmul = glsl_type_is_64bit(glsl_without_array(type)) ? 2 : 1; + unsigned comps = glsl_get_vector_elements(glsl_without_array(type)) * dmul; + if (is_dual_slot) { + if (i & 0x1) + comps -= 4; + else + comps = 4; + } + + _mesa_add_parameter(params, PROGRAM_UNIFORM, NULL, comps, + glsl_get_gl_type(type), NULL, NULL, false); + } + } else { + for (unsigned i = 0; i < num_params; i++) { + _mesa_add_parameter(params, PROGRAM_UNIFORM, NULL, 4, + glsl_get_gl_type(type), NULL, NULL, true); + } + } + + /* Each Parameter will hold the index to the backing uniform storage. + * This avoids relying on names to match parameters and uniform + * storages. + */ + for (unsigned i = 0; i < num_params; i++) { + struct gl_program_parameter *param = ¶ms->Parameters[base_index + i]; + param->UniformStorageIndex = uniform - prog->data->UniformStorage; + param->MainUniformStorageIndex = state->main_uniform_storage_index; + } +} /** * Creates the neccessary entries in UniformStorage for the uniform. Returns @@ -435,6 +490,9 @@ nir_link_uniform(struct gl_context *ctx, return -1; } + if (state->main_uniform_storage_index == -1) + state->main_uniform_storage_index = prog->data->NumUniformStorage; + uniform = &prog->data->UniformStorage[prog->data->NumUniformStorage]; prog->data->NumUniformStorage++; @@ -607,13 +665,17 @@ nir_link_uniform(struct gl_context *ctx, state->max_uniform_location < uniform->remap_location + entries) state->max_uniform_location = uniform->remap_location + entries; + if (!state->var_is_in_block) + add_parameter(uniform, ctx, prog, type, state); + return MAX2(uniform->array_elements, 1); } } bool gl_nir_link_uniforms(struct gl_context *ctx, - struct gl_shader_program *prog) + struct gl_shader_program *prog, + bool fill_parameters) { /* First free up any previous UniformStorage items */ ralloc_free(prog->data->UniformStorage); @@ -636,6 +698,7 @@ gl_nir_link_uniforms(struct gl_context *ctx, state.num_shader_uniform_components = 0; state.shader_samplers_used = 0; state.shader_shadow_samplers = 0; + state.params = fill_parameters ? sh->Program->Parameters : NULL; nir_foreach_variable(var, &nir->uniforms) { struct gl_uniform_storage *uniform = NULL; @@ -648,6 +711,9 @@ gl_nir_link_uniforms(struct gl_context *ctx, if (uniform) { var->data.location = uniform - prog->data->UniformStorage; + if (!state.var_is_in_block) + add_parameter(uniform, ctx, prog, var->type, &state); + continue; } @@ -660,6 +726,7 @@ gl_nir_link_uniforms(struct gl_context *ctx, state.var_is_in_block = nir_variable_is_in_block(var); state.top_level_array_size = 0; state.top_level_array_stride = 0; + state.main_uniform_storage_index = -1; /* * From ARB_program_interface spec, issue (16): diff --git a/src/compiler/glsl/gl_nir_linker.h b/src/compiler/glsl/gl_nir_linker.h index 20ed35fa0e4..ecbc3f39090 100644 --- a/src/compiler/glsl/gl_nir_linker.h +++ b/src/compiler/glsl/gl_nir_linker.h @@ -32,7 +32,8 @@ struct gl_context; struct gl_shader_program; bool gl_nir_link_uniforms(struct gl_context *ctx, - struct gl_shader_program *prog); + struct gl_shader_program *prog, + bool fill_parameters); void gl_nir_set_uniform_initializers(struct gl_context *ctx, struct gl_shader_program *prog); diff --git a/src/compiler/glsl/serialize.cpp b/src/compiler/glsl/serialize.cpp index 552300f7eaf..235188c5c59 100644 --- a/src/compiler/glsl/serialize.cpp +++ b/src/compiler/glsl/serialize.cpp @@ -1015,6 +1015,8 @@ write_shader_parameters(struct blob *metadata, blob_write_uint32(metadata, param->DataType); blob_write_bytes(metadata, param->StateIndexes, sizeof(param->StateIndexes)); + blob_write_uint32(metadata, param->UniformStorageIndex); + blob_write_uint32(metadata, param->MainUniformStorageIndex); i++; } @@ -1046,6 +1048,10 @@ read_shader_parameters(struct blob_reader *metadata, _mesa_add_parameter(params, type, name, size, data_type, NULL, state_indexes, padded); + gl_program_parameter *param = ¶ms->Parameters[i]; + param->UniformStorageIndex = blob_read_uint32(metadata); + param->MainUniformStorageIndex = blob_read_uint32(metadata); + i++; } diff --git a/src/mesa/drivers/dri/i965/brw_link.cpp b/src/mesa/drivers/dri/i965/brw_link.cpp index e4e0b5fe330..c726551513a 100644 --- a/src/mesa/drivers/dri/i965/brw_link.cpp +++ b/src/mesa/drivers/dri/i965/brw_link.cpp @@ -273,7 +273,7 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg) return GL_FALSE; } - if (!gl_nir_link_uniforms(ctx, shProg)) + if (!gl_nir_link_uniforms(ctx, shProg, /* fill_parameters */ false)) return GL_FALSE; gl_nir_link_assign_atomic_counter_resources(ctx, shProg); diff --git a/src/mesa/program/prog_parameter.h b/src/mesa/program/prog_parameter.h index 94aeb5540b5..c91156f623c 100644 --- a/src/mesa/program/prog_parameter.h +++ b/src/mesa/program/prog_parameter.h @@ -112,6 +112,17 @@ struct gl_program_parameter * A sequence of STATE_* tokens and integers to identify GL state. */ gl_state_index16 StateIndexes[STATE_LENGTH]; + + /** + * Index of this parameter's uniform storage. + */ + uint32_t UniformStorageIndex; + + /** + * Index of the first uniform storage that is associated with the same + * variable as this parameter. + */ + uint32_t MainUniformStorageIndex; }; -- 2.30.2