glsl/nir: Fill in the Parameters in NIR linker
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Wed, 21 Aug 2019 18:08:48 +0000 (11:08 -0700)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Tue, 10 Sep 2019 21:36:46 +0000 (14:36 -0700)
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>
src/compiler/glsl/gl_nir_link_uniforms.c
src/compiler/glsl/gl_nir_linker.h
src/compiler/glsl/serialize.cpp
src/mesa/drivers/dri/i965/brw_link.cpp
src/mesa/program/prog_parameter.h

index 6323d2940db1f8dc28777397db4027f7921ca5e9..7aebe0dd7e2dc997adde52a04e7cda9dc803b590 100644 (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):
index 20ed35fa0e4d3111edd485ebcdb01420b23172d6..ecbc3f390905c86124767c6eaf6c1ca5e05885cb 100644 (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);
index 552300f7eaf75664eb01dca53c91e927e38c4a91..235188c5c5931ac3747f8ef3bda00a6f0812b299 100644 (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++;
    }
 
index e4e0b5fe330ccdf077172b53d742acd2ae7b0b83..c726551513a3927f51866b3ebae77c93217d4b0a 100644 (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);
index 94aeb5540b503d2f29a33f9985a51e330c1b1083..c91156f623c57c298ad613a56b2035e643d7e755 100644 (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;
 };