summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2013-07-26 21:39:27 +0200
committerRoland Scheidegger <[email protected]>2013-07-27 16:41:29 +0200
commit47e528b740c2a470fbf612029c0255d1224d77cd (patch)
treea9482878bfda02a8ac85c9d275fbdb21855f6683 /src/gallium
parentabcc40e7f05fcc1fd28f226f132f500a703d1e5d (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c40
1 files changed, 35 insertions, 5 deletions
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);
}
}
}