* be reused.
*/
static GLboolean transform_TEX(
- struct radeon_program_transform_context* context,
+ GLcontext *ctx, struct gl_program *p,
struct prog_instruction* orig_inst, void* data)
{
struct r300_fragment_program_compiler *compiler =
return GL_FALSE;
if (inst.Opcode != OPCODE_KIL &&
- compiler->fp->mesa_program.Base.ShadowSamplers & (1 << inst.TexSrcUnit)) {
+ p->ShadowSamplers & (1 << inst.TexSrcUnit)) {
GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) {
- tgt = radeonClauseInsertInstructions(context->compiler, context->dest,
- context->dest->NumInstructions, 1);
+ tgt = radeonAppendInstructions(p, 1);
tgt->Opcode = OPCODE_MOV;
tgt->DstReg = inst.DstReg;
}
inst.DstReg.File = PROGRAM_TEMPORARY;
- inst.DstReg.Index = radeonCompilerAllocateTemporary(context->compiler);
+ inst.DstReg.Index = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
inst.DstReg.WriteMask = WRITEMASK_XYZW;
}
0
};
- int tempreg = radeonCompilerAllocateTemporary(context->compiler);
+ int tempreg = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
int factor_index;
tokens[2] = inst.TexSrcUnit;
_mesa_add_state_reference(
compiler->fp->mesa_program.Base.Parameters, tokens);
- tgt = radeonClauseInsertInstructions(context->compiler, context->dest,
- context->dest->NumInstructions, 1);
+ tgt = radeonAppendInstructions(p, 1);
tgt->Opcode = OPCODE_MUL;
tgt->DstReg.File = PROGRAM_TEMPORARY;
*/
if (inst.SrcReg[0].Swizzle != SWIZZLE_NOOP ||
inst.SrcReg[0].Abs || inst.SrcReg[0].NegateBase || inst.SrcReg[0].NegateAbs) {
- int tempreg = radeonCompilerAllocateTemporary(context->compiler);
+ int tempreg = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
- tgt = radeonClauseInsertInstructions(context->compiler, context->dest,
- context->dest->NumInstructions, 1);
+ tgt = radeonAppendInstructions(p, 1);
tgt->Opcode = OPCODE_MOV;
tgt->DstReg.File = PROGRAM_TEMPORARY;
if (inst.Opcode != OPCODE_KIL) {
if (inst.DstReg.File != PROGRAM_TEMPORARY ||
inst.DstReg.WriteMask != WRITEMASK_XYZW) {
- int tempreg = radeonCompilerAllocateTemporary(context->compiler);
+ int tempreg = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
inst.DstReg.File = PROGRAM_TEMPORARY;
inst.DstReg.Index = tempreg;
}
}
- tgt = radeonClauseInsertInstructions(context->compiler, context->dest,
- context->dest->NumInstructions, 1);
+ tgt = radeonAppendInstructions(p, 1);
_mesa_copy_instructions(tgt, &inst, 1);
if (inst.Opcode != OPCODE_KIL &&
- compiler->fp->mesa_program.Base.ShadowSamplers & (1 << inst.TexSrcUnit)) {
+ p->ShadowSamplers & (1 << inst.TexSrcUnit)) {
GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
GLuint depthmode = compiler->fp->state.unit[inst.TexSrcUnit].depth_texture_mode;
- int rcptemp = radeonCompilerAllocateTemporary(context->compiler);
+ int rcptemp = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
- tgt = radeonClauseInsertInstructions(context->compiler, context->dest,
- context->dest->NumInstructions, 3);
+ tgt = radeonAppendInstructions(p, 3);
tgt[0].Opcode = OPCODE_RCP;
tgt[0].DstReg.File = PROGRAM_TEMPORARY;
tgt[2].SrcReg[2].Swizzle = SWIZZLE_1111;
}
} else if (destredirect) {
- tgt = radeonClauseInsertInstructions(context->compiler, context->dest,
- context->dest->NumInstructions, 1);
+ tgt = radeonAppendInstructions(p, 1);
tgt->Opcode = OPCODE_MOV;
tgt->DstReg = orig_inst->DstReg;
struct prog_instruction *fpi;
GLuint window_index;
int i = 0;
- GLuint tempregi = radeonCompilerAllocateTemporary(&compiler->compiler);
+ GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY);
- fpi = radeonClauseInsertInstructions(&compiler->compiler, &compiler->compiler.Clauses[0], 0, 3);
+ _mesa_insert_instructions(compiler->program, 0, 3);
+ fpi = compiler->program->Instructions;
/* perspective divide */
fpi[i].Opcode = OPCODE_RCP;
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
i++;
- for (; i < compiler->compiler.Clauses[0].NumInstructions; ++i) {
+ for (; i < compiler->program->NumInstructions; ++i) {
int reg;
for (reg = 0; reg < 3; reg++) {
if (fpi[i].SrcReg[reg].File == PROGRAM_INPUT &&
compiler.r300 = r300;
compiler.fp = fp;
compiler.code = &fp->code;
-
- radeonCompilerInit(&compiler.compiler, r300->radeon.glCtx, &fp->mesa_program.Base);
+ compiler.program = _mesa_clone_program(r300->radeon.glCtx, &fp->mesa_program.Base);
insert_WPOS_trailer(&compiler);
{ &transform_TEX, &compiler },
{ &radeonTransformALU, 0 }
};
- radeonClauseLocalTransform(&compiler.compiler,
- &compiler.compiler.Clauses[0],
+ radeonLocalTransform(
+ r300->radeon.glCtx,
+ compiler.program,
2, transformations);
if (RADEON_DEBUG & DEBUG_PIXEL) {
- _mesa_printf("Compiler state after transformations:\n");
- radeonCompilerDump(&compiler.compiler);
+ _mesa_printf("Program after transformations:\n");
+ _mesa_print_program(compiler.program);
}
if (!r300FragmentProgramEmit(&compiler))
fp->error = GL_TRUE;
- radeonCompilerCleanup(&compiler.compiler);
+ _mesa_reference_program(r300->radeon.glCtx, &compiler.program, NULL);
if (!fp->error)
fp->translated = GL_TRUE;
r300ContextPtr r300;
struct r300_fragment_program *fp;
struct r300_fragment_program_code *code;
- struct radeon_compiler compiler;
+ struct gl_program *program;
};
-extern void r300FPTransformTextures(struct r300_fragment_program_compiler *compiler);
extern GLboolean r300FragmentProgramEmit(struct r300_fragment_program_compiler *compiler);
static GLboolean parse_program(struct r300_pfs_compile_state *cs)
{
COMPILE_STATE;
- int clauseidx;
+ struct prog_instruction* fpi;
- for (clauseidx = 0; clauseidx < cs->compiler->compiler.NumClauses; ++clauseidx) {
- struct radeon_clause* clause = &cs->compiler->compiler.Clauses[clauseidx];
- int ip;
+ for(fpi = cs->compiler->program->Instructions; fpi->Opcode != OPCODE_END; ++fpi) {
+ emit_instruction(cs, fpi);
- for(ip = 0; ip < clause->NumInstructions; ++ip) {
- emit_instruction(cs, clause->Instructions + ip);
-
- if (fp->error)
- return GL_FALSE;
- }
+ if (fp->error)
+ return GL_FALSE;
}
return GL_TRUE;
/* Pre-parse the program, grabbing refcounts on input/temp regs.
* That way, we can free up the reg when it's no longer needed
*/
- for (i = 0; i < cs->compiler->compiler.Clauses[0].NumInstructions; ++i) {
- struct prog_instruction *fpi = cs->compiler->compiler.Clauses[0].Instructions + i;
+ for (i = 0; i < cs->compiler->program->NumInstructions; ++i) {
+ struct prog_instruction *fpi = cs->compiler->program->Instructions + i;
int idx;
for (j = 0; j < 3; j++) {
*
*/
static GLboolean transform_TEX(
- struct radeon_program_transform_context* context,
+ GLcontext *ctx, struct gl_program *p,
struct prog_instruction* orig_inst, void* data)
{
struct r500_fragment_program_compiler *compiler =
/* ARB_shadow & EXT_shadow_funcs */
if (inst.Opcode != OPCODE_KIL &&
- compiler->fp->mesa_program.Base.ShadowSamplers & (1 << inst.TexSrcUnit)) {
+ p->ShadowSamplers & (1 << inst.TexSrcUnit)) {
GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) {
- tgt = radeonClauseInsertInstructions(context->compiler, context->dest,
- context->dest->NumInstructions, 1);
+ tgt = radeonAppendInstructions(p, 1);
tgt->Opcode = OPCODE_MOV;
tgt->DstReg.File = inst.DstReg.File;
}
inst.DstReg.File = PROGRAM_TEMPORARY;
- inst.DstReg.Index = radeonCompilerAllocateTemporary(context->compiler);
+ inst.DstReg.Index = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
inst.DstReg.WriteMask = WRITEMASK_XYZW;
}
- tgt = radeonClauseInsertInstructions(context->compiler, context->dest,
- context->dest->NumInstructions, 1);
+ tgt = radeonAppendInstructions(p, 1);
_mesa_copy_instructions(tgt, &inst, 1);
if (inst.Opcode != OPCODE_KIL &&
- compiler->fp->mesa_program.Base.ShadowSamplers & (1 << inst.TexSrcUnit)) {
+ p->ShadowSamplers & (1 << inst.TexSrcUnit)) {
GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
GLuint depthmode = compiler->fp->state.unit[inst.TexSrcUnit].depth_texture_mode;
- int rcptemp = radeonCompilerAllocateTemporary(context->compiler);
+ int rcptemp = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
- tgt = radeonClauseInsertInstructions(context->compiler, context->dest,
- context->dest->NumInstructions, 3);
+ tgt = radeonAppendInstructions(p, 3);
tgt[0].Opcode = OPCODE_RCP;
tgt[0].DstReg.File = PROGRAM_TEMPORARY;
tgt[2].SrcReg[2].Swizzle = SWIZZLE_1111;
}
} else if (destredirect) {
- tgt = radeonClauseInsertInstructions(context->compiler, context->dest,
- context->dest->NumInstructions, 1);
+ tgt = radeonAppendInstructions(p, 1);
- tgt->Opcode = OPCODE_MAD;
+ tgt->Opcode = OPCODE_MOV;
tgt->DstReg = orig_inst->DstReg;
tgt->SrcReg[0].File = PROGRAM_TEMPORARY;
tgt->SrcReg[0].Index = inst.DstReg.Index;
- tgt->SrcReg[1].File = PROGRAM_BUILTIN;
- tgt->SrcReg[1].Swizzle = SWIZZLE_1111;
- tgt->SrcReg[2].File = PROGRAM_BUILTIN;
- tgt->SrcReg[2].Swizzle = SWIZZLE_0000;
}
return GL_TRUE;
struct prog_instruction *fpi;
GLuint window_index;
int i = 0;
- GLuint tempregi = radeonCompilerAllocateTemporary(&compiler->compiler);
+ GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY);
- fpi = radeonClauseInsertInstructions(&compiler->compiler, &compiler->compiler.Clauses[0], 0, 3);
+ _mesa_insert_instructions(compiler->program, 0, 3);
+ fpi = compiler->program->Instructions;
/* perspective divide */
fpi[i].Opcode = OPCODE_RCP;
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
i++;
- for (; i < compiler->compiler.Clauses[0].NumInstructions; ++i) {
+ for (; i < compiler->program->NumInstructions; ++i) {
int reg;
for (reg = 0; reg < 3; reg++) {
if (fpi[i].SrcReg[reg].File == PROGRAM_INPUT &&
compiler.r300 = r300;
compiler.fp = fp;
compiler.code = &fp->code;
+ compiler.program = _mesa_clone_program(r300->radeon.glCtx, &fp->mesa_program.Base);
- radeonCompilerInit(&compiler.compiler, r300->radeon.glCtx, &fp->mesa_program.Base);
+ if (RADEON_DEBUG & DEBUG_PIXEL) {
+ _mesa_printf("Compiler: Initial program:\n");
+ _mesa_print_program(compiler.program);
+ }
insert_WPOS_trailer(&compiler);
struct radeon_program_transformation transformations[1] = {
{ &transform_TEX, &compiler }
};
- radeonClauseLocalTransform(&compiler.compiler,
- &compiler.compiler.Clauses[0],
+ radeonLocalTransform(r300->radeon.glCtx, compiler.program,
1, transformations);
if (RADEON_DEBUG & DEBUG_PIXEL) {
- _mesa_printf("Compiler state after transformations:\n");
- radeonCompilerDump(&compiler.compiler);
+ _mesa_printf("Compiler: after all transformations:\n");
+ _mesa_print_program(compiler.program);
}
fp->translated = r500FragmentProgramEmit(&compiler);
- radeonCompilerCleanup(&compiler.compiler);
+ _mesa_reference_program(r300->radeon.glCtx, &compiler.program, 0);
r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM);
r300ContextPtr r300;
struct r500_fragment_program *fp;
struct r500_fragment_program_code *code;
- struct radeon_compiler compiler;
+ struct gl_program *program;
};
extern GLboolean r500FragmentProgramEmit(struct r500_fragment_program_compiler *compiler);
break;
case PROGRAM_ENV_PARAM:
reg = emit_const4fv(cs,
- cs->compiler->compiler.Ctx->FragmentProgram.Parameters[src.Index]);
+ cs->compiler->r300->radeon.glCtx->FragmentProgram.Parameters[src.Index]);
break;
case PROGRAM_STATE_VAR:
case PROGRAM_NAMED_PARAM:
static GLboolean parse_program(struct r500_pfs_compile_state *cs)
{
PROG_CODE;
- int clauseidx, counter = 0;
+ int counter = 0;
+ struct prog_instruction* fpi;
- for (clauseidx = 0; clauseidx < cs->compiler->compiler.NumClauses; clauseidx++) {
- struct radeon_clause* clause = &cs->compiler->compiler.Clauses[clauseidx];
- struct prog_instruction* fpi;
+ for(fpi = cs->compiler->program->Instructions; fpi->Opcode != OPCODE_END; ++fpi) {
+ counter = do_inst(cs, fpi, counter);
- int ip;
-
- for (ip = 0; ip < clause->NumInstructions; ip++) {
- fpi = clause->Instructions + ip;
- counter = do_inst(cs, fpi, counter);
-
- if (cs->compiler->fp->error)
- return GL_FALSE;
- }
+ if (cs->compiler->fp->error)
+ return GL_FALSE;
}
/* Finish him! (If it's an ALU/OUT instruction...) */
cs->inputs[i].reg = 0;
}
- int clauseidx;
-
- for (clauseidx = 0; clauseidx < cs->compiler->compiler.NumClauses; ++clauseidx) {
- struct radeon_clause* clause = &cs->compiler->compiler.Clauses[clauseidx];
- int ip;
+ int ip;
- for (ip = 0; ip < clause->NumInstructions; ip++) {
- fpi = clause->Instructions + ip;
- for (i = 0; i < 3; i++) {
- if (fpi->SrcReg[i].File == PROGRAM_TEMPORARY) {
- if (fpi->SrcReg[i].Index >= temps_used)
- temps_used = fpi->SrcReg[i].Index + 1;
- }
+ for (ip = 0; ip < cs->compiler->program->NumInstructions; ip++) {
+ fpi = cs->compiler->program->Instructions + ip;
+ for (i = 0; i < 3; i++) {
+ if (fpi->SrcReg[i].File == PROGRAM_TEMPORARY) {
+ if (fpi->SrcReg[i].Index >= temps_used)
+ temps_used = fpi->SrcReg[i].Index + 1;
}
}
}
#include "shader/prog_print.h"
-/**
- * Initialize a compiler structure with a single mixed clause
- * containing all instructions from the source program.
- */
-void radeonCompilerInit(
- struct radeon_compiler *compiler,
- GLcontext *ctx,
- struct gl_program *source)
-{
- struct radeon_clause* clause;
-
- _mesa_memset(compiler, 0, sizeof(*compiler));
- compiler->Source = source;
- compiler->Ctx = ctx;
-
- compiler->NumTemporaries = source->NumTemporaries;
-
- clause = radeonCompilerInsertClause(compiler, 0, CLAUSE_MIXED);
- clause->NumInstructions = 0;
- while(source->Instructions[clause->NumInstructions].Opcode != OPCODE_END)
- clause->NumInstructions++;
- clause->ReservedInstructions = clause->NumInstructions;
- clause->Instructions = _mesa_alloc_instructions(clause->NumInstructions);
- _mesa_copy_instructions(clause->Instructions, source->Instructions, clause->NumInstructions);
-}
-
-
-/**
- * Free all data that is referenced by the compiler structure.
- * However, the compiler structure itself is not freed.
- */
-void radeonCompilerCleanup(struct radeon_compiler *compiler)
-{
- radeonCompilerEraseClauses(compiler, 0, compiler->NumClauses);
-}
-
-
-/**
- * Allocate and return a unique temporary register.
- */
-int radeonCompilerAllocateTemporary(struct radeon_compiler *compiler)
-{
- if (compiler->NumTemporaries >= 256) {
- _mesa_problem(compiler->Ctx, "radeonCompiler: Too many temporaries");
- return 0;
- }
-
- return compiler->NumTemporaries++;
-}
-
-
-static const char* clausename(int type)
-{
- switch(type) {
- case CLAUSE_MIXED: return "CLAUSE_MIXED";
- case CLAUSE_ALU: return "CLAUSE_ALU";
- case CLAUSE_TEX: return "CLAUSE_TEX";
- default: return "CLAUSE_UNKNOWN";
- }
-}
-
-
-/**
- * Dump the current compiler state to the console for debugging.
- */
-void radeonCompilerDump(struct radeon_compiler *compiler)
-{
- int i;
- for(i = 0; i < compiler->NumClauses; ++i) {
- struct radeon_clause *clause = &compiler->Clauses[i];
- int j;
-
- _mesa_printf("%2i: %s\n", i+1, clausename(clause->Type));
-
- for(j = 0; j < clause->NumInstructions; ++j) {
- _mesa_printf("%4i: ", j+1);
- _mesa_print_instruction(&clause->Instructions[j]);
- }
- }
-}
-
-
-/**
- * \p position index of the new clause; later clauses are moved
- * \p type of the new clause; one of CLAUSE_XXX
- * \return a pointer to the new clause
- */
-struct radeon_clause* radeonCompilerInsertClause(
- struct radeon_compiler *compiler,
- int position, int type)
-{
- struct radeon_clause* oldClauses = compiler->Clauses;
- struct radeon_clause* clause;
-
- assert(position >= 0 && position <= compiler->NumClauses);
-
- compiler->Clauses = (struct radeon_clause *)
- _mesa_malloc((compiler->NumClauses+1) * sizeof(struct radeon_clause));
- if (oldClauses) {
- _mesa_memcpy(compiler->Clauses, oldClauses,
- position*sizeof(struct radeon_clause));
- _mesa_memcpy(compiler->Clauses+position+1, oldClauses+position,
- (compiler->NumClauses - position) * sizeof(struct radeon_clause));
- _mesa_free(oldClauses);
- }
- compiler->NumClauses++;
-
- clause = compiler->Clauses + position;
- _mesa_memset(clause, 0, sizeof(*clause));
- clause->Type = type;
-
- return clause;
-}
-
-
-/**
- * Remove clauses in the range [start, end)
- */
-void radeonCompilerEraseClauses(
- struct radeon_compiler *compiler,
- int start, int end)
-{
- struct radeon_clause* oldClauses = compiler->Clauses;
- int i;
-
- assert(0 <= start);
- assert(start <= end);
- assert(end <= compiler->NumClauses);
-
- if (end == start)
- return;
-
- for(i = start; i < end; ++i) {
- struct radeon_clause* clause = oldClauses + i;
- _mesa_free_instructions(clause->Instructions, clause->NumInstructions);
- }
-
- if (start > 0 || end < compiler->NumClauses) {
- compiler->Clauses = (struct radeon_clause*)
- _mesa_malloc((compiler->NumClauses+start-end) * sizeof(struct radeon_clause));
- _mesa_memcpy(compiler->Clauses, oldClauses,
- start * sizeof(struct radeon_clause));
- _mesa_memcpy(compiler->Clauses + start, oldClauses + end,
- (compiler->NumClauses - end) * sizeof(struct radeon_clause));
- compiler->NumClauses -= end - start;
- } else {
- compiler->Clauses = 0;
- compiler->NumClauses = 0;
- }
-
- _mesa_free(oldClauses);
-}
-
-
-/**
- * Insert new instructions at the given position, initialize them as NOPs
- * and return a pointer to the first new instruction.
- */
-struct prog_instruction* radeonClauseInsertInstructions(
- struct radeon_compiler *compiler,
- struct radeon_clause *clause,
- int position, int count)
-{
- int newNumInstructions = clause->NumInstructions + count;
-
- assert(position >= 0 && position <= clause->NumInstructions);
-
- if (newNumInstructions <= clause->ReservedInstructions) {
- memmove(clause->Instructions + position + count, clause->Instructions + position,
- (clause->NumInstructions - position) * sizeof(struct prog_instruction));
- } else {
- struct prog_instruction *oldInstructions = clause->Instructions;
-
- clause->ReservedInstructions *= 2;
- if (newNumInstructions > clause->ReservedInstructions)
- clause->ReservedInstructions = newNumInstructions;
-
- clause->Instructions = (struct prog_instruction*)
- _mesa_malloc(clause->ReservedInstructions * sizeof(struct prog_instruction));
-
- if (oldInstructions) {
- _mesa_memcpy(clause->Instructions, oldInstructions,
- position * sizeof(struct prog_instruction));
- _mesa_memcpy(clause->Instructions + position + count, oldInstructions + position,
- (clause->NumInstructions - position) * sizeof(struct prog_instruction));
-
- _mesa_free(oldInstructions);
- }
- }
-
- clause->NumInstructions = newNumInstructions;
- _mesa_init_instructions(clause->Instructions + position, count);
- return clause->Instructions + position;
-}
-
/**
* Transform the given clause in the following way:
* \note The transform is called 'local' because it can only look at
* one instruction at a time.
*/
-void radeonClauseLocalTransform(
- struct radeon_compiler *compiler,
- struct radeon_clause *clause,
+void radeonLocalTransform(
+ GLcontext *ctx,
+ struct gl_program *program,
int num_transformations,
struct radeon_program_transformation* transformations)
{
- struct radeon_program_transform_context context;
- struct radeon_clause source;
+ struct prog_instruction *source;
+ int numinstructions;
int ip;
- source = *clause;
- clause->Instructions = 0;
- clause->NumInstructions = 0;
- clause->ReservedInstructions = 0;
+ source = program->Instructions;
+ numinstructions = program->NumInstructions;
- context.compiler = compiler;
- context.dest = clause;
- context.src = &source;
+ program->Instructions = 0;
+ program->NumInstructions = 0;
- for(ip = 0; ip < source.NumInstructions; ++ip) {
- struct prog_instruction *instr = source.Instructions + ip;
+ for(ip = 0; ip < numinstructions; ++ip) {
+ struct prog_instruction *instr = source + ip;
int i;
for(i = 0; i < num_transformations; ++i) {
struct radeon_program_transformation* t = transformations + i;
- if (t->function(&context, instr, t->userData))
+ if (t->function(ctx, program, instr, t->userData))
break;
}
if (i >= num_transformations) {
- struct prog_instruction *tgt =
- radeonClauseInsertInstructions(compiler, clause, clause->NumInstructions, 1);
- _mesa_copy_instructions(tgt, instr, 1);
+ struct prog_instruction* dest = radeonAppendInstructions(program, 1);
+ _mesa_copy_instructions(dest, instr, 1);
}
}
- _mesa_free_instructions(source.Instructions, source.NumInstructions);
+ _mesa_free_instructions(source, numinstructions);
+}
+
+
+/**
+ * Append the given number of instructions to the program and return a
+ * pointer to the first new instruction.
+ */
+struct prog_instruction *radeonAppendInstructions(struct gl_program *program, int count)
+{
+ int oldnum = program->NumInstructions;
+ _mesa_insert_instructions(program, oldnum, count);
+ return program->Instructions + oldnum;
}
#define SWIZZLE_1111 MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE)
/**
- * A clause is simply a sequence of instructions that are executed
- * in order.
- */
-struct radeon_clause {
- /**
- * Type of this clause, one of CLAUSE_XXX.
- */
- int Type : 2;
-
- /**
- * Pointer to an array of instructions.
- * The array is terminated by an OPCODE_END instruction.
- */
- struct prog_instruction *Instructions;
-
- /**
- * Number of instructions in this clause.
- */
- int NumInstructions;
-
- /**
- * Space reserved for instructions in this clause.
- */
- int ReservedInstructions;
-};
-
-/**
- * A compile object, holding the current intermediate state during compilation.
- */
-struct radeon_compiler {
- struct gl_program *Source;
- GLcontext* Ctx;
-
- /**
- * Number of clauses in this program.
- */
- int NumClauses;
-
- /**
- * Pointer to an array of NumClauses clauses.
- */
- struct radeon_clause *Clauses;
-
- /**
- * Number of registers in the PROGRAM_TEMPORARIES file.
- */
- int NumTemporaries;
-};
-
-void radeonCompilerInit(
- struct radeon_compiler *compiler,
- GLcontext *ctx,
- struct gl_program *source);
-void radeonCompilerCleanup(struct radeon_compiler *compiler);
-int radeonCompilerAllocateTemporary(struct radeon_compiler *compiler);
-void radeonCompilerDump(struct radeon_compiler *compiler);
-
-struct radeon_clause *radeonCompilerInsertClause(
- struct radeon_compiler *compiler,
- int position,
- int type);
-void radeonCompilerEraseClauses(
- struct radeon_compiler *compiler,
- int start,
- int end);
-
-struct prog_instruction* radeonClauseInsertInstructions(
- struct radeon_compiler *compiler,
- struct radeon_clause *clause,
- int position, int count);
-
-/**
- *
- */
-struct radeon_program_transform_context {
- struct radeon_compiler *compiler;
-
- /**
- * Destination clause where new instructions must be written.
- */
- struct radeon_clause *dest;
-
- /**
- * Original clause that is currently being transformed.
- */
- struct radeon_clause *src;
-};
-
-/**
- * A transformation that can be passed to \ref radeonClauseLinearTransform.
+ * A transformation that can be passed to \ref radeonLocalTransform.
*
* The function will be called once for each instruction.
* It has to either emit the appropriate transformed code for the instruction
*/
struct radeon_program_transformation {
GLboolean (*function)(
- struct radeon_program_transform_context*,
+ GLcontext*,
+ struct gl_program*,
struct prog_instruction*,
void*);
void *userData;
};
-void radeonClauseLocalTransform(
- struct radeon_compiler *compiler,
- struct radeon_clause *clause,
+void radeonLocalTransform(
+ GLcontext* ctx,
+ struct gl_program *program,
int num_transformations,
struct radeon_program_transformation* transformations);
+
+struct prog_instruction *radeonAppendInstructions(struct gl_program *program, int count);
+
#endif
#include "radeon_program_alu.h"
-static struct prog_instruction *emit1(struct radeon_program_transform_context* ctx,
+static struct prog_instruction *emit1(struct gl_program* p,
gl_inst_opcode Opcode, struct prog_dst_register DstReg,
struct prog_src_register SrcReg)
{
- struct prog_instruction *fpi =
- radeonClauseInsertInstructions(ctx->compiler, ctx->dest,
- ctx->dest->NumInstructions, 1);
+ struct prog_instruction *fpi = radeonAppendInstructions(p, 1);
fpi->Opcode = Opcode;
fpi->DstReg = DstReg;
return fpi;
}
-static struct prog_instruction *emit2(struct radeon_program_transform_context* ctx,
+static struct prog_instruction *emit2(struct gl_program* p,
gl_inst_opcode Opcode, struct prog_dst_register DstReg,
struct prog_src_register SrcReg0, struct prog_src_register SrcReg1)
{
- struct prog_instruction *fpi =
- radeonClauseInsertInstructions(ctx->compiler, ctx->dest,
- ctx->dest->NumInstructions, 1);
+ struct prog_instruction *fpi = radeonAppendInstructions(p, 1);
fpi->Opcode = Opcode;
fpi->DstReg = DstReg;
return fpi;
}
-static struct prog_instruction *emit3(struct radeon_program_transform_context* ctx,
+static struct prog_instruction *emit3(struct gl_program* p,
gl_inst_opcode Opcode, struct prog_dst_register DstReg,
struct prog_src_register SrcReg0, struct prog_src_register SrcReg1,
struct prog_src_register SrcReg2)
{
- struct prog_instruction *fpi =
- radeonClauseInsertInstructions(ctx->compiler, ctx->dest,
- ctx->dest->NumInstructions, 1);
+ struct prog_instruction *fpi = radeonAppendInstructions(p, 1);
fpi->Opcode = Opcode;
fpi->DstReg = DstReg;
return swizzle(reg, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
}
-static void transform_ABS(struct radeon_program_transform_context* ctx,
+static void transform_ABS(struct gl_program* p,
struct prog_instruction* inst)
{
struct prog_src_register src = inst->SrcReg[0];
src.Abs = 1;
src.NegateBase = 0;
src.NegateAbs = 0;
- emit1(ctx, OPCODE_MOV, inst->DstReg, src);
+ emit1(p, OPCODE_MOV, inst->DstReg, src);
}
-static void transform_DPH(struct radeon_program_transform_context* ctx,
+static void transform_DPH(struct gl_program* p,
struct prog_instruction* inst)
{
struct prog_src_register src0 = inst->SrcReg[0];
if (src0.NegateAbs) {
if (src0.Abs) {
- int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
- emit1(ctx, OPCODE_MOV, dstreg(PROGRAM_TEMPORARY, tempreg), src0);
+ int tempreg = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
+ emit1(p, OPCODE_MOV, dstreg(PROGRAM_TEMPORARY, tempreg), src0);
src0 = srcreg(src0.File, src0.Index);
} else {
src0.NegateAbs = 0;
}
set_swizzle(&src0, 3, SWIZZLE_ONE);
set_negate_base(&src0, 3, 0);
- emit2(ctx, OPCODE_DP4, inst->DstReg, src0, inst->SrcReg[1]);
+ emit2(p, OPCODE_DP4, inst->DstReg, src0, inst->SrcReg[1]);
}
-static void transform_FLR(struct radeon_program_transform_context* ctx,
+static void transform_FLR(struct gl_program* p,
struct prog_instruction* inst)
{
- int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
- emit1(ctx, OPCODE_FRC, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0]);
- emit2(ctx, OPCODE_ADD, inst->DstReg, inst->SrcReg[0], negate(srcreg(PROGRAM_TEMPORARY, tempreg)));
+ int tempreg = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
+ emit1(p, OPCODE_FRC, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0]);
+ emit2(p, OPCODE_ADD, inst->DstReg, inst->SrcReg[0], negate(srcreg(PROGRAM_TEMPORARY, tempreg)));
}
-static void transform_POW(struct radeon_program_transform_context* ctx,
+static void transform_POW(struct gl_program* p,
struct prog_instruction* inst)
{
- int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
+ int tempreg = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
struct prog_dst_register tempdst = dstreg(PROGRAM_TEMPORARY, tempreg);
struct prog_src_register tempsrc = srcreg(PROGRAM_TEMPORARY, tempreg);
tempdst.WriteMask = WRITEMASK_W;
tempsrc.Swizzle = SWIZZLE_WWWW;
- emit1(ctx, OPCODE_LG2, tempdst, scalar(inst->SrcReg[0]));
- emit2(ctx, OPCODE_MUL, tempdst, tempsrc, scalar(inst->SrcReg[1]));
- emit1(ctx, OPCODE_EX2, inst->DstReg, tempsrc);
+ emit1(p, OPCODE_LG2, tempdst, scalar(inst->SrcReg[0]));
+ emit2(p, OPCODE_MUL, tempdst, tempsrc, scalar(inst->SrcReg[1]));
+ emit1(p, OPCODE_EX2, inst->DstReg, tempsrc);
}
-static void transform_SGE(struct radeon_program_transform_context* ctx,
+static void transform_SGE(struct gl_program* p,
struct prog_instruction* inst)
{
- int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
+ int tempreg = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
- emit2(ctx, OPCODE_ADD, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0], negate(inst->SrcReg[1]));
- emit3(ctx, OPCODE_CMP, inst->DstReg, srcreg(PROGRAM_TEMPORARY, tempreg), builtin_zero, builtin_one);
+ emit2(p, OPCODE_ADD, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0], negate(inst->SrcReg[1]));
+ emit3(p, OPCODE_CMP, inst->DstReg, srcreg(PROGRAM_TEMPORARY, tempreg), builtin_zero, builtin_one);
}
-static void transform_SLT(struct radeon_program_transform_context* ctx,
+static void transform_SLT(struct gl_program* p,
struct prog_instruction* inst)
{
- int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
+ int tempreg = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
- emit2(ctx, OPCODE_ADD, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0], negate(inst->SrcReg[1]));
- emit3(ctx, OPCODE_CMP, inst->DstReg, srcreg(PROGRAM_TEMPORARY, tempreg), builtin_one, builtin_zero);
+ emit2(p, OPCODE_ADD, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0], negate(inst->SrcReg[1]));
+ emit3(p, OPCODE_CMP, inst->DstReg, srcreg(PROGRAM_TEMPORARY, tempreg), builtin_one, builtin_zero);
}
-static void transform_SUB(struct radeon_program_transform_context* ctx,
+static void transform_SUB(struct gl_program* p,
struct prog_instruction* inst)
{
- emit2(ctx, OPCODE_ADD, inst->DstReg, inst->SrcReg[0], negate(inst->SrcReg[1]));
+ emit2(p, OPCODE_ADD, inst->DstReg, inst->SrcReg[0], negate(inst->SrcReg[1]));
}
-static void transform_SWZ(struct radeon_program_transform_context* ctx,
+static void transform_SWZ(struct gl_program* p,
struct prog_instruction* inst)
{
- emit1(ctx, OPCODE_MOV, inst->DstReg, inst->SrcReg[0]);
+ emit1(p, OPCODE_MOV, inst->DstReg, inst->SrcReg[0]);
}
-static void transform_XPD(struct radeon_program_transform_context* ctx,
+static void transform_XPD(struct gl_program* p,
struct prog_instruction* inst)
{
- int tempreg = radeonCompilerAllocateTemporary(ctx->compiler);
+ int tempreg = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
- emit2(ctx, OPCODE_MUL, dstreg(PROGRAM_TEMPORARY, tempreg),
+ emit2(p, OPCODE_MUL, dstreg(PROGRAM_TEMPORARY, tempreg),
swizzle(inst->SrcReg[0], SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W),
swizzle(inst->SrcReg[1], SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W));
- emit3(ctx, OPCODE_MAD, inst->DstReg,
+ emit3(p, OPCODE_MAD, inst->DstReg,
swizzle(inst->SrcReg[0], SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W),
swizzle(inst->SrcReg[1], SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W),
negate(srcreg(PROGRAM_TEMPORARY, tempreg)));
* @todo add LIT here as well?
*/
GLboolean radeonTransformALU(
- struct radeon_program_transform_context* ctx,
+ GLcontext* ctx,
+ struct gl_program* prog,
struct prog_instruction* inst,
void* unused)
{
switch(inst->Opcode) {
- case OPCODE_ABS: transform_ABS(ctx, inst); return GL_TRUE;
- case OPCODE_DPH: transform_DPH(ctx, inst); return GL_TRUE;
- case OPCODE_FLR: transform_FLR(ctx, inst); return GL_TRUE;
- case OPCODE_POW: transform_POW(ctx, inst); return GL_TRUE;
- case OPCODE_SGE: transform_SGE(ctx, inst); return GL_TRUE;
- case OPCODE_SLT: transform_SLT(ctx, inst); return GL_TRUE;
- case OPCODE_SUB: transform_SUB(ctx, inst); return GL_TRUE;
- case OPCODE_SWZ: transform_SWZ(ctx, inst); return GL_TRUE;
- case OPCODE_XPD: transform_XPD(ctx, inst); return GL_TRUE;
+ case OPCODE_ABS: transform_ABS(prog, inst); return GL_TRUE;
+ case OPCODE_DPH: transform_DPH(prog, inst); return GL_TRUE;
+ case OPCODE_FLR: transform_FLR(prog, inst); return GL_TRUE;
+ case OPCODE_POW: transform_POW(prog, inst); return GL_TRUE;
+ case OPCODE_SGE: transform_SGE(prog, inst); return GL_TRUE;
+ case OPCODE_SLT: transform_SLT(prog, inst); return GL_TRUE;
+ case OPCODE_SUB: transform_SUB(prog, inst); return GL_TRUE;
+ case OPCODE_SWZ: transform_SWZ(prog, inst); return GL_TRUE;
+ case OPCODE_XPD: transform_XPD(prog, inst); return GL_TRUE;
default:
return GL_FALSE;
}
#include "radeon_program.h"
GLboolean radeonTransformALU(
- struct radeon_program_transform_context*,
+ GLcontext*,
+ struct gl_program*,
struct prog_instruction*,
void*);