d3d/archive/D3D11_3_FunctionalSpec.htm [9006:9382]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// This pointers are a four-element vector with indices for
// which constant buffer holds the instance data (.x element),
// the base offset of the instance data in the instance constant
// buffer, the base texture index and the base sampler index.
// Basic instance members will therefore be referenced with
// cb[r0.x][r0.y + member_offset].
// This pointers can be in arrays so the first [] index
// can also have a register to indicate array access.
//
//
// For this example assume that globals are put in cbuffers
// in the following order. Entries are offset:size in
// register (four-component) units.
//
// cb0:
// 0:1 - g_NumLights.
// 1:4 - g_LightsInUse.
// 5:1 - g_Ambient0.
// 6:2 - g_DirLight0.
// 8:2 - g_DirLight1.
// 10:2 - g_DirLight2.
// 12:2 - g_DirLight3.
// 14:2 - g_DirLight4.
// 16:2 - g_DirLight5.
// 18:2 - g_DirLight6.
// 20:2 - g_DirLight7.
// 22:1 - g_FlatMat0.
// 23:1 - g_TexMat0.
//
// g_StrangeMat0 takes no space.
//
// interfaces:
// 0:1 - MyMaterial.
// 1:9 - g_Lights.
//
// textures:
// 0:1 - g_TexMat0.
//
// samplers:
// 0:1 - g_TexMat0.
//
// The this pointers for the concrete objects would then be:
// g_Ambient0: { 0, 5, -, - }
// g_DirLight0: { 0, 6, -, - }
// g_DirLight1: { 0, 8, -, - }
// g_DirLight2: { 0, 10, -, - }
// g_DirLight3: { 0, 12, -, - }
// g_DirLight4: { 0, 14, -, - }
// g_DirLight5: { 0, 16, -, - }
// g_DirLight6: { 0, 18, -, - }
// g_DirLight7: { 0, 20, -, - }
// g_FlatMat0: { 0, 22, -, - }
// g_TexMat0: { 0, 23, 0, 0 }
// g_StrangeMat0: { -, -, -, - }
//
//
// Function bodies are declared explicitly so
// that it’s known in advance which bodies exist
// and how many bodies there are overall.
//
dcl_function_body fb0
dcl_function_body fb1
dcl_function_body fb2
dcl_function_body fb3
dcl_function_body fb4
dcl_function_body fb5
dcl_function_body fb6
dcl_function_body fb7
dcl_function_body fb8
dcl_function_body fb9
dcl_function_body fb10
dcl_function_body fb11
//
// Function tables work similarly to vtables for C++ except
// that a table has an entry per call site for an interface
// instead of per method.
//
// Function table for AmbientLight.
// One call site in AccumulateLighting multiplied by three calls of
// AccumulateLighting from CalculateLitColor.
dcl_function_table ft0 { fb3, fb6, fb9 }
// Function table for DirectionalLight.
// One call site in AccumulateLighting multiplied by three calls of
// AccumulateLighting from CalculateLitColor.
dcl_function_table ft1 { fb4, fb7, fb10 }
// Function table for FlatMaterial.
// One call to Perturb in main and one call to CalculateLitColor in main.
dcl_function_table ft2 { fb0, fb5 }
// Function table for TexturedMaterial.
// One call to Perturb in main and one call to CalculateLitColor in main.
dcl_function_table ft3 { fb1, fb8 }
// Function table for StrangeMaterial.
// One call to Perturb in main and one call to CalculateLitColor in main.
dcl_function_table ft4 { fb2, fb11 }
//
// Function table pointers. Each of these needs to bound before
// the shader is usable. The idea is that binding gives
// a reference to one of the function tables above so that
// the method slots can be filled in.
// The compiler will not generate pointers for unreferenced objects.
//
// A function table pointer has a full set of method slots to
// avoid the extra level of indirection that a C++ pointer-to-
// pointer-to-vtable representation would require (that would also
// require that this pointers be 5-tuples). In the HLSL virtual
// inlining model it's always known what global variable/input is
// used for a call so we can set up tables per root object.
//
// Function pointer decls indicate which function tables are
// legal to use with them. This also allows derivation of
// method correlation information.
//
// The first [] of an interface decl is the array size.
// If dynamic indexing is used the decl will indicate
// that, as shown below. An array of interface pointers can
// be indexed statically also, it isn’t required that
// arrays of interface pointers mean dynamic indexing.
//
// Numbering of interface pointers takes array size into
// account, so the first pointer after a four entry
// array fp6[4][1] would be fp10.
//
// The second [] of an interface decl is the number
// of call sites, which must match the number of bodies in
// each table referenced in the decl.
//
// main's MyMaterial parameter.
dcl_interface fp0[1][2] = { ft2, ft3, ft4 };
// g_Lights entries.
dcl_interface_dynamicindexed fp1[9][3] = { ft0, ft1 };
// main routine.
// TestValueFromLight is a regular routine and is inlined.
// The Calculate reference inside of it is passed the concrete
// instance DirLight0 so it is devirtualized and inlined.
dp3_sat r0.x, v1.xyzx, -cb0[6].xyzx
mul r0.yz, r0.xxxx, cb0[7].xxyx
add r0.y, r0.z, r0.y
mad_sat r0.x, cb0[7].z, r0.x, r0.y
// The return of TestValueFromLight is tested.
lt r0.x, l(0.500000), r0.x
if_nz r0.x
// The call to Perturb is a full fcall
fcall fp0[0][0]
mov r2.xyz, r0.xyzx
mov r0.x, r0.w
mov r0.y, r1.x
else
mov r2.xyz, v1.xyzx
mov r0.xy, v2.xyxx
endif
// The call to CalculateLitColor is a full fcall.
fcall fp0[0][1]
mov o0.xyz, r1.xyzx
mov o0.w, l(1.000000)
ret
//
// Function bodies.
//
// FlatMaterial version of main's call to Perturb.
label fb0
mov r0.xyz, v1.xyzx
mov r0.w, v2.y
mov r1.x, v2.x
ret
// TexturedMaterial version of main's call to Perturb.
label fb1
mov r0.xyz, v1.xyzx
mov r0.w, v2.x
mov r1.x, v2.y
ret
// StrangeMaterial version of main's call to Perturb.
// NOTE: Position is not used later so the compiler has killed
// the update to Position from this body.
label fb2
mov r0.xyz, v1.xyzx
mov r0.w, v2.x
mov r1.x, v2.y
ret
// AmbientLight version of FlatMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
// NOTE: the Calculate bodies all look superficially
// identical but all are different. In one case
// the array index is r1 and the return value is r4,
// in one case the array index is r1 and the return value
// is r5 and in the last case the array index is in r0
// and the return is in r5. Bodies are not interchangeable.
label fb3
// Array index is r1, return is r4.
mov r2.w, this[r1.w + 1].y
mov r1.w, this[r1.w + 1].x
mov r4.xyz, cb[r1.w + 0][r2.w + 0].xyzx
ret
// DirectionalLight version of FlatMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
label fb4
// Array index is r1, return is r4.
mov r2.w, this[r1.w + 1].y
mov r3.w, this[r1.w + 1].x
mov r4.w, this[r1.w + 1].y
mov r5.x, this[r1.w + 1].x
dp3_sat r4.w, r2.xyzx, -cb[r5.x + 0][r4.w + 0].xyzx
mul r5.xyz, r4.wwww, cb[r3.w + 0][r2.w + 1].xyzx
mov r4.xyz, r5.xyzx
ret
// FlatMaterial version of main's call to CalculateLitColor.
label fb5
// AccumulateLighting is inlined.
mov r3.xyz, l(0,0,0,0)
mov r0.w, l(0)
loop
// g_NumLights is cb0[0].
uge r1.w, r0.w, cb0[0].x
breakc_nz r1.w
// Get g_Lights[g_LightsInUse[i]].
// g_LightsInUse is cb0[1-4].
// g_Lights is cb0[5-13].
mov r1.w, cb0[r0.w + 1].x
// Call Calculate. Array index is r1.
fcall fp1[r1.w + 0][0]
// Return is expected in r4.
mov r0.xyz, r4.xyzx
add r3.xyz, r3.xyzx, r0.xyzx
iadd r0.w, r0.w, l(1)
endloop
// Multiply times color.
mov r0.xy, this[0].yxyy
mul r0.xyz, r3.xyzx, cb[r0.y + 0][r0.x + 0].xyzx
mov r1.xyz, r0.xyzx
ret
// AmbientLight version of TexturedMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
label fb6
// Array index is r1, return is r5.
mov r2.w, this[r1.w + 1].y
mov r1.w, this[r1.w + 1].x
mov r5.xyz, cb[r1.w + 0][r2.w + 0].xyzx
ret
// DirectionalLight version of TexturedMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
label fb7
// Array index is r1, return is r5.
mov r2.w, this[r1.w + 1].y
mov r3.w, this[r1.w + 1].x
mov r4.w, this[r1.w + 1].y
mov r5.w, this[r1.w + 1].x
dp3_sat r4.w, r2.xyzx, -cb[r5.w + 0][r4.w + 0].xyzx
mul r6.xyz, r4.wwww, cb[r3.w + 0][r2.w + 1].xyzx
mov r5.xyz, r6.xyzx
ret
// TexturedMaterial version of main's call to CalculateLitColor.
label fb8
// Texture sample.
mov r4.xy, this[0].zw
sample r0.xyz, v2.xy, t[r4.x].xyz, s[r4.y]
mul r0.xyz, r0.xyzx, l(0.123400, 0.123400, 0.123400, 0.000000)
// m_Color multiplied by texture sample.
mov r0.w, this[0].y
mov r1.w, this[0].x
mul r0.xyz, r0.xyzx, cb[r1.w + 0][r0.w + 0].xyzx
// AccumulateLighting is inlined.
mov r4.xyz, l(0,0,0,0)
mov r0.w, l(0)
loop
// g_NumLights is cb0[0].
uge r1.w, r0.w, cb0[0].x
breakc_nz r1.w
// Get g_Lights[g_LightsInUse[i]].
// g_LightsInUse is cb0[1-4].
// g_Lights is cb0[5-13].
mov r1.w, cb0[r0.w + 1].x
// Call Calculate. Array index is in r1.
fcall fp1[r1.w + 0][1]
// Return is expected in r5.
mov r3.xyz, r5.xyzx
add r4.xyz, r4.xyzx, r3.xyzx
iadd r0.w, r0.w, l(1)
endloop
// Multiply accumulated color times texture color.
mul r0.xyz, r0.xyzx, r4.xyzx
mov r1.xyz, r0.xyzx
ret
// AmbientLight version of StrangeMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
label fb9
// Array index is r0, return is r5.
mov r1.w, this[r0.w + 1].y
mov r0.w, this[r0.w + 1].x
mov r5.xyz, cb[r0.w + 0][r1.w + 0].xyzx
ret
// DirectionalLight version of StrangeMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
label fb10
// Array index is r0, return is r5.
mov r1.w, this[r0.w + 1].y
mov r2.w, this[r0.w + 1].x
mov r3.w, this[r0.w + 1].y
mov r4.w, this[r0.w + 1].x
dp3_sat r3.w, r2.xyzx, -cb[r4.w + 0][r3.w + 0].xyzx
mul r6.xyz, r3.wwww, cb[r2.w + 0][r1.w + 1].xyzx
mov r5.xyz, r6.xyzx
ret
// StrangeMaterial version of main's call to CalculateLitColor.
label fb11
// AccumulateLighting is inlined.
mov r4.xyz, l(0,0,0,0)
mov r0.z, l(0)
loop
// g_NumLights is cb0[0].x.
uge r0.w, r0.z, cb0[0].x
breakc_nz r0.w
// Get g_Lights[g_LightsInUse[i]].
// g_LightsInUse is cb0[1-4].
// g_Lights is cb0[5-13].
mov r0.w, cb0[r0.z + 1].x
// Call Calculate. Array index is in r0.
fcall fp1[r0.w + 0][2]
// Return is in r5.
mov r3.xyz, r5.xyzx
add r4.xyz, r4.xyzx, r3.xyzx
iadd r0.z, r0.z, l(1)
endloop
mov r1.xyz, r4.xyzx
ret
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
d3d/archive/images/d3d11/D3D11_3_FunctionalSpec.htm [8118:8494]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// This pointers are a four-element vector with indices for
// which constant buffer holds the instance data (.x element),
// the base offset of the instance data in the instance constant
// buffer, the base texture index and the base sampler index.
// Basic instance members will therefore be referenced with
// cb[r0.x][r0.y + member_offset].
// This pointers can be in arrays so the first [] index
// can also have a register to indicate array access.
//
//
// For this example assume that globals are put in cbuffers
// in the following order. Entries are offset:size in
// register (four-component) units.
//
// cb0:
// 0:1 - g_NumLights.
// 1:4 - g_LightsInUse.
// 5:1 - g_Ambient0.
// 6:2 - g_DirLight0.
// 8:2 - g_DirLight1.
// 10:2 - g_DirLight2.
// 12:2 - g_DirLight3.
// 14:2 - g_DirLight4.
// 16:2 - g_DirLight5.
// 18:2 - g_DirLight6.
// 20:2 - g_DirLight7.
// 22:1 - g_FlatMat0.
// 23:1 - g_TexMat0.
//
// g_StrangeMat0 takes no space.
//
// interfaces:
// 0:1 - MyMaterial.
// 1:9 - g_Lights.
//
// textures:
// 0:1 - g_TexMat0.
//
// samplers:
// 0:1 - g_TexMat0.
//
// The this pointers for the concrete objects would then be:
// g_Ambient0: { 0, 5, -, - }
// g_DirLight0: { 0, 6, -, - }
// g_DirLight1: { 0, 8, -, - }
// g_DirLight2: { 0, 10, -, - }
// g_DirLight3: { 0, 12, -, - }
// g_DirLight4: { 0, 14, -, - }
// g_DirLight5: { 0, 16, -, - }
// g_DirLight6: { 0, 18, -, - }
// g_DirLight7: { 0, 20, -, - }
// g_FlatMat0: { 0, 22, -, - }
// g_TexMat0: { 0, 23, 0, 0 }
// g_StrangeMat0: { -, -, -, - }
//
//
// Function bodies are declared explicitly so
// that it’s known in advance which bodies exist
// and how many bodies there are overall.
//
dcl_function_body fb0
dcl_function_body fb1
dcl_function_body fb2
dcl_function_body fb3
dcl_function_body fb4
dcl_function_body fb5
dcl_function_body fb6
dcl_function_body fb7
dcl_function_body fb8
dcl_function_body fb9
dcl_function_body fb10
dcl_function_body fb11
//
// Function tables work similarly to vtables for C++ except
// that a table has an entry per call site for an interface
// instead of per method.
//
// Function table for AmbientLight.
// One call site in AccumulateLighting multiplied by three calls of
// AccumulateLighting from CalculateLitColor.
dcl_function_table ft0 { fb3, fb6, fb9 }
// Function table for DirectionalLight.
// One call site in AccumulateLighting multiplied by three calls of
// AccumulateLighting from CalculateLitColor.
dcl_function_table ft1 { fb4, fb7, fb10 }
// Function table for FlatMaterial.
// One call to Perturb in main and one call to CalculateLitColor in main.
dcl_function_table ft2 { fb0, fb5 }
// Function table for TexturedMaterial.
// One call to Perturb in main and one call to CalculateLitColor in main.
dcl_function_table ft3 { fb1, fb8 }
// Function table for StrangeMaterial.
// One call to Perturb in main and one call to CalculateLitColor in main.
dcl_function_table ft4 { fb2, fb11 }
//
// Function table pointers. Each of these needs to bound before
// the shader is usable. The idea is that binding gives
// a reference to one of the function tables above so that
// the method slots can be filled in.
// The compiler will not generate pointers for unreferenced objects.
//
// A function table pointer has a full set of method slots to
// avoid the extra level of indirection that a C++ pointer-to-
// pointer-to-vtable representation would require (that would also
// require that this pointers be 5-tuples). In the HLSL virtual
// inlining model it's always known what global variable/input is
// used for a call so we can set up tables per root object.
//
// Function pointer decls indicate which function tables are
// legal to use with them. This also allows derivation of
// method correlation information.
//
// The first [] of an interface decl is the array size.
// If dynamic indexing is used the decl will indicate
// that, as shown below. An array of interface pointers can
// be indexed statically also, it isn’t required that
// arrays of interface pointers mean dynamic indexing.
//
// Numbering of interface pointers takes array size into
// account, so the first pointer after a four entry
// array fp6[4][1] would be fp10.
//
// The second [] of an interface decl is the number
// of call sites, which must match the number of bodies in
// each table referenced in the decl.
//
// main's MyMaterial parameter.
dcl_interface fp0[1][2] = { ft2, ft3, ft4 };
// g_Lights entries.
dcl_interface_dynamicindexed fp1[9][3] = { ft0, ft1 };
// main routine.
// TestValueFromLight is a regular routine and is inlined.
// The Calculate reference inside of it is passed the concrete
// instance DirLight0 so it is devirtualized and inlined.
dp3_sat r0.x, v1.xyzx, -cb0[6].xyzx
mul r0.yz, r0.xxxx, cb0[7].xxyx
add r0.y, r0.z, r0.y
mad_sat r0.x, cb0[7].z, r0.x, r0.y
// The return of TestValueFromLight is tested.
lt r0.x, l(0.500000), r0.x
if_nz r0.x
// The call to Perturb is a full fcall
fcall fp0[0][0]
mov r2.xyz, r0.xyzx
mov r0.x, r0.w
mov r0.y, r1.x
else
mov r2.xyz, v1.xyzx
mov r0.xy, v2.xyxx
endif
// The call to CalculateLitColor is a full fcall.
fcall fp0[0][1]
mov o0.xyz, r1.xyzx
mov o0.w, l(1.000000)
ret
//
// Function bodies.
//
// FlatMaterial version of main's call to Perturb.
label fb0
mov r0.xyz, v1.xyzx
mov r0.w, v2.y
mov r1.x, v2.x
ret
// TexturedMaterial version of main's call to Perturb.
label fb1
mov r0.xyz, v1.xyzx
mov r0.w, v2.x
mov r1.x, v2.y
ret
// StrangeMaterial version of main's call to Perturb.
// NOTE: Position is not used later so the compiler has killed
// the update to Position from this body.
label fb2
mov r0.xyz, v1.xyzx
mov r0.w, v2.x
mov r1.x, v2.y
ret
// AmbientLight version of FlatMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
// NOTE: the Calculate bodies all look superficially
// identical but all are different. In one case
// the array index is r1 and the return value is r4,
// in one case the array index is r1 and the return value
// is r5 and in the last case the array index is in r0
// and the return is in r5. Bodies are not interchangeable.
label fb3
// Array index is r1, return is r4.
mov r2.w, this[r1.w + 1].y
mov r1.w, this[r1.w + 1].x
mov r4.xyz, cb[r1.w + 0][r2.w + 0].xyzx
ret
// DirectionalLight version of FlatMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
label fb4
// Array index is r1, return is r4.
mov r2.w, this[r1.w + 1].y
mov r3.w, this[r1.w + 1].x
mov r4.w, this[r1.w + 1].y
mov r5.x, this[r1.w + 1].x
dp3_sat r4.w, r2.xyzx, -cb[r5.x + 0][r4.w + 0].xyzx
mul r5.xyz, r4.wwww, cb[r3.w + 0][r2.w + 1].xyzx
mov r4.xyz, r5.xyzx
ret
// FlatMaterial version of main's call to CalculateLitColor.
label fb5
// AccumulateLighting is inlined.
mov r3.xyz, l(0,0,0,0)
mov r0.w, l(0)
loop
// g_NumLights is cb0[0].
uge r1.w, r0.w, cb0[0].x
breakc_nz r1.w
// Get g_Lights[g_LightsInUse[i]].
// g_LightsInUse is cb0[1-4].
// g_Lights is cb0[5-13].
mov r1.w, cb0[r0.w + 1].x
// Call Calculate. Array index is r1.
fcall fp1[r1.w + 0][0]
// Return is expected in r4.
mov r0.xyz, r4.xyzx
add r3.xyz, r3.xyzx, r0.xyzx
iadd r0.w, r0.w, l(1)
endloop
// Multiply times color.
mov r0.xy, this[0].yxyy
mul r0.xyz, r3.xyzx, cb[r0.y + 0][r0.x + 0].xyzx
mov r1.xyz, r0.xyzx
ret
// AmbientLight version of TexturedMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
label fb6
// Array index is r1, return is r5.
mov r2.w, this[r1.w + 1].y
mov r1.w, this[r1.w + 1].x
mov r5.xyz, cb[r1.w + 0][r2.w + 0].xyzx
ret
// DirectionalLight version of TexturedMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
label fb7
// Array index is r1, return is r5.
mov r2.w, this[r1.w + 1].y
mov r3.w, this[r1.w + 1].x
mov r4.w, this[r1.w + 1].y
mov r5.w, this[r1.w + 1].x
dp3_sat r4.w, r2.xyzx, -cb[r5.w + 0][r4.w + 0].xyzx
mul r6.xyz, r4.wwww, cb[r3.w + 0][r2.w + 1].xyzx
mov r5.xyz, r6.xyzx
ret
// TexturedMaterial version of main's call to CalculateLitColor.
label fb8
// Texture sample.
mov r4.xy, this[0].zw
sample r0.xyz, v2.xy, t[r4.x].xyz, s[r4.y]
mul r0.xyz, r0.xyzx, l(0.123400, 0.123400, 0.123400, 0.000000)
// m_Color multiplied by texture sample.
mov r0.w, this[0].y
mov r1.w, this[0].x
mul r0.xyz, r0.xyzx, cb[r1.w + 0][r0.w + 0].xyzx
// AccumulateLighting is inlined.
mov r4.xyz, l(0,0,0,0)
mov r0.w, l(0)
loop
// g_NumLights is cb0[0].
uge r1.w, r0.w, cb0[0].x
breakc_nz r1.w
// Get g_Lights[g_LightsInUse[i]].
// g_LightsInUse is cb0[1-4].
// g_Lights is cb0[5-13].
mov r1.w, cb0[r0.w + 1].x
// Call Calculate. Array index is in r1.
fcall fp1[r1.w + 0][1]
// Return is expected in r5.
mov r3.xyz, r5.xyzx
add r4.xyz, r4.xyzx, r3.xyzx
iadd r0.w, r0.w, l(1)
endloop
// Multiply accumulated color times texture color.
mul r0.xyz, r0.xyzx, r4.xyzx
mov r1.xyz, r0.xyzx
ret
// AmbientLight version of StrangeMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
label fb9
// Array index is r0, return is r5.
mov r1.w, this[r0.w + 1].y
mov r0.w, this[r0.w + 1].x
mov r5.xyz, cb[r0.w + 0][r1.w + 0].xyzx
ret
// DirectionalLight version of StrangeMaterial.CalculateLitColor-calls-
// AccumulateLighting's call to Calculate.
label fb10
// Array index is r0, return is r5.
mov r1.w, this[r0.w + 1].y
mov r2.w, this[r0.w + 1].x
mov r3.w, this[r0.w + 1].y
mov r4.w, this[r0.w + 1].x
dp3_sat r3.w, r2.xyzx, -cb[r4.w + 0][r3.w + 0].xyzx
mul r6.xyz, r3.wwww, cb[r2.w + 0][r1.w + 1].xyzx
mov r5.xyz, r6.xyzx
ret
// StrangeMaterial version of main's call to CalculateLitColor.
label fb11
// AccumulateLighting is inlined.
mov r4.xyz, l(0,0,0,0)
mov r0.z, l(0)
loop
// g_NumLights is cb0[0].x.
uge r0.w, r0.z, cb0[0].x
breakc_nz r0.w
// Get g_Lights[g_LightsInUse[i]].
// g_LightsInUse is cb0[1-4].
// g_Lights is cb0[5-13].
mov r0.w, cb0[r0.z + 1].x
// Call Calculate. Array index is in r0.
fcall fp1[r0.w + 0][2]
// Return is in r5.
mov r3.xyz, r5.xyzx
add r4.xyz, r4.xyzx, r3.xyzx
iadd r0.z, r0.z, l(1)
endloop
mov r1.xyz, r4.xyzx
ret
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -