diff options
author | Brian <[email protected]> | 2007-02-26 14:34:57 -0700 |
---|---|---|
committer | Brian <[email protected]> | 2007-02-26 14:34:57 -0700 |
commit | ed0ae62ad746d10fe546c900a42e55af5d05c227 (patch) | |
tree | 3e743e4553ddc05a06ee3fe0303076a562e5fcac /src | |
parent | 4e53ce81cfa2a98d045433ffbc4d295a239ad0b6 (diff) | |
parent | ca279b80e686e2e590f1cf08ef22dabdead4d66f (diff) |
Merge branch 'glsl-compiler-1' of git+ssh://[email protected]/git/mesa/mesa into glsl-compiler-1
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 37 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_compile.c | 114 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_compile.h | 13 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 317 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.h | 3 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_error.c | 78 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_error.h | 85 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_log.c | 128 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_log.h | 56 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_preprocess.h | 23 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_simplify.c | 6 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_simplify.h | 3 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_typeinfo.c | 123 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_typeinfo.h | 9 | ||||
-rw-r--r-- | src/mesa/sources | 2 |
15 files changed, 470 insertions, 527 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index d239a97500d..efd330106be 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -47,7 +47,6 @@ #include "slang_typeinfo.h" #include "slang_codegen.h" #include "slang_compile.h" -#include "slang_error.h" #include "slang_label.h" #include "slang_simplify.h" #include "slang_emit.h" @@ -1154,7 +1153,7 @@ make_writemask(const char *field) */ static slang_ir_node * _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper, - slang_operation *dest) + slang_operation *dest) { const slang_asm_info *info; slang_ir_node *kids[3], *n; @@ -1280,15 +1279,15 @@ _slang_gen_function_call_name(slang_assemble_ctx *A, const char *name, * Use 'name' to find the function to call */ fun = _slang_locate_function(A->space.funcs, atom, params, param_count, - &A->space, A->atoms); + &A->space, A->atoms, A->log); if (!fun) { /* A function with exactly the right parameters/types was not found. * Try adapting the parameters. */ fun = _slang_first_function(A->space.funcs, name); - if (!_slang_adapt_call(oper, fun, &A->space, A->atoms)) { - RETURN_ERROR2("Undefined function (or no matching parameters)", - name, 0); + if (!_slang_adapt_call(oper, fun, &A->space, A->atoms, A->log)) { + slang_info_log_error(A->log, "Undefined function '%s'", name); + return NULL; } assert(fun); } @@ -1361,7 +1360,8 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) if (loop->BranchNode == 0 && isConst && constTrue) { /* infinite loop detected */ A->CurLoop = prevLoop; /* clean-up */ - RETURN_ERROR("Infinite loop detected!", 0); + slang_info_log_error(A->log, "Infinite loop detected!"); + return NULL; } /* pop loop, restore prev */ @@ -1816,7 +1816,8 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper) assert(oper->num_children == 1); var = new_var(A, oper, oper->a_id); if (!var) { - RETURN_ERROR2("Undefined variable:", varName, 0); + slang_info_log_error(A->log, "undefined variable '%s'", varName); + return NULL; } /* XXX make copy of this initializer? */ rhs = _slang_gen_operation(A, &oper->children[0]); @@ -1829,7 +1830,8 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper) slang_ir_node *var, *init, *rhs; var = new_var(A, oper, oper->a_id); if (!var) { - RETURN_ERROR2("Undefined variable:", varName, 0); + slang_info_log_error(A->log, "undefined variable '%s'", varName); + return NULL; } #if 0 /* XXX make copy of this initializer? */ @@ -1870,7 +1872,8 @@ _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); if (!n) { - RETURN_ERROR2("Undefined variable:", (char *) aVar, 0); + slang_info_log_error(A->log, "undefined variable '%s'", (char *) aVar); + return NULL; } return n; } @@ -2045,7 +2048,7 @@ _slang_gen_field(slang_assemble_ctx * A, slang_operation *oper) slang_ir_node *n; GLuint swizzle; if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) { - RETURN_ERROR("Bad swizzle", 0); + slang_info_log_error(A->log, "Bad swizzle"); } swizzle = MAKE_SWIZZLE4(swz.swizzle[0], swz.swizzle[1], @@ -2063,7 +2066,7 @@ _slang_gen_field(slang_assemble_ctx * A, slang_operation *oper) slang_ir_node *n; GLuint swizzle; if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) { - RETURN_ERROR("Bad swizzle", 0); + slang_info_log_error(A->log, "Bad swizzle"); } swizzle = MAKE_SWIZZLE4(swz.swizzle[0], swz.swizzle[1], @@ -2122,7 +2125,7 @@ _slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper) index = (GLint) oper->children[1].literal[0]; if (oper->children[1].type != SLANG_OPER_LITERAL_INT || index >= max) { - RETURN_ERROR("Invalid array index for vector type", 0); + slang_info_log_error(A->log, "Invalid array index for vector type"); } n = _slang_gen_operation(A, &oper->children[0]); @@ -2243,12 +2246,12 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return _slang_gen_while(A, oper); case SLANG_OPER_BREAK: if (!A->CurLoop) { - RETURN_ERROR("'break' not in loop", 0); + slang_info_log_error(A->log, "'break' not in loop"); } return new_break(A->CurLoop); case SLANG_OPER_CONTINUE: if (!A->CurLoop) { - RETURN_ERROR("'continue' not in loop", 0); + slang_info_log_error(A->log, "'continue' not in loop"); } return new_cont(A->CurLoop); case SLANG_OPER_DISCARD: @@ -2621,7 +2624,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, n = new_seq(n, init); } - success = _slang_emit_code(n, A->vartable, A->program, GL_FALSE); + success = _slang_emit_code(n, A->vartable, A->program, GL_FALSE, A->log); _slang_free_ir_tree(n); } @@ -2709,7 +2712,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun) #endif /* Emit program instructions */ - success = _slang_emit_code(n, A->vartable, A->program, GL_TRUE); + success = _slang_emit_code(n, A->vartable, A->program, GL_TRUE, A->log); _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 a1cae5d338d..1a4c7d31f16 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -37,8 +37,8 @@ #include "slang_compile.h" #include "slang_preprocess.h" #include "slang_storage.h" -#include "slang_error.h" #include "slang_emit.h" +#include "slang_log.h" #include "slang_vartable.h" #include "slang_simplify.h" @@ -115,110 +115,6 @@ _slang_code_object_dtr(slang_code_object * self) slang_atom_pool_destruct(&self->atompool); } -/* slang_info_log */ - -static char *out_of_memory = "Error: Out of memory.\n"; - -void -slang_info_log_construct(slang_info_log * log) -{ - log->text = NULL; - log->dont_free_text = 0; -} - -void -slang_info_log_destruct(slang_info_log * log) -{ - if (!log->dont_free_text) - slang_alloc_free(log->text); -} - -static int -slang_info_log_message(slang_info_log * log, const char *prefix, - const char *msg) -{ - GLuint size; - - if (log->dont_free_text) - return 0; - size = slang_string_length(msg) + 2; - if (prefix != NULL) - size += slang_string_length(prefix) + 2; - if (log->text != NULL) { - GLuint old_len = slang_string_length(log->text); - log->text = (char *) - slang_alloc_realloc(log->text, old_len + 1, old_len + size); - } - else { - log->text = (char *) (slang_alloc_malloc(size)); - if (log->text != NULL) - log->text[0] = '\0'; - } - if (log->text == NULL) - return 0; - if (prefix != NULL) { - slang_string_concat(log->text, prefix); - slang_string_concat(log->text, ": "); - } - slang_string_concat(log->text, msg); - slang_string_concat(log->text, "\n"); -#if 1 - abort(); /* XXX temporary */ -#endif - return 1; -} - -int -slang_info_log_print(slang_info_log * log, const char *msg, ...) -{ - va_list va; - char buf[1024]; - - va_start(va, msg); - _mesa_vsprintf(buf, msg, va); - va_end(va); - return slang_info_log_message(log, NULL, buf); -} - -int -slang_info_log_error(slang_info_log * log, const char *msg, ...) -{ - va_list va; - char buf[1024]; - - va_start(va, msg); - _mesa_vsprintf(buf, msg, va); - va_end(va); - if (slang_info_log_message(log, "Error", buf)) - return 1; - slang_info_log_memory(log); - return 0; -} - -int -slang_info_log_warning(slang_info_log * log, const char *msg, ...) -{ - va_list va; - char buf[1024]; - - va_start(va, msg); - _mesa_vsprintf(buf, msg, va); - va_end(va); - if (slang_info_log_message(log, "Warning", buf)) - return 1; - slang_info_log_memory(log); - return 0; -} - -void -slang_info_log_memory(slang_info_log * log) -{ - if (!slang_info_log_message(log, "Error", "Out of memory.")) { - log->dont_free_text = 1; - log->text = out_of_memory; - } - abort(); /* XXX temporary */ -} /* slang_parse_ctx */ @@ -1838,8 +1734,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, A.space.vars = O->vars; A.program = O->program; A.vartable = O->vartable; - - _slang_reset_error(); + A.log = C->L; _slang_codegen_function(&A, *parsed_func_ret); } @@ -2002,7 +1897,7 @@ compile_with_grammar(grammar id, const char *source, slang_code_unit * unit, slang_string_free(&preprocessed); grammar_get_last_error((byte *) (buf), sizeof(buf), &pos); slang_info_log_error(infolog, buf); - RETURN_ERROR("syntax error (possibly in library code)", 0); + /* syntax error (possibly in library code) */ } slang_string_free(&preprocessed); @@ -2175,7 +2070,7 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader) success = compile_shader(ctx, &obj, type, &info_log, shader); - if (success) { + if (success && !info_log.text) { #if 0 slang_create_uniforms(&object->expdata, shader); _mesa_print_program(program); @@ -2183,6 +2078,7 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader) #endif } else { + success = GL_FALSE; /* XXX more work on info log needed here */ if (info_log.text) { if (shader->InfoLog) { diff --git a/src/mesa/shader/slang/slang_compile.h b/src/mesa/shader/slang/slang_compile.h index 7abb92bd3b5..086e2d8dc4d 100644 --- a/src/mesa/shader/slang/slang_compile.h +++ b/src/mesa/shader/slang/slang_compile.h @@ -88,19 +88,6 @@ _slang_code_object_ctr (slang_code_object *); extern GLvoid _slang_code_object_dtr (slang_code_object *); -typedef struct slang_info_log_ -{ - char *text; - int dont_free_text; -} slang_info_log; - -void slang_info_log_construct (slang_info_log *); -void slang_info_log_destruct (slang_info_log *); -int slang_info_log_print (slang_info_log *, const char *, ...); -int slang_info_log_error (slang_info_log *, const char *, ...); -int slang_info_log_warning (slang_info_log *, const char *, ...); -void slang_info_log_memory (slang_info_log *); - extern GLboolean _slang_compile (GLcontext *ctx, struct gl_shader *shader); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index e57f215dfe9..b0776e93407 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -45,7 +45,6 @@ #include "prog_print.h" #include "slang_builtin.h" #include "slang_emit.h" -#include "slang_error.h" #define PEEPHOLE_OPTIMIZATIONS 1 @@ -57,6 +56,13 @@ static GLboolean EmitHighLevelInstructions = GL_TRUE; static GLboolean EmitComments = GL_FALSE; +typedef struct +{ + slang_info_log *log; + slang_var_table *vt; + struct gl_program *prog; +} slang_emit_info; + /** * Assembly and IR info @@ -408,14 +414,16 @@ slang_print_ir(const slang_ir_node *n, int indent) * a multiply or add, etc. */ static GLboolean -alloc_temp_storage(slang_var_table *vt, slang_ir_node *n, GLint size) +alloc_temp_storage(slang_emit_info *emitInfo, slang_ir_node *n, GLint size) { assert(!n->Var); assert(!n->Store); assert(size > 0); n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size); - if (!_slang_alloc_temp(vt, n->Store)) { - RETURN_ERROR("Ran out of registers, too many temporaries", 0); + if (!_slang_alloc_temp(emitInfo->vt, n->Store)) { + slang_info_log_error(emitInfo->log, + "Ran out of registers, too many temporaries"); + return GL_FALSE; } return GL_TRUE; } @@ -507,8 +515,9 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st) * \return pointer to the new instruction */ static struct prog_instruction * -new_instruction(struct gl_program *prog, gl_inst_opcode opcode) +new_instruction(slang_emit_info *emitInfo, gl_inst_opcode opcode) { + struct gl_program *prog = emitInfo->prog; struct prog_instruction *inst; prog->Instructions = _mesa_realloc_instructions(prog->Instructions, prog->NumInstructions, @@ -538,7 +547,7 @@ prev_instruction(struct gl_program *prog) static struct prog_instruction * -emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog); +emit(slang_emit_info *emitInfo, slang_ir_node *n); /** @@ -678,7 +687,7 @@ instruction_annotation(gl_inst_opcode opcode, char *dstAnnot, * Either 1, 2 or 3 operands. */ static struct prog_instruction * -emit_arith(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_arith(slang_emit_info *emitInfo, slang_ir_node *n) { struct prog_instruction *inst; const slang_ir_info *info = slang_find_ir_info(n->Opcode); @@ -695,34 +704,34 @@ emit_arith(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) if (info->NumParams == 2 && n->Opcode == IR_ADD && n->Children[0]->Opcode == IR_MUL) { /* found pattern IR_ADD(IR_MUL(A, B), C) */ - emit(vt, n->Children[0]->Children[0], prog); /* A */ - emit(vt, n->Children[0]->Children[1], prog); /* B */ - emit(vt, n->Children[1], prog); /* C */ + emit(emitInfo, n->Children[0]->Children[0]); /* A */ + emit(emitInfo, n->Children[0]->Children[1]); /* B */ + emit(emitInfo, n->Children[1]); /* C */ /* generate MAD instruction */ - inst = new_instruction(prog, OPCODE_MAD); + inst = new_instruction(emitInfo, OPCODE_MAD); /* operands: A, B, C: */ storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Children[0]->Store); storage_to_src_reg(&inst->SrcReg[1], n->Children[0]->Children[1]->Store); storage_to_src_reg(&inst->SrcReg[2], n->Children[1]->Store); - free_temp_storage(vt, n->Children[0]->Children[0]); - free_temp_storage(vt, n->Children[0]->Children[1]); - free_temp_storage(vt, n->Children[1]); + free_temp_storage(emitInfo->vt, n->Children[0]->Children[0]); + free_temp_storage(emitInfo->vt, n->Children[0]->Children[1]); + free_temp_storage(emitInfo->vt, n->Children[1]); } else if (info->NumParams == 2 && n->Opcode == IR_ADD && n->Children[1]->Opcode == IR_MUL) { /* found pattern IR_ADD(A, IR_MUL(B, C)) */ - emit(vt, n->Children[0], prog); /* A */ - emit(vt, n->Children[1]->Children[0], prog); /* B */ - emit(vt, n->Children[1]->Children[1], prog); /* C */ + emit(emitInfo, n->Children[0]); /* A */ + emit(emitInfo, n->Children[1]->Children[0]); /* B */ + emit(emitInfo, n->Children[1]->Children[1]); /* C */ /* generate MAD instruction */ - inst = new_instruction(prog, OPCODE_MAD); + inst = new_instruction(emitInfo, OPCODE_MAD); /* operands: B, C, A */ storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Children[0]->Store); storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Children[1]->Store); storage_to_src_reg(&inst->SrcReg[2], n->Children[0]->Store); - free_temp_storage(vt, n->Children[1]->Children[0]); - free_temp_storage(vt, n->Children[1]->Children[1]); - free_temp_storage(vt, n->Children[0]); + free_temp_storage(emitInfo->vt, n->Children[1]->Children[0]); + free_temp_storage(emitInfo->vt, n->Children[1]->Children[1]); + free_temp_storage(emitInfo->vt, n->Children[0]); } else #endif @@ -731,30 +740,30 @@ emit_arith(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) /* gen code for children */ for (i = 0; i < info->NumParams; i++) - emit(vt, n->Children[i], prog); + emit(emitInfo, n->Children[i]); /* gen this instruction and src registers */ - inst = new_instruction(prog, info->InstOpcode); + inst = new_instruction(emitInfo, info->InstOpcode); for (i = 0; i < info->NumParams; i++) storage_to_src_reg(&inst->SrcReg[i], n->Children[i]->Store); /* annotation */ for (i = 0; i < info->NumParams; i++) - srcAnnot[i] = storage_annotation(n->Children[i], prog); + srcAnnot[i] = storage_annotation(n->Children[i], emitInfo->prog); /* free temps */ for (i = 0; i < info->NumParams; i++) - free_temp_storage(vt, n->Children[i]); + free_temp_storage(emitInfo->vt, n->Children[i]); } /* result storage */ if (!n->Store) { - if (!alloc_temp_storage(vt, n, info->ResultSize)) + if (!alloc_temp_storage(emitInfo, n, info->ResultSize)) return NULL; } storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - dstAnnot = storage_annotation(n, prog); + dstAnnot = storage_annotation(n, emitInfo->prog); inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, srcAnnot[0], srcAnnot[1], srcAnnot[2]); @@ -768,7 +777,7 @@ emit_arith(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) * Generate code for an IR_CLAMP instruction. */ static struct prog_instruction * -emit_clamp(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n) { struct prog_instruction *inst; @@ -778,7 +787,7 @@ emit_clamp(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) * ch[2] = max limit */ - inst = emit(vt, n->Children[0], prog); + inst = emit(emitInfo, n->Children[0]); /* If lower limit == 0.0 and upper limit == 1.0, * set prev instruction's SaturateMode field to SATURATE_ZERO_ONE. @@ -810,20 +819,20 @@ emit_clamp(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) #endif if (!n->Store) - if (!alloc_temp_storage(vt, n, n->Children[0]->Store->Size)) + if (!alloc_temp_storage(emitInfo, n, n->Children[0]->Store->Size)) return NULL; - emit(vt, n->Children[1], prog); - emit(vt, n->Children[2], prog); + emit(emitInfo, n->Children[1]); + emit(emitInfo, n->Children[2]); /* tmp = max(ch[0], ch[1]) */ - inst = new_instruction(prog, OPCODE_MAX); + inst = new_instruction(emitInfo, OPCODE_MAX); storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); /* tmp = min(tmp, ch[2]) */ - inst = new_instruction(prog, OPCODE_MIN); + inst = new_instruction(emitInfo, OPCODE_MIN); storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Store); storage_to_src_reg(&inst->SrcReg[1], n->Children[2]->Store); @@ -833,7 +842,7 @@ emit_clamp(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) static struct prog_instruction * -emit_negation(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_negation(slang_emit_info *emitInfo, slang_ir_node *n) { /* Implement as MOV dst, -src; */ /* XXX we could look at the previous instruction and in some circumstances @@ -841,13 +850,13 @@ emit_negation(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) */ struct prog_instruction *inst; - emit(vt, n->Children[0], prog); + emit(emitInfo, n->Children[0]); if (!n->Store) - if (!alloc_temp_storage(vt, n, n->Children[0]->Store->Size)) + if (!alloc_temp_storage(emitInfo, n, n->Children[0]->Store->Size)) return NULL; - inst = new_instruction(prog, OPCODE_MOV); + inst = new_instruction(emitInfo, OPCODE_MOV); storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); inst->SrcReg[0].NegateBase = NEGATE_XYZW; @@ -856,21 +865,22 @@ emit_negation(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) static struct prog_instruction * -emit_label(const slang_ir_node *n, struct gl_program *prog) +emit_label(slang_emit_info *emitInfo, const slang_ir_node *n) { assert(n->Label); assert(_slang_label_get_location(n->Label) < 0); - _slang_label_set_location(n->Label, prog->NumInstructions, prog); + _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions, + emitInfo->prog); return NULL; } static struct prog_instruction * -emit_cjump(slang_ir_node *n, struct gl_program *prog, GLuint zeroOrOne) +emit_cjump(slang_emit_info *emitInfo, slang_ir_node *n, GLuint zeroOrOne) { struct prog_instruction *inst; assert(n->Opcode == IR_CJUMP0 || n->Opcode == IR_CJUMP1); - inst = new_instruction(prog, OPCODE_BRA); + inst = new_instruction(emitInfo, OPCODE_BRA); if (zeroOrOne) inst->DstReg.CondMask = COND_NE; /* branch if non-zero */ else @@ -878,61 +888,61 @@ emit_cjump(slang_ir_node *n, struct gl_program *prog, GLuint zeroOrOne) inst->DstReg.CondSwizzle = SWIZZLE_X; inst->BranchTarget = _slang_label_get_location(n->Label); if (inst->BranchTarget < 0) { - _slang_label_add_reference(n->Label, prog->NumInstructions - 1); + _slang_label_add_reference(n->Label, emitInfo->prog->NumInstructions - 1); } return inst; } static struct prog_instruction * -emit_jump(slang_ir_node *n, struct gl_program *prog) +emit_jump(slang_emit_info *emitInfo, slang_ir_node *n) { struct prog_instruction *inst; - inst = new_instruction(prog, OPCODE_BRA); + inst = new_instruction(emitInfo, OPCODE_BRA); inst->DstReg.CondMask = COND_TR; /* always branch */ inst->BranchTarget = _slang_label_get_location(n->Label); if (inst->BranchTarget < 0) { - _slang_label_add_reference(n->Label, prog->NumInstructions - 1); + _slang_label_add_reference(n->Label, emitInfo->prog->NumInstructions - 1); } return inst; } static struct prog_instruction * -emit_kill(struct gl_program *prog) +emit_kill(slang_emit_info *emitInfo) { struct prog_instruction *inst; /* NV-KILL - discard fragment depending on condition code. * Note that ARB-KILL depends on sign of vector operand. */ - inst = new_instruction(prog, OPCODE_KIL_NV); + inst = new_instruction(emitInfo, OPCODE_KIL_NV); inst->DstReg.CondMask = COND_TR; /* always branch */ return inst; } static struct prog_instruction * -emit_tex(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_tex(slang_emit_info *emitInfo, slang_ir_node *n) { struct prog_instruction *inst; if (n->Opcode == IR_TEX) { - inst = new_instruction(prog, OPCODE_TEX); + inst = new_instruction(emitInfo, OPCODE_TEX); } else if (n->Opcode == IR_TEXB) { - inst = new_instruction(prog, OPCODE_TXB); + inst = new_instruction(emitInfo, OPCODE_TXB); } else { assert(n->Opcode == IR_TEXP); - inst = new_instruction(prog, OPCODE_TXP); + inst = new_instruction(emitInfo, OPCODE_TXP); } if (!n->Store) - if (!alloc_temp_storage(vt, n, 4)) + if (!alloc_temp_storage(emitInfo, n, 4)) return NULL; storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - (void) emit(vt, n->Children[1], prog); + (void) emit(emitInfo, n->Children[1]); /* Child[1] is the coord */ storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); @@ -951,29 +961,29 @@ emit_tex(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) static struct prog_instruction * -emit_move(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_move(slang_emit_info *emitInfo, slang_ir_node *n) { struct prog_instruction *inst; /* rhs */ assert(n->Children[1]); - inst = emit(vt, n->Children[1], prog); + inst = emit(emitInfo, n->Children[1]); assert(n->Children[1]->Store->Index >= 0); /* lhs */ - emit(vt, n->Children[0], prog); + emit(emitInfo, n->Children[0]); assert(!n->Store); n->Store = n->Children[0]->Store; #if PEEPHOLE_OPTIMIZATIONS - if (inst && _slang_is_temp(vt, n->Children[1]->Store)) { + if (inst && _slang_is_temp(emitInfo->vt, n->Children[1]->Store)) { /* 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_temp(vt, n->Children[1]->Store); + _slang_free_temp(emitInfo->vt, n->Children[1]->Store); *n->Children[1]->Store = *n->Children[0]->Store; /* fixup the prev (RHS) instruction */ assert(n->Children[0]->Store->Index >= 0); @@ -994,7 +1004,7 @@ emit_move(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) dstStore.Size = 4; srcStore.Size = 4; while (size >= 4) { - inst = new_instruction(prog, OPCODE_MOV); + inst = new_instruction(emitInfo, OPCODE_MOV); inst->Comment = _mesa_strdup("IR_MOVE block"); storage_to_dst_reg(&inst->DstReg, &dstStore, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], &srcStore); @@ -1006,31 +1016,31 @@ emit_move(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) else { /* single register move */ char *srcAnnot, *dstAnnot; - inst = new_instruction(prog, OPCODE_MOV); + inst = new_instruction(emitInfo, OPCODE_MOV); assert(n->Children[0]->Store->Index >= 0); assert(n->Children[0]->Store->Index < 16); storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); - dstAnnot = storage_annotation(n->Children[0], prog); - srcAnnot = storage_annotation(n->Children[1], prog); + dstAnnot = storage_annotation(n->Children[0], emitInfo->prog); + srcAnnot = storage_annotation(n->Children[1], emitInfo->prog); inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, srcAnnot, NULL, NULL); } - free_temp_storage(vt, n->Children[1]); + free_temp_storage(emitInfo->vt, n->Children[1]); return inst; } } static struct prog_instruction * -emit_cond(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_cond(slang_emit_info *emitInfo, slang_ir_node *n) { /* Conditional expression (in if/while/for stmts). * Need to update condition code register. * Next instruction is typically an IR_CJUMP0/1. */ /* last child expr instruction: */ - struct prog_instruction *inst = emit(vt, n->Children[0], prog); + struct prog_instruction *inst = emit(emitInfo, n->Children[0]); if (inst) { /* set inst's CondUpdate flag */ inst->CondUpdate = GL_TRUE; @@ -1043,13 +1053,13 @@ emit_cond(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) * Note: must use full 4-component vector since all four * condition codes must be set identically. */ - if (!alloc_temp_storage(vt, n, 4)) + if (!alloc_temp_storage(emitInfo, n, 4)) return NULL; - inst = new_instruction(prog, OPCODE_MOV); + inst = new_instruction(emitInfo, 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); - _slang_free_temp(vt, n->Store); + _slang_free_temp(emitInfo->vt, n->Store); inst->Comment = _mesa_strdup("COND expr"); return inst; /* XXX or null? */ } @@ -1060,7 +1070,7 @@ emit_cond(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) * Logical-NOT */ static struct prog_instruction * -emit_not(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_not(slang_emit_info *emitInfo, slang_ir_node *n) { GLfloat zero = 0.0; slang_ir_storage st; @@ -1069,23 +1079,23 @@ emit_not(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) /* need zero constant */ st.File = PROGRAM_CONSTANT; st.Size = 1; - st.Index = _mesa_add_unnamed_constant(prog->Parameters, &zero, + st.Index = _mesa_add_unnamed_constant(emitInfo->prog->Parameters, &zero, 1, &st.Swizzle); /* child expr */ - (void) emit(vt, n->Children[0], prog); + (void) emit(emitInfo, n->Children[0]); /* XXXX if child instr is SGT convert to SLE, if SEQ, SNE, etc */ if (!n->Store) - if (!alloc_temp_storage(vt, n, n->Children[0]->Store->Size)) + if (!alloc_temp_storage(emitInfo, n, n->Children[0]->Store->Size)) return NULL; - inst = new_instruction(prog, OPCODE_SEQ); + inst = new_instruction(emitInfo, OPCODE_SEQ); storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); storage_to_src_reg(&inst->SrcReg[1], &st); - free_temp_storage(vt, n->Children[0]); + free_temp_storage(emitInfo->vt, n->Children[0]); inst->Comment = _mesa_strdup("NOT"); return inst; @@ -1093,46 +1103,47 @@ emit_not(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) static struct prog_instruction * -emit_if(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_if(slang_emit_info *emitInfo, slang_ir_node *n) { + struct gl_program *prog = emitInfo->prog; struct prog_instruction *ifInst; - GLuint ifInstLoc, elseInstLoc; + GLuint ifInstLoc, elseInstLoc = 0; - emit(vt, n->Children[0], prog); /* the condition */ + emit(emitInfo, n->Children[0]); /* the condition */ ifInstLoc = prog->NumInstructions; if (EmitHighLevelInstructions) { - ifInst = new_instruction(prog, OPCODE_IF); + ifInst = new_instruction(emitInfo, OPCODE_IF); ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ ifInst->DstReg.CondSwizzle = SWIZZLE_X; } else { /* conditional jump to else, or endif */ - ifInst = new_instruction(prog, OPCODE_BRA); + ifInst = new_instruction(emitInfo, OPCODE_BRA); ifInst->DstReg.CondMask = COND_EQ; /* BRA if cond is zero */ ifInst->DstReg.CondSwizzle = SWIZZLE_X; ifInst->Comment = _mesa_strdup("if zero"); } /* if body */ - emit(vt, n->Children[1], prog); + emit(emitInfo, n->Children[1]); if (n->Children[2]) { /* have else body */ elseInstLoc = prog->NumInstructions; if (EmitHighLevelInstructions) { - (void) new_instruction(prog, OPCODE_ELSE); + (void) new_instruction(emitInfo, OPCODE_ELSE); } else { /* jump to endif instruction */ struct prog_instruction *inst; - inst = new_instruction(prog, OPCODE_BRA); + inst = new_instruction(emitInfo, OPCODE_BRA); inst->Comment = _mesa_strdup("else"); inst->DstReg.CondMask = COND_TR; /* always branch */ } ifInst = prog->Instructions + ifInstLoc; ifInst->BranchTarget = prog->NumInstructions; - emit(vt, n->Children[2], prog); + emit(emitInfo, n->Children[2]); } else { /* no else body */ @@ -1141,7 +1152,7 @@ emit_if(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } if (EmitHighLevelInstructions) { - (void) new_instruction(prog, OPCODE_ENDIF); + (void) new_instruction(emitInfo, OPCODE_ENDIF); } if (n->Children[2]) { @@ -1154,8 +1165,9 @@ emit_if(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) static struct prog_instruction * -emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_loop(slang_emit_info *emitInfo, slang_ir_node *n) { + struct gl_program *prog = emitInfo->prog; struct prog_instruction *beginInst, *endInst; GLuint beginInstLoc, endInstLoc; slang_ir_node *ir; @@ -1163,20 +1175,20 @@ emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) /* emit OPCODE_BGNLOOP */ beginInstLoc = prog->NumInstructions; if (EmitHighLevelInstructions) { - (void) new_instruction(prog, OPCODE_BGNLOOP); + (void) new_instruction(emitInfo, OPCODE_BGNLOOP); } /* body */ - emit(vt, n->Children[0], prog); + emit(emitInfo, n->Children[0]); endInstLoc = prog->NumInstructions; if (EmitHighLevelInstructions) { /* emit OPCODE_ENDLOOP */ - endInst = new_instruction(prog, OPCODE_ENDLOOP); + endInst = new_instruction(emitInfo, OPCODE_ENDLOOP); } else { /* emit unconditional BRA-nch */ - endInst = new_instruction(prog, OPCODE_BRA); + endInst = new_instruction(emitInfo, OPCODE_BRA); endInst->DstReg.CondMask = COND_TR; /* always true */ } /* end instruction's BranchTarget points to top of loop */ @@ -1222,18 +1234,18 @@ emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted. */ static struct prog_instruction * -emit_cont_break(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_cont_break(slang_emit_info *emitInfo, slang_ir_node *n) { gl_inst_opcode opcode; struct prog_instruction *inst; - n->InstLocation = prog->NumInstructions; + n->InstLocation = emitInfo->prog->NumInstructions; if (EmitHighLevelInstructions) { opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK; } else { opcode = OPCODE_BRA; } - inst = new_instruction(prog, opcode); + inst = new_instruction(emitInfo, opcode); inst->DstReg.CondMask = COND_TR; /* always true */ return inst; } @@ -1244,18 +1256,18 @@ emit_cont_break(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted. */ static struct prog_instruction * -emit_cont_break_if(slang_var_table *vt, slang_ir_node *n, - struct gl_program *prog, GLboolean breakTrue) +emit_cont_break_if(slang_emit_info *emitInfo, slang_ir_node *n, + GLboolean breakTrue) { gl_inst_opcode opcode; struct prog_instruction *inst; /* evaluate condition expr, setting cond codes */ - inst = emit(vt, n->Children[0], prog); + inst = emit(emitInfo, n->Children[0]); assert(inst); inst->CondUpdate = GL_TRUE; - n->InstLocation = prog->NumInstructions; + n->InstLocation = emitInfo->prog->NumInstructions; if (EmitHighLevelInstructions) { if (n->Opcode == IR_CONT_IF_TRUE || n->Opcode == IR_CONT_IF_FALSE) @@ -1266,7 +1278,7 @@ emit_cont_break_if(slang_var_table *vt, slang_ir_node *n, else { opcode = OPCODE_BRA; } - inst = new_instruction(prog, opcode); + inst = new_instruction(emitInfo, opcode); inst->DstReg.CondMask = breakTrue ? COND_NE : COND_EQ; return inst; } @@ -1292,12 +1304,12 @@ fix_swizzle(GLuint swizzle) static struct prog_instruction * -emit_swizzle(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n) { GLuint swizzle; /* swizzled storage access */ - (void) emit(vt, n->Children[0], prog); + (void) emit(emitInfo, n->Children[0]); /* "pull-up" the child's storage info, applying our swizzle info */ n->Store->File = n->Children[0]->Store->File; @@ -1329,15 +1341,14 @@ emit_swizzle(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) * element represented by this node. */ static struct prog_instruction * -emit_array_element(slang_var_table *vt, slang_ir_node *n, - struct gl_program *prog) +emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n) { assert(n->Store); assert(n->Store->File != PROGRAM_UNDEFINED); assert(n->Store->Size > 0); if (n->Store->File == PROGRAM_STATE_VAR) { - n->Store->Index = _slang_alloc_statevar(n, prog->Parameters); + n->Store->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters); return NULL; } @@ -1363,11 +1374,10 @@ emit_array_element(slang_var_table *vt, slang_ir_node *n, * Resolve storage for accessing a structure field. */ static struct prog_instruction * -emit_struct_field(slang_var_table *vt, slang_ir_node *n, - struct gl_program *prog) +emit_struct_field(slang_emit_info *emitInfo, slang_ir_node *n) { if (n->Store->File == PROGRAM_STATE_VAR) { - n->Store->Index = _slang_alloc_statevar(n, prog->Parameters); + n->Store->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters); return NULL; } else { @@ -1378,7 +1388,7 @@ emit_struct_field(slang_var_table *vt, slang_ir_node *n, static struct prog_instruction * -emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +emit(slang_emit_info *emitInfo, slang_ir_node *n) { struct prog_instruction *inst; if (!n) @@ -1389,17 +1399,17 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) /* sequence of two sub-trees */ assert(n->Children[0]); assert(n->Children[1]); - emit(vt, n->Children[0], prog); - inst = emit(vt, n->Children[1], prog); + emit(emitInfo, n->Children[0]); + inst = emit(emitInfo, n->Children[1]); assert(!n->Store); n->Store = n->Children[1]->Store; return inst; case IR_SCOPE: /* new variable scope */ - _slang_push_var_table(vt); - inst = emit(vt, n->Children[0], prog); - _slang_pop_var_table(vt); + _slang_push_var_table(emitInfo->vt); + inst = emit(emitInfo, n->Children[0]); + _slang_pop_var_table(emitInfo->vt); return inst; case IR_VAR_DECL: @@ -1410,14 +1420,20 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) assert(n->Store->Index < 0); if (!n->Var || n->Var->isTemp) { /* a nameless/temporary variable, will be freed after first use */ - if (!_slang_alloc_temp(vt, n->Store)) - RETURN_ERROR("Ran out of registers, too many temporaries", 0); + if (!_slang_alloc_temp(emitInfo->vt, n->Store)) { + slang_info_log_error(emitInfo->log, + "Ran out of registers, too many temporaries"); + return NULL; + } } else { /* a regular variable */ - _slang_add_variable(vt, n->Var); - if (!_slang_alloc_var(vt, n->Store)) - RETURN_ERROR("Ran out of registers, too many variables", 0); + _slang_add_variable(emitInfo->vt, n->Var); + if (!_slang_alloc_var(emitInfo->vt, n->Store)) { + slang_info_log_error(emitInfo->log, + "Ran out of registers, too many variables"); + return NULL; + } /* printf("IR_VAR_DECL %s %d store %p\n", (char*) n->Var->a_name, n->Store->Index, (void*) n->Store); @@ -1432,7 +1448,7 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) _mesa_swizzle_string(n->Store->Swizzle, 0, GL_FALSE), (char *) n->Var->a_name, n->Store->Size); - inst = new_instruction(prog, OPCODE_NOP); + inst = new_instruction(emitInfo, OPCODE_NOP); inst->Comment = _mesa_strdup(s); return inst; } @@ -1447,7 +1463,7 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) if (n->Store->File == PROGRAM_STATE_VAR && n->Store->Index < 0) { - n->Store->Index = _slang_alloc_statevar(n, prog->Parameters); + n->Store->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters); } if (n->Store->Index < 0) { @@ -1458,11 +1474,11 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) break; case IR_ELEMENT: - return emit_array_element(vt, n, prog); + return emit_array_element(emitInfo, n); case IR_FIELD: - return emit_struct_field(vt, n, prog); + return emit_struct_field(emitInfo, n); case IR_SWIZZLE: - return emit_swizzle(vt, n, prog); + return emit_swizzle(emitInfo, n); case IR_I_TO_F: { @@ -1504,67 +1520,68 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_EXP2: /* trinary operators */ case IR_LRP: - return emit_arith(vt, n, prog); + return emit_arith(emitInfo, n); case IR_CLAMP: - return emit_clamp(vt, n, prog); + return emit_clamp(emitInfo, n); case IR_TEX: case IR_TEXB: case IR_TEXP: - return emit_tex(vt, n, prog); + return emit_tex(emitInfo, n); case IR_NEG: - return emit_negation(vt, n, prog); + return emit_negation(emitInfo, n); case IR_FLOAT: /* find storage location for this float constant */ - n->Store->Index = _mesa_add_unnamed_constant(prog->Parameters, n->Value, + n->Store->Index = _mesa_add_unnamed_constant(emitInfo->prog->Parameters, n->Value, n->Store->Size, &n->Store->Swizzle); if (n->Store->Index < 0) { - RETURN_ERROR("Ran out of space for constants.", 0); + slang_info_log_error(emitInfo->log, "Ran out of space for constants"); + return NULL; } return NULL; case IR_MOVE: - return emit_move(vt, n, prog); + return emit_move(emitInfo, n); case IR_COND: - return emit_cond(vt, n, prog); + return emit_cond(emitInfo, n); case IR_NOT: - return emit_not(vt, n, prog); + return emit_not(emitInfo, n); case IR_LABEL: - return emit_label(n, prog); + return emit_label(emitInfo, n); case IR_JUMP: - return emit_jump(n, prog); + return emit_jump(emitInfo, n); case IR_CJUMP0: - return emit_cjump(n, prog, 0); + return emit_cjump(emitInfo, n, 0); case IR_CJUMP1: - return emit_cjump(n, prog, 1); + return emit_cjump(emitInfo, n, 1); case IR_KILL: - return emit_kill(prog); + return emit_kill(emitInfo); case IR_IF: - return emit_if(vt, n, prog); + return emit_if(emitInfo, n); case IR_LOOP: - return emit_loop(vt, n, prog); + return emit_loop(emitInfo, n); case IR_BREAK_IF_FALSE: case IR_CONT_IF_FALSE: - return emit_cont_break_if(vt, n, prog, GL_FALSE); + return emit_cont_break_if(emitInfo, n, GL_FALSE); case IR_BREAK_IF_TRUE: case IR_CONT_IF_TRUE: - return emit_cont_break_if(vt, n, prog, GL_TRUE); + return emit_cont_break_if(emitInfo, n, GL_TRUE); case IR_BREAK: /* fall-through */ case IR_CONT: - return emit_cont_break(vt, n, prog); + return emit_cont_break(emitInfo, n); case IR_BEGIN_SUB: - return new_instruction(prog, OPCODE_BGNSUB); + return new_instruction(emitInfo, OPCODE_BGNSUB); case IR_END_SUB: - return new_instruction(prog, OPCODE_ENDSUB); + return new_instruction(emitInfo, OPCODE_ENDSUB); case IR_RETURN: - return new_instruction(prog, OPCODE_RET); + return new_instruction(emitInfo, OPCODE_RET); case IR_NOP: return NULL; @@ -1579,16 +1596,22 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) GLboolean _slang_emit_code(slang_ir_node *n, slang_var_table *vt, - struct gl_program *prog, GLboolean withEnd) + struct gl_program *prog, GLboolean withEnd, + slang_info_log *log) { GLboolean success; + slang_emit_info emitInfo; + + emitInfo.log = log; + emitInfo.vt = vt; + emitInfo.prog = prog; - (void) emit(vt, n, prog); + (void) emit(&emitInfo, n); /* finish up by adding the END opcode to program */ if (withEnd) { struct prog_instruction *inst; - inst = new_instruction(prog, OPCODE_END); + inst = new_instruction(&emitInfo, OPCODE_END); } success = GL_TRUE; diff --git a/src/mesa/shader/slang/slang_emit.h b/src/mesa/shader/slang/slang_emit.h index 1b792402dac..13ba6d7d6c7 100644 --- a/src/mesa/shader/slang/slang_emit.h +++ b/src/mesa/shader/slang/slang_emit.h @@ -42,7 +42,8 @@ _slang_new_ir_storage(enum register_file file, GLint index, GLint size); extern GLboolean _slang_emit_code(slang_ir_node *n, slang_var_table *vartable, - struct gl_program *prog, GLboolean withEnd); + struct gl_program *prog, GLboolean withEnd, + slang_info_log *log); #endif /* SLANG_EMIT_H */ diff --git a/src/mesa/shader/slang/slang_error.c b/src/mesa/shader/slang/slang_error.c deleted file mode 100644 index bfa8e80a05c..00000000000 --- a/src/mesa/shader/slang/slang_error.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "imports.h" -#include "slang_error.h" - - -static char ErrorText[10000]; -static char FormattedErrorText[10000]; -static int ErrorPos; - - -void -_slang_reset_error(void) -{ - ErrorText[0] = 0; - ErrorPos = -1; -} - - -/** - * Record an error message, if one hasn't been recorded already. - */ -void -_slang_record_error(const char *msg1, const char *msg2, - GLint pos, const char *file, int line) -{ - /* don't overwrite a previously recorded error */ - if (!ErrorText[0]) { - _mesa_sprintf(ErrorText, "%s %s", msg1, msg2); - ErrorPos = -1; -#ifdef DEBUG - fprintf(stderr, "Mesa shader compile error: %s %s at %d (%s line %d)\n", - msg1, msg2, pos, file, line); -#endif - } - abort(); -} - - -/** - * Return formatted error text. - */ -const char * -_slang_error_text(void) -{ - /* - * NVIDIA formats errors like this: - * (LINE_NUMBER) : error ERROR_CODE: ERROR_TEXT - * Example: - * (7) : error C1048: invalid character 'P' in swizzle "P" - */ - _mesa_sprintf(FormattedErrorText, - "(%d) : error: %s", ErrorPos, ErrorText); - return FormattedErrorText; -} - diff --git a/src/mesa/shader/slang/slang_error.h b/src/mesa/shader/slang/slang_error.h deleted file mode 100644 index d35ae83fba0..00000000000 --- a/src/mesa/shader/slang/slang_error.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef SLANG_ERROR_H -#define SLANG_ERROR_H - - -extern void -_slang_reset_error(void); - - -extern void -_slang_record_error(const char *msg1, const char *msg2, - GLint pos, const char *file, int line); - - -extern const char * -_slang_error_text(void); - - -/** - * Record a compilation error, single string message. - */ -#define RETURN_ERROR(MSG, POS) \ -do { \ - _slang_record_error(MSG, "", POS, __FILE__, __LINE__); \ - return GL_FALSE; \ -} while (0) - - -/** - * Record a compilation error, two-string message. - */ -#define RETURN_ERROR2(MSG1, MSG2, POS) \ -do { \ - _slang_record_error(MSG1, MSG2, POS, __FILE__, __LINE__); \ - return GL_FALSE; \ -} while (0) - - -/** - * Record a nil error. Either a real error message or out of memory should - * have already been recorded. - */ -#define RETURN_NIL() \ -do { \ - _slang_record_error("unknown", "", -1, __FILE__, __LINE__); \ - return GL_FALSE; \ -} while (0) - - -/** - * Used to report an out of memory condition. - */ -#define RETURN_OUT_OF_MEMORY() \ -do { \ - _slang_record_error("Out of memory", "", -1, __FILE__, __LINE__); \ - return GL_FALSE; \ -} while (0) - - - - -#endif /* SLANG_ERROR_H */ diff --git a/src/mesa/shader/slang/slang_log.c b/src/mesa/shader/slang/slang_log.c new file mode 100644 index 00000000000..b6545b2c2e9 --- /dev/null +++ b/src/mesa/shader/slang/slang_log.c @@ -0,0 +1,128 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "imports.h" +#include "slang_log.h" +#include "slang_utility.h" + + + +static char *out_of_memory = "Error: Out of memory.\n"; + +void +slang_info_log_construct(slang_info_log * log) +{ + log->text = NULL; + log->dont_free_text = 0; +} + +void +slang_info_log_destruct(slang_info_log * log) +{ + if (!log->dont_free_text) + slang_alloc_free(log->text); +} + +static int +slang_info_log_message(slang_info_log * log, const char *prefix, + const char *msg) +{ + GLuint size; + + if (log->dont_free_text) + return 0; + size = slang_string_length(msg) + 2; + if (prefix != NULL) + size += slang_string_length(prefix) + 2; + if (log->text != NULL) { + GLuint old_len = slang_string_length(log->text); + log->text = (char *) + slang_alloc_realloc(log->text, old_len + 1, old_len + size); + } + else { + log->text = (char *) (slang_alloc_malloc(size)); + if (log->text != NULL) + log->text[0] = '\0'; + } + if (log->text == NULL) + return 0; + if (prefix != NULL) { + slang_string_concat(log->text, prefix); + slang_string_concat(log->text, ": "); + } + slang_string_concat(log->text, msg); + slang_string_concat(log->text, "\n"); + return 1; +} + +int +slang_info_log_print(slang_info_log * log, const char *msg, ...) +{ + va_list va; + char buf[1024]; + + va_start(va, msg); + _mesa_vsprintf(buf, msg, va); + va_end(va); + return slang_info_log_message(log, NULL, buf); +} + +int +slang_info_log_error(slang_info_log * log, const char *msg, ...) +{ + va_list va; + char buf[1024]; + + va_start(va, msg); + _mesa_vsprintf(buf, msg, va); + va_end(va); + if (slang_info_log_message(log, "Error", buf)) + return 1; + slang_info_log_memory(log); + return 0; +} + +int +slang_info_log_warning(slang_info_log * log, const char *msg, ...) +{ + va_list va; + char buf[1024]; + + va_start(va, msg); + _mesa_vsprintf(buf, msg, va); + va_end(va); + if (slang_info_log_message(log, "Warning", buf)) + return 1; + slang_info_log_memory(log); + return 0; +} + +void +slang_info_log_memory(slang_info_log * log) +{ + if (!slang_info_log_message(log, "Error", "Out of memory.")) { + log->dont_free_text = 1; + log->text = out_of_memory; + } +} diff --git a/src/mesa/shader/slang/slang_log.h b/src/mesa/shader/slang/slang_log.h new file mode 100644 index 00000000000..e4ca3a22f11 --- /dev/null +++ b/src/mesa/shader/slang/slang_log.h @@ -0,0 +1,56 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef SLANG_LOG_H +#define SLANG_LOG_H + + +typedef struct slang_info_log_ +{ + char *text; + int dont_free_text; +} slang_info_log; + + +extern void +slang_info_log_construct(slang_info_log *); + +extern void +slang_info_log_destruct(slang_info_log *); + +extern int +slang_info_log_print(slang_info_log *, const char *, ...); + +extern int +slang_info_log_error(slang_info_log *, const char *, ...); + +extern int +slang_info_log_warning(slang_info_log *, const char *, ...); + +extern void +slang_info_log_memory(slang_info_log *); + + +#endif /* SLANG_LOG_H */ diff --git a/src/mesa/shader/slang/slang_preprocess.h b/src/mesa/shader/slang/slang_preprocess.h index f83e6e6e3fc..d8eb12e4ff2 100644 --- a/src/mesa/shader/slang/slang_preprocess.h +++ b/src/mesa/shader/slang/slang_preprocess.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.6 + * Version: 6.5.3 * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,24 +22,19 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_PREPROCESS_H +#ifndef SLANG_PREPROCESS_H #define SLANG_PREPROCESS_H #include "slang_compile.h" +#include "slang_log.h" -#if defined __cplusplus -extern "C" { -#endif -GLboolean +extern GLboolean _slang_preprocess_version (const char *, GLuint *, GLuint *, slang_info_log *); -GLboolean -_slang_preprocess_directives (slang_string *output, const char *input, slang_info_log *); +extern GLboolean +_slang_preprocess_directives (slang_string *output, const char *input, + slang_info_log *); -#ifdef __cplusplus -} -#endif - -#endif +#endif /* SLANG_PREPROCESS_H */ diff --git a/src/mesa/shader/slang/slang_simplify.c b/src/mesa/shader/slang/slang_simplify.c index 07b4ae27600..87b117874fd 100644 --- a/src/mesa/shader/slang/slang_simplify.c +++ b/src/mesa/shader/slang/slang_simplify.c @@ -292,7 +292,7 @@ _slang_simplify(slang_operation *oper, GLboolean _slang_adapt_call(slang_operation *callOper, const slang_function *fun, const slang_name_space * space, - slang_atom_pool * atoms) + slang_atom_pool * atoms, slang_info_log *log) { const GLboolean haveRetValue = _slang_function_has_return_value(fun); const int numParams = fun->param_count - haveRetValue; @@ -317,7 +317,7 @@ _slang_adapt_call(slang_operation *callOper, const slang_function *fun, if (!slang_typeinfo_construct(&argType)) return GL_FALSE; if (!_slang_typeof_operation_(&callOper->children[i], space, - &argType, atoms)) { + &argType, atoms, log)) { slang_typeinfo_destruct(&argType); return GL_FALSE; } @@ -392,7 +392,7 @@ _slang_adapt_call(slang_operation *callOper, const slang_function *fun, if (!slang_typeinfo_construct(&argType)) return GL_FALSE; if (!_slang_typeof_operation_(&callOper->children[i], space, - &argType, atoms)) { + &argType, atoms, log)) { slang_typeinfo_destruct(&argType); return GL_FALSE; } diff --git a/src/mesa/shader/slang/slang_simplify.h b/src/mesa/shader/slang/slang_simplify.h index d6979a800a1..b3840ee9df8 100644 --- a/src/mesa/shader/slang/slang_simplify.h +++ b/src/mesa/shader/slang/slang_simplify.h @@ -16,8 +16,7 @@ _slang_simplify(slang_operation *oper, extern GLboolean _slang_adapt_call(slang_operation *callOper, const slang_function *fun, const slang_name_space * space, - slang_atom_pool * atoms); - + slang_atom_pool * atoms, slang_info_log *log); #endif /* SLANG_SIMPLIFY_H */ diff --git a/src/mesa/shader/slang/slang_typeinfo.c b/src/mesa/shader/slang/slang_typeinfo.c index bbcc1c740c1..fe3834994dd 100644 --- a/src/mesa/shader/slang/slang_typeinfo.c +++ b/src/mesa/shader/slang/slang_typeinfo.c @@ -31,7 +31,7 @@ #include "imports.h" #include "slang_typeinfo.h" #include "slang_compile.h" -#include "slang_error.h" +#include "slang_log.h" #include "prog_instruction.h" @@ -302,14 +302,15 @@ typeof_existing_function(const char *name, const slang_operation * params, GLuint num_params, const slang_name_space * space, slang_type_specifier * spec, - slang_atom_pool * atoms) + slang_atom_pool * atoms, + slang_info_log *log) { slang_atom atom; GLboolean exists; atom = slang_atom_pool_atom(atoms, name); if (!_slang_typeof_function(atom, params, num_params, space, spec, - &exists, atoms)) + &exists, atoms, log)) return GL_FALSE; return exists; } @@ -319,7 +320,7 @@ _slang_typeof_operation(const slang_assemble_ctx * A, const slang_operation * op, slang_typeinfo * ti) { - return _slang_typeof_operation_(op, &A->space, ti, A->atoms); + return _slang_typeof_operation_(op, &A->space, ti, A->atoms, A->log); } @@ -335,7 +336,8 @@ GLboolean _slang_typeof_operation_(const slang_operation * op, const slang_name_space * space, slang_typeinfo * ti, - slang_atom_pool * atoms) + slang_atom_pool * atoms, + slang_info_log *log) { ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; @@ -364,7 +366,7 @@ _slang_typeof_operation_(const slang_operation * op, case SLANG_OPER_DIVASSIGN: case SLANG_OPER_PREINCREMENT: case SLANG_OPER_PREDECREMENT: - if (!_slang_typeof_operation_(op->children, space, ti, atoms)) + if (!_slang_typeof_operation_(op->children, space, ti, atoms, log)) return GL_FALSE; break; case SLANG_OPER_LITERAL_BOOL: @@ -431,18 +433,24 @@ _slang_typeof_operation_(const slang_operation * op, { slang_variable *var; var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); - if (var == NULL) - RETURN_ERROR2("undefined variable", (char *) op->a_id, 0); - if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) - RETURN_OUT_OF_MEMORY(); + if (!var) { + slang_info_log_error(log, "undefined variable '%s'", + (char *) op->a_id); + return GL_FALSE; + } + if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) { + slang_info_log_memory(log); + return GL_FALSE; + } ti->can_be_referenced = GL_TRUE; ti->array_len = var->array_len; } break; case SLANG_OPER_SEQUENCE: /* TODO: check [0] and [1] if they match */ - if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms)) - RETURN_NIL(); + if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms, log)) { + return GL_FALSE; + } ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; @@ -454,8 +462,9 @@ _slang_typeof_operation_(const slang_operation * op, /*case SLANG_OPER_ANDASSIGN: */ case SLANG_OPER_SELECT: /* TODO: check [1] and [2] if they match */ - if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms)) - RETURN_NIL(); + if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms, log)) { + return GL_FALSE; + } ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; @@ -466,35 +475,35 @@ _slang_typeof_operation_(const slang_operation * op, /*case SLANG_OPER_RSHIFT: */ case SLANG_OPER_ADD: if (!typeof_existing_function("+", op->children, 2, space, - &ti->spec, atoms)) - RETURN_NIL(); + &ti->spec, atoms, log)) + return GL_FALSE; break; case SLANG_OPER_SUBTRACT: if (!typeof_existing_function("-", op->children, 2, space, - &ti->spec, atoms)) - RETURN_NIL(); + &ti->spec, atoms, log)) + return GL_FALSE; break; case SLANG_OPER_MULTIPLY: if (!typeof_existing_function("*", op->children, 2, space, - &ti->spec, atoms)) - RETURN_NIL(); + &ti->spec, atoms, log)) + return GL_FALSE; break; case SLANG_OPER_DIVIDE: if (!typeof_existing_function("/", op->children, 2, space, - &ti->spec, atoms)) - RETURN_NIL(); + &ti->spec, atoms, log)) + return GL_FALSE; break; /*case SLANG_OPER_MODULUS: */ case SLANG_OPER_PLUS: - if (!_slang_typeof_operation_(op->children, space, ti, atoms)) - RETURN_NIL(); + if (!_slang_typeof_operation_(op->children, space, ti, atoms, log)) + return GL_FALSE; ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; case SLANG_OPER_MINUS: if (!typeof_existing_function("-", op->children, 1, space, - &ti->spec, atoms)) - RETURN_NIL(); + &ti->spec, atoms, log)) + return GL_FALSE; break; /*case SLANG_OPER_COMPLEMENT: */ case SLANG_OPER_SUBSCRIPT: @@ -502,23 +511,24 @@ _slang_typeof_operation_(const slang_operation * op, slang_typeinfo _ti; if (!slang_typeinfo_construct(&_ti)) - RETURN_NIL(); - if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) { + return GL_FALSE; + if (!_slang_typeof_operation_(op->children, space, &_ti, atoms, log)) { slang_typeinfo_destruct(&_ti); - RETURN_NIL(); + return GL_FALSE; } ti->can_be_referenced = _ti.can_be_referenced; if (_ti.spec.type == SLANG_SPEC_ARRAY) { if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) { slang_typeinfo_destruct(&_ti); - RETURN_NIL(); + return GL_FALSE; } } else { if (!_slang_type_is_vector(_ti.spec.type) && !_slang_type_is_matrix(_ti.spec.type)) { slang_typeinfo_destruct(&_ti); - RETURN_ERROR("cannot index a non-array type", 0); + slang_info_log_error(log, "cannot index a non-array type"); + return GL_FALSE; } ti->spec.type = _slang_type_base(_ti.spec.type); } @@ -530,8 +540,8 @@ _slang_typeof_operation_(const slang_operation * op, GLboolean exists; if (!_slang_typeof_function(op->a_id, op->children, op->num_children, - space, &ti->spec, &exists, atoms)) - RETURN_NIL(); + space, &ti->spec, &exists, atoms, log)) + return GL_FALSE; if (!exists) { slang_struct *s = slang_struct_scope_find(space->structs, op->a_id, GL_TRUE); @@ -540,14 +550,14 @@ _slang_typeof_operation_(const slang_operation * op, ti->spec._struct = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); if (ti->spec._struct == NULL) - RETURN_NIL(); + return GL_FALSE; if (!slang_struct_construct(ti->spec._struct)) { slang_alloc_free(ti->spec._struct); ti->spec._struct = NULL; - RETURN_NIL(); + return GL_FALSE; } if (!slang_struct_copy(ti->spec._struct, s)) - RETURN_NIL(); + return GL_FALSE; } else { const char *name; @@ -555,8 +565,10 @@ _slang_typeof_operation_(const slang_operation * op, name = slang_atom_pool_id(atoms, op->a_id); type = slang_type_specifier_type_from_string(name); - if (type == SLANG_SPEC_VOID) - RETURN_ERROR2("function not found", name, 0); + if (type == SLANG_SPEC_VOID) { + slang_info_log_error(log, "undefined function '%s'", name); + return GL_FALSE; + } ti->spec.type = type; } } @@ -567,10 +579,10 @@ _slang_typeof_operation_(const slang_operation * op, slang_typeinfo _ti; if (!slang_typeinfo_construct(&_ti)) - RETURN_NIL(); - if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) { + return GL_FALSE; + if (!_slang_typeof_operation_(op->children, space, &_ti, atoms, log)) { slang_typeinfo_destruct(&_ti); - RETURN_NIL(); + return GL_FALSE; } if (_ti.spec.type == SLANG_SPEC_STRUCT) { slang_variable *field; @@ -579,11 +591,11 @@ _slang_typeof_operation_(const slang_operation * op, GL_FALSE); if (field == NULL) { slang_typeinfo_destruct(&_ti); - RETURN_NIL(); + return GL_FALSE; } if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) { slang_typeinfo_destruct(&_ti); - RETURN_NIL(); + return GL_FALSE; } ti->can_be_referenced = _ti.can_be_referenced; } @@ -593,17 +605,19 @@ _slang_typeof_operation_(const slang_operation * op, slang_type_specifier_type base; /* determine the swizzle of the field expression */ -#if 000 +#if 000 /*XXX re-enable? */ if (!_slang_type_is_vector(_ti.spec.type)) { slang_typeinfo_destruct(&_ti); - RETURN_ERROR("Can't swizzle scalar expression", 0); + slang_info_log_error(log, "Can't swizzle scalar expression"); + return GL_FALSE; } #endif rows = _slang_type_dim(_ti.spec.type); swizzle = slang_atom_pool_id(atoms, op->a_id); if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) { slang_typeinfo_destruct(&_ti); - RETURN_ERROR("Bad swizzle", 0); + slang_info_log_error(log, "bad swizzle '%s'", swizzle); + return GL_FALSE; } ti->is_swizzled = GL_TRUE; ti->can_be_referenced = _ti.can_be_referenced @@ -674,13 +688,13 @@ _slang_typeof_operation_(const slang_operation * op, break; case SLANG_OPER_POSTINCREMENT: case SLANG_OPER_POSTDECREMENT: - if (!_slang_typeof_operation_(op->children, space, ti, atoms)) - RETURN_NIL(); + if (!_slang_typeof_operation_(op->children, space, ti, atoms, log)) + return GL_FALSE; ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; default: - RETURN_NIL(); + return GL_FALSE; } return GL_TRUE; @@ -693,7 +707,8 @@ _slang_typeof_operation_(const slang_operation * op, slang_function * _slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, const slang_operation * args, GLuint num_args, - const slang_name_space * space, slang_atom_pool * atoms) + const slang_name_space * space, slang_atom_pool * atoms, + slang_info_log *log) { GLuint i; @@ -713,7 +728,7 @@ _slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, if (!slang_typeinfo_construct(&ti)) return NULL; - if (!_slang_typeof_operation_(&args[j], space, &ti, atoms)) { + if (!_slang_typeof_operation_(&args[j], space, &ti, atoms, log)) { slang_typeinfo_destruct(&ti); return NULL; } @@ -737,7 +752,7 @@ _slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, } if (funcs->outer_scope != NULL) return _slang_locate_function(funcs->outer_scope, a_name, args, - num_args, space, atoms); + num_args, space, atoms, log); return NULL; } @@ -757,10 +772,10 @@ _slang_typeof_function(slang_atom a_name, const slang_operation * params, GLuint num_params, const slang_name_space * space, slang_type_specifier * spec, GLboolean * exists, - slang_atom_pool * atoms) + slang_atom_pool *atoms, slang_info_log *log) { slang_function *fun = _slang_locate_function(space->funcs, a_name, params, - num_params, space, atoms); + num_params, space, atoms, log); *exists = fun != NULL; if (!fun) return GL_TRUE; /* yes, not false */ diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h index 3115b71e085..62cf0009d3c 100644 --- a/src/mesa/shader/slang/slang_typeinfo.h +++ b/src/mesa/shader/slang/slang_typeinfo.h @@ -27,6 +27,7 @@ #include "imports.h" #include "mtypes.h" +#include "slang_log.h" #include "slang_utility.h" #include "slang_vartable.h" @@ -60,6 +61,7 @@ typedef struct slang_assemble_ctx_ slang_name_space space; struct gl_program *program; slang_var_table *vartable; + slang_info_log *log; struct slang_function_ *CurFunction; struct slang_ir_node_ *CurLoop; } slang_assemble_ctx; @@ -70,7 +72,7 @@ _slang_locate_function(const struct slang_function_scope_ *funcs, slang_atom name, const struct slang_operation_ *params, GLuint num_params, const slang_name_space *space, - slang_atom_pool *); + slang_atom_pool *atoms, slang_info_log *log); extern GLboolean @@ -170,7 +172,8 @@ _slang_typeof_operation(const slang_assemble_ctx *, extern GLboolean _slang_typeof_operation_(const struct slang_operation_ *, const slang_name_space *, - slang_typeinfo *, slang_atom_pool *); + slang_typeinfo *, slang_atom_pool *, + slang_info_log *log); /** * Retrieves type of a function prototype, if one exists. @@ -182,7 +185,7 @@ _slang_typeof_function(slang_atom a_name, const struct slang_operation_ *params, GLuint num_params, const slang_name_space *, slang_type_specifier *spec, GLboolean *exists, - slang_atom_pool *); + slang_atom_pool *, slang_info_log *log); extern GLboolean _slang_type_is_matrix(slang_type_specifier_type); diff --git a/src/mesa/sources b/src/mesa/sources index a7bbc020125..628599c3c59 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -179,10 +179,10 @@ SLANG_SOURCES = \ shader/slang/slang_compile_struct.c \ shader/slang/slang_compile_variable.c \ shader/slang/slang_emit.c \ - shader/slang/slang_error.c \ shader/slang/slang_label.c \ shader/slang/slang_library_noise.c \ shader/slang/slang_link.c \ + shader/slang/slang_log.c \ shader/slang/slang_preprocess.c \ shader/slang/slang_print.c \ shader/slang/slang_simplify.c \ |