r300/compiler: allocate at least FS inputs if register allocation is disabled
authorMarek Olšák <maraeo@gmail.com>
Thu, 2 Sep 2010 05:01:36 +0000 (07:01 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sat, 4 Sep 2010 16:56:22 +0000 (18:56 +0200)
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h

index 137267f4a635052cbcc807eb4d62cbc65d59ee3a..4793f3357701a5805b3fd696c248e777c80ad674 100644 (file)
@@ -141,6 +141,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
                {"pair translate",              1, 1,           rc_pair_translate,              NULL},
                {"pair scheduling",             1, 1,           rc_pair_schedule,               NULL},
                {"register allocation",         1, opt,         rc_pair_regalloc,               NULL},
+               {"dumb register allocation",    1, !opt,        rc_pair_regalloc_inputs_only,   NULL},
                {"final code validation",       0, 1,           rc_validate_final_shader,       NULL},
                {"machine code generation",     0, is_r500,     r500BuildFragmentProgramHwCode, NULL},
                {"machine code generation",     0, !is_r500,    r300BuildFragmentProgramHwCode, NULL},
index d0ee497eca55ea17e8eba16e9a53233b922376bd..e54c93aee32148cee9ba7914a891cdb65a0f98ac 100644 (file)
@@ -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);
+               }
+       }
+}
index 28a163ff4471730bfe6e5fbd0b30fc57cb140aae..ef5a034700953742e09334edebe2d05d26607eb7 100644 (file)
@@ -121,6 +121,7 @@ struct radeon_pair_handler;
 void rc_pair_translate(struct radeon_compiler *cc, void *user);
 void rc_pair_schedule(struct radeon_compiler *cc, void *user);
 void rc_pair_regalloc(struct radeon_compiler *cc, void *user);
+void rc_pair_regalloc_inputs_only(struct radeon_compiler *cc, void *user);
 /*@}*/
 
 #endif /* __RADEON_PROGRAM_PAIR_H_ */