From: Brian Date: Sat, 13 Jan 2007 21:49:52 +0000 (-0700) Subject: Rework code related to temp register allocation, both for user variables X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=691ed5e54b0dc305c9a117a6a9804435041a86f0;p=mesa.git Rework code related to temp register allocation, both for user variables and expression temporarires. Much better register utilization now. Lots of other fixes. The OpenGL GLSL "orange book" brick shader demo works now. --- 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