From 47e528b740c2a470fbf612029c0255d1224d77cd Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 26 Jul 2013 21:39:27 +0200 Subject: tgsi: handle texel swizzles correctly for d3d10-style sample opcodes Same as for gallivm (though these don't quite work correctly in softpipe, so untested). Reviewed-by: Jose Fonseca --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 40 +++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'src/gallium/auxiliary/tgsi/tgsi_exec.c') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 1f8e62d6f3e..3ac69017a80 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -2041,9 +2041,25 @@ exec_txf(struct tgsi_exec_machine *mach, r[3].f[j] = rgba[3][j]; } - for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { - if (inst->Dst[0].Register.WriteMask & (1 << chan)) { - store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); + if (inst->Instruction.Opcode == TGSI_OPCODE_SAMPLE_I) { + unsigned char swizzles[4]; + swizzles[0] = inst->Src[1].Register.SwizzleX; + swizzles[1] = inst->Src[1].Register.SwizzleY; + swizzles[2] = inst->Src[1].Register.SwizzleZ; + swizzles[3] = inst->Src[1].Register.SwizzleW; + + for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + store_dest(mach, &r[swizzles[chan]], + &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); + } + } + } + else { + for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); + } } } } @@ -2087,6 +2103,7 @@ exec_sample(struct tgsi_exec_machine *mach, const union tgsi_exec_channel *lod = &ZeroVec; enum tgsi_sampler_control control = tgsi_sampler_lod_none; uint chan; + unsigned char swizzles[4]; int8_t offsets[3]; /* always fetch all 3 offsets, overkill but keeps code simple */ @@ -2193,9 +2210,15 @@ exec_sample(struct tgsi_exec_machine *mach, assert(0); } + swizzles[0] = inst->Src[1].Register.SwizzleX; + swizzles[1] = inst->Src[1].Register.SwizzleY; + swizzles[2] = inst->Src[1].Register.SwizzleZ; + swizzles[3] = inst->Src[1].Register.SwizzleW; + for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { if (inst->Dst[0].Register.WriteMask & (1 << chan)) { - store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); + store_dest(mach, &r[swizzles[chan]], + &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); } } } @@ -2209,6 +2232,7 @@ exec_sample_d(struct tgsi_exec_machine *mach, union tgsi_exec_channel r[4]; float derivs[3][2][TGSI_QUAD_SIZE]; uint chan; + unsigned char swizzles[4]; int8_t offsets[3]; /* always fetch all 3 offsets, overkill but keeps code simple */ @@ -2268,9 +2292,15 @@ exec_sample_d(struct tgsi_exec_machine *mach, assert(0); } + swizzles[0] = inst->Src[1].Register.SwizzleX; + swizzles[1] = inst->Src[1].Register.SwizzleY; + swizzles[2] = inst->Src[1].Register.SwizzleZ; + swizzles[3] = inst->Src[1].Register.SwizzleW; + for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { if (inst->Dst[0].Register.WriteMask & (1 << chan)) { - store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); + store_dest(mach, &r[swizzles[chan]], + &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); } } } -- cgit v1.2.3