r300: Remove dependency on GLcontext from compiler
authorNicolai Hähnle <nhaehnle@gmail.com>
Thu, 23 Jul 2009 19:10:37 +0000 (21:10 +0200)
committerNicolai Hähnle <nhaehnle@gmail.com>
Mon, 27 Jul 2009 18:32:06 +0000 (20:32 +0200)
Unfortunately, this does cause some code duplication (which we can hopefully
eliminate eventually).

Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
src/mesa/drivers/dri/r300/r300_vertprog.c

index 400408620ea465f7c1c434d46994976fcfdbed31..a0e081fe6f8eb6fa65f23cacf903d4d15e9ada15 100644 (file)
@@ -28,7 +28,6 @@
 #include "radeon_program.h"
 #include "radeon_program_alu.h"
 
-#include "shader/prog_optimize.h"
 #include "shader/prog_print.h"
 
 
@@ -438,6 +437,100 @@ static GLboolean translate_vertex_program(struct r300_vertex_program_compiler *
        return GL_TRUE;
 }
 
+struct temporary_allocation {
+       GLuint Allocated:1;
+       GLuint HwTemp:15;
+       struct prog_instruction * LastRead;
+};
+
+static void allocate_temporary_registers(struct r300_vertex_program_compiler * compiler)
+{
+       struct prog_instruction *inst;
+       GLuint num_orig_temps = 0;
+       GLboolean hwtemps[VSF_MAX_FRAGMENT_TEMPS];
+       struct temporary_allocation * ta;
+       GLuint i, j;
+
+       compiler->code->num_temporaries = 0;
+       memset(hwtemps, 0, sizeof(hwtemps));
+
+       /* Pass 1: Count original temporaries and allocate structures */
+       for(inst = compiler->program->Instructions; inst->Opcode != OPCODE_END; inst++) {
+               GLuint numsrcs = _mesa_num_inst_src_regs(inst->Opcode);
+               GLuint numdsts = _mesa_num_inst_dst_regs(inst->Opcode);
+
+               for (i = 0; i < numsrcs; ++i) {
+                       if (inst->SrcReg[i].File == PROGRAM_TEMPORARY) {
+                               if (inst->SrcReg[i].Index >= num_orig_temps)
+                                       num_orig_temps = inst->SrcReg[i].Index + 1;
+                       }
+               }
+
+               if (numdsts) {
+                       if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+                               if (inst->DstReg.Index >= num_orig_temps)
+                                       num_orig_temps = inst->DstReg.Index + 1;
+                       }
+               }
+       }
+
+       ta = (struct temporary_allocation*)memory_pool_malloc(&compiler->Base.Pool,
+                       sizeof(struct temporary_allocation) * num_orig_temps);
+       memset(ta, 0, sizeof(struct temporary_allocation) * num_orig_temps);
+
+       /* Pass 2: Determine original temporary lifetimes */
+       for(inst = compiler->program->Instructions; inst->Opcode != OPCODE_END; inst++) {
+               GLuint numsrcs = _mesa_num_inst_src_regs(inst->Opcode);
+
+               for (i = 0; i < numsrcs; ++i) {
+                       if (inst->SrcReg[i].File == PROGRAM_TEMPORARY)
+                               ta[inst->SrcReg[i].Index].LastRead = inst;
+               }
+       }
+
+       /* Pass 3: Register allocation */
+       for(inst = compiler->program->Instructions; inst->Opcode != OPCODE_END; inst++) {
+               GLuint numsrcs = _mesa_num_inst_src_regs(inst->Opcode);
+               GLuint numdsts = _mesa_num_inst_dst_regs(inst->Opcode);
+
+               for (i = 0; i < numsrcs; ++i) {
+                       if (inst->SrcReg[i].File == PROGRAM_TEMPORARY) {
+                               GLuint orig = inst->SrcReg[i].Index;
+                               inst->SrcReg[i].Index = ta[orig].HwTemp;
+
+                               if (ta[orig].Allocated && inst == ta[orig].LastRead)
+                                       hwtemps[ta[orig].HwTemp] = GL_FALSE;
+                       }
+               }
+
+               if (numdsts) {
+                       if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+                               GLuint orig = inst->DstReg.Index;
+
+                               if (!ta[orig].Allocated) {
+                                       for(j = 0; j < VSF_MAX_FRAGMENT_TEMPS; ++j) {
+                                               if (!hwtemps[j])
+                                                       break;
+                                       }
+                                       if (j >= VSF_MAX_FRAGMENT_TEMPS) {
+                                               fprintf(stderr, "Out of hw temporaries\n");
+                                       } else {
+                                               ta[orig].Allocated = GL_TRUE;
+                                               ta[orig].HwTemp = j;
+                                               hwtemps[j] = GL_TRUE;
+
+                                               if (j >= compiler->code->num_temporaries)
+                                                       compiler->code->num_temporaries = j + 1;
+                                       }
+                               }
+
+                               inst->DstReg.Index = ta[orig].HwTemp;
+                       }
+               }
+       }
+}
+
+
 /**
  * Vertex engine cannot read two inputs or two constants at the same time.
  * Introduce intermediate MOVs to temporary registers to account for this.
@@ -675,7 +768,7 @@ static GLboolean swizzleIsNative(GLuint opcode, struct prog_src_register reg)
 
 
 
-GLboolean r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler, GLcontext * ctx)
+GLboolean r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
 {
        GLboolean success;
 
@@ -728,7 +821,7 @@ GLboolean r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compi
                radeonNqssaDce(compiler->program, &nqssadce, compiler);
 
                /* We need this step for reusing temporary registers */
-               _mesa_optimize_program(ctx, compiler->program);
+               allocate_temporary_registers(compiler);
 
                if (compiler->Base.Debug) {
                        fprintf(stderr, "Vertex program after NQSSADCE:\n");
@@ -738,38 +831,6 @@ GLboolean r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compi
        }
 
        assert(compiler->program->NumInstructions);
-       {
-               struct prog_instruction *inst;
-               int max, i, tmp;
-
-               inst = compiler->program->Instructions;
-               max = -1;
-               while (inst->Opcode != OPCODE_END) {
-                       tmp = _mesa_num_inst_src_regs(inst->Opcode);
-                       for (i = 0; i < tmp; ++i) {
-                               if (inst->SrcReg[i].File == PROGRAM_TEMPORARY) {
-                                       if ((int) inst->SrcReg[i].Index > max) {
-                                               max = inst->SrcReg[i].Index;
-                                       }
-                               }
-                       }
-
-                       if (_mesa_num_inst_dst_regs(inst->Opcode)) {
-                               if (inst->DstReg.File == PROGRAM_TEMPORARY) {
-                                       if ((int) inst->DstReg.Index > max) {
-                                               max = inst->DstReg.Index;
-                                       }
-                               }
-                       }
-                       ++inst;
-               }
-
-               /* We actually want highest index of used temporary register,
-                * not the number of temporaries used.
-                * These values aren't always the same.
-                */
-               compiler->code->num_temporaries = max + 1;
-       }
 
        success = translate_vertex_program(compiler);
 
index f8e4b3c681afc320d3977fe2e6b2a8e7cc1576ab..b98b1c9e6b5c3290abfeb1c956a2c02c59f6559b 100644 (file)
@@ -74,6 +74,6 @@ struct r300_vertex_program_compiler {
        struct gl_program *program;
 };
 
-GLboolean r3xx_compile_vertex_program(struct r300_vertex_program_compiler* c, GLcontext * ctx);
+GLboolean r3xx_compile_vertex_program(struct r300_vertex_program_compiler* c);
 
 #endif /* RADEON_COMPILER_H */
index ec4ba9ca7daf2b225d90adabfab182064a2b6c8e..dfb2a9e3d859a5cb8a00e3e835aa7a7e84a9095b 100644 (file)
@@ -125,7 +125,7 @@ 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, ctx))
+       if (!r3xx_compile_vertex_program(&compiler))
                vp->error = GL_TRUE;
 
        rc_destroy(&compiler.Base);