Mesa (glsl2): ir_to_mesa: Support for struct uniforms.

Eric Anholt anholt at kemper.freedesktop.org
Tue Aug 3 00:51:21 UTC 2010


Module: Mesa
Branch: glsl2
Commit: 26675e37bc5a086c6df77946d2dada34dc9129f0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=26675e37bc5a086c6df77946d2dada34dc9129f0

Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug  2 14:32:52 2010 -0700

ir_to_mesa: Support for struct uniforms.

Fixes glsl-uniform-struct.

---

 src/mesa/program/ir_to_mesa.cpp |   78 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 5510440..7d5761f 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -252,6 +252,11 @@ public:
    GLboolean try_emit_mad(ir_expression *ir,
 			  int mul_operand);
 
+   void add_aggregate_uniform(ir_instruction *ir,
+			      const char *name,
+			      const struct glsl_type *type,
+			      struct ir_to_mesa_dst_reg temp);
+
    int *sampler_map;
    int sampler_map_size;
 
@@ -1241,6 +1246,62 @@ get_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
    return NULL;
 }
 
+/* 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");
+
+   int len;
+
+   if (type->is_vector() ||
+       type->is_scalar()) {
+      len = type->vector_elements;
+   } else {
+      len = type_size(type) * 4;
+   }
+
+   loc = _mesa_add_uniform(this->prog->Parameters,
+			   name,
+			   len,
+			   type->gl_type,
+			   NULL);
+
+
+   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)
 {
@@ -1276,6 +1337,23 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
 	 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;
+	 }
+
 	 if (ir->var->type->is_vector() ||
 	     ir->var->type->is_scalar()) {
 	    len = ir->var->type->vector_elements;




More information about the mesa-commit mailing list