diff options
author | Nicolai Hähnle <[email protected]> | 2009-10-06 20:07:38 +0200 |
---|---|---|
committer | Nicolai Hähnle <[email protected]> | 2009-10-06 20:08:32 +0200 |
commit | 9e42f0ebc7e538e0bff7c8c8539532ff2fc3c475 (patch) | |
tree | c1d17aadad12c2a25231dc4368b683dd3893f702 /src/mesa | |
parent | a6b300ac98427eece73c312e6fc73f4127c6ab65 (diff) |
r300/compiler: Fix regression in pair scheduling
Signed-off-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c index ea01bb78819..df67aafe028 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c @@ -179,8 +179,19 @@ static void commit_instruction(struct schedule_state * s, struct schedule_instru for(unsigned int i = 0; i < sinst->NumWriteValues; ++i) { struct reg_value * v = sinst->WriteValues[i]; - for(struct reg_value_reader * r = v->Readers; r; r = r->Next) { - decrease_dependencies(s, r->Reader); + if (v->NumReaders) { + for(struct reg_value_reader * r = v->Readers; r; r = r->Next) { + decrease_dependencies(s, r->Reader); + } + } else { + /* This happens in instruction sequences of the type + * OP r.x, ...; + * OP r.x, r.x, ...; + * See also the subtlety in how instructions that both + * read and write the same register are scanned. + */ + if (v->Next) + decrease_dependencies(s, v->Next->Writer); } } } @@ -360,6 +371,13 @@ static void scan_read(void * data, struct rc_instruction * inst, if (!v) return; + if (v->Writer == s->Current) { + /* The instruction reads and writes to a register component. + * In this case, we only want to increment dependencies by one. + */ + return; + } + DBG("%i: read %i[%i] chan %i\n", s->Current->Instruction->IP, file, index, chan); struct reg_value_reader * reader = memory_pool_malloc(&s->C->Pool, sizeof(*reader)); @@ -426,8 +444,12 @@ static void schedule_block(struct r300_fragment_program_compiler * c, DBG("%i: Scanning\n", inst->IP); - rc_for_all_reads(inst, &scan_read, &s); + /* The order of things here is subtle and maybe slightly + * counter-intuitive, to account for the case where an + * instruction writes to the same register as it reads + * from. */ rc_for_all_writes(inst, &scan_write, &s); + rc_for_all_reads(inst, &scan_read, &s); DBG("%i: Has %i dependencies\n", inst->IP, s.Current->NumDependencies); |