Browse Source

r300/compiler: Use consistent src swizzles for transcendent instructions

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__;
tags/mesa-8.0-rc1
Tom Stellard 14 years ago
parent
commit
b5ecf5ba46

+ 6
- 4
src/gallium/drivers/r300/compiler/r3xx_vertprog.c View File

/* src->Negate uses the RC_MASK_ flags from program_instruction.h, /* 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. * 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), 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), t_src_class(src->File),
src->Negate ? RC_MASK_XYZW : RC_MASK_NONE) | src->Negate ? RC_MASK_XYZW : RC_MASK_NONE) |
(src->RelAddr << 4) | (src->Abs << 3); (src->RelAddr << 4) | (src->Abs << 3);

+ 18
- 0
src/gallium/drivers/r300/compiler/radeon_compiler_util.c View File

return base * return base *
c->Program.Constants.Constants[index].u.Immediate[swz]; 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;
}

+ 1
- 0
src/gallium/drivers/r300/compiler/radeon_compiler_util.h View File

unsigned int negate, unsigned int negate,
unsigned int chan); unsigned int chan);


unsigned int rc_get_scalar_src_swz(unsigned int swizzle);


#endif /* RADEON_PROGRAM_UTIL_H */ #endif /* RADEON_PROGRAM_UTIL_H */

+ 1
- 1
src/gallium/drivers/r300/compiler/radeon_opcodes.c View File

srcmasks[src] |= writemask; srcmasks[src] |= writemask;
} else if (opcode->IsStandardScalar) { } else if (opcode->IsStandardScalar) {
for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
srcmasks[src] |= RC_MASK_X;
srcmasks[src] |= writemask;
} else { } else {
switch(opcode->Opcode) { switch(opcode->Opcode) {
case RC_OPCODE_ARL: case RC_OPCODE_ARL:

+ 7
- 1
src/gallium/drivers/r300/compiler/radeon_pair_translate.c View File

if (needalpha) { if (needalpha) {
unsigned int srcrgb = 0; unsigned int srcrgb = 0;
unsigned int srcalpha = 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) if (swz < 3)
srcrgb = 1; srcrgb = 1;
else if (swz < 4) else if (swz < 4)

Loading…
Cancel
Save