ir_to_mesa: Add support for array constants.
authorEric Anholt <eric@anholt.net>
Tue, 27 Jul 2010 18:58:32 +0000 (11:58 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 27 Jul 2010 19:02:11 +0000 (12:02 -0700)
Fixes:
glsl1-GLSL 1.20 array constructor 1
glsl1-GLSL 1.20 array constructor 2
glsl1-GLSL 1.20 array.length()
glsl1-GLSL 1.20 const array constructor 1
glsl1-GLSL 1.20 const array constructor 2

src/mesa/program/ir_to_mesa.cpp

index 409b6d72881edf2da4e1986ba7b46dde1308cb9c..bd79913dcf40c1b1800c7db94a36f9cf6614fae6 100644 (file)
@@ -518,19 +518,21 @@ ir_to_mesa_visitor::get_temp(const glsl_type *type)
    int swizzle[4];
    int i;
 
-   assert(!type->is_array());
-
    src_reg.file = PROGRAM_TEMPORARY;
    src_reg.index = next_temp;
    src_reg.reladdr = NULL;
    next_temp += type_size(type);
 
-   for (i = 0; i < type->vector_elements; i++)
-      swizzle[i] = i;
-   for (; i < 4; i++)
-      swizzle[i] = type->vector_elements - 1;
-   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
-                                  swizzle[2], swizzle[3]);
+   if (type->is_array() || type->is_record()) {
+      src_reg.swizzle = SWIZZLE_NOOP;
+   } else {
+      for (i = 0; i < type->vector_elements; i++)
+        swizzle[i] = i;
+      for (; i < 4; i++)
+        swizzle[i] = type->vector_elements - 1;
+      src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
+                                     swizzle[2], swizzle[3]);
+   }
    src_reg.negate = 0;
 
    return src_reg;
@@ -1329,8 +1331,6 @@ ir_to_mesa_visitor::visit(ir_assignment *ir)
    struct ir_to_mesa_src_reg r;
    int i;
 
-   assert(!ir->lhs->type->is_array());
-
    ir->rhs->accept(this);
    r = this->result;
 
@@ -1375,12 +1375,6 @@ ir_to_mesa_visitor::visit(ir_constant *ir)
    GLfloat *values = stack_vals;
    unsigned int i;
 
-   if (ir->type->is_array()) {
-      ir->print();
-      printf("\n");
-      assert(!"FINISHME: array constants");
-   }
-
    /* Unfortunately, 4 floats is all we can get into
     * _mesa_add_unnamed_constant.  So, make a temp to store an
     * aggregate constant and move each constant value into it.  If we
@@ -1389,7 +1383,6 @@ ir_to_mesa_visitor::visit(ir_constant *ir)
 
    if (ir->type->base_type == GLSL_TYPE_STRUCT) {
       ir_to_mesa_src_reg temp_base = get_temp(ir->type);
-      temp_base.swizzle = SWIZZLE_NOOP;
       ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
 
       foreach_iter(exec_list_iterator, iter, ir->components) {
@@ -1412,6 +1405,27 @@ ir_to_mesa_visitor::visit(ir_constant *ir)
       return;
    }
 
+   if (ir->type->is_array()) {
+      ir_to_mesa_src_reg temp_base = get_temp(ir->type);
+      ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
+      int size = type_size(ir->type->fields.array);
+
+      assert(size > 0);
+
+      for (i = 0; i < ir->type->length; i++) {
+        ir->array_elements[i]->accept(this);
+        src_reg = this->result;
+        for (int j = 0; j < size; j++) {
+           ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg);
+
+           src_reg.index++;
+           temp.index++;
+        }
+      }
+      this->result = temp_base;
+      return;
+   }
+
    if (ir->type->is_matrix()) {
       ir_to_mesa_src_reg mat = get_temp(ir->type);
       ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat);