@Relic:
If I remove if statement shader works perfectly, but with if statement shader doesn’t work. 
There is a similar example in NVSDK (glsl_skinning) but without my optimization and it works with or without if statement!
I know for nvemulate and I was looking to precompiled shader. It uses BRA instruction for FOR loop but I didn’t see any BRA instruction for if statement.
@Ingenu
FX5900 reports NV_vertex_program2 extension. NVidia introduce branching and few more things in this extension.
Here is a my vertex shader code that work corretly wit asm out:
attribute vec4 vWeight;
attribute vec4 vBoneIndex;
uniform mat4 bones[30];
const vec4 nula = vec4(0.0, 0.0, 0.0, 0.0);
varying vec4 col;
mat4 BuildSkinMatrix()
{
vec4 b = vBoneIndex;
vec4 w = vWeight;
mat4 result;
int i;
for (i=0; i<4; i++)
{
result = result + (w[i] * bones[int(b[i])]);
}
return result;
}
void main(void)
{
vec4 vtx;
vec4 nrm;
mat4 skinmatrix = BuildSkinMatrix();
vtx = skinmatrix * gl_Vertex;
nrm = skinmatrix * vec4(gl_Normal, 0.0);
nrm = vec4(gl_NormalMatrix * nrm.xyz, 0.0);
col = nrm;
gl_Position = gl_ModelViewProjectionMatrix * vtx;
}
!!VP2.0
# cgc version 1.3.0001, build date Sep 30 2004 14:14:01
# command line args: -q -profile vp30 -entry main -oglsl -D__GLSL_CG_DATA_TYPES -D__GLSL_CG_STDLIB -D__GLSL_SAMPLER_RECT
#vendor NVIDIA Corporation
#version 1.0.02
#profile vp30
#program main
#semantic gl_ModelViewProjectionMatrix
#semantic gl_NormalMatrix
#semantic bones
#var float3 gl_Normal : $vin.ATTR2 : ATTR2 : -1 : 1
#var float4 gl_Vertex : $vin.ATTR0 : ATTR0 : -1 : 1
#var float4 gl_Position : $vout.HPOS : HPOS : -1 : 1
#var float4x4 gl_ModelViewProjectionMatrix : : c[0], 4 : -1 : 1
#var float3x3 gl_NormalMatrix : : c[4], 3 : -1 : 1
#var float4 vWeight : $vin.ATTR13 : ATTR13 : -1 : 1
#var float4 vBoneIndex : $vin.ATTR14 : ATTR14 : -1 : 1
#var float4x4 bones[0] : : c[7], 4 : -1 : 1
#var float4x4 bones[1] : : c[11], 4 : -1 : 1
#var float4x4 bones[2] : : c[15], 4 : -1 : 1
#var float4x4 bones[3] : : c[19], 4 : -1 : 1
#var float4x4 bones[4] : : c[23], 4 : -1 : 1
#var float4x4 bones[5] : : c[27], 4 : -1 : 1
#var float4x4 bones[6] : : c[31], 4 : -1 : 1
#var float4x4 bones[7] : : c[35], 4 : -1 : 1
#var float4x4 bones[8] : : c[39], 4 : -1 : 1
#var float4x4 bones[9] : : c[43], 4 : -1 : 1
#var float4x4 bones[10] : : c[47], 4 : -1 : 1
#var float4x4 bones[11] : : c[51], 4 : -1 : 1
#var float4x4 bones[12] : : c[55], 4 : -1 : 1
#var float4x4 bones[13] : : c[59], 4 : -1 : 1
#var float4x4 bones[14] : : c[63], 4 : -1 : 1
#var float4x4 bones[15] : : c[67], 4 : -1 : 1
#var float4x4 bones[16] : : c[71], 4 : -1 : 1
#var float4x4 bones[17] : : c[75], 4 : -1 : 1
#var float4x4 bones[18] : : c[79], 4 : -1 : 1
#var float4x4 bones[19] : : c[83], 4 : -1 : 1
#var float4x4 bones[20] : : c[87], 4 : -1 : 1
#var float4x4 bones[21] : : c[91], 4 : -1 : 1
#var float4x4 bones[22] : : c[95], 4 : -1 : 1
#var float4x4 bones[23] : : c[99], 4 : -1 : 1
#var float4x4 bones[24] : : c[103], 4 : -1 : 1
#var float4x4 bones[25] : : c[107], 4 : -1 : 1
#var float4x4 bones[26] : : c[111], 4 : -1 : 1
#var float4x4 bones[27] : : c[115], 4 : -1 : 1
#var float4x4 bones[28] : : c[119], 4 : -1 : 1
#var float4x4 bones[29] : : c[123], 4 : -1 : 1
#var float4 col : $vout.TEX0 : TEX0 : -1 : 1
#const c[127] = 4 0
BB1:
MOV o[TEX0].w, c[127].y;
FLR R1.x, v[14].w;
FLR R1.w, v[14].x;
FLR R1.y, v[14].z;
FLR R1.z, v[14].y;
MUL R1.z, R1, c[127].x;
MUL R1.y, R1, c[127].x;
MUL R1.w, R1, c[127].x;
MUL R1.x, R1, c[127];
ARL A0.x, R1;
ARL A0.w, R1;
ARL A0.y, R1;
ARL A0.z, R1;
MAD R2, v[13].x, c[A0.w + 7], R0;
MAD R3, v[13].x, c[A0.w + 8], R0;
MAD R1, v[13].x, c[A0.w + 9], R0;
MAD R0, v[13].x, c[A0.w + 10], R0;
MAD R0, v[13].y, c[A0.z + 10], R0;
MAD R1, v[13].y, c[A0.z + 9], R1;
MAD R3, v[13].y, c[A0.z + 8], R3;
MAD R2, v[13].y, c[A0.z + 7], R2;
MAD R2, v[13].z, c[A0.y + 7], R2;
MAD R3, v[13].z, c[A0.y + 8], R3;
MAD R1, v[13].z, c[A0.y + 9], R1;
MAD R0, v[13].z, c[A0.y + 10], R0;
MAD R0, v[13].w, c[A0.x + 10], R0;
MAD R1, v[13].w, c[A0.x + 9], R1;
MAD R3, v[13].w, c[A0.x + 8], R3;
MAD R2, v[13].w, c[A0.x + 7], R2;
MUL R4.xyz, v[2].y, R3;
MUL R3, v[0].y, R3;
MAD R3, v[0].x, R2, R3;
MAD R2.xyz, v[2].x, R2, R4;
MAD R2.xyz, v[2].z, R1, R2;
MAD R1, v[0].z, R1, R3;
MAD R0, v[0].w, R0, R1;
ADD R2.xyz, R2, c[127].y;
MUL R1, R0.y, c[1];
MAD R1, R0.x, c[0], R1;
MUL R3.xyz, R2.y, c[5];
MAD R3.xyz, R2.x, c[4], R3;
MAD R1, R0.z, c[2], R1;
MAD o[HPOS], R0.w, c[3], R1;
MAD o[TEX0].xyz, R2.z, c[6], R3;
END
# 44 instructions, 5 R-regs
This shader doen’t work. Difference is if statement in BuildSkinMatrix function.
attribute vec4 vWeight;
attribute vec4 vBoneIndex;
uniform mat4 bones[30];
const vec4 nula = vec4(0.0, 0.0, 0.0, 0.0);
varying vec4 col;
mat4 BuildSkinMatrix()
{
vec4 b = vBoneIndex;
vec4 w = vWeight;
mat4 result;// = w[0] * bones[int(b[0])];
int i;
for (i=0; i<4; i++)
{
if (w[i] != 0.0)
result = result + (w[i] * bones[int(b[i])]);
}
return result;
}
void main(void)
{
vec4 vtx;
vec4 nrm;
mat4 skinmatrix = BuildSkinMatrix();
vtx = skinmatrix * gl_Vertex;
nrm = skinmatrix * vec4(gl_Normal, 0.0);
nrm = vec4(gl_NormalMatrix * nrm.xyz, 0.0);
col = nrm;
gl_Position = gl_ModelViewProjectionMatrix * vtx;
}
!!VP2.0
# cgc version 1.3.0001, build date Sep 30 2004 14:14:01
# command line args: -q -profile vp30 -entry main -oglsl -D__GLSL_CG_DATA_TYPES -D__GLSL_CG_STDLIB -D__GLSL_SAMPLER_RECT
#vendor NVIDIA Corporation
#version 1.0.02
#profile vp30
#program main
#semantic gl_ModelViewProjectionMatrix
#semantic gl_NormalMatrix
#semantic bones
#var float3 gl_Normal : $vin.ATTR2 : ATTR2 : -1 : 1
#var float4 gl_Vertex : $vin.ATTR0 : ATTR0 : -1 : 1
#var float4 gl_Position : $vout.HPOS : HPOS : -1 : 1
#var float4x4 gl_ModelViewProjectionMatrix : : c[0], 4 : -1 : 1
#var float3x3 gl_NormalMatrix : : c[4], 3 : -1 : 1
#var float4 vWeight : $vin.ATTR13 : ATTR13 : -1 : 1
#var float4 vBoneIndex : $vin.ATTR14 : ATTR14 : -1 : 1
#var float4x4 bones[0] : : c[7], 4 : -1 : 1
#var float4x4 bones[1] : : c[11], 4 : -1 : 1
#var float4x4 bones[2] : : c[15], 4 : -1 : 1
#var float4x4 bones[3] : : c[19], 4 : -1 : 1
#var float4x4 bones[4] : : c[23], 4 : -1 : 1
#var float4x4 bones[5] : : c[27], 4 : -1 : 1
#var float4x4 bones[6] : : c[31], 4 : -1 : 1
#var float4x4 bones[7] : : c[35], 4 : -1 : 1
#var float4x4 bones[8] : : c[39], 4 : -1 : 1
#var float4x4 bones[9] : : c[43], 4 : -1 : 1
#var float4x4 bones[10] : : c[47], 4 : -1 : 1
#var float4x4 bones[11] : : c[51], 4 : -1 : 1
#var float4x4 bones[12] : : c[55], 4 : -1 : 1
#var float4x4 bones[13] : : c[59], 4 : -1 : 1
#var float4x4 bones[14] : : c[63], 4 : -1 : 1
#var float4x4 bones[15] : : c[67], 4 : -1 : 1
#var float4x4 bones[16] : : c[71], 4 : -1 : 1
#var float4x4 bones[17] : : c[75], 4 : -1 : 1
#var float4x4 bones[18] : : c[79], 4 : -1 : 1
#var float4x4 bones[19] : : c[83], 4 : -1 : 1
#var float4x4 bones[20] : : c[87], 4 : -1 : 1
#var float4x4 bones[21] : : c[91], 4 : -1 : 1
#var float4x4 bones[22] : : c[95], 4 : -1 : 1
#var float4x4 bones[23] : : c[99], 4 : -1 : 1
#var float4x4 bones[24] : : c[103], 4 : -1 : 1
#var float4x4 bones[25] : : c[107], 4 : -1 : 1
#var float4x4 bones[26] : : c[111], 4 : -1 : 1
#var float4x4 bones[27] : : c[115], 4 : -1 : 1
#var float4x4 bones[28] : : c[119], 4 : -1 : 1
#var float4x4 bones[29] : : c[123], 4 : -1 : 1
#var float4 col : $vout.TEX0 : TEX0 : -1 : 1
#const c[127] = 0
BB1:
MOV R3.xyz, v[2];
MOVC CC.x, v[13];
MOV R0, v[0];
MOV R1.yzw, v[13];
BRA BB3 (EQ.x);
BB2:
MOV R0, v[0];
MOV R3.xyz, v[2];
BB3:
MOVC CC.x, R1.y;
BRA BB5 (EQ.x);
BB4:
BB5:
MOVC CC.x, R1.z;
BRA BB7 (EQ.x);
BB6:
BB7:
MOVC CC.x, R1.w;
BRA BB9 (EQ.x);
BB8:
BB9:
MOV o[TEX0].w, c[127].x;
MUL R2.xyz, R3.y, R0;
MUL R1, R0.y, R0;
MAD R1, R0.x, R0, R1;
MAD R2.xyz, R3.x, R0, R2;
MAD R2.xyz, R3.z, R0, R2;
MAD R1, R0.z, R0, R1;
MAD R0, R0.w, R0, R1;
ADD R2.xyz, R2, c[127].x;
MUL R1, R0.y, c[1];
MAD R1, R0.x, c[0], R1;
MUL R3.xyz, R2.y, c[5];
MAD R3.xyz, R2.x, c[4], R3;
MAD R1, R0.z, c[2], R1;
MAD o[HPOS], R0.w, c[3], R1;
MAD o[TEX0].xyz, R2.z, c[6], R3;
END
# 29 instructions, 4 R-regs
# 29 instructions, 4 R-regs
yooyo