st/nine: Fix SINCOS input
authorAxel Davy <davyaxel0@gmail.com>
Sat, 13 Apr 2019 10:25:57 +0000 (12:25 +0200)
committerAxel Davy <davyaxel0@gmail.com>
Tue, 30 Apr 2019 17:18:50 +0000 (19:18 +0200)
SINCOS takes an input with replicated swizzle.
the swizzle can be on any component, not just x.
Enable it to read from any component, but also
use a temporary register to avoid dst/src aliasing.

No known game is fixed by this change as it seems
the input swizzle is commonly on x for this instruction,
and src and dst don't alias.

Signed-off-by: Axel Davy <davyaxel0@gmail.com>
src/gallium/state_trackers/nine/nine_shader.c

index 0da60932f482b1b228a4853c545d78caad5181fc..57bf5efd5dcc0fe95e14a9db60e06ea23d30d428 100644 (file)
@@ -1807,14 +1807,19 @@ DECL_SPECIAL(SINCOS)
     struct ureg_program *ureg = tx->ureg;
     struct ureg_dst dst = tx_dst_param(tx, &tx->insn.dst[0]);
     struct ureg_src src = tx_src_param(tx, &tx->insn.src[0]);
+    struct ureg_dst tmp = tx_scratch_scalar(tx);
 
     assert(!(dst.WriteMask & 0xc));
 
+    /* Copying to a temporary register avoids src/dst aliasing.
+     * src is supposed to have replicated swizzle. */
+    ureg_MOV(ureg, tmp, src);
+
     /* z undefined, w untouched */
     ureg_COS(ureg, ureg_writemask(dst, TGSI_WRITEMASK_X),
-             ureg_scalar(src, TGSI_SWIZZLE_X));
+             tx_src_scalar(tmp));
     ureg_SIN(ureg, ureg_writemask(dst, TGSI_WRITEMASK_Y),
-             ureg_scalar(src, TGSI_SWIZZLE_X));
+             tx_src_scalar(tmp));
     return D3D_OK;
 }