First off, I’m experiencing this on WinXP/Radeon9800SE/1.4.4145. The problem doesn’t appear on MacOSX/Radeon9800Pro. Don’t have access to NVIDIA boards.
Here’s the gist. The VP addresses xy-offsets for billboards with an ARL instruction. Initially it worked fine, but with minor changes to the VP, the xy-offset appears to be stuck at 0. But in the latter case, there appears to be a workaround whereby multiplying the xy-offset by 1 kicks the value back to what it should be. Now for some details…
In the code below, the 4 xy-offsets (one for each corner of a billboard) are passed via the spriteOffsets' param. Each vertex stores its "corner ID" in the
corner.x’ attrib (vertex.attrib[9]), which is used to define the address register arOffset' with an ARL instruction. The initial version of the VP (which worked fine) used spriteOffsets[arOffset.x] directly in an arithmetic instruction. Among other details, the salient change appears to be that the value of spriteOffsets[arOffset.x] is now copied (MOV) to a temp,
xyoffset’.
In debugging the problem, I first noticed that multiplying xyoffset by a constant had no effect, but if I masked the dest register with `.xy’, it all worked. So the following line seems to work around the problem:
MUL xyoffset.xy, xyoffset, 1;
Any thoughts, insights, or similar experiences?
Here’s the complete VP:
!!ARBvp1.0
PARAM animationAlpha = program.local[0];
PARAM zoffset = program.local[1];
PARAM spriteOffsets[4] = { program.local[2…5] };
PARAM defaultColor = program.local[6];
PARAM sizeModulation = program.local[7];
PARAM mvp[4] = { state.matrix.mvp };
PARAM zero = { 0, 0, 0, 1 };
ATTRIB corner = vertex.attrib[9];
TEMP centerPos, cornerPos, nodeSize, color, texcoord, xyoffset;
ADDRESS arOffset;
DP4 centerPos.x, mvp[0], vertex.position;
DP4 centerPos.y, mvp[1], vertex.position;
DP4 centerPos.z, mvp[2], vertex.position;
DP4 centerPos.w, mvp[3], vertex.position;
ARL arOffset.x, corner.x;
MOV xyoffset, spriteOffsets[arOffset.x];
MUL xyoffset.xy, xyoffset, 1; # workaround for bug on WinXP/Radeon9800
MOV nodeSize, 1;
MOV nodeSize.xy, vertex.attrib[10].x;
nodeSize = sizeModulation * nodeSize + 1 - sizeModulation;
cornerPos = nodeSize * xyoffset + centerPos;
result.position = cornerPos + zoffset;
MAD nodeSize.xy, sizeModulation.x, nodeSize, 1;
ADD nodeSize.xy, nodeSize, -sizeModulation.x;
MAD cornerPos, nodeSize, xyoffset, centerPos;
ADD result.position, cornerPos, zoffset;
MUL color, defaultColor, vertex.color;
MUL color.w, color, animationAlpha;
MOV result.color, color;
MOV texcoord, zero;
MOV texcoord.xy, vertex.texcoord[0];
MOV result.texcoord[0], texcoord;
END