diff options
| -rw-r--r-- | ir_to_mesa.cpp | 26 | ||||
| -rw-r--r-- | ir_to_mesa.h | 4 | ||||
| -rw-r--r-- | mesa_codegen.brg | 15 | 
3 files changed, 38 insertions, 7 deletions
| diff --git a/ir_to_mesa.cpp b/ir_to_mesa.cpp index 3451fc887d..44786258db 100644 --- a/ir_to_mesa.cpp +++ b/ir_to_mesa.cpp @@ -51,7 +51,7 @@ extern "C" {  }  ir_to_mesa_src_reg ir_to_mesa_undef = { -   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP +   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, false,  };  ir_to_mesa_dst_reg ir_to_mesa_undef_dst = { @@ -659,13 +659,11 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir)      */     assert(!var->type->is_matrix()); -   tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL); -     if (strncmp(var->name, "gl_", 3) == 0) {        unsigned int i;        unsigned int offset = 0; -      assert(index); /* FINISHME: Handle variable indexing of builtins. */ +      tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);        offset = index->value.i[0]; @@ -677,11 +675,24 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir)        ir_to_mesa_set_tree_reg(tree, builtin_var_to_mesa_reg[i].file,  			      builtin_var_to_mesa_reg[i].index + offset);     } else { +      tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);        this->get_temp_for_var(var, tree); -      assert(index); /* FINISHME: Handle variable indexing. */ -      tree->src_reg.index += index->value.i[0]; -      tree->dst_reg.index += index->value.i[0]; +      if (index) { +	 tree->src_reg.index += index->value.i[0]; +	 tree->dst_reg.index += index->value.i[0]; +      } else { +	 /* Variable index array dereference.  It eats the "vec4" of the +	  * base of the array and an index that offsets the Mesa register +	  * index. +	  */ +	 ir->array_index->accept(this); + +	 tree->src_reg.reladdr = true; +	 tree = this->create_tree(MB_TERM_array_reference_vec4_vec4, +				  ir, tree, this->result); +	 this->get_temp(tree, ir->type->vector_elements); +      }     }     /* If the type is smaller than a vec4, replicate the last channel out. */ @@ -841,6 +852,7 @@ mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)     assert(reg.index < (1 << INST_INDEX_BITS) - 1);     mesa_reg.Index = reg.index;     mesa_reg.Swizzle = reg.swizzle; +   mesa_reg.RelAddr = reg.reladdr;     return mesa_reg;  } diff --git a/ir_to_mesa.h b/ir_to_mesa.h index 43ddd5fe51..515feb19a3 100644 --- a/ir_to_mesa.h +++ b/ir_to_mesa.h @@ -40,6 +40,7 @@ typedef struct ir_to_mesa_src_reg {     int file; /**< PROGRAM_* from Mesa */     int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */     int swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ +   bool reladdr; /**< Register index should be offset by address reg. */  } ir_to_mesa_src_reg;  typedef struct ir_to_mesa_dst_reg { @@ -145,6 +146,9 @@ public:     exec_list instructions;  }; +extern ir_to_mesa_src_reg ir_to_mesa_undef; +extern ir_to_mesa_dst_reg ir_to_mesa_undef_dst; +  ir_to_mesa_instruction *  ir_to_mesa_emit_op1(struct mbtree *tree, enum prog_opcode op); diff --git a/mesa_codegen.brg b/mesa_codegen.brg index a906542dd5..109e8b2d51 100644 --- a/mesa_codegen.brg +++ b/mesa_codegen.brg @@ -48,6 +48,7 @@  # generate in its trees.  %term assign  %term reference_vec4 +%term array_reference_vec4_vec4  %term exp_vec4  %term exp2_vec4  %term log_vec4 @@ -93,6 +94,20 @@  # so it can be used as an argument for pretty much anything.  vec4: reference_vec4 0 +# A reference of a variable is just a vec4 register location, +# so it can be used as an argument for pretty much anything. +vec4: array_reference_vec4_vec4 1 +{ +	ir_to_mesa_dst_reg address_reg = {PROGRAM_ADDRESS, 0, WRITEMASK_X}; + +	ir_to_mesa_emit_op1_full(tree->v, tree->ir, OPCODE_ARL, +				 address_reg, +				 tree->right->src_reg); +	ir_to_mesa_emit_op1_full(tree->v, tree->ir, OPCODE_MOV, +				 tree->dst_reg, +				 tree->left->src_reg); +} +  # Here's the rule everyone will hit: Moving the result of an  # expression into a variable-dereference register location.  # | 
