i965/vs: Avoid generating extra moves when setting up large ir_constants.
authorEric Anholt <eric@anholt.net>
Sat, 6 Aug 2011 04:22:36 +0000 (21:22 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 16 Aug 2011 20:04:42 +0000 (13:04 -0700)
We were also screwing up the types in the process, and just not
emitting moves was easier.

src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index 1619c2e1ef6011d1dc6bc33eff9894fb031b1b5b..3e457fc61aa5f774a4bc5b1fe097152dd508c24b 100644 (file)
@@ -393,6 +393,8 @@ public:
    void emit_block_move(dst_reg *dst, src_reg *src,
                        const struct glsl_type *type, bool predicated);
 
+   void emit_constant_values(dst_reg *dst, ir_constant *value);
+
    /**
     * Emit the correct dot-product instruction for the type of arguments
     */
index 5e2b3e5a5feac250192666241ac54335371836c6..3562779413f31972d1938d2a3c815a90e88d2b7a 100644 (file)
@@ -1387,96 +1387,71 @@ vec4_visitor::visit(ir_assignment *ir)
    }
 }
 
-
 void
-vec4_visitor::visit(ir_constant *ir)
+vec4_visitor::emit_constant_values(dst_reg *dst, ir_constant *ir)
 {
    if (ir->type->base_type == GLSL_TYPE_STRUCT) {
-      src_reg temp_base = src_reg(this, ir->type);
-      dst_reg temp = dst_reg(temp_base);
-
-      foreach_iter(exec_list_iterator, iter, ir->components) {
-        ir_constant *field_value = (ir_constant *)iter.get();
-        int size = type_size(field_value->type);
-
-        assert(size > 0);
-
-        field_value->accept(this);
-        src_reg src = this->result;
-
-        for (int i = 0; i < (unsigned int)size; i++) {
-           emit(BRW_OPCODE_MOV, temp, src);
+      foreach_list(node, &ir->components) {
+        ir_constant *field_value = (ir_constant *)node;
 
-           src.reg_offset++;
-           temp.reg_offset++;
-        }
+        emit_constant_values(dst, field_value);
       }
-      this->result = temp_base;
       return;
    }
 
    if (ir->type->is_array()) {
-      src_reg temp_base = src_reg(this, ir->type);
-      dst_reg temp = dst_reg(temp_base);
-      int size = type_size(ir->type->fields.array);
-
-      assert(size > 0);
-
       for (unsigned int i = 0; i < ir->type->length; i++) {
-        ir->array_elements[i]->accept(this);
-        src_reg src = this->result;
-        for (int j = 0; j < size; j++) {
-           emit(BRW_OPCODE_MOV, temp, src);
-
-           src.reg_offset++;
-           temp.reg_offset++;
-        }
+        emit_constant_values(dst, ir->array_elements[i]);
       }
-      this->result = temp_base;
       return;
    }
 
    if (ir->type->is_matrix()) {
-      this->result = src_reg(this, ir->type);
-      dst_reg dst = dst_reg(this->result);
-
-      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
-
       for (int i = 0; i < ir->type->matrix_columns; i++) {
         for (int j = 0; j < ir->type->vector_elements; j++) {
-           dst.writemask = 1 << j;
-           emit(BRW_OPCODE_MOV, dst,
+           dst->writemask = 1 << j;
+           dst->type = BRW_REGISTER_TYPE_F;
+
+           emit(BRW_OPCODE_MOV, *dst,
                 src_reg(ir->value.f[i * ir->type->vector_elements + j]));
         }
-        dst.reg_offset++;
+        dst->reg_offset++;
       }
       return;
    }
 
-   this->result = src_reg(this, ir->type);
-   dst_reg dst = dst_reg(this->result);
-
    for (int i = 0; i < ir->type->vector_elements; i++) {
-      dst.writemask = 1 << i;
+      dst->writemask = 1 << i;
+      dst->type = brw_type_for_base_type(ir->type);
 
       switch (ir->type->base_type) {
       case GLSL_TYPE_FLOAT:
-        emit(BRW_OPCODE_MOV, dst, src_reg(ir->value.f[i]));
+        emit(BRW_OPCODE_MOV, *dst, src_reg(ir->value.f[i]));
         break;
       case GLSL_TYPE_INT:
-        emit(BRW_OPCODE_MOV, dst, src_reg(ir->value.i[i]));
+        emit(BRW_OPCODE_MOV, *dst, src_reg(ir->value.i[i]));
         break;
       case GLSL_TYPE_UINT:
-        emit(BRW_OPCODE_MOV, dst, src_reg(ir->value.u[i]));
+        emit(BRW_OPCODE_MOV, *dst, src_reg(ir->value.u[i]));
         break;
       case GLSL_TYPE_BOOL:
-        emit(BRW_OPCODE_MOV, dst, src_reg(ir->value.b[i]));
+        emit(BRW_OPCODE_MOV, *dst, src_reg(ir->value.b[i]));
         break;
       default:
         assert(!"Non-float/uint/int/bool constant");
         break;
       }
    }
+   dst->reg_offset++;
+}
+
+void
+vec4_visitor::visit(ir_constant *ir)
+{
+   dst_reg dst = dst_reg(this, ir->type);
+   this->result = src_reg(dst);
+
+   emit_constant_values(&dst, ir);
 }
 
 void