diff options
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 239 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_compile.c | 56 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 206 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.h | 13 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_ir.h | 1 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_link2.c | 2 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_print.c | 207 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_print.h | 4 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_storage.c | 4 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_vartable.c | 202 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_vartable.h | 38 | ||||
-rw-r--r-- | src/mesa/sources | 1 |
12 files changed, 496 insertions, 477 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 46a5ecd5d5a..aff108daced 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -38,6 +38,7 @@ #include "slang_error.h" #include "slang_simplify.h" #include "slang_emit.h" +#include "slang_vartable.h" #include "slang_ir.h" #include "mtypes.h" #include "program.h" @@ -259,10 +260,10 @@ _slang_sizeof_type_specifier(const slang_type_specifier *spec) * 4. other? */ static void -slang_allocate_storage(slang_gen_context *gc, slang_ir_node *n, - struct gl_program *prog) +slang_allocate_storage(slang_assemble_ctx *A, slang_ir_node *n) { - assert(gc); + struct gl_program *prog = A->program; + assert(A->vartable); assert(n); assert(n->Opcode == IR_VAR_DECL || n->Opcode == IR_VAR); assert(prog); @@ -285,33 +286,22 @@ slang_allocate_storage(slang_gen_context *gc, slang_ir_node *n, /* variable declaration */ assert(n->Var); assert(!is_sampler_type(&n->Var->type)); - printf("Alloc storage for %p %s:\n", (void*) n->Var, (char*) n->Var->a_name); - /* - assert(n->Store->Index < 0); - */ n->Store->File = PROGRAM_TEMPORARY; n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier); assert(n->Store->Size > 0); - if (n->Store->Index < 0) - n->Store->Index = _slang_alloc_temporary(gc, n->Store->Size); - printf(" Location = %d\n", n->Store->Index); - /* - printf("alloc var %s storage at %d (size %d)\n", - (char *) n->Var->a_name, - n->Store->Index, - n->Store->Size); - */ - assert(n->Store->Size > 0); - n->Var->declared = GL_TRUE; return; } +#if 00 if (n->Store->File == PROGRAM_UNDEFINED) { printf("*** Var %s size %d\n", (char*) n->Var->a_name, n->Store->Size); - assert(n->Store->File != PROGRAM_UNDEFINED); } +#endif + /** + ** XXX this all has to be redone + **/ if (n->Store->Index < 0) { /* determine storage location for this var */ @@ -342,7 +332,6 @@ slang_allocate_storage(slang_gen_context *gc, slang_ir_node *n, } else { /* what's this??? */ - abort(); } } } @@ -533,54 +522,6 @@ static slang_asm_info AsmInfo[] = { }; -#if 000 /* prototype for future symbol table scheme */ - -#define MAX_DEPTH 100 -static slang_variable_scope *Stack[MAX_DEPTH]; -static int CurDepth; - -static void -_slang_push_scope(slang_variable_scope *scope) -{ - Stack[CurDepth++] = scope; - assert(CurDepth < MAX_DEPTH); -} - -static void -_slang_pop_scope(void) -{ - CurDepth--; - assert(CurDepth >= 0); -} - -static slang_variable_scope * -_slang_current_scope(void) -{ - if (CurDepth > 0) - return Stack[CurDepth - 1]; - else - return NULL; -} - -static slang_variable * -_slang_find_variable(slang_atom name) -{ - int i; - for (i = CurDepth - 1; i >= 0; i--) { - int j; - for (j = 0; j < Stack[i]->num_variables; j++) { - if (Stack[i]->variables[j].a_name == name) { - return Stack[i]->variables + j; - } - } - } - return NULL; -} - -#endif - - - /** * Recursively free an IR tree. */ @@ -675,15 +616,14 @@ new_var(slang_assemble_ctx *A, slang_operation *oper, printf("VAR NOT FOUND %s\n", (char *) name); assert(v); } - /** - assert(v->declared); - **/ assert(!oper->var || oper->var == v); v->used = GL_TRUE; - oper->var = v; + n->Swizzle = swizzle; n->Var = v; - slang_allocate_storage(A->codegen, n, A->program); + + slang_allocate_storage(A, n); + return n; } @@ -725,7 +665,7 @@ slang_is_writemask(const char *field, GLuint *mask) /** - * Check if the given function is really just a wrapper for an + * Check if the given function is really just a wrapper for a * basic assembly instruction. */ static GLboolean @@ -753,7 +693,7 @@ slang_inline_asm_function(slang_assemble_ctx *A, slang_operation *inlined = slang_operation_new(1); /*assert(oper->type == slang_oper_call); or vec4_add, etc */ - + printf("Inline asm %s\n", (char*) fun->header.a_name); inlined->type = fun->body->children[0].type; inlined->a_id = fun->body->children[0].a_id; inlined->num_children = numArgs; @@ -833,9 +773,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, for (i = 0; i < substCount; i++) { if (v == substOld[i]) { /* OK, replace this slang_oper_identifier with a new expr */ - assert(substNew[i]->type == slang_oper_identifier || - substNew[i]->type == slang_oper_literal_float); -#if 1 /* DEBUG only */ +#if 0 /* DEBUG only */ if (substNew[i]->type == slang_oper_identifier) { assert(substNew[i]->var); assert(substNew[i]->var->a_name); @@ -843,7 +781,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, (char*)v->a_name, (char*) substNew[i]->var->a_name, (void*) oper); } - else + else { printf("Substitute %s with %f in id node %p\n", (char*)v->a_name, substNew[i]->literal[0], (void*) oper); @@ -958,15 +896,15 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, substNew = (slang_operation **) _mesa_calloc(totalArgs * sizeof(slang_operation *)); - printf("\nInline call to %s (total vars=%d nparams=%d)\n", + printf("Inline call to %s (total vars=%d nparams=%d)\n", (char *) fun->header.a_name, fun->parameters->num_variables, numArgs); - if (haveRetValue && !returnOper) { - /* Create comma sequence for inlined code, the left child will be the - * function body and the right child will be a variable (__retVal) - * that will get the return value. + /* Create 3-child comma sequence for inlined code: + * child[0]: declare __resultTmp + * child[1]: inlined function body + * child[2]: __resultTmp */ slang_operation *commaSeq; slang_operation *declOper = NULL; @@ -981,13 +919,13 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, /* allocate the return var */ resultVar = slang_variable_scope_grow(commaSeq->locals); /* - printf("Alloc __resultTemp in scope %p for retval of calling %s\n", + printf("Alloc __resultTmp in scope %p for retval of calling %s\n", (void*)commaSeq->locals, (char *) fun->header.a_name); */ resultVar->a_name = slang_atom_pool_atom(A->atoms, "__resultTmp"); resultVar->type = fun->header.type; /* XXX copy? */ - /*resultVar->type.qualifier = slang_qual_out;*/ + resultVar->isTemp = GL_TRUE; /* child[0] = __resultTmp declaration */ declOper = &commaSeq->children[0]; @@ -1027,12 +965,12 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, */ substCount = 0; for (i = 0; i < totalArgs; i++) { - slang_variable *p = &fun->parameters->variables[i]; - + slang_variable *p = fun->parameters->variables[i]; + /* printf("Param %d: %s %s \n", i, slang_type_qual_string(p->type.qualifier), (char *) p->a_name); - + */ if (p->type.qualifier == slang_qual_inout || p->type.qualifier == slang_qual_out) { /* an output param */ @@ -1042,9 +980,10 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, else arg = returnOper; paramMode[i] = SUBST; - assert(arg->type == slang_oper_identifier - /*||arg->type == slang_oper_variable_decl*/); - slang_resolve_variable(arg); + + if (arg->type == slang_oper_identifier) + slang_resolve_variable(arg); + /* replace parameter 'p' with argument 'arg' */ substOld[substCount] = p; substNew[substCount] = arg; /* will get copied */ @@ -1073,15 +1012,14 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, assert(paramMode[i]); } -#if 00 - printf("ABOUT to inline body %p with checksum %d\n", - (char *) fun->body, slang_checksum_tree(fun->body)); -#endif - /* actual code inlining: */ slang_operation_copy(inlined, fun->body); -#if 000 + /*** XXX review this */ + assert(inlined->type = slang_oper_block_no_new_scope); + inlined->type = slang_oper_block_new_scope; + +#if 0 printf("======================= orig body code ======================\n"); printf("=== params scope = %p\n", (void*) fun->parameters); slang_print_tree(fun->body, 8); @@ -1092,7 +1030,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, /* do parameter substitution in inlined code: */ slang_substitute(A, inlined, substCount, substOld, substNew, GL_FALSE); -#if 000 +#if 0 printf("======================= subst code ==========================\n"); slang_print_tree(inlined, 8); printf("=============================================================\n"); @@ -1104,7 +1042,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, numCopyIn = 0; for (i = 0; i < numArgs; i++) { if (paramMode[i] == COPY_IN) { - slang_variable *p = &fun->parameters->variables[i]; + slang_variable *p = fun->parameters->variables[i]; /* declare parameter 'p' */ slang_operation *decl = slang_operation_insert(&inlined->num_children, &inlined->children, @@ -1138,7 +1076,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, for (i = 0; i < totalArgs; i++) { if (paramMode[i] == COPY_OUT) { - const slang_variable *p = &fun->parameters->variables[i]; + const slang_variable *p = fun->parameters->variables[i]; /* actualCallVar = outParam */ /*if (i > 0 || !haveRetValue)*/ slang_operation *ass = slang_operation_insert(&inlined->num_children, @@ -1215,7 +1153,6 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, printf("\n"); #endif - /* assemble what we just made XXX here??? */ n = _slang_gen_operation(A, oper); CurFunction->end_label = NULL; @@ -1323,7 +1260,6 @@ _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper, dest_oper = &dest_oper->children[0]; } - assert(dest_oper->type == slang_oper_identifier); n0 = _slang_gen_operation(A, dest_oper); assert(n0->Var); assert(n0->Store); @@ -1676,9 +1612,8 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper) return NULL; varDecl->Var = v; - v->declared = GL_TRUE; - slang_allocate_storage(A->codegen, varDecl, A->program); + slang_allocate_storage(A, varDecl); if (oper->num_children > 0) { /* child is initializer */ @@ -1728,7 +1663,9 @@ _slang_gen_variable(slang_assemble_ctx * A, slang_operation *oper) */ slang_atom aVar = oper->var ? oper->var->a_name : oper->a_id; slang_ir_node *n = new_var(A, oper, aVar, SWIZZLE_NOOP); + /* assert(oper->var); + */ return n; } @@ -1856,7 +1793,7 @@ _slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper) /* 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 (vec3) */ + /* 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); @@ -1888,39 +1825,60 @@ static slang_ir_node * _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) { switch (oper->type) { - case slang_oper_block_no_new_scope: case slang_oper_block_new_scope: + { + slang_ir_node *n; + + A->vartable = _slang_push_var_table(A->vartable); + + oper->type = slang_oper_block_no_new_scope; /* temp change */ + n = _slang_gen_operation(A, oper); + oper->type = slang_oper_block_new_scope; /* restore */ + + A->vartable = _slang_pop_var_table(A->vartable); + + if (n) + n = new_node(IR_SCOPE, n, NULL); + return n; + } + break; + + case slang_oper_block_no_new_scope: /* list of operations */ assert(oper->num_children > 0); { slang_ir_node *n, *tree = NULL; GLuint i; + for (i = 0; i < oper->num_children; i++) { n = _slang_gen_operation(A, &oper->children[i]); - if (!n) + if (!n) { + _slang_free_ir_tree(tree); return NULL; /* error must have occured */ + } tree = tree ? new_seq(tree, n) : n; } - if (oper->locals->num_variables > 0) { - int i; - /* - printf("\n****** Deallocate vars in scope!\n"); - */ - for (i = 0; i < oper->locals->num_variables; i++) { - slang_variable *v = oper->locals->variables + i; - if (v->aux) { - slang_ir_storage *store = (slang_ir_storage *) v->aux; - /* - printf(" Deallocate var %s\n", (char*) v->a_name); - */ - assert(store->File == PROGRAM_TEMPORARY); - assert(store->Index >= 0); - _slang_free_temporary(A->codegen, store->Index, store->Size); +#if 00 + if (oper->locals->num_variables > 0) { + int i; + /* + printf("\n****** Deallocate vars in scope!\n"); + */ + for (i = 0; i < oper->locals->num_variables; i++) { + slang_variable *v = oper->locals->variables + i; + if (v->aux) { + slang_ir_storage *store = (slang_ir_storage *) v->aux; + /* + printf(" Deallocate var %s\n", (char*) v->a_name); + */ + assert(store->File == PROGRAM_TEMPORARY); + assert(store->Index >= 0); + _slang_free_temp(A->vartable, store->Index, store->Size); + } } } - } - +#endif return tree; } break; @@ -2022,12 +1980,10 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return _slang_gen_assignment(A, oper); case slang_oper_addassign: { + /* XXX this is broken */ slang_ir_node *n; assert(oper->num_children == 2); - n = _slang_gen_function_call_name(A, "+=", oper, NULL); - /* The result of this operation should be stored back into child[0] */ - assert(n->Children[0]->Store); - n->Store = n->Children[0]->Store; + n = _slang_gen_function_call_name(A, "+=", oper, &oper->children[0]); return n; } case slang_oper_subassign: @@ -2171,9 +2127,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, /* We know it's a uniform, but don't allocate storage unless * it's really used. */ - store = _slang_new_ir_storage(PROGRAM_STATE_VAR, -1, size); - } if (dbg) printf("UNIFORM "); } @@ -2260,10 +2214,12 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, if (!n) return GL_FALSE; n->Var = var; - var->declared = GL_TRUE; store = _slang_new_ir_storage(PROGRAM_TEMPORARY, index, size); var->aux = store; /* save var's storage info */ - slang_allocate_storage(A->codegen, n, A->program); + + slang_allocate_storage(A, n); + + _slang_add_variable(A->vartable, var); /* IR code for the var's initializer, if present */ if (var->initializer) { @@ -2284,7 +2240,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, n = new_seq(n, init); } - success = _slang_emit_code(n, A->codegen, A->program, GL_FALSE); + success = _slang_emit_code(n, A->vartable, A->program, GL_FALSE); _slang_free_ir_tree(n); } @@ -2328,8 +2284,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun) assert(A->program->Parameters ); assert(A->program->Varying); - assert(A->codegen); - /* A->codegen = _slang_new_codegen_context();*/ + assert(A->vartable); /* fold constant expressions, etc. */ slang_simplify(fun->body, &A->space, A->atoms); @@ -2340,8 +2295,16 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun) if (!CurFunction->end_label) CurFunction->end_label = slang_atom_pool_gen(A->atoms, "__endOfFunc_main_"); + /* push new vartable scope */ + A->vartable = _slang_push_var_table(A->vartable); + /* Generate IR tree for the function body code */ n = _slang_gen_operation(A, fun->body); + if (n) + n = new_node(IR_SCOPE, n, NULL); + + /* pop vartable, restore previous */ + A->vartable = _slang_pop_var_table(A->vartable); if (!n) { /* XXX record error */ @@ -2361,11 +2324,13 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun) #if 0 printf("************* IR for %s *******\n", (char*)fun->header.a_name); slang_print_ir(n, 0); +#endif +#if 1 printf("************* End codegen function ************\n\n"); #endif /* Emit program instructions */ - success = _slang_emit_code(n, A->codegen, A->program, GL_TRUE); + success = _slang_emit_code(n, A->vartable, A->program, GL_TRUE); _slang_free_ir_tree(n); /* free codegen context */ diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 9a77c5a3d67..c459eb29e74 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -39,6 +39,7 @@ #include "slang_storage.h" #include "slang_error.h" #include "slang_emit.h" +#include "slang_vartable.h" #include "slang_print.h" @@ -98,7 +99,9 @@ _slang_code_object_ctr(slang_code_object * self) for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) _slang_code_unit_ctr(&self->builtin[i], self); _slang_code_unit_ctr(&self->unit, self); +#if 01 _slang_assembly_file_ctr(&self->assembly); +#endif slang_machine_ctr(&self->machine); self->varpool.next_addr = 0; slang_atom_pool_construct(&self->atompool); @@ -116,7 +119,9 @@ _slang_code_object_dtr(slang_code_object * self) for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) _slang_code_unit_dtr(&self->builtin[i]); _slang_code_unit_dtr(&self->unit); +#if 01 slang_assembly_file_destruct(&self->assembly); +#endif slang_machine_dtr(&self->machine); slang_atom_pool_destruct(&self->atompool); slang_export_data_table_dtr(&self->expdata); @@ -248,7 +253,7 @@ typedef struct slang_output_ctx_ slang_var_pool *global_pool; slang_machine *machine; struct gl_program *program; - slang_gen_context *codegen; + slang_var_table *vartable; } slang_output_ctx; /* _slang_compile() */ @@ -868,7 +873,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, slang_operation *o = &oper->children[i - first_var]; o->type = slang_oper_variable_decl; o->locals->outer_scope = O->vars; - o->a_id = O->vars->variables[i].a_name; + o->a_id = O->vars->variables[i]->a_name; } } } @@ -879,9 +884,6 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, */ oper->type = slang_oper_asm; oper->a_id = parse_identifier(C); - if (strcmp((char*)oper->a_id, "dot") == 0) { - printf("Assemble dot! **************************\n"); - } if (oper->a_id == SLANG_ATOM_NULL) return 0; while (*C->I != OP_END) { @@ -1547,15 +1549,19 @@ parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O, static GLboolean initialize_global(slang_assemble_ctx * A, slang_variable * var) { +#if 01 slang_assembly_file_restore_point point; +#endif slang_machine mach; slang_assembly_local_info save_local = A->local; slang_operation op_id, op_assign; GLboolean result; +#if 01 /* save the current assembly */ if (!slang_assembly_file_restore_point_save(A->file, &point)) return GL_FALSE; +#endif /* setup the machine */ mach = *A->mach; @@ -1578,13 +1584,13 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) /* put the variable into operation's scope */ op_id.locals->variables = - (slang_variable *) slang_alloc_malloc(sizeof(slang_variable)); + (slang_variable **) slang_alloc_malloc(sizeof(slang_variable *)); if (op_id.locals->variables == NULL) { slang_operation_destruct(&op_id); return GL_FALSE; } op_id.locals->num_variables = 1; - op_id.locals->variables[0] = *var; + op_id.locals->variables[0] = var; /* construct the assignment expression */ if (!slang_operation_construct(&op_assign)) { @@ -1605,8 +1611,12 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) op_assign.children[0] = op_id; op_assign.children[1] = *var->initializer; +#if 0 /* this should go away */ /* insert the actual expression */ result = _slang_assemble_operation(A, &op_assign, slang_ref_forbid); +#else + result = 1; +#endif /* carefully destroy the operations */ op_assign.num_children = 0; @@ -1627,9 +1637,11 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) return GL_FALSE; #endif +#if 01 /* restore the old assembly */ if (!slang_assembly_file_restore_point_load(A->file, &point)) return GL_FALSE; +#endif A->local = save_local; /* now we copy the contents of the initialized variable back to the original machine */ @@ -1732,8 +1744,11 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, A.space.funcs = O->funs; A.space.structs = O->structs; A.space.vars = O->vars; - A.codegen = O->codegen; A.program = O->program; +#if 0 + A.codegen = O->codegen; +#endif + A.vartable = O->vartable; _slang_codegen_global_variable(&A, var, C->type); } @@ -1896,7 +1911,10 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, A.space.structs = O->structs; A.space.vars = O->vars; A.program = O->program; +#if 0 A.codegen = O->codegen; +#endif + A.vartable = O->vartable; _slang_reset_error(); @@ -1906,14 +1924,14 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, (*parsed_func_ret)->param_count); #endif - +#if 0 if (!_slang_assemble_function(&A, *parsed_func_ret)) { /* propogate the error message back through the info log */ C->L->text = _mesa_strdup(_slang_error_text()); C->L->dont_free_text = GL_FALSE; return GL_FALSE; } - +#endif #if 0 printf("**************************************\n"); @@ -1961,6 +1979,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, struct gl_program *program) { slang_output_ctx o; + GLboolean success; /* setup output context */ o.funs = &unit->funs; @@ -1970,7 +1989,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, o.global_pool = &unit->object->varpool; o.machine = &unit->object->machine; o.program = program; - o.codegen = _slang_new_codegen_context(); + o.vartable = _slang_push_var_table(NULL); /* parse individual functions and declarations */ while (*C->I != EXTERNAL_NULL) { @@ -1978,20 +1997,25 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, case EXTERNAL_FUNCTION_DEFINITION: { slang_function *func; - - if (!parse_function(C, &o, 1, &func)) - return GL_FALSE; + success = parse_function(C, &o, 1, &func); } break; case EXTERNAL_DECLARATION: - if (!parse_declaration(C, &o)) - return GL_FALSE; + success = parse_declaration(C, &o); break; default: + success = GL_FALSE; + } + + if (!success) { + /* xxx free codegen */ + _slang_pop_var_table(o.vartable); return GL_FALSE; } } C->I++; + + _slang_pop_var_table(o.vartable); return GL_TRUE; } diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 26701340256..81f85655023 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -34,6 +34,7 @@ #include "program.h" #include "prog_instruction.h" #include "prog_parameter.h" +#include "prog_print.h" #include "slang_emit.h" @@ -83,6 +84,7 @@ static slang_ir_info IrInfo[] = { { IR_COS, "IR_COS", OPCODE_COS, 1, 1 }, /* other */ { IR_SEQ, "IR_SEQ", 0, 0, 0 }, + { IR_SCOPE, "IR_SCOPE", 0, 0, 0 }, { IR_LABEL, "IR_LABEL", 0, 0, 0 }, { IR_JUMP, "IR_JUMP", 0, 0, 0 }, { IR_CJUMP, "IR_CJUMP", 0, 0, 0 }, @@ -227,6 +229,11 @@ slang_print_ir(const slang_ir_node *n, int indent) slang_print_ir(n->Children[0], indent + IND); slang_print_ir(n->Children[1], indent + IND); break; + case IR_SCOPE: + printf("NEW SCOPE\n"); + assert(!n->Children[1]); + slang_print_ir(n->Children[0], indent + 3); + break; case IR_MOVE: printf("MOVE (writemask = %s)\n", writemask_string(n->Writemask)); slang_print_ir(n->Children[0], indent+3); @@ -279,71 +286,36 @@ slang_print_ir(const slang_ir_node *n, int indent) } -GLint -_slang_alloc_temporary(slang_gen_context *gc, GLint size) -{ - const GLuint sz4 = (size + 3) / 4; - GLuint i, j; - ASSERT(size > 0); /* number of floats */ - - for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { - GLuint found = 0; - for (j = 0; j < sz4; j++) { - if (!gc->TempUsed[i + j]) { - found++; - } - } - if (found == sz4) { - /* found block of size/4 free regs */ - for (j = 0; j < sz4; j++) - gc->TempUsed[i + j] = GL_TRUE; - return i; - } - } - return -1; -} - - - -static GLboolean -is_temporary(const slang_gen_context *gc, const slang_ir_storage *st) -{ - if (st->File == PROGRAM_TEMPORARY && gc->TempUsed[st->Index]) - return gc->TempUsed[st->Index]; - else - return GL_FALSE; -} - - -void -_slang_free_temporary(slang_gen_context *gc, GLuint r, GLint size) -{ - const GLuint sz4 = (size + 3) / 4; - GLuint i; - for (i = 0; i < sz4; i++) { - if (gc->TempUsed[r + i]) - gc->TempUsed[r + i] = GL_FALSE; - } -} - - /** * Allocate temporary storage for an intermediate result (such as for * a multiply or add, etc. */ static void -slang_alloc_temp_storage(slang_gen_context *gc, slang_ir_node *n, GLint size) +alloc_temp_storage(slang_var_table *vt, slang_ir_node *n, GLint size) { GLint indx; assert(!n->Var); assert(!n->Store); assert(size > 0); - printf("Allocate binop temp:\n"); - indx = _slang_alloc_temporary(gc, size); + indx = _slang_alloc_temp(vt, size); n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, indx, size); } +static void +free_temp_storage(slang_var_table *vt, slang_ir_node *n) +{ + if (n->Store->File == PROGRAM_TEMPORARY && n->Store->Index >= 0) { + if (_slang_is_temp(vt, n->Store->Index)) { + _slang_free_temp(vt, n->Store->Index, n->Store->Size); + /* XXX free(store)? */ + n->Store->Index = -1; + n->Store->Size = -1; + } + } +} + + static slang_ir_storage * alloc_constant(const GLfloat v[], GLuint size, struct gl_program *prog) { @@ -445,14 +417,14 @@ new_instruction(struct gl_program *prog, gl_inst_opcode opcode) static struct prog_instruction * -emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog); +emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog); /** * Generate code for a simple binary-op instruction. */ static struct prog_instruction * -emit_binop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) +emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) { struct prog_instruction *inst; const slang_ir_info *info = slang_find_ir_info(n->Opcode); @@ -460,25 +432,32 @@ emit_binop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) assert(info->InstOpcode != OPCODE_NOP); - emit(gc, n->Children[0], prog); - emit(gc, n->Children[1], prog); + /* gen code for children */ + emit(vt, n->Children[0], prog); + emit(vt, n->Children[1], prog); + + /* gen this instruction */ inst = new_instruction(prog, info->InstOpcode); - /* alloc temp storage for the result: */ - if (!n->Store || n->Store->File == PROGRAM_UNDEFINED) { - slang_alloc_temp_storage(gc, n, info->ResultSize); - } - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store, n->Children[0]->Swizzle); storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store, n->Children[1]->Swizzle); + free_temp_storage(vt, n->Children[0]); + free_temp_storage(vt, n->Children[1]); + + if (!n->Store) { + alloc_temp_storage(vt, n, info->ResultSize); + } + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + inst->Comment = n->Comment; + /*_mesa_print_instruction(inst);*/ return inst; } static struct prog_instruction * -emit_unop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) +emit_unop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) { struct prog_instruction *inst; const slang_ir_info *info = slang_find_ir_info(n->Opcode); @@ -486,26 +465,28 @@ emit_unop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) assert(info->NumParams == 1); - emit(gc, n->Children[0], prog); + /* gen code for child */ + emit(vt, n->Children[0], prog); + /* gen this instruction */ inst = new_instruction(prog, info->InstOpcode); - - if (!n->Store) - slang_alloc_temp_storage(gc, n, info->ResultSize); - - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store, n->Children[0]->Swizzle); + free_temp_storage(vt, n->Children[0]); - inst->Comment = n->Comment; + if (!n->Store) { + alloc_temp_storage(vt, n, info->ResultSize); + } + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + inst->Comment = n->Comment; + /*_mesa_print_instruction(inst);*/ return inst; } static struct prog_instruction * -emit_negation(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) +emit_negation(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) { /* Implement as MOV dst, -src; */ /* XXX we could look at the previous instruction and in some circumstances @@ -513,10 +494,10 @@ emit_negation(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) */ struct prog_instruction *inst; - emit(gc, n->Children[0], prog); + emit(vt, n->Children[0], prog); if (!n->Store) - slang_alloc_temp_storage(gc, n, n->Children[0]->Store->Size); + alloc_temp_storage(vt, n, n->Children[0]->Store->Size); inst = new_instruction(prog, OPCODE_MOV); storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); @@ -563,7 +544,7 @@ emit_jump(const char *target, struct gl_program *prog) static struct prog_instruction * -emit_tex(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) +emit_tex(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) { struct prog_instruction *inst; if (n->Opcode == IR_TEX) { @@ -578,7 +559,7 @@ emit_tex(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) } if (!n->Store) - slang_alloc_temp_storage(gc, n, 4); + alloc_temp_storage(vt, n, 4); storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); @@ -600,7 +581,7 @@ emit_tex(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) static struct prog_instruction * -emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) +emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) { struct prog_instruction *inst; if (!n) @@ -610,34 +591,54 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) case IR_SEQ: assert(n->Children[0]); assert(n->Children[1]); - emit(gc, n->Children[0], prog); - inst = emit(gc, n->Children[1], prog); + emit(vt, n->Children[0], prog); + inst = emit(vt, n->Children[1], prog); n->Store = n->Children[1]->Store; return inst; - break; + + case IR_SCOPE: + /* new variable scope */ + vt = _slang_push_var_table(vt); + inst = emit(vt, n->Children[0], prog); + vt = _slang_pop_var_table(vt); + return inst; + case IR_VAR_DECL: + /* Variable declaration - allocate a register for it */ + assert(n->Store); + assert(n->Store->File != PROGRAM_UNDEFINED); + assert(n->Store->Size > 0); + if (n->Var->isTemp) + n->Store->Index = _slang_alloc_temp(vt, n->Store->Size); + else + n->Store->Index = _slang_alloc_var(vt, n->Store->Size); + break; + case IR_VAR: - /* Storage should have already been resolved/allocated */ + /* Reference to a variable + * Storage should have already been resolved/allocated. + */ assert(n->Store); assert(n->Store->File != PROGRAM_UNDEFINED); assert(n->Store->Index >= 0); assert(n->Store->Size > 0); break; + case IR_MOVE: /* rhs */ assert(n->Children[1]); - inst = emit(gc, n->Children[1], prog); + inst = emit(vt, n->Children[1], prog); /* lhs */ - emit(gc, n->Children[0], prog); + emit(vt, n->Children[0], prog); #if 1 - if (inst && is_temporary(gc, n->Children[1]->Store)) { + if (inst && _slang_is_temp(vt, n->Children[1]->Store->Index)) { /* Peephole optimization: * Just modify the RHS to put its result into the dest of this * MOVE operation. Then, this MOVE is a no-op. */ - _slang_free_temporary(gc, n->Children[1]->Store->Index, - n->Children[1]->Store->Size); + _slang_free_temp(vt, n->Children[1]->Store->Index, + n->Children[1]->Store->Size); *n->Children[1]->Store = *n->Children[0]->Store; /* fixup the prev (RHS) instruction */ storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask); @@ -673,9 +674,9 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) n->Children[1]->Swizzle); } /* XXX is this test correct? */ - if (n->Children[1]->Store->File == PROGRAM_TEMPORARY) { - _slang_free_temporary(gc, n->Children[1]->Store->Index, - n->Children[1]->Store->Size); + if (_slang_is_temp(vt, n->Children[1]->Store->Index)) { + _slang_free_temp(vt, n->Children[1]->Store->Index, + n->Children[1]->Store->Size); } /*inst->Comment = _mesa_strdup("IR_MOVE");*/ n->Store = n->Children[0]->Store; /*XXX new */ @@ -697,7 +698,7 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) case IR_POW: case IR_EXP: case IR_EXP2: - return emit_binop(gc, n, prog); + return emit_binop(vt, n, prog); case IR_RSQ: case IR_RCP: case IR_FLOOR: @@ -707,13 +708,13 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) case IR_COS: case IR_DDX: case IR_DDY: - return emit_unop(gc, n, prog); + return emit_unop(vt, n, prog); case IR_TEX: case IR_TEXB: case IR_TEXP: - return emit_tex(gc, n, prog); + return emit_tex(vt, n, prog); case IR_NEG: - return emit_negation(gc, n, prog); + return emit_negation(vt, n, prog); case IR_LABEL: return emit_label(n->Target, prog); case IR_FLOAT: @@ -726,7 +727,7 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) * Next instruction is typically an IR_CJUMP. */ /* last child expr instruction: */ - struct prog_instruction *inst = emit(gc, n->Children[0], prog); + struct prog_instruction *inst = emit(vt, n->Children[0], prog); if (inst) { /* set inst's CondUpdate flag */ inst->CondUpdate = GL_TRUE; @@ -737,13 +738,13 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) * is normally generated for the expression "i". * Generate a move instruction just to set condition codes. */ - slang_alloc_temp_storage(gc, n, 1); + alloc_temp_storage(vt, n, 1); inst = new_instruction(prog, OPCODE_MOV); inst->CondUpdate = GL_TRUE; storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store, n->Children[0]->Swizzle); - _slang_free_temporary(gc, n->Store->Index, n->Store->Size); + _slang_free_temp(vt, n->Store->Index, n->Store->Size); return inst; /* XXX or null? */ } } @@ -760,23 +761,14 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) } -slang_gen_context * -_slang_new_codegen_context(void) -{ - slang_gen_context *gc = (slang_gen_context *) _mesa_calloc(sizeof(*gc)); - return gc; -} - - - GLboolean -_slang_emit_code(slang_ir_node *n, slang_gen_context *gc, +_slang_emit_code(slang_ir_node *n, slang_var_table *vt, struct gl_program *prog, GLboolean withEnd) { GLboolean success; - if (emit(gc, n, prog)) { - /* finish up by addeing the END opcode to program */ + if (emit(vt, n, prog)) { + /* finish up by adding the END opcode to program */ if (withEnd) { struct prog_instruction *inst; inst = new_instruction(prog, OPCODE_END); @@ -788,8 +780,8 @@ _slang_emit_code(slang_ir_node *n, slang_gen_context *gc, success = GL_FALSE; } -#if 0 printf("*********** End generate code (%u inst):\n", prog->NumInstructions); +#if 0 _mesa_print_program(prog); _mesa_print_program_parameters(ctx,prog); #endif diff --git a/src/mesa/shader/slang/slang_emit.h b/src/mesa/shader/slang/slang_emit.h index 73ae0827c0b..7a845feac2b 100644 --- a/src/mesa/shader/slang/slang_emit.h +++ b/src/mesa/shader/slang/slang_emit.h @@ -32,10 +32,6 @@ #include "mtypes.h" -extern slang_gen_context * -_slang_new_codegen_context(void); - - extern void slang_print_ir(const slang_ir_node *n, int indent); @@ -48,15 +44,8 @@ extern slang_ir_storage * _slang_clone_ir_storage(slang_ir_storage *store); -extern GLint -_slang_alloc_temporary(slang_gen_context *gc, GLint size); - -extern void -_slang_free_temporary(slang_gen_context *gc, GLuint r, GLint size); - - extern GLboolean -_slang_emit_code(slang_ir_node *n, slang_gen_context *gc, +_slang_emit_code(slang_ir_node *n, slang_var_table *vartable, struct gl_program *prog, GLboolean withEnd); diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index b106e85dbb5..baf1137e731 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -45,6 +45,7 @@ typedef enum { IR_NOP = 0, IR_SEQ, /* sequence (eval left, then right) */ + IR_SCOPE, /* new variable scope (one child) */ IR_LABEL, /* target of a jump or cjump */ IR_JUMP, /* unconditional jump */ IR_CJUMP, /* conditional jump */ diff --git a/src/mesa/shader/slang/slang_link2.c b/src/mesa/shader/slang/slang_link2.c index 7dfdd288e12..3ea79544517 100644 --- a/src/mesa/shader/slang/slang_link2.c +++ b/src/mesa/shader/slang/slang_link2.c @@ -259,8 +259,10 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) if (inst->Opcode == OPCODE_TEX || inst->Opcode == OPCODE_TXB || inst->Opcode == OPCODE_TXP) { + /* printf("====== remap sampler from %d to %d\n", inst->Sampler, map[ inst->Sampler ]); + */ inst->Sampler = map[ inst->Sampler ]; } } diff --git a/src/mesa/shader/slang/slang_print.c b/src/mesa/shader/slang/slang_print.c index 020f30a9402..07509cddbca 100644 --- a/src/mesa/shader/slang/slang_print.c +++ b/src/mesa/shader/slang/slang_print.c @@ -188,7 +188,7 @@ find_scope(const slang_variable_scope *s, slang_atom name) { GLuint i; for (i = 0; i < s->num_variables; i++) { - if (s->variables[i].a_name == name) + if (s->variables[i]->a_name == name) return s; } if (s->outer_scope) @@ -202,8 +202,8 @@ find_var(const slang_variable_scope *s, slang_atom name) { GLuint i; for (i = 0; i < s->num_variables; i++) { - if (s->variables[i].a_name == name) - return &s->variables[i]; + if (s->variables[i]->a_name == name) + return s->variables[i]; } if (s->outer_scope) return find_var(s->outer_scope, name); @@ -621,7 +621,7 @@ slang_print_function(const slang_function *f, GLboolean body) (char *) f->header.a_name); for (i = 0; i < f->param_count; i++) { - print_variable(&f->parameters->variables[i], 3); + print_variable(f->parameters->variables[i], 3); } printf(")\n"); @@ -632,199 +632,6 @@ slang_print_function(const slang_function *f, GLboolean body) -/* operation */ -#define OP_END 0 -#define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1 -#define OP_BLOCK_BEGIN_NEW_SCOPE 2 -#define OP_DECLARE 3 -#define OP_ASM 4 -#define OP_BREAK 5 -#define OP_CONTINUE 6 -#define OP_DISCARD 7 -#define OP_RETURN 8 -#define OP_EXPRESSION 9 -#define OP_IF 10 -#define OP_WHILE 11 -#define OP_DO 12 -#define OP_FOR 13 -#define OP_PUSH_VOID 14 -#define OP_PUSH_BOOL 15 -#define OP_PUSH_INT 16 -#define OP_PUSH_FLOAT 17 -#define OP_PUSH_IDENTIFIER 18 -#define OP_SEQUENCE 19 -#define OP_ASSIGN 20 -#define OP_ADDASSIGN 21 -#define OP_SUBASSIGN 22 -#define OP_MULASSIGN 23 -#define OP_DIVASSIGN 24 -/*#define OP_MODASSIGN 25*/ -/*#define OP_LSHASSIGN 26*/ -/*#define OP_RSHASSIGN 27*/ -/*#define OP_ORASSIGN 28*/ -/*#define OP_XORASSIGN 29*/ -/*#define OP_ANDASSIGN 30*/ -#define OP_SELECT 31 -#define OP_LOGICALOR 32 -#define OP_LOGICALXOR 33 -#define OP_LOGICALAND 34 -/*#define OP_BITOR 35*/ -/*#define OP_BITXOR 36*/ -/*#define OP_BITAND 37*/ -#define OP_EQUAL 38 -#define OP_NOTEQUAL 39 -#define OP_LESS 40 -#define OP_GREATER 41 -#define OP_LESSEQUAL 42 -#define OP_GREATEREQUAL 43 -/*#define OP_LSHIFT 44*/ -/*#define OP_RSHIFT 45*/ -#define OP_ADD 46 -#define OP_SUBTRACT 47 -#define OP_MULTIPLY 48 -#define OP_DIVIDE 49 -/*#define OP_MODULUS 50*/ -#define OP_PREINCREMENT 51 -#define OP_PREDECREMENT 52 -#define OP_PLUS 53 -#define OP_MINUS 54 -/*#define OP_COMPLEMENT 55*/ -#define OP_NOT 56 -#define OP_SUBSCRIPT 57 -#define OP_CALL 58 -#define OP_FIELD 59 -#define OP_POSTINCREMENT 60 -#define OP_POSTDECREMENT 61 - - -void -slang_print_opcode(unsigned int opcode) -{ - switch (opcode) { - case OP_PUSH_VOID: - printf("OP_PUSH_VOID\n"); - break; - case OP_PUSH_BOOL: - printf("OP_PUSH_BOOL\n"); - break; - case OP_PUSH_INT: - printf("OP_PUSH_INT\n"); - break; - case OP_PUSH_FLOAT: - printf("OP_PUSH_FLOAT\n"); - break; - case OP_PUSH_IDENTIFIER: - printf("OP_PUSH_IDENTIFIER\n"); - break; - case OP_SEQUENCE: - printf("OP_SEQUENCE\n"); - break; - case OP_ASSIGN: - printf("OP_ASSIGN\n"); - break; - case OP_ADDASSIGN: - printf("OP_ADDASSIGN\n"); - break; - case OP_SUBASSIGN: - printf("OP_SUBASSIGN\n"); - break; - case OP_MULASSIGN: - printf("OP_MULASSIGN\n"); - break; - case OP_DIVASSIGN: - printf("OP_DIVASSIGN\n"); - break; - /*case OP_MODASSIGN:*/ - /*case OP_LSHASSIGN:*/ - /*case OP_RSHASSIGN:*/ - /*case OP_ORASSIGN:*/ - /*case OP_XORASSIGN:*/ - /*case OP_ANDASSIGN:*/ - case OP_SELECT: - printf("OP_SELECT\n"); - break; - case OP_LOGICALOR: - printf("OP_LOGICALOR\n"); - break; - case OP_LOGICALXOR: - printf("OP_LOGICALXOR\n"); - break; - case OP_LOGICALAND: - printf("OP_LOGICALAND\n"); - break; - /*case OP_BITOR:*/ - /*case OP_BITXOR:*/ - /*case OP_BITAND:*/ - case OP_EQUAL: - printf("OP_EQUAL\n"); - break; - case OP_NOTEQUAL: - printf("OP_NOTEQUAL\n"); - break; - case OP_LESS: - printf("OP_LESS\n"); - break; - case OP_GREATER: - printf("OP_GREATER\n"); - break; - case OP_LESSEQUAL: - printf("OP_LESSEQUAL\n"); - break; - case OP_GREATEREQUAL: - printf("OP_GREATEREQUAL\n"); - break; - /*case OP_LSHIFT:*/ - /*case OP_RSHIFT:*/ - case OP_ADD: - printf("OP_ADD\n"); - break; - case OP_SUBTRACT: - printf("OP_SUBTRACT\n"); - break; - case OP_MULTIPLY: - printf("OP_MULTIPLY\n"); - break; - case OP_DIVIDE: - printf("OP_DIVIDE\n"); - break; - /*case OP_MODULUS:*/ - case OP_PREINCREMENT: - printf("OP_PREINCREMENT\n"); - break; - case OP_PREDECREMENT: - printf("OP_PREDECREMENT\n"); - break; - case OP_PLUS: - printf("OP_PLUS\n"); - break; - case OP_MINUS: - printf("OP_MINUS\n"); - break; - case OP_NOT: - printf("OP_NOT\n"); - break; - /*case OP_COMPLEMENT:*/ - case OP_SUBSCRIPT: - printf("OP_SUBSCRIPT\n"); - break; - case OP_CALL: - printf("OP_CALL\n"); - break; - case OP_FIELD: - printf("OP_FIELD\n"); - break; - case OP_POSTINCREMENT: - printf("OP_POSTINCREMENT\n"); - break; - case OP_POSTDECREMENT: - printf("OP_POSTDECREMENT\n"); - break; - default: - printf("UNKNOWN OP %d\n", opcode); - } -} - - const char * slang_asm_string(slang_assembly_type t) @@ -1083,6 +890,7 @@ slang_print_type(const slang_fully_specified_type *t) } +#if 0 static char * slang_var_string(const slang_variable *v) { @@ -1092,6 +900,7 @@ slang_var_string(const slang_variable *v) slang_fq_type_string(&v->type)); return str; } +#endif void @@ -1111,13 +920,13 @@ _slang_print_var_scope(const slang_variable_scope *vars, int indent) printf("Var scope %p %d vars:\n", (void *) vars, vars->num_variables); for (i = 0; i < vars->num_variables; i++) { spaces(indent + 3); - printf("%s\n", (char *) vars->variables[i].a_name); + printf("%s (at %p)\n", (char *) vars->variables[i]->a_name, (void*) (vars->variables + i)); } spaces(indent + 3); printf("outer_scope = %p\n", (void*) vars->outer_scope); if (vars->outer_scope) { - spaces(indent + 3); + /*spaces(indent + 3);*/ _slang_print_var_scope(vars->outer_scope, indent + 3); } } diff --git a/src/mesa/shader/slang/slang_print.h b/src/mesa/shader/slang/slang_print.h index a98607a540f..ae39be68060 100644 --- a/src/mesa/shader/slang/slang_print.h +++ b/src/mesa/shader/slang/slang_print.h @@ -10,10 +10,6 @@ extern void slang_print_tree(const slang_operation *op, int indent); -extern void -slang_print_opcode(unsigned int opcode); - - extern const char * slang_asm_string(slang_assembly_type t); diff --git a/src/mesa/shader/slang/slang_storage.c b/src/mesa/shader/slang/slang_storage.c index 6220b7c5bf6..71ac0692e1d 100644 --- a/src/mesa/shader/slang/slang_storage.c +++ b/src/mesa/shader/slang/slang_storage.c @@ -126,8 +126,8 @@ static GLboolean aggregate_variables (slang_storage_aggregate *agg, slang_variab GLuint i; for (i = 0; i < vars->num_variables; i++) - if (!_slang_aggregate_variable (agg, &vars->variables[i].type.specifier, - vars->variables[i].array_len, funcs, structs, globals, mach, file, atoms)) + if (!_slang_aggregate_variable (agg, &vars->variables[i]->type.specifier, + vars->variables[i]->array_len, funcs, structs, globals, mach, file, atoms)) return GL_FALSE; return GL_TRUE; } diff --git a/src/mesa/shader/slang/slang_vartable.c b/src/mesa/shader/slang/slang_vartable.c new file mode 100644 index 00000000000..cd6a081e04b --- /dev/null +++ b/src/mesa/shader/slang/slang_vartable.c @@ -0,0 +1,202 @@ + +#include "imports.h" +#include "slang_compile.h" +#include "slang_compile_variable.h" +#include "slang_vartable.h" + + +static int dbg = 0; + + +typedef enum { + FREE, + VAR, + TEMP +} TempState; + +static int Level = 0; + +struct slang_var_table_ +{ + int level; + int num_entries; + slang_variable **vars; /* array [num_entries] */ + + TempState temps[MAX_PROGRAM_TEMPS]; + + struct slang_var_table_ *parent; +}; + + + +/** + * Create new table, put at head, return ptr to it. + */ +slang_var_table * +_slang_push_var_table(slang_var_table *parent) +{ + slang_var_table *t + = (slang_var_table *) _mesa_calloc(sizeof(slang_var_table)); + if (t) { + t->level = Level++; + t->parent = parent; + if (parent) { + /* copy the info indicating which temp regs are in use */ + memcpy(t->temps, parent->temps, sizeof(t->temps)); + } + if (dbg) printf("Pushing level %d\n", t->level); + } + return t; +} + + +/** + * Destroy given table, return ptr to parent + */ +slang_var_table * +_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); + if (t->parent) { + for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { + if (t->temps[i] && !t->parent->temps[i]) + if (dbg) printf(" Free reg %d\n", i); + } + } + 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); + free(t); + Level--; + return parent; +} + + +/** + * Add a new variable to the given symbol table. + */ +void +_slang_add_variable(slang_var_table *t, slang_variable *v) +{ + assert(t); + t->vars = realloc(t->vars, (t->num_entries + 1) * sizeof(slang_variable *)); + t->vars[t->num_entries] = v; + t->num_entries++; +} + + +/** + * Look for variable by name in given table. + * If not found, parent table will be searched. + */ +slang_variable * +_slang_find_variable(const slang_var_table *t, slang_atom name) +{ + while (1) { + int i; + for (i = 0; i < t->num_entries; i++) { + if (t->vars[i]->a_name == name) + return t->vars[i]; + } + if (t->parent) + t = t->parent; + else + return NULL; + } +} + + +static GLint +alloc_reg(slang_var_table *t, GLint size, GLboolean isTemp) +{ + const GLuint sz4 = (size + 3) / 4; + GLuint i, j; + assert(size > 0); /* number of floats */ + + for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { + GLuint found = 0; + for (j = 0; j < sz4; j++) { + if (!t->temps[i + j]) { + found++; + } + else { + break; + } + } + if (found == sz4) { + /* found block of size/4 free regs */ + for (j = 0; j < sz4; j++) + t->temps[i + j] = isTemp ? TEMP : VAR; + return i; + } + } + return -1; +} + + +/** + * Allocate temp register(s) for storing a variable. + */ +GLint +_slang_alloc_var(slang_var_table *t, GLint size) +{ + int i = alloc_reg(t, size, GL_FALSE); + if (dbg) printf("Alloc var %d (level %d)\n", i, t->level); + return i; +} + + +void +_slang_reserve_var(slang_var_table *t, GLint r, GLint size) +{ + const GLint sz4 = (size + 3) / 4; + GLint i; + for (i = 0; i < sz4; i++) { + t->temps[r + i] = VAR; + } +} + + +/** + * Allocate temp register(s) for storing an unnamed intermediate value. + */ +GLint +_slang_alloc_temp(slang_var_table *t, GLint size) +{ + int i = alloc_reg(t, size, GL_TRUE); + if (dbg) printf("Alloc temp %d (level %d)\n", i, t->level); + return i; +} + + +void +_slang_free_temp(slang_var_table *t, GLint r, GLint size) +{ + const GLuint sz4 = (size + 3) / 4; + GLuint i; + assert(size > 0); + assert(r >= 0); + assert(r < MAX_PROGRAM_TEMPS); + if (dbg) printf("Free temp %d (level %d)\n", r, t->level); + for (i = 0; i < sz4; i++) { + assert(t->temps[r + i] == TEMP); + t->temps[r + i] = FREE; + } +} + + +GLboolean +_slang_is_temp(slang_var_table *t, GLint r) +{ + assert(r >= 0); + assert(r < MAX_PROGRAM_TEMPS); + if (t->temps[r] == TEMP) + return GL_TRUE; + else + return GL_FALSE; +} diff --git a/src/mesa/shader/slang/slang_vartable.h b/src/mesa/shader/slang/slang_vartable.h new file mode 100644 index 00000000000..c8e37c94aa5 --- /dev/null +++ b/src/mesa/shader/slang/slang_vartable.h @@ -0,0 +1,38 @@ + +#ifndef SLANG_VARTABLE_H +#define SLANG_VARTABLE_H + + +typedef struct slang_var_table_ slang_var_table; + +struct slang_variable_; + +extern slang_var_table * +_slang_push_var_table(slang_var_table *parent); + +extern slang_var_table * +_slang_pop_var_table(slang_var_table *t); + +extern void +_slang_add_variable(slang_var_table *t, struct slang_variable_ *v); + +extern struct slang_variable_ * +_slang_find_variable(const slang_var_table *t, slang_atom name); + +extern GLint +_slang_alloc_var(slang_var_table *t, GLint size); + +extern void +_slang_reserve_var(slang_var_table *t, GLint r, GLint size); + +extern GLint +_slang_alloc_temp(slang_var_table *t, GLint size); + +extern void +_slang_free_temp(slang_var_table *t, GLint r, GLint size); + +extern GLboolean +_slang_is_temp(slang_var_table *t, GLint r); + + +#endif /* SLANG_VARTABLE_H */ diff --git a/src/mesa/sources b/src/mesa/sources index 19f43384ea1..1b0474c14b4 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -189,6 +189,7 @@ SLANG_SOURCES = \ shader/slang/slang_preprocess.c \ shader/slang/slang_simplify.c \ shader/slang/slang_storage.c \ + shader/slang/slang_vartable.c \ shader/slang/slang_print.c \ shader/slang/slang_utility.c |