summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r300/compiler/r3xx_vertprog.c10
-rw-r--r--src/gallium/drivers/r300/compiler/radeon_compiler_util.c18
-rw-r--r--src/gallium/drivers/r300/compiler/radeon_compiler_util.h1
-rw-r--r--src/gallium/drivers/r300/compiler/radeon_opcodes.c2
-rw-r--r--src/gallium/drivers/r300/compiler/radeon_pair_translate.c8
5 files changed, 33 insertions, 6 deletions
diff --git a/src/gallium/drivers/r300/compiler/r3xx_vertprog.c b/src/gallium/drivers/r300/compiler/r3xx_vertprog.c
index 654f9a070d5..a8d8ebc2dc8 100644
--- a/src/gallium/drivers/r300/compiler/r3xx_vertprog.c
+++ b/src/gallium/drivers/r300/compiler/r3xx_vertprog.c
@@ -163,11 +163,13 @@ static unsigned long t_src_scalar(struct r300_vertex_program_code *vp,
/* src->Negate uses the RC_MASK_ flags from program_instruction.h,
* which equal our VSF_FLAGS_ values, so it's safe to just pass it here.
*/
+ unsigned int swz = rc_get_scalar_src_swz(src->Swizzle);
+
return PVS_SRC_OPERAND(t_src_index(vp, src),
- t_swizzle(GET_SWZ(src->Swizzle, 0)),
- t_swizzle(GET_SWZ(src->Swizzle, 0)),
- t_swizzle(GET_SWZ(src->Swizzle, 0)),
- t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_swizzle(swz),
+ t_swizzle(swz),
+ t_swizzle(swz),
+ t_swizzle(swz),
t_src_class(src->File),
src->Negate ? RC_MASK_XYZW : RC_MASK_NONE) |
(src->RelAddr << 4) | (src->Abs << 3);
diff --git a/src/gallium/drivers/r300/compiler/radeon_compiler_util.c b/src/gallium/drivers/r300/compiler/radeon_compiler_util.c
index 33dbe0e86e9..36a634114d6 100644
--- a/src/gallium/drivers/r300/compiler/radeon_compiler_util.c
+++ b/src/gallium/drivers/r300/compiler/radeon_compiler_util.c
@@ -734,3 +734,21 @@ float rc_get_constant_value(
return base *
c->Program.Constants.Constants[index].u.Immediate[swz];
}
+
+/**
+ * This function returns the component value (RC_SWIZZLE_*) of the first used
+ * channel in the swizzle. This is only useful for scalar instructions that are
+ * known to use only one channel of the swizzle.
+ */
+unsigned int rc_get_scalar_src_swz(unsigned int swizzle)
+{
+ unsigned int swz, chan;
+ for (chan = 0; chan < 4; chan++) {
+ swz = GET_SWZ(swizzle, chan);
+ if (swz != RC_SWIZZLE_UNUSED) {
+ break;
+ }
+ }
+ assert(swz != RC_SWIZZLE_UNUSED);
+ return swz;
+}
diff --git a/src/gallium/drivers/r300/compiler/radeon_compiler_util.h b/src/gallium/drivers/r300/compiler/radeon_compiler_util.h
index 58bdb3c684b..ae5288e405e 100644
--- a/src/gallium/drivers/r300/compiler/radeon_compiler_util.h
+++ b/src/gallium/drivers/r300/compiler/radeon_compiler_util.h
@@ -98,5 +98,6 @@ float rc_get_constant_value(
unsigned int negate,
unsigned int chan);
+unsigned int rc_get_scalar_src_swz(unsigned int swizzle);
#endif /* RADEON_PROGRAM_UTIL_H */
diff --git a/src/gallium/drivers/r300/compiler/radeon_opcodes.c b/src/gallium/drivers/r300/compiler/radeon_opcodes.c
index 527db9a1f69..3b49ad7114c 100644
--- a/src/gallium/drivers/r300/compiler/radeon_opcodes.c
+++ b/src/gallium/drivers/r300/compiler/radeon_opcodes.c
@@ -463,7 +463,7 @@ void rc_compute_sources_for_writemask(
srcmasks[src] |= writemask;
} else if (opcode->IsStandardScalar) {
for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
- srcmasks[src] |= RC_MASK_X;
+ srcmasks[src] |= writemask;
} else {
switch(opcode->Opcode) {
case RC_OPCODE_ARL:
diff --git a/src/gallium/drivers/r300/compiler/radeon_pair_translate.c b/src/gallium/drivers/r300/compiler/radeon_pair_translate.c
index 3d9cf3b43ed..7d9c8d1fab6 100644
--- a/src/gallium/drivers/r300/compiler/radeon_pair_translate.c
+++ b/src/gallium/drivers/r300/compiler/radeon_pair_translate.c
@@ -247,7 +247,13 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c,
if (needalpha) {
unsigned int srcrgb = 0;
unsigned int srcalpha = 0;
- unsigned int swz = GET_SWZ(inst->SrcReg[i].Swizzle, istranscendent ? 0 : 3);
+ unsigned int swz;
+ if (istranscendent) {
+ swz = rc_get_scalar_src_swz(inst->SrcReg[i].Swizzle);
+ } else {
+ swz = GET_SWZ(inst->SrcReg[i].Swizzle, 3);
+ }
+
if (swz < 3)
srcrgb = 1;
else if (swz < 4)