r300/compiler: Lay groundwork for better error handling
authorNicolai Hähnle <nhaehnle@gmail.com>
Thu, 23 Jul 2009 19:38:28 +0000 (21:38 +0200)
committerNicolai Hähnle <nhaehnle@gmail.com>
Mon, 27 Jul 2009 18:32:06 +0000 (20:32 +0200)
Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
12 files changed:
src/mesa/drivers/dri/r300/compiler/r300_fragprog.h
src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
src/mesa/drivers/dri/r300/compiler/r500_fragprog.h
src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
src/mesa/drivers/dri/r300/r300_fragprog_common.c
src/mesa/drivers/dri/r300/r300_vertprog.c

index 21507bd8e06ce264be1d083148f8951fae8464dc..2d094c3618623ab29a65eca64b6eefa2b911d5a5 100644 (file)
@@ -40,7 +40,7 @@
 #include "radeon_program.h"
 
 
-extern GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);
+extern void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);
 
 extern void r300FragmentProgramDump(struct rX00_fragment_program_code *c);
 
index 672b36532c9a6bfd6fa0b10ab84f446680a5fab0..f2472d6ce1ca2e90016a96dee58fb4bae0464b57 100644 (file)
@@ -51,7 +51,7 @@
        struct r300_fragment_program_code *code = &c->code->code.r300
 
 #define error(fmt, args...) do {                       \
-               fprintf(stderr, "%s::%s(): " fmt "\n",  \
+               rc_error(&c->Base, "%s::%s(): " fmt "\n",       \
                        __FILE__, __FUNCTION__, ##args);        \
        } while(0)
 
@@ -91,7 +91,7 @@ static void use_temporary(struct r300_fragment_program_code *code, GLuint index)
 }
 
 
-static GLuint translate_rgb_opcode(GLuint opcode)
+static GLuint translate_rgb_opcode(struct r300_fragment_program_compiler * c, GLuint opcode)
 {
        switch(opcode) {
        case OPCODE_CMP: return R300_ALU_OUTC_CMP;
@@ -110,7 +110,7 @@ static GLuint translate_rgb_opcode(GLuint opcode)
        }
 }
 
-static GLuint translate_alpha_opcode(GLuint opcode)
+static GLuint translate_alpha_opcode(struct r300_fragment_program_compiler * c, GLuint opcode)
 {
        switch(opcode) {
        case OPCODE_CMP: return R300_ALU_OUTA_CMP;
@@ -148,8 +148,8 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst)
        int j;
        code->node[code->cur_node].alu_end++;
 
-       code->alu.inst[ip].inst0 = translate_rgb_opcode(inst->RGB.Opcode);
-       code->alu.inst[ip].inst2 = translate_alpha_opcode(inst->Alpha.Opcode);
+       code->alu.inst[ip].inst0 = translate_rgb_opcode(c, inst->RGB.Opcode);
+       code->alu.inst[ip].inst2 = translate_alpha_opcode(c, inst->Alpha.Opcode);
 
        for(j = 0; j < 3; ++j) {
                GLuint src = inst->RGB.Src[j].Index | (inst->RGB.Src[j].Constant << 5);
@@ -326,7 +326,7 @@ static const struct radeon_pair_handler pair_handler = {
  * Final compilation step: Turn the intermediate radeon_program into
  * machine-readable instructions.
  */
-GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler)
+void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler)
 {
        struct r300_fragment_program_code *code = &compiler->code->code.r300;
 
@@ -334,12 +334,10 @@ GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *
        code->node[0].alu_end = -1;
        code->node[0].tex_end = -1;
 
-       if (!radeonPairProgram(&compiler->Base, &pair_handler, compiler))
-               return GL_FALSE;
-
-       if (!finish_node(compiler))
-               return GL_FALSE;
+       radeonPairProgram(&compiler->Base, &pair_handler, compiler);
+       if (compiler->Base.Error)
+               return;
 
-       return GL_TRUE;
+       finish_node(compiler);
 }
 
index 30fedb42118a0de32baac15c2f81b02518ab31a7..dae77a575ccbc0dbb1bbaec0ae49d047163145e3 100644 (file)
@@ -235,10 +235,8 @@ static void rewrite_depth_out(struct gl_program *prog)
        }
 }
 
-GLboolean r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
+void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
 {
-       GLboolean success = GL_FALSE;
-
        if (c->Base.Debug) {
                fflush(stdout);
                _mesa_printf("Fragment Program: Initial program:\n");
@@ -300,18 +298,16 @@ GLboolean r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c
        rc_mesa_to_rc_program(&c->Base, c->program);
 
        if (c->is_r500) {
-               success = r500BuildFragmentProgramHwCode(c);
+               r500BuildFragmentProgramHwCode(c);
        } else {
-               success = r300BuildFragmentProgramHwCode(c);
+               r300BuildFragmentProgramHwCode(c);
        }
 
-       if (!success || c->Base.Debug) {
+       if (c->Base.Debug) {
                if (c->is_r500) {
                        r500FragmentProgramDump(c->code);
                } else {
                        r300FragmentProgramDump(c->code);
                }
        }
-
-       return success;
 }
index a0e081fe6f8eb6fa65f23cacf903d4d15e9ada15..9edff6b0393f61a8b31a5941e65aeb80b875ba49 100644 (file)
@@ -384,22 +384,25 @@ static void t_inputs_outputs(struct r300_vertex_program_code *vp, struct gl_prog
        }
 }
 
-static GLboolean translate_vertex_program(struct r300_vertex_program_compiler * compiler)
+static void translate_vertex_program(struct r300_vertex_program_compiler * compiler)
 {
        struct prog_instruction *vpi = compiler->program->Instructions;
-       GLuint *inst;
 
        compiler->code->pos_end = 0;    /* Not supported yet */
        compiler->code->length = 0;
 
        t_inputs_outputs(compiler->code, compiler->program);
 
-       for (inst = compiler->code->body.d; vpi->Opcode != OPCODE_END;
-            vpi++, inst += 4) {
+       for (; vpi->Opcode != OPCODE_END; vpi++) {
+               GLuint *inst = compiler->code->body.d + compiler->code->length;
+
                /* Skip instructions writing to non-existing destination */
-               if (!valid_dst(compiler->code, &vpi->DstReg)) {
-                       inst -= 4;
+               if (!valid_dst(compiler->code, &vpi->DstReg))
                        continue;
+
+               if (compiler->code->length >= VSF_MAX_FRAGMENT_LENGTH) {
+                       rc_error(&compiler->Base, "Vertex program has too many instructions\n");
+                       return;
                }
 
                switch (vpi->Opcode) {
@@ -424,17 +427,15 @@ static GLboolean translate_vertex_program(struct r300_vertex_program_compiler *
                case OPCODE_SGE: ei_vector2(compiler->code, VE_SET_GREATER_THAN_EQUAL, vpi, inst); break;
                case OPCODE_SLT: ei_vector2(compiler->code, VE_SET_LESS_THAN, vpi, inst); break;
                default:
-                       fprintf(stderr, "Unknown opcode %i\n", vpi->Opcode);
-                       return GL_FALSE;
+                       rc_error(&compiler->Base, "Unknown opcode %i\n", vpi->Opcode);
+                       return;
                }
-       }
 
-       compiler->code->length = (inst - compiler->code->body.d);
-       if (compiler->code->length >= VSF_MAX_FRAGMENT_LENGTH) {
-               return GL_FALSE;
-       }
+               compiler->code->length += 4;
 
-       return GL_TRUE;
+               if (compiler->Base.Error)
+                       return;
+       }
 }
 
 struct temporary_allocation {
@@ -768,10 +769,8 @@ static GLboolean swizzleIsNative(GLuint opcode, struct prog_src_register reg)
 
 
 
-GLboolean r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
+void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
 {
-       GLboolean success;
-
        if (compiler->state.WPosAttr != FRAG_ATTRIB_MAX) {
                pos_as_texcoord(compiler->program, compiler->state.WPosAttr - FRAG_ATTRIB_TEX0);
        }
@@ -832,10 +831,8 @@ GLboolean r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compi
 
        assert(compiler->program->NumInstructions);
 
-       success = translate_vertex_program(compiler);
+       translate_vertex_program(compiler);
 
        compiler->code->InputsRead = compiler->program->InputsRead;
        compiler->code->OutputsWritten = compiler->program->OutputsWritten;
-
-       return success;
 }
index a1ffde1e8382c4b1b971093639cd1d79e7cb0778..e405267bb35baaa3c97547de71ccfd13067d3619 100644 (file)
@@ -39,7 +39,7 @@
 #include "radeon_compiler.h"
 #include "radeon_nqssadce.h"
 
-extern GLboolean r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);
+extern void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);
 
 extern void r500FragmentProgramDump(struct rX00_fragment_program_code *c);
 
index f8a1dc5fbebea8f6dffaf36e31acb716d19a2fa5..5b0b306b9cf2cbae0982190dc96795364fade1e4 100644 (file)
@@ -55,7 +55,7 @@
        struct r500_fragment_program_code *code = &c->code->code.r500
 
 #define error(fmt, args...) do {                       \
-               fprintf(stderr, "%s::%s(): " fmt "\n",  \
+               rc_error(&c->Base, "%s::%s(): " fmt "\n",       \
                        __FILE__, __FUNCTION__, ##args);        \
        } while(0)
 
@@ -87,7 +87,7 @@ static GLboolean emit_const(void *data, GLuint file, GLuint idx, GLuint *hwindex
        return GL_TRUE;
 }
 
-static GLuint translate_rgb_op(GLuint opcode)
+static GLuint translate_rgb_op(struct r300_fragment_program_compiler *c, GLuint opcode)
 {
        switch(opcode) {
        case OPCODE_CMP: return R500_ALU_RGBA_OP_CMP;
@@ -108,7 +108,7 @@ static GLuint translate_rgb_op(GLuint opcode)
        }
 }
 
-static GLuint translate_alpha_op(GLuint opcode)
+static GLuint translate_alpha_op(struct r300_fragment_program_compiler *c, GLuint opcode)
 {
        switch(opcode) {
        case OPCODE_CMP: return R500_ALPHA_OP_CMP;
@@ -191,8 +191,8 @@ static GLboolean emit_paired(void *data, struct radeon_pair_instruction *inst)
 
        int ip = ++code->inst_end;
 
-       code->inst[ip].inst5 = translate_rgb_op(inst->RGB.Opcode);
-       code->inst[ip].inst4 = translate_alpha_op(inst->Alpha.Opcode);
+       code->inst[ip].inst5 = translate_rgb_op(c, inst->RGB.Opcode);
+       code->inst[ip].inst4 = translate_alpha_op(c, inst->Alpha.Opcode);
 
        if (inst->RGB.OutputWriteMask || inst->Alpha.OutputWriteMask || inst->Alpha.DepthWriteMask)
                code->inst[ip].inst0 = R500_INST_TYPE_OUT;
@@ -301,7 +301,7 @@ static const struct radeon_pair_handler pair_handler = {
        .MaxHwTemps = 128
 };
 
-GLboolean r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler)
+void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler)
 {
        struct r500_fragment_program_code *code = &compiler->code->code.r500;
 
@@ -310,20 +310,19 @@ GLboolean r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *
        code->inst_offset = 0;
        code->inst_end = -1;
 
-       if (!radeonPairProgram(&compiler->Base, &pair_handler, compiler))
-               return GL_FALSE;
+       radeonPairProgram(&compiler->Base, &pair_handler, compiler);
+       if (compiler->Base.Error)
+               return;
 
        if ((code->inst[code->inst_end].inst0 & R500_INST_TYPE_MASK) != R500_INST_TYPE_OUT) {
                /* This may happen when dead-code elimination is disabled or
                 * when most of the fragment program logic is leading to a KIL */
                if (code->inst_end >= 511) {
-                       error("Introducing fake OUT: Too many instructions");
-                       return GL_FALSE;
+                       rc_error(&compiler->Base, "Introducing fake OUT: Too many instructions");
+                       return;
                }
 
                int ip = ++code->inst_end;
                code->inst[ip].inst0 = R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT;
        }
-
-       return GL_TRUE;
 }
index 17c9b17682cb54ccc10673f9c21545ded536174b..7b8322c201db3fd7d3171f5f0cf80250a3cd5bf5 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "radeon_compiler.h"
 
+#include <stdarg.h>
+
 
 void rc_init(struct radeon_compiler * c)
 {
@@ -36,4 +38,52 @@ void rc_init(struct radeon_compiler * c)
 void rc_destroy(struct radeon_compiler * c)
 {
        memory_pool_destroy(&c->Pool);
+       free(c->ErrorMsg);
+}
+
+void rc_debug(struct radeon_compiler * c, const char * fmt, ...)
+{
+       va_list ap;
+
+       if (!c->Debug)
+               return;
+
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+}
+
+void rc_error(struct radeon_compiler * c, const char * fmt, ...)
+{
+       va_list ap;
+
+       c->Error = GL_TRUE;
+
+       if (!c->ErrorMsg) {
+               /* Only remember the first error */
+               char buf[1024];
+               int written;
+
+               va_start(ap, fmt);
+               written = vsnprintf(buf, sizeof(buf), fmt, ap);
+               va_end(ap);
+
+               if (written < sizeof(buf)) {
+                       c->ErrorMsg = strdup(buf);
+               } else {
+                       c->ErrorMsg = malloc(written + 1);
+
+                       va_start(ap, fmt);
+                       vsnprintf(c->ErrorMsg, written + 1, fmt, ap);
+                       va_end(ap);
+               }
+       }
+
+       if (c->Debug) {
+               fprintf(stderr, "r300compiler error: ");
+
+               va_start(ap, fmt);
+               vfprintf(stderr, fmt, ap);
+               va_end(ap);
+       }
 }
index b98b1c9e6b5c3290abfeb1c956a2c02c59f6559b..f0ed78a11fc7f53f27c9f107540c0badf61f73df 100644 (file)
@@ -51,11 +51,16 @@ struct radeon_compiler {
        struct memory_pool Pool;
        struct rc_program Program;
        GLboolean Debug;
+       GLboolean Error;
+       char * ErrorMsg;
 };
 
 void rc_init(struct radeon_compiler * c);
 void rc_destroy(struct radeon_compiler * c);
 
+void rc_debug(struct radeon_compiler * c, const char * fmt, ...);
+void rc_error(struct radeon_compiler * c, const char * fmt, ...);
+
 struct r300_fragment_program_compiler {
        struct radeon_compiler Base;
        struct rX00_fragment_program_code *code;
@@ -64,7 +69,7 @@ struct r300_fragment_program_compiler {
        GLboolean is_r500;
 };
 
-GLboolean r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c);
+void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c);
 
 
 struct r300_vertex_program_compiler {
@@ -74,6 +79,6 @@ struct r300_vertex_program_compiler {
        struct gl_program *program;
 };
 
-GLboolean r3xx_compile_vertex_program(struct r300_vertex_program_compiler* c);
+void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* c);
 
 #endif /* RADEON_COMPILER_H */
index ffc218b5ecc8f707dcf7f6f2d71d1e35372b126a..ca63b906964afc334b91ace97cab03a19af721e2 100644 (file)
@@ -40,9 +40,8 @@
 #include "shader/prog_print.h"
 
 #define error(fmt, args...) do { \
-       fprintf(stderr, "r300 driver problem: %s::%s(): " fmt "\n",     \
+       rc_error(s->Compiler, "%s::%s(): " fmt "\n",    \
                __FILE__, __FUNCTION__, ##args);        \
-       s->Error = GL_TRUE;                             \
 } while(0)
 
 struct pair_state_instruction {
@@ -121,7 +120,6 @@ struct pair_register_translation {
 struct pair_state {
        struct radeon_compiler * Compiler;
        const struct radeon_pair_handler *Handler;
-       GLboolean Error;
        GLboolean Verbose;
        void *UserData;
 
@@ -583,7 +581,7 @@ static void emit_all_tex(struct pair_state *s)
                _mesa_printf(" BEGIN_TEX\n");
 
        if (s->Handler->BeginTexBlock)
-               s->Error = s->Error || !s->Handler->BeginTexBlock(s->UserData);
+               s->Compiler->Error = s->Compiler->Error || !s->Handler->BeginTexBlock(s->UserData);
 
        for(pairinst = readytex; pairinst; pairinst = pairinst->NextReady) {
                struct prog_instruction *inst = &pairinst->Instruction;
@@ -616,7 +614,7 @@ static void emit_all_tex(struct pair_state *s)
                rpti.SrcIndex = inst->SrcReg[0].Index;
                rpti.SrcSwizzle = inst->SrcReg[0].Swizzle;
 
-               s->Error = s->Error || !s->Handler->EmitTex(s->UserData, &rpti);
+               s->Compiler->Error = s->Compiler->Error || !s->Handler->EmitTex(s->UserData, &rpti);
        }
 
        if (s->Compiler->Debug)
@@ -642,7 +640,7 @@ static int alloc_pair_source(struct pair_state *s, struct radeon_pair_instructio
                index = get_hw_reg(s, src.File, src.Index);
        } else {
                constant = 1;
-               s->Error |= !s->Handler->EmitConst(s->UserData, src.File, src.Index, &index);
+               s->Compiler->Error |= !s->Handler->EmitConst(s->UserData, src.File, src.Index, &index);
        }
 
        for(i = 0; i < 3; ++i) {
@@ -869,11 +867,11 @@ static void emit_alu(struct pair_state *s)
        if (s->Compiler->Debug)
                radeonPrintPairInstruction(&pair);
 
-       s->Error = s->Error || !s->Handler->EmitPaired(s->UserData, &pair);
+       s->Compiler->Error = s->Compiler->Error || !s->Handler->EmitPaired(s->UserData, &pair);
 }
 
 
-GLboolean radeonPairProgram(
+void radeonPairProgram(
        struct radeon_compiler * compiler,
        const struct radeon_pair_handler* handler, void *userdata)
 {
@@ -891,7 +889,7 @@ GLboolean radeonPairProgram(
        scan_instructions(&s);
        allocate_input_registers(&s);
 
-       while(!s.Error &&
+       while(!s.Compiler->Error &&
              (s.ReadyTEX || s.ReadyRGB || s.ReadyAlpha || s.ReadyFullALU)) {
                if (s.ReadyTEX)
                        emit_all_tex(&s);
@@ -902,8 +900,6 @@ GLboolean radeonPairProgram(
 
        if (s.Compiler->Debug)
                _mesa_printf(" END\n");
-
-       return !s.Error;
 }
 
 
index 3992082662b570ade881b41ac0241558f3279485..46196fb1c87f2fe09f180acaa7254fe02372a001 100644 (file)
@@ -141,7 +141,7 @@ struct radeon_pair_handler {
        GLuint MaxHwTemps;
 };
 
-GLboolean radeonPairProgram(
+void radeonPairProgram(
        struct radeon_compiler * compiler,
        const struct radeon_pair_handler*, void *userdata);
 
index 27aec645759883427c97c7d36ecc1e9fa8412f65..0ce57e834b4084c94ef91d2b15b15d0d611cb8bb 100644 (file)
@@ -99,8 +99,8 @@ static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_prog
        compiler.program = _mesa_clone_program(ctx, &cont->Base.Base);
        compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ? GL_TRUE : GL_FALSE;
 
-       if (!r3xx_compile_fragment_program(&compiler))
-               fp->error = GL_TRUE;
+       r3xx_compile_fragment_program(&compiler);
+       fp->error = compiler.Base.Error;
 
        fp->InputsRead = compiler.Base.Program.InputsRead;
        fp->Base = compiler.program;
index dfb2a9e3d859a5cb8a00e3e835aa7a7e84a9095b..91d9d8ae949140f6c999d6dca5b5783c699d9ed8 100644 (file)
@@ -125,8 +125,8 @@ static struct r300_vertex_program *build_program(GLcontext *ctx,
                _mesa_insert_mvp_code(ctx, (struct gl_vertex_program *)compiler.program);
        }
 
-       if (!r3xx_compile_vertex_program(&compiler))
-               vp->error = GL_TRUE;
+       r3xx_compile_vertex_program(&compiler);
+       vp->error = compiler.Base.Error;
 
        rc_destroy(&compiler.Base);