mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-22 12:00:28 +01:00
r300/compiler: Lay groundwork for better error handling
Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
This commit is contained in:
parent
c5cb9a3378
commit
8bcb6ef786
12 changed files with 113 additions and 72 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
radeonPairProgram(&compiler->Base, &pair_handler, compiler);
|
||||
if (compiler->Base.Error)
|
||||
return;
|
||||
|
||||
if (!finish_node(compiler))
|
||||
return GL_FALSE;
|
||||
|
||||
return GL_TRUE;
|
||||
finish_node(compiler);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue