diff options
| author | Eric Anholt <eric@anholt.net> | 2010-08-02 14:32:52 -0700 | 
|---|---|---|
| committer | Eric Anholt <eric@anholt.net> | 2010-08-02 17:47:35 -0700 | 
| commit | 26675e37bc5a086c6df77946d2dada34dc9129f0 (patch) | |
| tree | c6f7378f3b204ae6bfcbb9b7a8f7a17730a05237 | |
| parent | 9c02412cdc0270f2b0dc64afe709721e049fd5b0 (diff) | |
ir_to_mesa: Support for struct uniforms.
Fixes glsl-uniform-struct.
| -rw-r--r-- | 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 5510440475..7d5761f699 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; | 
