[Mesa-dev] [PATCH 06/78] i965/nir/vec4: Add setup of uniform variables

Jason Ekstrand jason at jlekstrand.net
Mon Jun 29 16:22:08 PDT 2015


On Fri, Jun 26, 2015 at 1:06 AM, Eduardo Lima Mitev <elima at igalia.com> wrote:
> From: Iago Toral Quiroga <itoral at igalia.com>
>
> This is based on similar code existing in vec4_visitor. It builds the
> uniform register file iterating through each uniform variable. It
> also stores the index of each register at the corresponding offset
> in a map. This map will later be used by load_uniform intrinsic
> instructions to build the correct UNIFORM source register.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89580
> ---
>  src/mesa/drivers/dri/i965/brw_vec4.h       |   2 +
>  src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 115 ++++++++++++++++++++++++++++-
>  2 files changed, 114 insertions(+), 3 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
> index 673df4e..6535f19 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4.h
> +++ b/src/mesa/drivers/dri/i965/brw_vec4.h
> @@ -414,6 +414,8 @@ public:
>     src_reg *nir_inputs;
>     int *nir_outputs;
>     brw_reg_type *nir_output_types;
> +   unsigned *nir_uniform_offset;
> +   unsigned *nir_uniform_driver_location;
>
>  protected:
>     void emit_vertex();
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
> index 2d457a6..40ec66f 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
> @@ -106,19 +106,128 @@ vec4_visitor::nir_setup_outputs(nir_shader *shader)
>  void
>  vec4_visitor::nir_setup_uniforms(nir_shader *shader)
>  {
> -   /* @TODO: Not yet implemented */
> +   uniforms = 0;
> +
> +   nir_uniform_offset =
> +      rzalloc_array(mem_ctx, unsigned, this->uniform_array_size);
> +   memset(nir_uniform_offset, 0, this->uniform_array_size * sizeof(unsigned));

rzalloc memsets the whole thing to 0 for you, this memset is redundant.

> +
> +   nir_uniform_driver_location =
> +      rzalloc_array(mem_ctx, unsigned, this->uniform_array_size);
> +   memset(nir_uniform_driver_location, 0,
> +          this->uniform_array_size * sizeof(unsigned));

Same here.

> +
> +   if (shader_prog) {
> +      foreach_list_typed(nir_variable, var, node, &shader->uniforms) {
> +         /* UBO's, atomics and samplers don't take up space in the
> +            uniform file */
> +         if (var->interface_type != NULL || var->type->contains_atomic() ||
> +             type_size(var->type) == 0) {

I'm curious as to why you have this extra type_size() == 0 condition.
We don't have that in the FS NIR code.  What caused you to add it?

> +            continue;
> +         }
> +
> +         assert(uniforms < uniform_array_size);
> +         this->uniform_size[uniforms] = type_size(var->type);
> +
> +         if (strncmp(var->name, "gl_", 3) == 0)
> +            nir_setup_builtin_uniform(var);
> +         else
> +            nir_setup_uniform(var);
> +      }
> +   } else {
> +      /* ARB_vertex_program is not supported yet */
> +      assert("Not implemented");
> +   }
>  }
>
>  void
>  vec4_visitor::nir_setup_uniform(nir_variable *var)
>  {
> -   /* @TODO: Not yet implemented */
> +   int namelen = strlen(var->name);
> +
> +   /* The data for our (non-builtin) uniforms is stored in a series of
> +    * gl_uniform_driver_storage structs for each subcomponent that
> +    * glGetUniformLocation() could name.  We know it's been set up in the same
> +    * order we'd walk the type, so walk the list of storage and find anything
> +    * with our name, or the prefix of a component that starts with our name.
> +    */
> +    unsigned offset = 0;
> +    for (unsigned u = 0; u < shader_prog->NumUniformStorage; u++) {
> +       struct gl_uniform_storage *storage = &shader_prog->UniformStorage[u];
> +
> +       if (storage->builtin)
> +          continue;
> +
> +       if (strncmp(var->name, storage->name, namelen) != 0 ||
> +           (storage->name[namelen] != 0 &&
> +            storage->name[namelen] != '.' &&
> +            storage->name[namelen] != '[')) {
> +          continue;
> +       }
> +
> +       gl_constant_value *components = storage->storage;
> +       unsigned vector_count = (MAX2(storage->array_elements, 1) *
> +                                storage->type->matrix_columns);

In the FS backend, we simply use storage->type->component_slots().
Why can't we do that here?  It seems to be performing the same
calculation.

> +
> +       for (unsigned s = 0; s < vector_count; s++) {
> +          assert(uniforms < uniform_array_size);
> +          uniform_vector_size[uniforms] = storage->type->vector_elements;
> +
> +          int i;
> +          for (i = 0; i < uniform_vector_size[uniforms]; i++) {
> +             stage_prog_data->param[uniforms * 4 + i] = components;
> +             components++;
> +          }
> +          for (; i < 4; i++) {
> +             static gl_constant_value zero = { 0.0 };

This should probably be const.

> +             stage_prog_data->param[uniforms * 4 + i] = &zero;
> +          }
> +
> +          int uniform_offset = var->data.driver_location + offset;
> +          nir_uniform_offset[uniform_offset] = uniforms;
> +          offset++;
> +
> +          nir_uniform_driver_location[uniforms] = var->data.driver_location;
> +          uniforms++;
> +       }
> +    }
>  }
>
>  void
>  vec4_visitor::nir_setup_builtin_uniform(nir_variable *var)
>  {
> -   /* @TODO: Not yet implemented */
> +   const nir_state_slot *const slots = var->state_slots;
> +   assert(var->state_slots != NULL);
> +
> +   unsigned offset = 0;
> +   for (unsigned int i = 0; i < var->num_state_slots; i++) {
> +      /* This state reference has already been setup by ir_to_mesa,
> +       * but we'll get the same index back here.  We can reference
> +       * ParameterValues directly, since unlike brw_fs.cpp, we never
> +       * add new state references during compile.
> +       */
> +      int index = _mesa_add_state_reference(this->prog->Parameters,
> +                                           (gl_state_index *)slots[i].tokens);
> +      gl_constant_value *values =
> +         &this->prog->Parameters->ParameterValues[index][0];
> +
> +      assert(this->uniforms < uniform_array_size);
> +
> +      for (unsigned j = 0; j < 4; j++)
> +         stage_prog_data->param[this->uniforms * 4 + j] =
> +            &values[GET_SWZ(slots[i].swizzle, j)];
> +
> +      this->uniform_vector_size[this->uniforms] =
> +         (var->type->is_scalar() || var->type->is_vector() ||
> +          var->type->is_matrix() ? var->type->vector_elements : 4);
> +
> +      int uniform_offset = var->data.driver_location + offset;
> +      nir_uniform_offset[uniform_offset] = uniforms;
> +      offset++;
> +
> +      nir_uniform_driver_location[uniforms] = var->data.driver_location;
> +      this->uniforms++;
> +   }
>  }
>
>  void
> --
> 2.1.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list