summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2010-09-02 07:01:36 +0200
committerMarek Olšák <maraeo@gmail.com>2010-09-04 18:56:22 +0200
commitf90c870304ad7222779c3e3bed0e2bbd4214d0cf (patch)
treec64f0816e48a730c6082dadb7b4dacaec5478620 /src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
parentcfc461fca6ad5656f58c48803d13052537063316 (diff)
r300/compiler: allocate at least FS inputs if register allocation is disabled
Diffstat (limited to 'src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c')
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c59
1 files changed, 50 insertions, 9 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
index d0ee497eca..e54c93aee3 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
@@ -189,8 +189,17 @@ static void scan_callback(void * data, struct rc_instruction * inst,
reg->Live.End = inst->IP;
}
-static void compute_live_intervals(struct regalloc_state * s)
+static void compute_live_intervals(struct radeon_compiler *c,
+ struct regalloc_state *s)
{
+ memset(s, 0, sizeof(*s));
+ s->C = c;
+ s->NumHwTemporaries = c->max_temp_regs;
+ s->HwTemporary =
+ memory_pool_malloc(&c->Pool,
+ s->NumHwTemporaries * sizeof(struct hardware_register));
+ memset(s->HwTemporary, 0, s->NumHwTemporaries * sizeof(struct hardware_register));
+
rc_recompute_ips(s->C);
for(struct rc_instruction * inst = s->C->Program.Instructions.Next;
@@ -295,18 +304,50 @@ static void alloc_input(void * data, unsigned int input, unsigned int hwreg)
void rc_pair_regalloc(struct radeon_compiler *cc, void *user)
{
struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc;
- unsigned maxtemps = c->Base.max_temp_regs;
struct regalloc_state s;
- memset(&s, 0, sizeof(s));
- s.C = &c->Base;
- s.NumHwTemporaries = maxtemps;
- s.HwTemporary = memory_pool_malloc(&s.C->Pool, maxtemps*sizeof(struct hardware_register));
- memset(s.HwTemporary, 0, maxtemps*sizeof(struct hardware_register));
-
- compute_live_intervals(&s);
+ compute_live_intervals(cc, &s);
c->AllocateHwInputs(c, &alloc_input, &s);
do_regalloc(&s);
}
+
+/* This functions offsets the temporary register indices by the number
+ * of input registers, because input registers are actually temporaries and
+ * should not occupy the same space.
+ *
+ * This pass is supposed to be used to maintain correct allocation of inputs
+ * if the standard register allocation is disabled. */
+void rc_pair_regalloc_inputs_only(struct radeon_compiler *cc, void *user)
+{
+ struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc;
+ struct regalloc_state s;
+
+ compute_live_intervals(cc, &s);
+
+ c->AllocateHwInputs(c, &alloc_input, &s);
+
+ int temp_reg_offset = 0;
+ for (unsigned i = 0; i < RC_REGISTER_MAX_INDEX; i++) {
+ if (s.Input[i].Allocated && temp_reg_offset <= s.Input[i].Index)
+ temp_reg_offset = s.Input[i].Index + 1;
+ }
+
+ if (temp_reg_offset) {
+ for (unsigned i = 0; i < RC_REGISTER_MAX_INDEX; i++) {
+ if (s.Temporary[i].Used) {
+ s.Temporary[i].Allocated = 1;
+ s.Temporary[i].File = RC_FILE_TEMPORARY;
+ s.Temporary[i].Index = i + temp_reg_offset;
+ }
+ }
+
+ /* Rewrite all registers. */
+ for (struct rc_instruction *inst = cc->Program.Instructions.Next;
+ inst != &cc->Program.Instructions;
+ inst = inst->Next) {
+ rc_remap_registers(inst, &remap_register, &s);
+ }
+ }
+}