diff options
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 68 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 25 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_ir.h | 1 |
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 899aa32d4a8..3d79d77aced 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 5d7e5b318f5..f0bcb7a0aee 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 baf1137e731..2589d688722 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 */ |