#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);
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)
}
-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;
}
}
-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;
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);
* 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;
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);
}
}
}
-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");
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;
}
}
}
-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) {
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 {
-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);
}
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;
}
#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);
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)
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;
}
}
-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;
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;
.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;
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;
}
#include "radeon_compiler.h"
+#include <stdarg.h>
+
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);
+ }
}
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;
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 {
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 */
#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 {
struct pair_state {
struct radeon_compiler * Compiler;
const struct radeon_pair_handler *Handler;
- GLboolean Error;
GLboolean Verbose;
void *UserData;
_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;
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)
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) {
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)
{
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);
if (s.Compiler->Debug)
_mesa_printf(" END\n");
-
- return !s.Error;
}
GLuint MaxHwTemps;
};
-GLboolean radeonPairProgram(
+void radeonPairProgram(
struct radeon_compiler * compiler,
const struct radeon_pair_handler*, void *userdata);
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;
_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);