diff options
author | marha <marha@users.sourceforge.net> | 2011-02-09 07:47:31 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-02-09 07:47:31 +0000 |
commit | 51a59b7f7f9b134791d3b09673063e4c45ea9eee (patch) | |
tree | 52bb43362452042efcdebd64a85d7aa75319b64a /mesalib/src/mesa/program | |
parent | 53bf2508fe3d5bd7889ccf4817fcd2bcc531d6ae (diff) | |
download | vcxsrv-51a59b7f7f9b134791d3b09673063e4c45ea9eee.tar.gz vcxsrv-51a59b7f7f9b134791d3b09673063e4c45ea9eee.tar.bz2 vcxsrv-51a59b7f7f9b134791d3b09673063e4c45ea9eee.zip |
libX11 mesa git update 9 Feb 2011
Diffstat (limited to 'mesalib/src/mesa/program')
-rw-r--r-- | mesalib/src/mesa/program/ir_to_mesa.cpp | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 3794c0de0..d0ec23fc8 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -2742,13 +2742,46 @@ ir_to_mesa_visitor::copy_propagate(void) /* Continuing the block, clear any written channels from * the ACP. */ - if (inst->dst_reg.file == PROGRAM_TEMPORARY) { - if (inst->dst_reg.reladdr) { - memset(acp, 0, sizeof(*acp) * this->next_temp * 4); - } else { - for (int i = 0; i < 4; i++) { - if (inst->dst_reg.writemask & (1 << i)) { - acp[4 * inst->dst_reg.index + i] = NULL; + if (inst->dst_reg.file == PROGRAM_TEMPORARY && inst->dst_reg.reladdr) { + /* Any temporary might be written, so no copy propagation + * across this instruction. + */ + memset(acp, 0, sizeof(*acp) * this->next_temp * 4); + } else if (inst->dst_reg.file == PROGRAM_OUTPUT && + inst->dst_reg.reladdr) { + /* Any output might be written, so no copy propagation + * from outputs across this instruction. + */ + for (int r = 0; r < this->next_temp; r++) { + for (int c = 0; c < 4; c++) { + if (acp[4 * r + c]->src_reg[0].file == PROGRAM_OUTPUT) + acp[4 * r + c] = NULL; + } + } + } else if (inst->dst_reg.file == PROGRAM_TEMPORARY || + inst->dst_reg.file == PROGRAM_OUTPUT) { + /* Clear where it's used as dst. */ + if (inst->dst_reg.file == PROGRAM_TEMPORARY) { + for (int c = 0; c < 4; c++) { + if (inst->dst_reg.writemask & (1 << c)) { + acp[4 * inst->dst_reg.index + c] = NULL; + } + } + } + + /* Clear where it's used as src. */ + for (int r = 0; r < this->next_temp; r++) { + for (int c = 0; c < 4; c++) { + if (!acp[4 * r + c]) + continue; + + int src_chan = GET_SWZ(acp[4 * r + c]->src_reg[0].swizzle, c); + + if (acp[4 * r + c]->src_reg[0].file == inst->dst_reg.file && + acp[4 * r + c]->src_reg[0].index == inst->dst_reg.index && + inst->dst_reg.writemask & (1 << src_chan)) + { + acp[4 * r + c] = NULL; } } } |