r300/compiler: Use consistent src swizzles for transcendent instructions
authorTom Stellard <tstellar@gmail.com>
Sun, 2 Oct 2011 04:06:12 +0000 (21:06 -0700)
committerTom Stellard <tstellar@gmail.com>
Sun, 2 Oct 2011 22:21:15 +0000 (15:21 -0700)
Source swizzles for transcendent instructions were being stored in the X
channel regardless of what channel the instruction was writing.
This was causing problems for some helper functions that were expecting
source swizzles to occupy channels corresponding to the instruction's
writemask.  This commit makes transcendent instructions follow the same
convention as normal instructions for representing source swizzles.

Previous behavior:
LG2 temp[0].y, input[0].x___;

Current behavior:
LG2 temp[0].y, input[0]._x__;

src/gallium/drivers/r300/compiler/r3xx_vertprog.c
src/gallium/drivers/r300/compiler/radeon_compiler_util.c
src/gallium/drivers/r300/compiler/radeon_compiler_util.h
src/gallium/drivers/r300/compiler/radeon_opcodes.c
src/gallium/drivers/r300/compiler/radeon_pair_translate.c

index 654f9a070d57bc9c9deb306e9dc4ceade71c8e21..a8d8ebc2dc829b5e1d166f9fe37867fe978c2617 100644 (file)
@@ -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);
index 33dbe0e86e9f06ae699147375c62494782e9528c..36a634114d6a42e93dcaf17a0a2b1d7a5c007905 100644 (file)
@@ -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;
+}
index 58bdb3c684b7a258c52c03038c720c5503272adb..ae5288e405e8d7153373cf6272d4a99d62cbba50 100644 (file)
@@ -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 */
index 527db9a1f696c24a69018772821b7266002cb730..3b49ad7114c9743eb38ab3ad1a108b49548e118d 100644 (file)
@@ -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:
index 3d9cf3b43ed5964d7323baee1d6774213359ac6f..7d9c8d1fab6b682f33dd8acede8fd58af702ff65 100644 (file)
@@ -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)