---
 src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp |   39 +++++++++++++++++++-----
 1 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp 
b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
index 13ba18b..88b8a9d 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
@@ -832,6 +832,7 @@ vec4_visitor::visit(ir_variable *ir)
 {
    dst_reg *reg = NULL;
 
+   unsigned components;
    if (variable_storage(ir))
       return;
 
@@ -854,15 +855,26 @@ vec4_visitor::visit(ir_variable *ir)
       break;
 
    case ir_var_out:
-      reg = new(mem_ctx) dst_reg(this, ir->type);
+      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);
 
-      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;
-      }
+          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[ir->location + i].writemask = (((1 << components) - 1) 
<< ir->horizontal_location);
+           output_reg_annotation[ir->location + i] = ir->name;
+          }
+       } 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:
@@ -1404,6 +1416,12 @@ vec4_visitor::visit(ir_dereference_variable *ir)
 
    if (type->is_scalar() || type->is_vector() || type->is_matrix())
       this->result.swizzle = swizzle_for_size(type->vector_elements);
+   unsigned swz = this->result.swizzle;
+   this->result.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(swz, 0) + 
ir->var->horizontal_location % 4,
+                                       BRW_GET_SWZ(swz, 1) + 
ir->var->horizontal_location % 4,
+                                       BRW_GET_SWZ(swz, 2) + 
ir->var->horizontal_location % 4,
+                                       BRW_GET_SWZ(swz, 3) + 
ir->var->horizontal_location % 4
+                                       );
 }
 
 void
@@ -1660,6 +1678,10 @@ vec4_visitor::visit(ir_assignment *ir)
    assert(ir->lhs->type->is_vector() ||
          ir->lhs->type->is_scalar());
    dst.writemask = ir->write_mask;
+   
+   if (ir_variable *inside_var = ir->lhs->variable_referenced()) {
+       dst.writemask = dst.writemask << inside_var->horizontal_location;
+   }
 
    for (int i = 0; i < 4; i++) {
       if (dst.writemask & (1 << i)) {
@@ -2616,6 +2638,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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to