[Mesa-dev] [PATCH 2/7] i965: Adds support for horizontal location

Vincent Lejeune vljn at ovi.com
Thu Feb 16 13:03:08 PST 2012


---
 src/mesa/drivers/dri/i965/brw_fs.cpp           |    4 +-
 src/mesa/drivers/dri/i965/brw_vec4.h           |   13 ++++
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp |   89 +++++++++++++++++++++---
 3 files changed, 93 insertions(+), 13 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 6ecaa6c..d095e86 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -462,7 +462,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 + ir->horizontal_location);
 	       interp = suboffset(interp, 3);
                interp.type = reg->type;
 	       emit(FS_OPCODE_CINTERP, attr, fs_reg(interp));
@@ -482,7 +482,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 + ir->horizontal_location);
                   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..54aa99e 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -293,6 +293,17 @@ public:
 
 class vec4_visitor : public ir_visitor
 {
+protected:
+   class output_info : public exec_node {
+   public:
+	const ir_variable *var;
+	const dst_reg *reg;
+	output_info(const ir_variable *v, const dst_reg *r) 
+	   : var(v), reg(r)
+	   {
+	   }
+   };
+
 public:
    vec4_visitor(struct brw_vs_compile *c,
 		struct gl_shader_program *prog, struct brw_shader *shader);
@@ -388,6 +399,7 @@ public:
     */
    dst_reg output_reg[BRW_VERT_RESULT_MAX];
    const char *output_reg_annotation[BRW_VERT_RESULT_MAX];
+   exec_list custom_outputs;
    int uniform_size[MAX_UNIFORMS];
    int uniform_vector_size[MAX_UNIFORMS];
    int uniforms;
@@ -504,6 +516,7 @@ public:
    void emit_clip_distances(struct brw_reg reg, int offset);
    void emit_generic_urb_slot(dst_reg reg, int vert_result);
    void emit_urb_slot(int mrf, int vert_result);
+   void emit_custom_output(bool is_first_pass, int &max_mrf, int result_vert_to_slot[]);
    void emit_urb_writes(void);
 
    src_reg get_scratch_offset(vec4_instruction *inst,
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 13ba18b..fd76cff 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -855,16 +855,32 @@ vec4_visitor::visit(ir_variable *ir)
 
    case ir_var_out:
       reg = new(mem_ctx) dst_reg(this, ir->type);
-
-      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;
+      if (ir->location < VERT_RESULT_VAR0) {
+	   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;
+	   }
+      } else {
+	   output_info *oi = new (mem_ctx) output_info(ir, reg);
+	   custom_outputs.push_tail(oi);
       }
-      break;
+   /*   components = (ir->type->is_array())?ir->type->fields.array->vector_elements:ir->type->vector_elements;
+	if (!output_reg_annotation[ir->location]) {
+	   // The reg has not been set
+         reg = new(mem_ctx) dst_reg(this, ir->type);
 
+
+	} else {
+	   // The reg has already been set : this output is packed
+	   reg = &(output_reg[ir->location]);
+	   output_reg[ir->location].writemask |= (((1 << components) - 1) << ir->horizontal_location);
+	   char * new_annotation = ralloc_asprintf(mem_ctx, "%s ; %s", output_reg_annotation[ir->location], ir->name);
+	   output_reg_annotation[ir->location] = new_annotation;
+	}*/
+      break;
    case ir_var_auto:
    case ir_var_temporary:
       reg = new(mem_ctx) dst_reg(this, ir->type);
@@ -2148,6 +2164,8 @@ vec4_visitor::emit_clip_distances(struct brw_reg reg, int offset)
 void
 vec4_visitor::emit_generic_urb_slot(dst_reg reg, int vert_result)
 {
+   if (vert_result >= VERT_RESULT_VAR0)
+	return;
    assert (vert_result < VERT_RESULT_MAX);
    reg.type = output_reg[vert_result].type;
    current_annotation = output_reg_annotation[vert_result];
@@ -2203,6 +2221,50 @@ vec4_visitor::emit_urb_slot(int mrf, int vert_result)
    }
 }
 
+void
+vec4_visitor::emit_custom_output(bool is_first_pass, int &max_mrf, int result_vert_to_slot[])
+{
+   int new_max = 0;
+   foreach_list_const(node, &custom_outputs) {
+	output_info *oi = (output_info *) node;
+	current_annotation = oi->var->name;
+	const glsl_type *const type = oi->var->type;
+	unsigned components = (type->is_array())?type->fields.array->vector_elements:type->vector_elements;
+	src_reg associed_gpr = src_reg(*(oi->reg));
+      unsigned swz = swizzle_for_size(components);
+      associed_gpr.swizzle = BRW_SWIZZLE4(
+               BRW_GET_SWZ(swz,(0 + oi->var->horizontal_location) % 4),
+               BRW_GET_SWZ(swz,(1 + oi->var->horizontal_location) % 4),
+               BRW_GET_SWZ(swz,(2 + oi->var->horizontal_location) % 4),
+               BRW_GET_SWZ(swz,(3 + oi->var->horizontal_location) % 4)
+               );
+	
+	unsigned size = type_size(type);
+	for (unsigned i = 0; i < size; i++) {
+	   unsigned mrf = result_vert_to_slot[oi->var->location + i] + 2;
+	   if (is_first_pass && mrf > max_mrf)
+		break;
+	   else if (!is_first_pass) {
+		if (mrf > max_mrf)
+		   mrf = mrf - max_mrf + 1;
+		else
+		   continue;
+	   }
+	   new_max = MAX2(mrf, new_max);
+	   dst_reg reg = dst_reg(MRF, mrf);   
+	   reg.type = brw_type_for_base_type(oi->var->type);
+	   associed_gpr.reg_offset = i;
+	   
+	   reg.writemask = ((1 << components) - 1) << oi->var->horizontal_location;
+	   /* Copy the register, saturating if necessary */
+	   vec4_instruction *inst = emit(MOV(reg,
+	                                     associed_gpr));
+	}
+   }
+   if (!is_first_pass)
+	max_mrf = new_max;
+}
+
 static int
 align_interleaved_urb_mlen(struct brw_context *brw, int mlen)
 {
@@ -2277,6 +2339,8 @@ vec4_visitor::emit_urb_writes()
 	 break;
       }
    }
+   
+   emit_custom_output(true, max_usable_mrf, c->vue_map.vert_result_to_slot);
 
    current_annotation = "URB write";
    vec4_instruction *inst = emit(VS_OPCODE_URB_WRITE);
@@ -2286,18 +2350,20 @@ vec4_visitor::emit_urb_writes()
 
    /* Optional second URB write */
    if (!inst->eot) {
-      mrf = base_mrf + 1;
+      /*mrf = base_mrf + 1;
 
       for (; slot < c->vue_map.num_slots; ++slot) {
 	 assert(mrf < max_usable_mrf);
 
          emit_urb_slot(mrf++, c->vue_map.slot_to_vert_result[slot]);
-      }
+      }*/
+      int tmp = max_usable_mrf;
+      emit_custom_output(false, tmp, c->vue_map.vert_result_to_slot);
 
       current_annotation = "URB write";
       inst = emit(VS_OPCODE_URB_WRITE);
       inst->base_mrf = base_mrf;
-      inst->mlen = align_interleaved_urb_mlen(brw, mrf - base_mrf);
+      inst->mlen = align_interleaved_urb_mlen(brw, tmp);
       inst->eot = true;
       /* URB destination offset.  In the previous write, we got MRFs
        * 2-13 minus the one header MRF, so 12 regs.  URB offset is in
@@ -2616,6 +2682,7 @@ vec4_visitor::vec4_visitor(struct brw_vs_compile *c,
    this->live_intervals_valid = false;
 
    this->uniforms = 0;
+   memset(output_reg_annotation, 0, sizeof(output_reg_annotation));
 }
 
 vec4_visitor::~vec4_visitor()
-- 
1.7.7



More information about the mesa-dev mailing list