I missed the fact that the ARB_fragment_program SWZ instruction allows per-component negation. To fix this, move Abs/Negate handling into both the simple case and the SWZ case's per-component loop.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90000 Signed-off-by: Kenneth Graunke <kenn...@whitecape.org> --- src/mesa/program/prog_to_nir.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c index c738f50..ff3d9f3 100644 --- a/src/mesa/program/prog_to_nir.c +++ b/src/mesa/program/prog_to_nir.c @@ -222,12 +222,23 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src) } nir_ssa_def *def; - if (!HAS_EXTENDED_SWIZZLE(prog_src->Swizzle)) { + if (!HAS_EXTENDED_SWIZZLE(prog_src->Swizzle) && + (prog_src->Negate == NEGATE_NONE || prog_src->Negate == NEGATE_XYZW)) { + /* The simple non-SWZ case. */ for (int i = 0; i < 4; i++) src.swizzle[i] = GET_SWZ(prog_src->Swizzle, i); def = nir_fmov_alu(b, src, 4); + + if (prog_src->Abs) + def = nir_fabs(b, def); + + if (prog_src->Negate) + def = nir_fneg(b, def); } else { + /* The SWZ instruction allows per-component zero/one swizzles, and also + * per-component negation. + */ nir_ssa_def *chans[4]; for (int i = 0; i < 4; i++) { int swizzle = GET_SWZ(prog_src->Swizzle, i); @@ -246,16 +257,16 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src) chans[i] = &mov->dest.dest.ssa; } + + if (prog_src->Abs) + chans[i] = nir_fabs(b, chans[i]); + + if (prog_src->Negate & (1 << i)) + chans[i] = nir_fneg(b, chans[i]); } def = nir_vec4(b, chans[0], chans[1], chans[2], chans[3]); } - if (prog_src->Abs) - def = nir_fabs(b, def); - - if (prog_src->Negate) - def = nir_fneg(b, def); - return def; } -- 2.3.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev