Redo the way array indexes are handled. Resolve storage location at code emit time...
authorBrian <brian@yutani.localnet.net>
Mon, 15 Jan 2007 20:58:45 +0000 (13:58 -0700)
committerBrian <brian@yutani.localnet.net>
Mon, 15 Jan 2007 20:58:45 +0000 (13:58 -0700)
src/mesa/shader/slang/slang_codegen.c
src/mesa/shader/slang/slang_emit.c
src/mesa/shader/slang/slang_ir.h

index 899aa32..3d79d77 100644 (file)
@@ -1234,7 +1234,7 @@ _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper,
       n0 = _slang_gen_operation(A, dest_oper);
       assert(n0->Var);
       assert(n0->Store);
-
+      assert(!n->Store);
       n->Store = n0->Store;
       n->Writemask = writemask;
 
@@ -1735,60 +1735,32 @@ _slang_gen_field(slang_assemble_ctx * A, slang_operation *oper)
 
 
 /**
- * Generate IR tree for an array element reference.
+ * Gen code for array indexing.
  */
 static slang_ir_node *
 _slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper)
 {
-   if (oper->children[1].type == slang_oper_literal_int) {
-      /* compile-time constant index - OK */
-      slang_assembly_typeinfo array_ti, elem_ti;
-      slang_ir_node *base;
-      GLint index;
-
-      /* get type of array element */
-      slang_assembly_typeinfo_construct(&elem_ti);
-      _slang_typeof_operation(A, oper, &elem_ti);
-
-      /* get type of array */
-      slang_assembly_typeinfo_construct(&array_ti);
-      _slang_typeof_operation(A, &oper->children[0], &array_ti);
-
-
-      base = _slang_gen_operation(A, &oper->children[0]);
-      assert(base->Opcode == IR_VAR);
-      assert(base->Store);
-
-      index = (GLint) oper->children[1].literal[0];
-      /*printf("element[%d]\n", index);*/
-      /* new storage info since we don't want to change the original */
-      base->Store = _slang_clone_ir_storage(base->Store);
-      if (_slang_type_is_vector(array_ti.spec.type)) {
-         /* scalar element (float) of a basic vector (ex: vec3) */
-         const GLuint max = _slang_type_dim(array_ti.spec.type);
-         if (index >= max) {
-            RETURN_ERROR("array index out of bounds", 0);
-         }
-         assert(index < 4);
-         /* use swizzle to access the element */
-         base->Swizzle = SWIZZLE_X + index;
-         base->Writemask = WRITEMASK_X << index;
-      }
-      else {
-         /* bias Index by array subscript, update storage size */
-         base->Store->Index += index;
-         base->Store->Size = _slang_sizeof_type_specifier(&elem_ti.spec);
-      }
-      return base;
-   }
-   else {
-      /* run-time index - not supported yet - TBD */
-      abort();
-      return NULL;
-   }
+   slang_assembly_typeinfo elem_ti;
+   slang_ir_node *elem, *array, *index;
+   GLint elemSize;
+
+   /* size of array element */
+   slang_assembly_typeinfo_construct(&elem_ti);
+   _slang_typeof_operation(A, oper, &elem_ti);
+   elemSize = _slang_sizeof_type_specifier(&elem_ti.spec);
+   assert(elemSize >= 1);
+
+   array = _slang_gen_operation(A, &oper->children[0]);
+   index = _slang_gen_operation(A, &oper->children[1]);
+   elem = new_node(IR_ELEMENT, array, index);
+   elem->Store = _slang_new_ir_storage(array->Store->File,
+                                       array->Store->Index,
+                                       elemSize);
+   return elem;
 }
 
 
+
 /**
  * Generate IR tree for a slang_operation (AST node)
  */
index 5d7e5b3..f0bcb7a 100644 (file)
@@ -600,6 +600,7 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
       assert(n->Children[1]);
       emit(vt, n->Children[0], prog);
       inst = emit(vt, n->Children[1], prog);
+      assert(!n->Store);
       n->Store = n->Children[1]->Store;
       return inst;
 
@@ -619,6 +620,7 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
          n->Store->Index = _slang_alloc_temp(vt, n->Store->Size);
       else
          n->Store->Index = _slang_alloc_var(vt, n->Store->Size);
+      assert(n->Store->Index >= 0);
       break;
 
    case IR_VAR:
@@ -631,6 +633,28 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
       assert(n->Store->Size > 0);
       break;
 
+   case IR_ELEMENT:
+      /* Dereference array element.  Just resolve storage for the array
+       * element represented by this node.
+       */
+      assert(n->Store);
+      assert(n->Store->File != PROGRAM_UNDEFINED);
+      assert(n->Store->Size > 0);
+      if (n->Children[1]->Opcode == IR_FLOAT) {
+         /* OK, constant index */
+         const GLint arrayAddr = n->Children[0]->Store->Index;
+         const GLint index = n->Children[1]->Value[0];
+         n->Store->Index = arrayAddr + index;
+      }
+      else {
+         /* Problem: variable index */
+         const GLint arrayAddr = n->Children[0]->Store->Index;
+         const GLint index = 0;
+         _mesa_problem(NULL, "variable array indexes not supported yet!");
+         n->Store->Index = arrayAddr + index;
+      }
+      return NULL; /* no instruction */
+
    case IR_MOVE:
       /* rhs */
       assert(n->Children[1]);
@@ -686,6 +710,7 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
                              n->Children[1]->Store->Size);
          }
          /*inst->Comment = _mesa_strdup("IR_MOVE");*/
+         assert(!n->Store);
          n->Store = n->Children[0]->Store; /*XXX new */
          return inst;
       }
index baf1137..2589d68 100644 (file)
@@ -82,6 +82,7 @@ typedef enum
    IR_NOT,     /* logical not */
    IR_VAR,     /* variable reference */
    IR_VAR_DECL,/* var declaration */
+   IR_ELEMENT, /* array element */
    IR_TEX,     /* texture lookup */
    IR_TEXB,    /* texture lookup with LOD bias */
    IR_TEXP,    /* texture lookup with projection */