diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c index faf531b412..acdb371de9 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c @@ -157,8 +157,12 @@ static void update_instruction(struct deadcode_state * s, struct rc_instruction unsigned char * pused = get_used_ptr(s, inst->U.I.DstReg.File, inst->U.I.DstReg.Index); if (pused) { usedmask = *pused & inst->U.I.DstReg.WriteMask; - *pused &= ~usedmask; + if (!inst->U.I.DstReg.RelAddr) + *pused &= ~usedmask; } + + if (inst->U.I.DstReg.RelAddr) + mark_used(s, RC_FILE_ADDRESS, 0, RC_MASK_X); } insts->WriteMask |= usedmask; @@ -213,6 +217,7 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f { struct deadcode_state s; unsigned int nr_instructions; + unsigned has_temp_reladdr_src = 0; memset(&s, 0, sizeof(s)); s.C = c; @@ -300,6 +305,30 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f rc_error(c, "%s: Unhandled control flow instruction %s\n", __FUNCTION__, opcode->Name); } } + + if (!has_temp_reladdr_src) { + for (unsigned i = 0; i < opcode->NumSrcRegs; i++) { + if (inst->U.I.SrcReg[i].File == RC_FILE_TEMPORARY && + inst->U.I.SrcReg[i].RelAddr) { + /* If there is a register read from a temporary file with relative addressing, + * mark all preceding written registers as used. */ + for (struct rc_instruction *ptr = inst->Prev; + ptr != &c->Program.Instructions; + ptr = ptr->Prev) { + if (opcode->HasDstReg && + ptr->U.I.DstReg.File == RC_FILE_TEMPORARY && + ptr->U.I.DstReg.WriteMask) { + mark_used(&s, + ptr->U.I.DstReg.File, + ptr->U.I.DstReg.Index, + ptr->U.I.DstReg.WriteMask); + } + } + + has_temp_reladdr_src = 1; + } + } + } } update_instruction(&s, inst); |