/* 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);
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;
+}
unsigned int negate,
unsigned int chan);
+unsigned int rc_get_scalar_src_swz(unsigned int swizzle);
#endif /* RADEON_PROGRAM_UTIL_H */
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:
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)