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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -