r300: Remove clause stuff for now in favour of a cloned generic gl_program

This commit is contained in:
Nicolai Haehnle
2008-07-05 11:53:39 +02:00
parent 85b46fbe9c
commit dea8719f00
10 changed files with 157 additions and 460 deletions
+25 -30
View File
@@ -68,7 +68,7 @@ static void reset_srcreg(struct prog_src_register* reg)
* 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 =
@@ -84,12 +84,11 @@ static GLboolean transform_TEX(
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;
@@ -99,7 +98,7 @@ static GLboolean transform_TEX(
}
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;
}
@@ -114,7 +113,7 @@ static GLboolean transform_TEX(
0
};
int tempreg = radeonCompilerAllocateTemporary(context->compiler);
int tempreg = _mesa_find_free_register(p, PROGRAM_TEMPORARY);
int factor_index;
tokens[2] = inst.TexSrcUnit;
@@ -122,8 +121,7 @@ static GLboolean transform_TEX(
_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;
@@ -142,10 +140,9 @@ static GLboolean transform_TEX(
*/
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;
@@ -160,7 +157,7 @@ static GLboolean transform_TEX(
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;
@@ -169,18 +166,16 @@ static GLboolean transform_TEX(
}
}
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;
@@ -227,8 +222,7 @@ static GLboolean transform_TEX(
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;
@@ -274,9 +268,10 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
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;
@@ -333,7 +328,7 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
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 &&
@@ -404,8 +399,7 @@ void r300TranslateFragmentShader(r300ContextPtr r300,
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);
@@ -413,19 +407,20 @@ void r300TranslateFragmentShader(r300ContextPtr r300,
{ &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;
+1 -2
View File
@@ -146,10 +146,9 @@ struct r300_fragment_program_compiler {
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);
+7 -12
View File
@@ -1887,18 +1887,13 @@ static void emit_instruction(struct r300_pfs_compile_state *cs, struct prog_inst
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;
@@ -1988,8 +1983,8 @@ static void init_program(struct r300_pfs_compile_state *cs)
/* 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++) {
+23 -27
View File
@@ -36,7 +36,7 @@
*
*/
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 =
@@ -53,12 +53,11 @@ static GLboolean transform_TEX(
/* 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;
@@ -70,22 +69,20 @@ static GLboolean transform_TEX(
}
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;
@@ -132,17 +129,12 @@ static GLboolean transform_TEX(
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;
@@ -183,9 +175,10 @@ static void insert_WPOS_trailer(struct r500_fragment_program_compiler *compiler)
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;
@@ -242,7 +235,7 @@ static void insert_WPOS_trailer(struct r500_fragment_program_compiler *compiler)
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 &&
@@ -314,26 +307,29 @@ void r500TranslateFragmentShader(r300ContextPtr r300,
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);
+1 -1
View File
@@ -84,7 +84,7 @@ struct r500_fragment_program_compiler {
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);
+14 -26
View File
@@ -282,7 +282,7 @@ static GLuint make_src(struct r500_pfs_compile_state *cs, struct prog_src_regist
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:
@@ -1256,21 +1256,14 @@ static int do_inst(struct r500_pfs_compile_state *cs, struct prog_instruction *f
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...) */
@@ -1365,19 +1358,14 @@ static void init_program(struct r500_pfs_compile_state *cs)
cs->inputs[i].reg = 0;
}
int clauseidx;
int ip;
for (clauseidx = 0; clauseidx < cs->compiler->compiler.NumClauses; ++clauseidx) {
struct radeon_clause* clause = &cs->compiler->compiler.Clauses[clauseidx];
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;
}
}
}
+27 -214
View File
@@ -29,201 +29,6 @@
#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:
@@ -240,42 +45,50 @@ struct prog_instruction* radeonClauseInsertInstructions(
* \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;
}
+9 -94
View File
@@ -49,96 +49,7 @@ enum {
#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
@@ -149,16 +60,20 @@ struct radeon_program_transform_context {
*/
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
+48 -53
View File
@@ -36,13 +36,11 @@
#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;
@@ -50,13 +48,11 @@ static struct prog_instruction *emit1(struct radeon_program_transform_context* c
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;
@@ -65,14 +61,12 @@ static struct prog_instruction *emit2(struct radeon_program_transform_context* c
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;
@@ -154,24 +148,24 @@ static struct prog_src_register scalar(struct prog_src_register reg)
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;
@@ -180,70 +174,70 @@ static void transform_DPH(struct radeon_program_transform_context* ctx,
}
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)));
@@ -264,20 +258,21 @@ static void transform_XPD(struct radeon_program_transform_context* ctx,
* @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;
}
@@ -31,7 +31,8 @@
#include "radeon_program.h"
GLboolean radeonTransformALU(
struct radeon_program_transform_context*,
GLcontext*,
struct gl_program*,
struct prog_instruction*,
void*);