summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/r300/radeon_program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/r300/radeon_program.c')
-rw-r--r--src/mesa/drivers/dri/r300/radeon_program.c275
1 files changed, 61 insertions, 214 deletions
diff --git a/src/mesa/drivers/dri/r300/radeon_program.c b/src/mesa/drivers/dri/r300/radeon_program.c
index c8f40e81893..da5e7aefce5 100644
--- a/src/mesa/drivers/dri/r300/radeon_program.c
+++ b/src/mesa/drivers/dri/r300/radeon_program.c
@@ -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,84 @@ 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 radeon_transform_context ctx;
int ip;
- source = *clause;
- clause->Instructions = 0;
- clause->NumInstructions = 0;
- clause->ReservedInstructions = 0;
+ ctx.Ctx = Ctx;
+ ctx.Program = program;
+ ctx.OldInstructions = program->Instructions;
+ ctx.OldNumInstructions = 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 < ctx.OldNumInstructions; ++ip) {
+ struct prog_instruction *instr = ctx.OldInstructions + 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, 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(ctx.OldInstructions, ctx.OldNumInstructions);
+}
+
+
+static void scan_instructions(GLboolean* used, const struct prog_instruction* insts, GLuint count)
+{
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ const struct prog_instruction *inst = insts + i;
+ const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
+ GLuint k;
+
+ for (k = 0; k < n; k++) {
+ if (inst->SrcReg[k].File == PROGRAM_TEMPORARY)
+ used[inst->SrcReg[k].Index] = GL_TRUE;
}
}
+}
- _mesa_free_instructions(source.Instructions, source.NumInstructions);
+GLint radeonFindFreeTemporary(struct radeon_transform_context *t)
+{
+ GLboolean used[MAX_PROGRAM_TEMPS];
+ GLuint i;
+
+ _mesa_memset(used, 0, sizeof(used));
+ scan_instructions(used, t->Program->Instructions, t->Program->NumInstructions);
+ scan_instructions(used, t->OldInstructions, t->OldNumInstructions);
+
+ for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+ if (!used[i])
+ return i;
+ }
+
+ return -1;
+}
+
+
+/**
+ * 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;
}