diff options
Diffstat (limited to 'src/mesa/shader')
-rw-r--r-- | src/mesa/shader/arbprogparse.c | 9 | ||||
-rw-r--r-- | src/mesa/shader/shader_api.c | 50 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 62 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_compile.c | 21 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_ir.c | 2 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_print.c | 80 |
6 files changed, 182 insertions, 42 deletions
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index a6bbdc64f16..ff583352cec 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -1133,7 +1133,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program, gl_state_index state_tokens[STATE_LENGTH]) { - switch (*(*inst)++) { + GLubyte token = *(*inst)++; + + switch (token) { case STATE_MATERIAL_PARSER: state_tokens[0] = STATE_MATERIAL; state_tokens[1] = parse_face_type (inst); @@ -1318,7 +1320,6 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, case STATE_CLIP_PLANE: state_tokens[0] = STATE_CLIPPLANE; - state_tokens[1] = parse_integer (inst, Program); if (parse_clipplane_num (ctx, inst, Program, (GLint *) &state_tokens[1])) return 1; @@ -1770,7 +1771,9 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0}; GLfloat const_values[4]; - switch (*(*inst)++) { + GLubyte token = *(*inst)++; + + switch (token) { case PARAM_STATE_ELEMENT: if (parse_state_single_item (ctx, inst, Program, state_tokens)) return 1; diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 3e28d92fe18..c1fbcde61e4 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -955,12 +955,15 @@ _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength, } +#define MAX_UNIFORM_ELEMENTS 16 + /** - * Called via ctx->Driver.GetUniformfv(). + * Helper for GetUniformfv(), GetUniformiv() + * Returns number of elements written to 'params' output. */ -static void -_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, - GLfloat *params) +static GLuint +get_uniformfv(GLcontext *ctx, GLuint program, GLint location, + GLfloat *params) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); @@ -984,9 +987,13 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, ASSERT(prog); if (prog) { + /* See uniformiv() below */ + assert(prog->Parameters->Parameters[progPos].Size <= MAX_UNIFORM_ELEMENTS); + for (i = 0; i < prog->Parameters->Parameters[progPos].Size; i++) { params[i] = prog->Parameters->ParameterValues[progPos][i]; } + return prog->Parameters->Parameters[progPos].Size; } } else { @@ -996,6 +1003,35 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, else { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)"); } + return 0; +} + + +/** + * Called via ctx->Driver.GetUniformfv(). + */ +static void +_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, + GLfloat *params) +{ + (void) get_uniformfv(ctx, program, location, params); +} + + +/** + * Called via ctx->Driver.GetUniformiv(). + */ +static void +_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location, + GLint *params) +{ + GLfloat fparams[MAX_UNIFORM_ELEMENTS]; + GLuint n = get_uniformfv(ctx, program, location, fparams); + GLuint i; + assert(n <= MAX_UNIFORM_ELEMENTS); + for (i = 0; i < n; i++) { + params[i] = (GLint) fparams[i]; + } } @@ -1011,6 +1047,11 @@ _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name) if (!shProg) return -1; + if (shProg->LinkStatus == GL_FALSE) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)"); + return -1; + } + /* XXX we should return -1 if the uniform was declared, but not * actually used. */ @@ -1408,6 +1449,7 @@ _mesa_init_glsl_driver_functions(struct dd_function_table *driver) driver->GetShaderInfoLog = _mesa_get_shader_info_log; driver->GetShaderSource = _mesa_get_shader_source; driver->GetUniformfv = _mesa_get_uniformfv; + driver->GetUniformiv = _mesa_get_uniformiv; driver->GetUniformLocation = _mesa_get_uniform_location; driver->IsProgram = _mesa_is_program; driver->IsShader = _mesa_is_shader; diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 14fa38c3cda..af45dfb2e88 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -924,6 +924,30 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, } +/** + * Recursively traverse 'oper', replacing occurances of 'oldScope' with + * 'newScope' in the oper->locals->outer_scope filed. + * + * This is used after function inlining to update the scoping of + * the newly copied/inlined code so that vars are found in the new, + * inlined scope and not in the original function code. + */ +static void +slang_replace_scope(slang_operation *oper, + slang_variable_scope *oldScope, + slang_variable_scope *newScope) +{ + GLuint i; + if (oper->locals != newScope && + oper->locals->outer_scope == oldScope) { + oper->locals->outer_scope = newScope; + } + for (i = 0; i < oper->num_children; i++) { + slang_replace_scope(&oper->children[i], oldScope, newScope); + } +} + + /** * Produce inline code for a call to an assembly instruction. @@ -985,6 +1009,13 @@ slang_inline_asm_function(slang_assemble_ctx *A, _slang_free(substOld); _slang_free(substNew); +#if 0 + printf("+++++++++++++ inlined asm function %s +++++++++++++\n", + (char *) fun->header.a_name); + slang_print_tree(inlined, 3); + printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); +#endif + return inlined; } @@ -1012,6 +1043,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_operation **substNew; GLuint substCount, numCopyIn, i; slang_function *prevFunction; + slang_variable_scope *newScope = NULL; /* save / push */ prevFunction = A->CurFunction; @@ -1029,7 +1061,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, _slang_alloc(totalArgs * sizeof(slang_operation *)); #if 0 - printf("Inline call to %s (total vars=%d nparams=%d)\n", + printf("\nInline call to %s (total vars=%d nparams=%d)\n", (char *) fun->header.a_name, fun->parameters->num_variables, numArgs); #endif @@ -1179,9 +1211,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_operation *decl = slang_operation_insert(&inlined->num_children, &inlined->children, numCopyIn); - /* - printf("COPY_IN %s from expr\n", (char*)p->a_name); - */ + decl->type = SLANG_OPER_VARIABLE_DECL; assert(decl->locals); decl->locals->outer_scope = inlined->locals; @@ -1192,6 +1222,15 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, /* child[0] is the var's initializer */ slang_operation_copy(&decl->children[0], args + i); + /* add parameter 'p' to the local variable scope here */ + { + slang_variable *pCopy = slang_variable_scope_grow(inlined->locals); + pCopy->type = p->type; + pCopy->a_name = p->a_name; + pCopy->array_len = p->array_len; + } + + newScope = inlined->locals; numCopyIn++; } } @@ -1231,8 +1270,15 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, _slang_free(substOld); _slang_free(substNew); + /* Update scoping to use the new local vars instead of the + * original function's vars. This is especially important + * for nested inlining. + */ + if (newScope) + slang_replace_scope(inlined, fun->parameters, newScope); + #if 0 - printf("Done Inline call to %s (total vars=%d nparams=%d)\n", + printf("Done Inline call to %s (total vars=%d nparams=%d)\n\n", (char *) fun->header.a_name, fun->parameters->num_variables, numArgs); slang_print_tree(top, 0); @@ -2063,7 +2109,11 @@ _slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var) n = new_node0(IR_VAR_DECL); if (n) { _slang_attach_storage(n, var); - +#if 0 + printf("%s var %p %s store=%p\n", + __FUNCTION__, (void *) var, (char *) var->a_name, + (void *) n->Store); +#endif assert(var->aux); assert(n->Store == var->aux); assert(n->Store); diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index e2117c03e67..ccb04494bf6 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -1634,6 +1634,15 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, return 0; } + /* allocate global address space for a variable with a known size */ + if (C->global_scope + && !(var->type.specifier.type == SLANG_SPEC_ARRAY + && var->array_len == 0)) { + if (!calculate_var_size(C, O, var)) + return GL_FALSE; + var->address = slang_var_pool_alloc(O->global_pool, var->size); + } + /* emit code for global var decl */ if (C->global_scope) { slang_assemble_ctx A; @@ -1648,15 +1657,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, return 0; } - /* allocate global address space for a variable with a known size */ - if (C->global_scope - && !(var->type.specifier.type == SLANG_SPEC_ARRAY - && var->array_len == 0)) { - if (!calculate_var_size(C, O, var)) - return GL_FALSE; - var->address = slang_var_pool_alloc(O->global_pool, var->size); - } - /* initialize global variable */ if (C->global_scope) { if (var->initializer != NULL) { @@ -2167,6 +2167,9 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader) type = SLANG_UNIT_FRAGMENT_SHADER; } + if (!shader->Source) + return GL_FALSE; + ctx->Shader.MemPool = _slang_new_mempool(1024*1024); /* XXX temporary hack */ diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c index 31ad94183c2..16c36aad0c1 100644 --- a/src/mesa/shader/slang/slang_ir.c +++ b/src/mesa/shader/slang/slang_ir.c @@ -218,12 +218,14 @@ storage_string(const slang_ir_storage *st) "NAMED_PARAM", "CONSTANT", "UNIFORM", + "VARYING", "WRITE_ONLY", "ADDRESS", "SAMPLER", "UNDEFINED" }; static char s[100]; + assert(Elements(files) == PROGRAM_FILE_MAX); #if 0 if (st->Size == 1) sprintf(s, "%s[%d]", files[st->File], st->Index); diff --git a/src/mesa/shader/slang/slang_print.c b/src/mesa/shader/slang/slang_print.c index 4a7d4bbbc74..ff9c62c929e 100644 --- a/src/mesa/shader/slang/slang_print.c +++ b/src/mesa/shader/slang/slang_print.c @@ -171,9 +171,15 @@ static void print_binary(const slang_operation *op, const char *oper, int indent) { assert(op->num_children == 2); + printf("binary at %p locals=%p outer=%p\n", + (void *) op, + (void *) op->locals, + (void *) op->locals->outer_scope); slang_print_tree(&op->children[0], indent + 3); spaces(indent); - printf("%s\n", oper); + printf("%s at %p locals=%p outer=%p\n", + oper, (void *) op, (void *) op->locals, + (void *) op->locals->outer_scope); slang_print_tree(&op->children[1], indent + 3); } @@ -185,11 +191,13 @@ print_generic2(const slang_operation *op, const char *oper, GLuint i; if (oper) { spaces(indent); - printf("[%p locals %p] %s %s\n", (void*) op, (void*) op->locals, oper, s); + printf("%s %s at %p locals=%p outer=%p\n", + oper, s, (void *) op, (void *) op->locals, + (void *) op->locals->outer_scope); } for (i = 0; i < op->num_children; i++) { spaces(indent); - printf("//child %u:\n", i); + printf("//child %u of %u:\n", i, op->num_children); slang_print_tree(&op->children[i], indent); } } @@ -244,7 +252,7 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_BLOCK_NO_NEW_SCOPE: spaces(indent); - printf("{ locals %p outer %p\n", (void*)op->locals, (void*)op->locals->outer_scope); + printf("{ locals=%p outer=%p\n", (void*)op->locals, (void*)op->locals->outer_scope); print_generic(op, NULL, indent+3); spaces(indent); printf("}\n"); @@ -252,7 +260,14 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_BLOCK_NEW_SCOPE: spaces(indent); - printf("{{ // new scope locals %p\n", (void*)op->locals); + printf("{{ // new scope locals=%p: ", (void*)op->locals); + { + int i; + for (i = 0; i < op->locals->num_variables; i++) { + printf("%s ", (char *) op->locals->variables[i]->a_name); + } + printf("\n"); + } print_generic(op, NULL, indent+3); spaces(indent); printf("}}\n"); @@ -264,14 +279,16 @@ slang_print_tree(const slang_operation *op, int indent) slang_variable *v; v = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); if (v) { + const slang_variable_scope *scope; spaces(indent); printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope); print_type(&v->type); printf(" %s (%p)", (char *) op->a_id, (void *) find_var(op->locals, op->a_id)); - printf(" (in scope %p) ", - (void *) find_scope(op->locals, op->a_id)); + scope = find_scope(op->locals, op->a_id); + printf(" (in scope %p) ", (void *) scope); + assert(scope); if (op->num_children == 1) { printf(" :=\n"); slang_print_tree(&op->children[0], indent + 3); @@ -300,8 +317,12 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_ASM: spaces(indent); - printf("ASM: %s\n", (char*) op->a_id); - print_generic(op, NULL, indent+3); + printf("ASM: %s at %p locals=%p outer=%p\n", + (char *) op->a_id, + (void *) op, + (void *) op->locals, + (void *) op->locals->outer_scope); + print_generic(op, "ASM", indent+3); break; case SLANG_OPER_BREAK: @@ -333,7 +354,9 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_EXPRESSION: spaces(indent); - printf("EXPR: locals %p\n", (void*) op->locals); + printf("EXPR: locals=%p outer=%p\n", + (void *) op->locals, + (void *) op->locals->outer_scope); /*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/ slang_print_tree(&op->children[0], indent + 3); break; @@ -422,13 +445,25 @@ slang_print_tree(const slang_operation *op, int indent) break; case SLANG_OPER_IDENTIFIER: - spaces(indent); - if (op->var && op->var->a_name) - printf("VAR %s (in scope %p)\n", (char *) op->var->a_name, - (void *) find_scope(op->locals, op->a_id)); - else - printf("VAR' %s (in scope %p)\n", (char *) op->a_id, - (void *) find_scope(op->locals, op->a_id)); + { + const slang_variable_scope *scope; + spaces(indent); + if (op->var && op->var->a_name) { + scope = find_scope(op->locals, op->var->a_name); + printf("VAR %s (in scope %p)\n", (char *) op->var->a_name, + (void *) scope); + assert(scope); + } + else { + scope = find_scope(op->locals, op->a_id); + printf("VAR' %s (in scope %p) locals=%p outer=%p\n", + (char *) op->a_id, + (void *) scope, + (void *) op->locals, + (void *) op->locals->outer_scope); + assert(scope); + } + } break; case SLANG_OPER_SEQUENCE: @@ -437,7 +472,9 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_ASSIGN: spaces(indent); - printf("ASSIGNMENT locals %p\n", (void*)op->locals); + printf("ASSIGNMENT locals=%p outer=%p\n", + (void *) op->locals, + (void *) op->locals->outer_scope); print_binary(op, ":=", indent); break; @@ -573,7 +610,9 @@ slang_print_tree(const slang_operation *op, int indent) case SLANG_OPER_SUBSCRIPT: spaces(indent); - printf("SLANG_OPER_SUBSCRIPT\n"); + printf("SLANG_OPER_SUBSCRIPT locals=%p outer=%p\n", + (void *) op->locals, + (void *) op->locals->outer_scope); print_generic(op, NULL, indent+3); break; @@ -640,7 +679,8 @@ slang_print_function(const slang_function *f, GLboolean body) print_variable(f->parameters->variables[i], 3); } - printf(")\n"); + printf(") param scope = %p\n", (void *) f->parameters); + if (body && f->body) slang_print_tree(f->body, 0); } |