cell: fix code emit for RSQ/RCP when src arg == dst arg
authorBrian Paul <brianp@vmware.com>
Tue, 6 Jan 2009 02:50:54 +0000 (19:50 -0700)
committerBrian Paul <brianp@vmware.com>
Tue, 6 Jan 2009 02:51:17 +0000 (19:51 -0700)
Fixes moire-like artifacts seen in fslight demo.

src/gallium/drivers/cell/ppu/cell_gen_fp.c

index b503bf56af6b0f75b74a0035ba09938a126323d5..8f3deb482e6ee337f26093716f263f23fcd49cbb 100644 (file)
@@ -728,7 +728,7 @@ emit_LERP(struct codegen *gen, const struct tgsi_full_instruction *inst)
 static boolean
 emit_RCP_RSQ(struct codegen *gen, const struct tgsi_full_instruction *inst)
 {
-   int ch, s1_reg[4], d_reg[4];
+   int ch, s1_reg[4], d_reg[4], tmp_reg[4];
 
    if (inst->Instruction.Opcode == TGSI_OPCODE_RCP) {
       spe_comment(gen->f, -4, "RCP:");
@@ -741,21 +741,23 @@ emit_RCP_RSQ(struct codegen *gen, const struct tgsi_full_instruction *inst)
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
       s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
       d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      tmp_reg[ch] = get_itemp(gen);
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
       if (inst->Instruction.Opcode == TGSI_OPCODE_RCP) {
-         /* d = 1/s1 */
-         spe_frest(gen->f, d_reg[ch], s1_reg[ch]);
+         /* tmp = 1/s1 */
+         spe_frest(gen->f, tmp_reg[ch], s1_reg[ch]);
       }
       else {
-         /* d = 1/sqrt(s1) */
-         spe_frsqest(gen->f, d_reg[ch], s1_reg[ch]);
+         /* tmp = 1/sqrt(s1) */
+         spe_frsqest(gen->f, tmp_reg[ch], s1_reg[ch]);
       }
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      spe_fi(gen->f, d_reg[ch], s1_reg[ch], d_reg[ch]);
+      /* d = float_interp(s1, tmp) */
+      spe_fi(gen->f, d_reg[ch], s1_reg[ch], tmp_reg[ch]);
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {