[Mesa-dev] [PATCH 07/17] mesa/st: allow for uniform packing when adding uniforms to param list

Timothy Arceri tarceri at itsqueeze.com
Sun Jun 25 01:31:39 UTC 2017


---
 src/mesa/program/ir_to_mesa.cpp            | 45 +++++++++++++++++++++++-------
 src/mesa/program/ir_to_mesa.h              |  3 +-
 src/mesa/state_tracker/st_glsl_to_nir.cpp  |  2 +-
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |  2 +-
 4 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 3fb5a24..fcf1b01 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2401,43 +2401,45 @@ print_program(struct prog_instruction *mesa_instructions,
 
       indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent,
 					    PROG_PRINT_DEBUG, NULL);
    }
 }
 
 namespace {
 
 class add_uniform_to_shader : public program_resource_visitor {
 public:
-   add_uniform_to_shader(struct gl_shader_program *shader_program,
+   add_uniform_to_shader(struct gl_context *ctx,
+                         struct gl_shader_program *shader_program,
 			 struct gl_program_parameter_list *params,
                          gl_shader_stage shader_type)
-      : shader_program(shader_program), params(params), idx(-1),
+      : ctx(ctx), shader_program(shader_program), params(params), idx(-1),
         shader_type(shader_type)
    {
       /* empty */
    }
 
    void process(ir_variable *var)
    {
       this->idx = -1;
       this->var = var;
       this->program_resource_visitor::process(var);
       var->data.param_index = this->idx;
    }
 
 private:
    virtual void visit_field(const glsl_type *type, const char *name,
                             bool row_major, const glsl_type *record_type,
                             const enum glsl_interface_packing packing,
                             bool last_field);
 
+   struct gl_context *ctx;
    struct gl_shader_program *shader_program;
    struct gl_program_parameter_list *params;
    int idx;
    ir_variable *var;
    gl_shader_stage shader_type;
 };
 
 } /* anonymous namespace */
 
 void
@@ -2458,50 +2460,67 @@ add_uniform_to_shader::visit_field(const glsl_type *type, const char *name,
       unsigned num_params = type->arrays_of_arrays_size();
       num_params = MAX2(num_params, 1);
       num_params *= type->without_array()->matrix_columns;
 
       bool is_dual_slot = type->without_array()->is_dual_slot();
       if (is_dual_slot)
          num_params *= 2;
 
       _mesa_reserve_parameter_storage(params, num_params);
       index = params->NumParameters;
-      for (unsigned i = 0; i < num_params; i++) {
-         unsigned comps = 4;
-         _mesa_add_parameter(params, PROGRAM_UNIFORM, name, comps,
-                             type->gl_type, NULL, NULL, false);
+
+      if (ctx->Const.PackedDriverUniformStorage) {
+         for (unsigned i = 0; i < num_params; i++) {
+            unsigned dmul = type->without_array()->is_64bit() ? 2 : 1;
+            unsigned comps = type->without_array()->vector_elements * dmul;
+            if (is_dual_slot) {
+               if (i & 0x1)
+                  comps -= 4;
+               else
+                  comps = 4;
+            }
+
+            _mesa_add_parameter(params, PROGRAM_UNIFORM, name, comps,
+                                type->gl_type, NULL, NULL, false);
+         }
+      } else {
+         for (unsigned i = 0; i < num_params; i++) {
+            _mesa_add_parameter(params, PROGRAM_UNIFORM, name, 4,
+                                type->gl_type, NULL, NULL, false);
+         }
       }
    }
 
    /* The first part of the uniform that's processed determines the base
     * location of the whole uniform (for structures).
     */
    if (this->idx < 0)
       this->idx = index;
 }
 
 /**
  * Generate the program parameters list for the user uniforms in a shader
  *
  * \param shader_program Linked shader program.  This is only used to
  *                       emit possible link errors to the info log.
  * \param sh             Shader whose uniforms are to be processed.
  * \param params         Parameter list to be filled in.
  */
 void
-_mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
+_mesa_generate_parameters_list_for_uniforms(struct gl_context *ctx,
+                                            struct gl_shader_program
 					    *shader_program,
 					    struct gl_linked_shader *sh,
 					    struct gl_program_parameter_list
 					    *params)
 {
-   add_uniform_to_shader add(shader_program, params, sh->Stage);
+   add_uniform_to_shader add(ctx, shader_program, params, sh->Stage);
 
    foreach_in_list(ir_instruction, node, sh->ir) {
       ir_variable *var = node->as_variable();
 
       if ((var == NULL) || (var->data.mode != ir_var_uniform)
 	  || var->is_in_buffer_block() || (strncmp(var->name, "gl_", 3) == 0))
 	 continue;
 
       add.process(var);
    }
@@ -2536,21 +2555,27 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
       struct gl_uniform_storage *storage =
          &shader_program->data->UniformStorage[location];
 
       /* Do not associate any uniform storage to built-in uniforms */
       if (storage->builtin)
          continue;
 
       if (location != last_location) {
          enum gl_uniform_driver_format format = uniform_native;
          unsigned columns = 0;
-         int dmul = 4 * sizeof(float);
+
+         int dmul;
+         if (ctx->Const.PackedDriverUniformStorage) {
+            dmul = storage->type->vector_elements * sizeof(float);
+         } else {
+            dmul = 4 * sizeof(float);
+         }
 
          switch (storage->type->base_type) {
          case GLSL_TYPE_UINT64:
             if (storage->type->vector_elements > 2)
                dmul *= 2;
             /* fallthrough */
          case GLSL_TYPE_UINT:
             assert(ctx->Const.NativeIntegers);
             format = uniform_native;
             columns = 1;
@@ -2850,21 +2875,21 @@ get_mesa_program(struct gl_context *ctx,
 
    validate_ir_tree(shader->ir);
 
    prog = shader->Program;
    prog->Parameters = _mesa_new_parameter_list();
    v.ctx = ctx;
    v.prog = prog;
    v.shader_program = shader_program;
    v.options = options;
 
-   _mesa_generate_parameters_list_for_uniforms(shader_program, shader,
+   _mesa_generate_parameters_list_for_uniforms(ctx, shader_program, shader,
 					       prog->Parameters);
 
    /* Emit Mesa IR for main(). */
    visit_exec_list(shader->ir, &v);
    v.emit(NULL, OPCODE_END);
 
    prog->arb.NumTemporaries = v.next_temp;
 
    unsigned num_instructions = v.instructions.length();
 
diff --git a/src/mesa/program/ir_to_mesa.h b/src/mesa/program/ir_to_mesa.h
index e3d3644..9714f50 100644
--- a/src/mesa/program/ir_to_mesa.h
+++ b/src/mesa/program/ir_to_mesa.h
@@ -31,21 +31,22 @@ extern "C" {
 #endif
 
 struct gl_context;
 struct gl_shader;
 struct gl_shader_program;
 
 void _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
 GLboolean _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
 
 void
-_mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
+_mesa_generate_parameters_list_for_uniforms(struct gl_context *ctx,
+                                            struct gl_shader_program
 					    *shader_program,
 					    struct gl_linked_shader *sh,
 					    struct gl_program_parameter_list
 					    *params);
 void
 _mesa_associate_uniform_storage(struct gl_context *ctx,
                                 struct gl_shader_program *shader_program,
                                 struct gl_program *prog,
                                 bool propagate_to_storage);
 
diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp
index 524eefa..8bf4006 100644
--- a/src/mesa/state_tracker/st_glsl_to_nir.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp
@@ -380,21 +380,21 @@ st_nir_get_mesa_program(struct gl_context *ctx,
 
    validate_ir_tree(shader->ir);
 
    prog = shader->Program;
 
    prog->Parameters = _mesa_new_parameter_list();
 
    do_set_program_inouts(shader->ir, prog, shader->Stage);
 
    _mesa_copy_linked_program_data(shader_program, shader);
-   _mesa_generate_parameters_list_for_uniforms(shader_program, shader,
+   _mesa_generate_parameters_list_for_uniforms(ctx, shader_program, shader,
                                                prog->Parameters);
 
    /* Make a pass over the IR to add state references for any built-in
     * uniforms that are used.  This has to be done now (during linking).
     * Code generation doesn't happen until the first time this shader is
     * used for rendering.  Waiting until then to generate the parameters is
     * too late.  At that point, the values for the built-in uniforms won't
     * get sent to the shader.
     */
    foreach_in_list(ir_instruction, node, shader->ir) {
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 1998852..5c540c1 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -6829,21 +6829,21 @@ get_mesa_program_tgsi(struct gl_context *ctx,
                                            PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED);
    v->has_tex_txf_lz = pscreen->get_param(pscreen,
                                           PIPE_CAP_TGSI_TEX_TXF_LZ);
 
    v->variables = _mesa_hash_table_create(v->mem_ctx, _mesa_hash_pointer,
                                           _mesa_key_pointer_equal);
    skip_merge_registers =
       pscreen->get_shader_param(pscreen, ptarget,
                                 PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS);
 
-   _mesa_generate_parameters_list_for_uniforms(shader_program, shader,
+   _mesa_generate_parameters_list_for_uniforms(ctx, shader_program, shader,
                                                prog->Parameters);
 
    /* Remove reads from output registers. */
    if (!pscreen->get_param(pscreen, PIPE_CAP_TGSI_CAN_READ_OUTPUTS))
       lower_output_reads(shader->Stage, shader->ir);
 
    /* Emit intermediate IR for main(). */
    visit_exec_list(shader->ir, v);
 
 #if 0
-- 
2.9.4



More information about the mesa-dev mailing list