summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2010-08-22 03:20:19 +0200
committerMarek Olšák <maraeo@gmail.com>2010-08-25 02:44:28 +0200
commit3aee8c3b1d10f8e8978c1b902aff4347684d4e79 (patch)
tree63abb22b3867af002b2737c64b3937ac17936153 /src/mesa
parentcb925970eeade17016f59497d2123e4e8a447164 (diff)
r300/compiler: disable register allocation for indexable temporaries in VS
If there is relative addressing of temporaries, we cannot change register indices, so skip register allocation entirely. To utilize register allocation at least partially, we need separate indexable and non-indexable register files in both TGSI and Mesa IR.
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
index 666c9c2a7a..56c5fe6d96 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
@@ -624,10 +624,9 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
struct temporary_allocation * ta;
unsigned int i, j;
- compiler->code->num_temporaries = 0;
memset(hwtemps, 0, sizeof(hwtemps));
- /* Pass 1: Count original temporaries and allocate structures */
+ /* Pass 1: Count original temporaries. */
for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
@@ -645,12 +644,30 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
}
}
}
+ compiler->code->num_temporaries = num_orig_temps;
+
+ /* Pass 2: If there is relative addressing of temporaries, we cannot change register indices. Give up. */
+ for (inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
+ const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->U.I.Opcode);
+
+ if (opcode->HasDstReg)
+ if (inst->U.I.DstReg.RelAddr)
+ return;
+ for (i = 0; i < opcode->NumSrcRegs; ++i) {
+ if (inst->U.I.SrcReg[i].File == RC_FILE_TEMPORARY &&
+ inst->U.I.SrcReg[i].RelAddr) {
+ return;
+ }
+ }
+ }
+
+ compiler->code->num_temporaries = 0;
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 */
+ /* Pass 3: Determine original temporary lifetimes */
for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
/* Instructions inside of loops need to use the ENDLOOP
@@ -685,7 +702,7 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
}
}
- /* Pass 3: Register allocation */
+ /* Pass 4: Register allocation */
for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
@@ -937,9 +954,12 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
rc_dataflow_swizzles(&compiler->Base);
+ debug_program_log(compiler, "after dataflow");
+
allocate_temporary_registers(compiler);
- debug_program_log(compiler, "after dataflow");
+ debug_program_log(compiler, "after register allocation");
+
translate_vertex_program(compiler);