diff options
author | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2010-09-09 19:18:42 +0200 |
---|---|---|
committer | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2010-09-09 19:21:34 +0200 |
commit | 246ebd7df1854db22a7f46302ecb1b5d56b68855 (patch) | |
tree | b52b055476a8f91919cd09bb741489cf2eca54eb | |
parent | 9cc80e25db3d0bfd38015a197de3a1a80b6733ab (diff) |
nv50: duplicate interps in load_proj_tex_coords
Otherwise we might clobber the origin interpolation result or
use the result of the RCP before its definition.
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tgsi_to_nc.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c index 50f0151b53..4168bbbc95 100644 --- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c +++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c @@ -555,6 +555,34 @@ bld_insn_3(struct bld_context *bld, uint opcode, return bld_def(insn, 0, new_value(bld->pc, NV_FILE_GPR, src0->reg.as_type)); } +static struct nv_value * +bld_duplicate_insn(struct bld_context *bld, struct nv_instruction *nvi) +{ + struct nv_instruction *dupi = new_instruction(bld->pc, nvi->opcode); + int c; + + if (nvi->def[0]) + bld_def(dupi, 0, new_value_like(bld->pc, nvi->def[0])); + + if (nvi->flags_def) { + dupi->flags_def = new_value_like(bld->pc, nvi->flags_def); + dupi->flags_def->insn = dupi; + } + + for (c = 0; c < 5; ++c) + if (nvi->src[c]) + nv_reference(bld->pc, &dupi->src[c], nvi->src[c]->value); + if (nvi->flags_src) + nv_reference(bld->pc, &dupi->flags_src, nvi->flags_src->value); + + dupi->cc = nvi->cc; + dupi->saturate = nvi->saturate; + dupi->centroid = nvi->centroid; + dupi->flat = nvi->flat; + + return dupi->def[0]; +} + static void bld_lmem_store(struct bld_context *bld, struct nv_value *ptr, int ofst, struct nv_value *val) @@ -1232,6 +1260,7 @@ load_proj_tex_coords(struct bld_context *bld, t[3] = emit_fetch(bld, insn, 0, 3); if (t[3]->insn->opcode == NV_OP_PINTERP) { + t[3] = bld_duplicate_insn(bld, t[3]->insn); t[3]->insn->opcode = NV_OP_LINTERP; nv_reference(bld->pc, &t[3]->insn->src[1], NULL); } @@ -1240,13 +1269,15 @@ load_proj_tex_coords(struct bld_context *bld, for (c = 0; c < dim; ++c) { t[c] = emit_fetch(bld, insn, 0, c); - if (t[c]->insn->opcode == NV_OP_LINTERP) - t[c]->insn->opcode = NV_OP_PINTERP; - if (t[c]->insn->opcode == NV_OP_PINTERP) + if (t[c]->insn->opcode == NV_OP_LINTERP || + t[c]->insn->opcode == NV_OP_PINTERP) { + t[c] = bld_duplicate_insn(bld, t[c]->insn); + t[c]->insn->opcode = NV_OP_PINTERP; nv_reference(bld->pc, &t[c]->insn->src[1], t[3]); - else + } else { mask |= 1 << c; + } } for (c = 0; mask; ++c, mask >>= 1) { |