Mesa (master): ir_to_mesa: Convert this code to using linker.cpp' s uniform locations.

Eric Anholt anholt at kemper.freedesktop.org
Wed Aug 25 19:40:11 UTC 2010


Module: Mesa
Branch: master
Commit: 0924ba0c3496160a134d37cec800f902ae805b9c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0924ba0c3496160a134d37cec800f902ae805b9c

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 24 14:27:27 2010 -0700

ir_to_mesa: Convert this code to using linker.cpp's uniform locations.

Fixes: glsl-fs-uniform-array-4.

---

 src/glsl/linker.cpp             |    1 +
 src/mesa/program/ir_to_mesa.cpp |  199 +++++++++++++++------------------------
 src/mesa/program/prog_uniform.h |    5 +-
 3 files changed, 78 insertions(+), 127 deletions(-)

diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index cb06036..0348bd0 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -929,6 +929,7 @@ add_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht,
 	 n->slots = vec4_slots;
 
 	 n->u->Name = strdup(name);
+	 n->u->Type = type;
 	 n->u->VertPos = -1;
 	 n->u->FragPos = -1;
 	 n->u->GeomPos = -1;
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 4429b74..4a4278e 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -260,13 +260,6 @@ public:
    GLboolean try_emit_mad(ir_expression *ir,
 			  int mul_operand);
 
-   int add_uniform(const char *name,
-		   const glsl_type *type);
-   void add_aggregate_uniform(ir_instruction *ir,
-			      const char *name,
-			      const struct glsl_type *type,
-			      struct ir_to_mesa_dst_reg temp);
-
    struct hash_table *sampler_map;
 
    void set_sampler_location(ir_variable *sampler, int location);
@@ -522,10 +515,10 @@ type_size(const struct glsl_type *type)
       }
       return size;
    case GLSL_TYPE_SAMPLER:
-      /* Samplers take up no register space, since they're baked in at
-       * link time.
+      /* Samplers take up one slot in UNIFORMS[], but they're baked in
+       * at link time.
        */
-      return 0;
+      return 1;
    default:
       assert(0);
       return 0;
@@ -1290,7 +1283,6 @@ get_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
 	    tokens[1] = 0; /* unused array index */
 	    base_pos = add_matrix_ref(prog, tokens);
 	 }
-	 tokens[4] = matrices[i].modifier;
 
 	 entry = new(mem_ctx) variable_storage(var,
 					       PROGRAM_STATE_VAR,
@@ -1303,76 +1295,10 @@ get_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
    return NULL;
 }
 
-int
-ir_to_mesa_visitor::add_uniform(const char *name,
-				const glsl_type *type)
-{
-   int len;
-
-   if (type->is_vector() ||
-       type->is_scalar()) {
-      len = type->vector_elements;
-   } else {
-      len = type_size(type) * 4;
-   }
-
-   int loc = _mesa_add_uniform(this->prog->Parameters,
-			       name,
-			       len,
-			       type->gl_type,
-			       NULL);
-
-   return loc;
-}
-
-/* Recursively add all the members of the aggregate uniform as uniform names
- * to Mesa, moving those uniforms to our structured temporary.
- */
-void
-ir_to_mesa_visitor::add_aggregate_uniform(ir_instruction *ir,
-					  const char *name,
-					  const struct glsl_type *type,
-					  struct ir_to_mesa_dst_reg temp)
-{
-   int loc;
-
-   if (type->is_record()) {
-      void *mem_ctx = talloc_new(NULL);
-
-      for (unsigned int i = 0; i < type->length; i++) {
-	 const glsl_type *field_type = type->fields.structure[i].type;
-
-	 add_aggregate_uniform(ir,
-			       talloc_asprintf(mem_ctx, "%s.%s", name,
-					       type->fields.structure[i].name),
-			       field_type, temp);
-	 temp.index += type_size(field_type);
-      }
-
-      talloc_free(mem_ctx);
-
-      return;
-   }
-
-   assert(type->is_vector() || type->is_scalar() || !"FINISHME: other types");
-
-   loc = add_uniform(name, type);
-
-   ir_to_mesa_src_reg uniform(PROGRAM_UNIFORM, loc, type);
-
-   for (int i = 0; i < type_size(type); i++) {
-      ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, uniform);
-      temp.index++;
-      uniform.index++;
-   }
-}
-
-
 void
 ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
 {
    variable_storage *entry = find_variable_storage(ir->var);
-   unsigned int loc;
 
    if (!entry) {
       switch (ir->var->mode) {
@@ -1382,7 +1308,6 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
 	 if (entry)
 	    break;
 
-	 /* FINISHME: Fix up uniform name for arrays and things */
 	 if (ir->var->type->base_type == GLSL_TYPE_SAMPLER ||
 	     (ir->var->type->base_type == GLSL_TYPE_ARRAY &&
 	      ir->var->type->fields.array->base_type == GLSL_TYPE_SAMPLER)) {
@@ -1404,30 +1329,8 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
 	    break;
 	 }
 
-	 assert(ir->var->type->gl_type != 0 &&
-		ir->var->type->gl_type != GL_INVALID_ENUM);
-
-	 /* Oh, the joy of aggregate types in Mesa.  Like constants,
-	  * we can only really do vec4s.  So, make a temp, chop the
-	  * aggregate up into vec4s, and move those vec4s to the temp.
-	  */
-	 if (ir->var->type->is_record()) {
-	    ir_to_mesa_src_reg temp = get_temp(ir->var->type);
-
-	    entry = new(mem_ctx) variable_storage(ir->var,
-						  temp.file,
-						  temp.index);
-	    this->variables.push_tail(entry);
-
-	    add_aggregate_uniform(ir->var, ir->var->name, ir->var->type,
-				  ir_to_mesa_dst_reg_from_src(temp));
-	    break;
-	 }
-
-	 loc = add_uniform(ir->var->name,
-			   ir->var->type);
-
-	 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM, loc);
+	 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM,
+					       ir->var->location);
 	 this->variables.push_tail(entry);
 	 break;
       case ir_var_in:
@@ -2338,25 +2241,81 @@ count_resources(struct gl_program *prog)
    _mesa_update_shader_textures_used(prog);
 }
 
-/* Each stage has some uniforms in its Parameters list.  The Uniforms
- * list for the linked shader program has a pointer to these uniforms
- * in each of the stage's Parameters list, so that their values can be
- * updated when a uniform is set.
+/* Add the uniforms to the parameters.  The linker chose locations
+ * in our parameters lists (which weren't created yet), which the
+ * uniforms code will use to poke values into our parameters list
+ * when uniforms are updated.
  */
 static void
-link_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms,
-				     struct gl_program *prog)
+add_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
+				struct gl_shader *shader,
+				struct gl_program *prog)
 {
    unsigned int i;
 
-   for (i = 0; i < prog->Parameters->NumParameters; i++) {
-      const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
+   for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) {
+      struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i;
+      const glsl_type *type = uniform->Type;
+      unsigned int size;
+      int parameter_index = -1;
+
+      switch (shader->Type) {
+      case GL_VERTEX_SHADER:
+	 parameter_index = uniform->VertPos;
+	 break;
+      case GL_FRAGMENT_SHADER:
+	 parameter_index = uniform->FragPos;
+	 break;
+      case GL_GEOMETRY_SHADER:
+	 parameter_index = uniform->GeomPos;
+	 break;
+      }
+
+      /* Only add uniforms used in our target. */
+      if (parameter_index == -1)
+	 continue;
+
+      if (type->is_vector() ||
+	  type->is_scalar()) {
+	 size = type->vector_elements;
+      } else {
+	 size = type_size(type) * 4;
+      }
+
+      if (type->is_sampler() ||
+	  (type->is_array() && type->fields.array->is_sampler())) {
+	 int array_length;
 
-      if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) {
-	 struct gl_uniform *uniform =
-	    _mesa_append_uniform(uniforms, p->Name, prog->Target, i);
-	 if (uniform)
-	    uniform->Initialized = p->Initialized;
+	 if (type->is_array())
+	    array_length = type->length;
+	 else
+	    array_length = 1;
+
+	 (void)_mesa_add_sampler(prog->Parameters,
+				 uniform->Name,
+				 type->gl_type,
+				 array_length);
+      } else {
+	 GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
+						    uniform->Name);
+
+	 if (index < 0) {
+	    index = _mesa_add_parameter(prog->Parameters, PROGRAM_UNIFORM,
+					uniform->Name, size, type->gl_type,
+					NULL, NULL, 0x0);
+
+	    /* The location chosen in the Parameters list here (returned
+	     * from _mesa_add_uniform) has to match what the linker chose.
+	     */
+	    if (index != parameter_index) {
+	       shader_program->InfoLog =
+		  talloc_asprintf_append(shader_program->InfoLog,
+					 "Allocation of uniform `%s' to target "
+					 "failed (%d vs %d)\n", uniform->Name,
+					 index, parameter_index);
+	       shader_program->LinkStatus = false;
+	    }
+	 }
       }
    }
 }
@@ -2498,6 +2457,8 @@ get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
    v.ctx = ctx;
    v.prog = prog;
 
+   add_uniforms_to_parameters_list(shader_program, shader, prog);
+
    /* Emit Mesa IR for main(). */
    visit_exec_list(shader->ir, &v);
    v.ir_to_mesa_emit_op0(NULL, OPCODE_END);
@@ -2676,8 +2637,6 @@ _mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
 
       linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
 
-      link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
-
       switch (prog->_LinkedShaders[i]->Type) {
       case GL_VERTEX_SHADER:
 	 _mesa_reference_vertprog(ctx, &prog->VertexProgram,
@@ -2801,12 +2760,6 @@ _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
 
    if (prog->LinkStatus) {
       link_shaders(ctx, prog);
-
-      /* We don't use the linker's uniforms list, and cook up our own at
-       * generate time.
-       */
-      _mesa_free_uniform_list(prog->Uniforms);
-      prog->Uniforms = _mesa_new_uniform_list();
    }
 
    if (prog->LinkStatus) {
diff --git a/src/mesa/program/prog_uniform.h b/src/mesa/program/prog_uniform.h
index 7988d53..67f7800 100644
--- a/src/mesa/program/prog_uniform.h
+++ b/src/mesa/program/prog_uniform.h
@@ -51,10 +51,7 @@ struct gl_uniform
    GLint FragPos;
    GLint GeomPos;
    GLboolean Initialized;   /**< For debug.  Has this uniform been set? */
-#if 0
-   GLenum DataType;         /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
-   GLuint Size;             /**< Number of components (1..4) */
-#endif
+   const struct glsl_type *Type;
 };
 
 




More information about the mesa-commit mailing list