diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 52 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 9 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_vartable.c | 22 |
3 files changed, 54 insertions, 29 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 0189b75134..31f2576cb5 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -266,6 +266,7 @@ slang_allocate_storage(slang_assemble_ctx *A, slang_ir_node *n) n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -5); if (n->Var) n->Var->aux = n->Store; + assert(n->Var->aux); } } @@ -281,7 +282,6 @@ slang_allocate_storage(slang_assemble_ctx *A, slang_ir_node *n) else { assert(n->Opcode == IR_VAR); assert(n->Var); - assert(n->Store->Size > 0); if (n->Store->Index < 0) { const char *varName = (char *) n->Var->a_name; @@ -1501,6 +1501,29 @@ _slang_gen_temporary(GLint size) /** + * Generate IR node for allocating/declaring a variable. + */ +static slang_ir_node * +_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var) +{ + slang_ir_node *n; + n = new_node(IR_VAR_DECL, NULL, NULL); + if (n) { + n->Var = var; + slang_allocate_storage(A, n); + assert(n->Store); + assert(n->Store->Index < 0); + assert(n->Store->Size > 0); + assert(var->aux); + assert(n->Store == var->aux); + } + return n; +} + + + + +/** * Generate code for a selection expression: b ? x : y */ static slang_ir_node * @@ -1670,13 +1693,7 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper) v = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE); assert(v); - varDecl = new_node(IR_VAR_DECL, NULL, NULL); - if (!varDecl) - return NULL; - - varDecl->Var = v; - - slang_allocate_storage(A, varDecl); + varDecl = _slang_gen_var_decl(A, v); if (oper->num_children > 0) { /* child is initializer */ @@ -2314,21 +2331,10 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, } else { /* ordinary variable (may be const) */ - const GLint size = _slang_sizeof_type_specifier(&var->type.specifier); - const GLint index = -1; slang_ir_node *n; /* IR node to declare the variable */ - n = new_node(IR_VAR_DECL, NULL, NULL); - if (!n) - return GL_FALSE; - n->Var = var; - store = _slang_new_ir_storage(PROGRAM_TEMPORARY, index, size); - var->aux = store; /* save var's storage info */ - - slang_allocate_storage(A, n); - - _slang_add_variable(A->vartable, var); + n = _slang_gen_var_decl(A, var); /* IR code for the var's initializer, if present */ if (var->initializer) { @@ -2338,7 +2344,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, lhs = new_node(IR_VAR, NULL, NULL); lhs->Var = var; lhs->Swizzle = SWIZZLE_NOOP; - lhs->Store = store; + lhs->Store = n->Store; /* constant folding, etc */ slang_simplify(var->initializer, &A->space, A->atoms); @@ -2357,8 +2363,8 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, if (dbg) printf("GLOBAL VAR %s idx %d\n", (char*) var->a_name, store ? store->Index : -2); - - var->aux = store; /* save var's storage info */ + if (store) + var->aux = store; /* save var's storage info */ return success; } diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 1142bc6416..52627486bd 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -618,10 +618,15 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) assert(n->Store->File != PROGRAM_UNDEFINED); assert(n->Store->Size > 0); assert(n->Store->Index < 0); - if (!n->Var || n->Var->isTemp) + if (!n->Var || n->Var->isTemp) { + /* a nameless/temporary variable, will be freed after first use */ n->Store->Index = _slang_alloc_temp(vt, n->Store->Size); - else + } + else { + /* a regular variable */ + _slang_add_variable(vt, n->Var); n->Store->Index = _slang_alloc_var(vt, n->Store->Size); + } assert(n->Store->Index >= 0); break; diff --git a/src/mesa/shader/slang/slang_vartable.c b/src/mesa/shader/slang/slang_vartable.c index cd6a081e04..d4ec848a0a 100644 --- a/src/mesa/shader/slang/slang_vartable.c +++ b/src/mesa/shader/slang/slang_vartable.c @@ -3,6 +3,7 @@ #include "slang_compile.h" #include "slang_compile_variable.h" #include "slang_vartable.h" +#include "slang_ir.h" static int dbg = 0; @@ -58,16 +59,28 @@ _slang_pop_var_table(slang_var_table *t) { slang_var_table *parent = t->parent; int i; + if (dbg) printf("Popping level %d\n", t->level); + + /* free the storage allocated for each variable */ + for (i = 0; i < t->num_entries; i++) { + slang_ir_storage *store = (slang_ir_storage *) t->vars[i]->aux; + if (dbg) printf(" Free var %s\n", (char*) t->vars[i]->a_name); + assert(t->temps[store->Index] == VAR); + t->temps[store->Index] = FREE; + store->Index = -1; + } if (t->parent) { + /* just verify that any remaining allocations in this scope + * were for temps + */ for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { - if (t->temps[i] && !t->parent->temps[i]) + if (t->temps[i] && !t->parent->temps[i]) { if (dbg) printf(" Free reg %d\n", i); + assert(t->temps[i] == TEMP); + } } } - for (i = 0; i < t->num_entries; i++) { - if (dbg) printf(" Free var %s\n", (char*) t->vars[i]->a_name); - } if (t->vars) free(t->vars); @@ -84,6 +97,7 @@ void _slang_add_variable(slang_var_table *t, slang_variable *v) { assert(t); + if (dbg) printf("Adding var %s\n", (char *) v->a_name); t->vars = realloc(t->vars, (t->num_entries + 1) * sizeof(slang_variable *)); t->vars[t->num_entries] = v; t->num_entries++; |