summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2007-01-15 13:58:45 -0700
committerBrian <brian@yutani.localnet.net>2007-01-15 13:58:45 -0700
commit83d3ff590d0024b63501db91c9a3137e9ec959a0 (patch)
tree90d07ce95d9727c3bf2869556c0d7797ca398759 /src
parentc807169888c900dd303adb260c3cfeb744ed842d (diff)
Redo the way array indexes are handled. Resolve storage location at code emit time, not codegen time.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/shader/slang/slang_codegen.c68
-rw-r--r--src/mesa/shader/slang/slang_emit.c25
-rw-r--r--src/mesa/shader/slang/slang_ir.h1
3 files changed, 46 insertions, 48 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 899aa32d4a..3d79d77ace 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -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)
*/
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 5d7e5b318f..f0bcb7a0ae 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -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;
}
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index baf1137e73..2589d68872 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -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 */