[Mesa-dev] [PATCH 5/5] i965: Code generation uses complete_location now

Vincent Lejeune vljn at ovi.com
Tue Jan 24 13:05:14 PST 2012


Linker generates location_tree * instead of single ints to store
varying locations, this patch makes i965 VS and FS code generator
able to produce output register access accordingly.
---
 src/mesa/drivers/dri/i965/brw_fs.cpp           |   14 +++-
 src/mesa/drivers/dri/i965/brw_vec4.h           |    3 +
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp |  106 +++++++++++++++++++++--
 3 files changed, 111 insertions(+), 12 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 40327ac..a16e47a 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -444,7 +444,17 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
    glsl_interp_qualifier interpolation_mode =
       ir->determine_interpolation_mode(c->key.flat_shade);
 
+   unsigned delta = 0;
    int location = ir->location;
+   if (ir->complete_location) {
+      unsigned size;
+      const struct register_info *tmp = get_register_info(ir->complete_location,ir->type,size);
+      location = tmp[0].index;
+      delta += tmp[0].writemask_offset;
+      ralloc_free((void *)tmp);
+   }
+
+
    for (unsigned int i = 0; i < array_elements; i++) {
       for (unsigned int j = 0; j < type->matrix_columns; j++) {
 	 if (urb_setup[location] == -1) {
@@ -462,7 +472,7 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
 	     * field of the setup reg.
 	     */
 	    for (unsigned int k = 0; k < type->vector_elements; k++) {
-	       struct brw_reg interp = interp_reg(location, k);
+	       struct brw_reg interp = interp_reg(location, k + delta);
 	       interp = suboffset(interp, 3);
                interp.type = reg->type;
 	       emit(FS_OPCODE_CINTERP, attr, fs_reg(interp));
@@ -482,7 +492,7 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
 		   k == 3 && !(c->key.proj_attrib_mask & (1 << location))) {
 		  emit(BRW_OPCODE_MOV, attr, fs_reg(1.0f));
 	       } else {
-		  struct brw_reg interp = interp_reg(location, k);
+                 struct brw_reg interp = interp_reg(location, k + delta);
                   brw_wm_barycentric_interp_mode barycoord_mode;
                   if (interpolation_mode == INTERP_QUALIFIER_SMOOTH)
                      barycoord_mode = BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 2555fa7..602ccf6 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -354,6 +354,8 @@ public:
 
    src_reg src_reg_for_float(float val);
 
+   bool handle_output_dereference(ir_dereference *ir);
+
    /**
     * \name Visit methods
     *
@@ -387,6 +389,7 @@ public:
     * for the ir->location's used.
     */
    dst_reg output_reg[BRW_VERT_RESULT_MAX];
+   ir_variable *is_output_set[BRW_VERT_RESULT_MAX];
    const char *output_reg_annotation[BRW_VERT_RESULT_MAX];
    int uniform_size[MAX_UNIFORMS];
    int uniform_vector_size[MAX_UNIFORMS];
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 06bde92..2af6008 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -850,17 +850,27 @@ vec4_visitor::visit(ir_variable *ir)
       break;
 
    case ir_var_out:
-      reg = new(mem_ctx) dst_reg(this, ir->type);
+   {
+      const struct range_info &tmp = get_varying_range_info(ir->complete_location, ir->type);
+      if (is_output_set[tmp.index]) {
+         reg = variable_storage(is_output_set[tmp.index]);
+      } else {
+         reg = new(mem_ctx) dst_reg(this, ir->type);
+         is_output_set[tmp.index] = ir;
+      }
 
-      for (int i = 0; i < type_size(ir->type); i++) {
-	 output_reg[ir->location + i] = *reg;
-	 output_reg[ir->location + i].reg_offset = i;
-	 output_reg[ir->location + i].type =
-            brw_type_for_base_type(ir->type->get_scalar_type());
-	 output_reg_annotation[ir->location + i] = ir->name;
+      unsigned location = tmp.index;
+      unsigned count = tmp.involved_reg_counts;
+
+      for (unsigned i = 0; i < count; i++) {
+         output_reg[location + i] = *reg;
+         output_reg[location + i].reg_offset = i;
+         output_reg[location + i].type =
+               brw_type_for_base_type(ir->type->get_scalar_type());
+         output_reg_annotation[location + i] = ir->name;
       }
       break;
-
+   }
    case ir_var_auto:
    case ir_var_temporary:
       reg = new(mem_ctx) dst_reg(this, ir->type);
@@ -1374,9 +1384,71 @@ vec4_visitor::visit(ir_swizzle *ir)
    this->result = src;
 }
 
+bool
+vec4_visitor::handle_output_dereference(ir_dereference *ir)
+{
+   ir_variable *inside_var = ir->variable_referenced();
+   if (!inside_var)
+      return false;
+
+   if (inside_var->mode != ir_var_out)
+      return false;
+
+   dst_reg *reg = variable_storage(inside_var);
+
+   location_tree_visitor v;
+   ir->accept(&v);
+   unsigned size;
+   const struct register_info *dst_regs = v.get_result_registers(ir->type, size);
+   // FINISHME : handle struct/array assignment
+
+   src_reg result_reg = src_reg (output_reg[dst_regs[0].index + v.static_offset]);
+
+   //result_reg.reg_offset = v.static_offset;
+
+   for (unsigned i = 0; i < v.indirect_strides_count; i++) {
+      /* Variable index array dereference.  It eats the "vec4" of the
+       * base of the array and an index that offsets the Mesa register
+       * index.
+       */
+      v.indirections[i].rvalue->accept(this);
+      int element_size = v.indirections[i].stride;
+
+      src_reg index_reg;
+
+      if (element_size == 1) {
+       index_reg = this->result;
+      } else {
+       index_reg = src_reg(this, glsl_type::int_type);
+
+       emit(MUL(dst_reg(index_reg), this->result, src_reg(element_size)));
+      }
+
+      if (result_reg.reladdr) {
+       src_reg temp = src_reg(this, glsl_type::int_type);
+
+       emit(ADD(dst_reg(temp), *result_reg.reladdr, index_reg));
+
+       index_reg = temp;
+      }
+
+      result_reg.reladdr = ralloc(mem_ctx, src_reg);
+      memcpy(result_reg.reladdr, &index_reg, sizeof(index_reg));
+   }
+
+   this->result = result_reg;
+
+   if (ir->type->is_scalar() || ir->type->is_vector() || ir->type->is_matrix())
+      this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
+
+   return true;
+}
+
 void
 vec4_visitor::visit(ir_dereference_variable *ir)
 {
+   if(handle_output_dereference(ir))
+      return;
    const struct glsl_type *type = ir->type;
    dst_reg *reg = variable_storage(ir->var);
 
@@ -1395,6 +1467,8 @@ vec4_visitor::visit(ir_dereference_variable *ir)
 void
 vec4_visitor::visit(ir_dereference_array *ir)
 {
+   if(handle_output_dereference(ir))
+      return;
    ir_constant *constant_index;
    src_reg src;
    int element_size = type_size(ir->type);
@@ -1448,6 +1522,8 @@ vec4_visitor::visit(ir_dereference_array *ir)
 void
 vec4_visitor::visit(ir_dereference_record *ir)
 {
+   if(handle_output_dereference(ir))
+      return;
    unsigned int i;
    const glsl_type *struct_type = ir->record->type;
    int offset = 0;
@@ -1641,6 +1717,13 @@ vec4_visitor::visit(ir_assignment *ir)
 	  ir->lhs->type->is_scalar());
    dst.writemask = ir->write_mask;
 
+   if (ir->lhs->variable_referenced()->complete_location ) {
+      unsigned size;
+      const struct register_info *tmp = get_register_info(ir->lhs->variable_referenced()->complete_location,ir->lhs->variable_referenced()->type,size);
+      dst.writemask = dst.writemask << tmp[0].writemask_offset;
+      ralloc_free((void *)tmp);
+   }
+
    for (int i = 0; i < 4; i++) {
       if (dst.writemask & (1 << i)) {
 	 first_enabled_chan = BRW_GET_SWZ(src.swizzle, i);
@@ -2131,9 +2214,11 @@ vec4_visitor::emit_generic_urb_slot(dst_reg reg, int vert_result)
    assert (vert_result < VERT_RESULT_MAX);
    reg.type = output_reg[vert_result].type;
    current_annotation = output_reg_annotation[vert_result];
+   src_reg res =src_reg(output_reg[vert_result]);
+   res.swizzle = BRW_SWIZZLE4(SWIZZLE_X,SWIZZLE_Y,SWIZZLE_Z,SWIZZLE_W);
    /* Copy the register, saturating if necessary */
    vec4_instruction *inst = emit(MOV(reg,
-                                     src_reg(output_reg[vert_result])));
+                                     res));
    if ((vert_result == VERT_RESULT_COL0 ||
         vert_result == VERT_RESULT_COL1 ||
         vert_result == VERT_RESULT_BFC0 ||
@@ -2246,7 +2331,7 @@ vec4_visitor::emit_urb_writes()
 
    /* Set up the VUE data for the first URB write */
    int slot;
-   for (slot = 0; slot < c->vue_map.num_slots; ++slot) {
+   for (slot = 0; slot < c->vue_map.num_slots;++slot){//c->vue_map.num_slots; ++slot) {
       emit_urb_slot(mrf++, c->vue_map.slot_to_vert_result[slot]);
 
       /* If this was max_usable_mrf, we can't fit anything more into this URB
@@ -2596,6 +2681,7 @@ vec4_visitor::vec4_visitor(struct brw_vs_compile *c,
    this->live_intervals_valid = false;
 
    this->uniforms = 0;
+   memset(this->is_output_set, 0, sizeof(this->is_output_set));
 }
 
 vec4_visitor::~vec4_visitor()
-- 
1.7.7



More information about the mesa-dev mailing list