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 <tarceri@itsqueeze.com>
This commit is contained in:
Caio Marcelo de Oliveira Filho 2019-08-21 11:08:48 -07:00
parent eea3aa25aa
commit 664e4a610d
5 changed files with 88 additions and 3 deletions

View File

@ -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 = &params->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):

View File

@ -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);

View File

@ -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 = &params->Parameters[i];
param->UniformStorageIndex = blob_read_uint32(metadata);
param->MainUniformStorageIndex = blob_read_uint32(metadata);
i++;
}

View File

@ -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);

View File

@ -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;
};