BVB Source Codes

CRYENGINE Show CCullRenderer.h Source code

Return Download CRYENGINE: download CCullRenderer.h Source code - Download CRYENGINE Source code - Type:.h
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #ifndef __CCULLRENDERER__
  4. #define __CCULLRENDERER__
  5.  
  6. #include "VMath.hpp"
  7.  
  8. //#define CULL_RENDERER_REPROJ_DEBUG
  9. #define CULL_RENDERER_MINZ
  10.  
  11. // enable this define to allow ingame debugging of the coverage buffer
  12. #define CULLING_ENABLE_DEBUG_OVERLAY
  13.  
  14. #pragma warning(push)
  15. #pragma warning(disable:6262)
  16.  
  17. namespace NAsyncCull
  18. {
  19. namespace Debug
  20. {
  21.  
  22. inline void Draw2DBox(float fX, float fY, float fHeigth, float fWidth, const ColorB& rColor, float fScreenHeigth, float fScreenWidth, IRenderAuxGeom* pAuxRenderer)
  23. {
  24.         float fPosition[4][2] =
  25.         {
  26.                 { fX,          fY           },
  27.                 { fX,          fY + fHeigth },
  28.                 { fX + fWidth, fY + fHeigth },
  29.                 { fX + fWidth, fY           }
  30.         };
  31.  
  32.         // compute normalized position from absolute points
  33.         Vec3 vPosition[4] =
  34.         {
  35.                 Vec3(fPosition[0][0] / fScreenWidth, fPosition[0][1] / fScreenHeigth, 0.0f),
  36.                 Vec3(fPosition[1][0] / fScreenWidth, fPosition[1][1] / fScreenHeigth, 0.0f),
  37.                 Vec3(fPosition[2][0] / fScreenWidth, fPosition[2][1] / fScreenHeigth, 0.0f),
  38.                 Vec3(fPosition[3][0] / fScreenWidth, fPosition[3][1] / fScreenHeigth, 0.0f)
  39.         };
  40.  
  41.         vtx_idx const anTriangleIndices[6] =
  42.         {
  43.                 0, 1, 2,
  44.                 0, 2, 3
  45.         };
  46.  
  47.         pAuxRenderer->DrawTriangles(vPosition, 4, anTriangleIndices, 6, rColor);
  48. }
  49.  
  50. } // namesapce Debug
  51. } //namespace NasyncCull
  52.  
  53. namespace NAsyncCull
  54. {
  55.  
  56. typedef float                   tdZexel;
  57. typedef uint16                  tdIndex;
  58.  
  59. typedef PodArray<NVMath::vec4>& tdVertexCacheArg;
  60. typedef PodArray<NVMath::vec4>  tdVertexCache;
  61.  
  62. enum {VERTEX_CACHE_COUNT = 64 * 1024};
  63.  
  64. extern const NVMath::vec4 MaskNot3;
  65.  
  66. template<uint32 SIZEX, uint32 SIZEY>
  67. class CCullRenderer
  68. {
  69. public:
  70.         enum { RESOLUTION_X = SIZEX };
  71.         enum { RESOLUTION_Y = SIZEY };
  72. private:
  73.  
  74.         CRY_ALIGN(16) NVMath::vec4 m_VMaxXY;
  75.         static CRY_ALIGN(128) float m_ZBufferMainMemory[SIZEX * SIZEY];
  76.         uint32    m_SizeX4;
  77.         Matrix44A m_Reproject;
  78.         uint32    m_nNumWorker;
  79.         tdZexel*  m_ZBuffer;
  80.  
  81.         tdZexel** m_ZBufferSwap;
  82.  
  83.         CRY_ALIGN(128) tdZexel m_ZBufferSwapMerged[SIZEX * SIZEY]; // 128 byte for XMemSet128
  84.  
  85. #ifdef CULL_RENDERER_REPROJ_DEBUG
  86.         tdZexel m_ZBufferOrig[SIZEX * SIZEY];
  87. #endif
  88.  
  89.         uint32 m_DrawCall;
  90.         uint32 m_PolyCount;
  91.  
  92.         template<bool WRITE, bool CULL, bool CULL_BACKFACES>
  93.         inline bool Triangle(
  94.           const NVMath::vec4& rV0,
  95.           const NVMath::vec4& rV1,
  96.           const NVMath::vec4& rV2)
  97.         {
  98.                 using namespace NVMath;
  99.  
  100.                 vec4 V0 = rV0;
  101.                 vec4 V1 = rV1;
  102.                 vec4 V2 = rV2;
  103.  
  104.                 const uint32 Idx = SignMask(Shuffle<xzzz>(Shuffle<zzzz>(V0, V1), V2)) & (BitX | BitY | BitZ);
  105.                 if (Idx == (BitX | BitY | BitZ))
  106.                 {
  107.                         return false;
  108.                 }
  109.  
  110.                 bool Visible = false;
  111.                 switch (Idx)
  112.                 {
  113.                 case 0:
  114.                         break;
  115.                 case BitX:
  116.                         {
  117.                                 const vec4 F0 = Splat<2>(V0);
  118.                                 const vec4 F1 = Splat<2>(V1);
  119.                                 const vec4 F2 = Splat<2>(V2);
  120.                                 const vec4 M0 = Div(F0, Sub(F0, F2));
  121.                                 const vec4 M1 = Div(F0, Sub(F0, F1));
  122.                                 const vec4 P0 = Madd(Sub(V2, V0), M0, V0);
  123.                                 const vec4 P1 = Madd(Sub(V1, V0), M1, V0);
  124.                                 Visible = Triangle2D<WRITE, CULL, true, CULL_BACKFACES>(P0, P1, V1);
  125.                                 V0 = P0;
  126.                         }
  127.                         break;
  128.                 case BitY:
  129.                         {
  130.                                 const vec4 F0 = Splat<2>(V0);
  131.                                 const vec4 F1 = Splat<2>(V1);
  132.                                 const vec4 F2 = Splat<2>(V2);
  133.                                 const vec4 M0 = Div(F1, Sub(F1, F0));
  134.                                 const vec4 M1 = Div(F1, Sub(F1, F2));
  135.                                 const vec4 P0 = Madd(Sub(V0, V1), M0, V1);
  136.                                 const vec4 P1 = Madd(Sub(V2, V1), M1, V1);
  137.                                 Visible = Triangle2D<WRITE, CULL, true, CULL_BACKFACES>(P0, P1, V2);
  138.                                 V1 = P0;
  139.                         }
  140.                         break;
  141.                 case BitX | BitY:
  142.                         {
  143.                                 const vec4 F0 = Splat<2>(V0);
  144.                                 const vec4 F1 = Splat<2>(V1);
  145.                                 const vec4 F2 = Splat<2>(V2);
  146.                                 const vec4 M0 = Div(F0, Sub(F0, F2));
  147.                                 const vec4 M1 = Div(F1, Sub(F1, F2));
  148.                                 V0 = Madd(Sub(V2, V0), M0, V0);
  149.                                 V1 = Madd(Sub(V2, V1), M1, V1);
  150.                         }
  151.                         break;
  152.                 case BitZ:
  153.                         {
  154.                                 const vec4 F0 = Splat<2>(V0);
  155.                                 const vec4 F1 = Splat<2>(V1);
  156.                                 const vec4 F2 = Splat<2>(V2);
  157.                                 const vec4 M0 = Div(F2, Sub(F2, F1));
  158.                                 const vec4 M1 = Div(F2, Sub(F2, F0));
  159.                                 const vec4 P0 = Madd(Sub(V1, V2), M0, V2);
  160.                                 const vec4 P1 = Madd(Sub(V0, V2), M1, V2);
  161.                                 Visible = Triangle2D<WRITE, CULL, true, CULL_BACKFACES>(V0, P0, P1);
  162.                                 V2 = P0;
  163.                         }
  164.                         break;
  165.                 case BitX | BitZ:
  166.                         {
  167.                                 const vec4 F0 = Splat<2>(V0);
  168.                                 const vec4 F1 = Splat<2>(V1);
  169.                                 const vec4 F2 = Splat<2>(V2);
  170.                                 const vec4 M0 = Div(F0, Sub(F0, F1));
  171.                                 const vec4 M1 = Div(F2, Sub(F2, F1));
  172.                                 V0 = Madd(Sub(V1, V0), M0, V0);
  173.                                 V2 = Madd(Sub(V1, V2), M1, V2);
  174.                         }
  175.                         break;
  176.                 case BitY | BitZ:
  177.                         {
  178.                                 const vec4 F0 = Splat<2>(V0);
  179.                                 const vec4 F1 = Splat<2>(V1);
  180.                                 const vec4 F2 = Splat<2>(V2);
  181.                                 const vec4 M0 = Div(F1, Sub(F1, F0));
  182.                                 const vec4 M1 = Div(F2, Sub(F2, F0));
  183.                                 V1 = Madd(Sub(V0, V1), M0, V1);
  184.                                 V2 = Madd(Sub(V0, V2), M1, V2);
  185.                         }
  186.                         break;
  187.                 case BitX | BitY | BitZ:
  188.                         break;
  189. #if !CRY_PLATFORM_ORBIS && !CRY_PLATFORM_ANDROID
  190.                 default:
  191.                         __assume(0);
  192. #endif
  193.                 }
  194.  
  195.                 return Visible | Triangle2D<WRITE, CULL, true, CULL_BACKFACES>(V0, V1, V2);
  196.         }
  197.  
  198.         template<bool WRITE, bool CULL, bool PROJECT, bool CULL_BACKFACES>
  199. #if CRY_PLATFORM_WINDOWS && CRY_PLATFORM_32BIT
  200.         inline bool Triangle2D(NVMath::vec4 rV0, NVMath::vec4 rV1, NVMath::vec4 rV2, uint32 MinX = 0, uint32 MinY = 0, uint32 MaxX = 0, uint32 MaxY = 0, NVMath::vec4& VMinMax = NVMath::Vec4Zero(), NVMath::vec4& V210 = NVMath::Vec4Zero())
  201. #else
  202.         inline bool Triangle2D(NVMath::vec4 rV0, NVMath::vec4 rV1, NVMath::vec4 rV2, uint32 MinX = 0, uint32 MinY = 0, uint32 MaxX = 0, uint32 MaxY = 0, NVMath::vec4 VMinMax = NVMath::Vec4Zero (), NVMath::vec4 V210 = NVMath::Vec4Zero ())
  203. #endif
  204.         {
  205.                 using namespace NVMath;
  206.  
  207.                 vec4 V0, V1, V2;
  208.                 if (PROJECT)
  209.                 {
  210.                         const vec4 WWW = Shuffle<xzww>(Shuffle<wwww>(rV0, rV1), rV2);
  211.                         const vec4 iWWW = Rcp(WWW);
  212.                         V0 = Mul(rV0, Splat<0>(iWWW));
  213.                         V1 = Mul(rV1, Splat<1>(iWWW));
  214.                         V2 = Mul(rV2, Splat<2>(iWWW));
  215.                         V210 = Sub(Shuffle<xyxy>(V1, V2), Swizzle<xyxy>(V0));
  216.                         vec4 Det = Mul(V210, Swizzle<wzwz>(V210));
  217.                         Det = Sub(Det, Splat<1>(Det));
  218.                         if (CULL_BACKFACES)
  219.                         {
  220.                                 if ((SignMask(CmpLE(Det, Vec4Epsilon())) & BitX) != 0)
  221.                                 {
  222.                                         return false;
  223.                                 }
  224.                         }
  225.  
  226.                         Det = Select(Det, NVMath::Vec4(-FLT_EPSILON), CmpEq(Det, Vec4Zero()));
  227.                         V210 = Div(V210, Swizzle<xxxx>(Det));
  228.  
  229.                         vec4 VMax = Max(Max(V0, V1), V2);
  230.                         vec4 VMin = Min(Min(V0, V1), V2);
  231.                         VMax = Add(VMax, Vec4One());
  232.                         VMinMax = Shuffle<xyxy>(VMin, VMax);
  233.                         VMinMax = Max(VMinMax, Vec4Zero());
  234.                         VMinMax = Min(VMinMax, m_VMaxXY);
  235.                         VMinMax = floatToint32(VMinMax);
  236.  
  237.                         const uint32* pMM = reinterpret_cast<uint32*>(&VMinMax);
  238.                         MinX = pMM[0];
  239.                         MinY = pMM[1];
  240.                         MaxX = pMM[2];
  241.                         MaxY = pMM[3];
  242.                         if (MinX >= MaxX || MinY >= MaxY)
  243.                         {
  244.                                 return false;
  245.                         }
  246.                 }
  247.                 else
  248.                 {
  249.                         V0 = rV0;
  250.                         V1 = rV1;
  251.                         V2 = rV2;
  252.                 }
  253.  
  254.                 MinX &= ~3;
  255.  
  256.                 VMinMax = And(VMinMax, MaskNot3);
  257.  
  258. #ifdef CULL_RENDERER_MINZ
  259.                 const vec4 VMinZ = Splat<2>(Min(Min(rV0, rV1), rV2));
  260. #endif
  261.                 const vec4 V0z = Splat<2>(rV0);
  262.                 const vec4 Z10 = Sub(Splat<2>(rV1), V0z);
  263.                 const vec4 Z20 = Sub(Splat<2>(rV2), V0z);
  264.  
  265.                 const vec4 X20 = Splat<0>(V210);
  266.                 const vec4 Y20 = Splat<1>(V210);
  267.                 const vec4 X10 = Sub(Vec4Zero(), Splat<2>(V210));
  268.                 const vec4 Y10 = Splat<3>(V210);
  269.  
  270.                 VMinMax = Sub(int32Tofloat(VMinMax), V0);
  271.                 const vec4 dx4 = Add(Splat<0>(VMinMax), Vec4ZeroOneTwoThree());
  272.                 const vec4 Y1x = Mul(Y10, dx4);
  273.                 const vec4 Y2x = Sub(Vec4Zero(), Mul(Y20, dx4));
  274.                 vec4 dy4 = Splat<1>(VMinMax);
  275.                 const vec4 Y14 = Mul(Y10, Vec4Four());
  276.                 const vec4 Y24 = Sub(Vec4Zero(), Mul(Y20, Vec4Four()));
  277.                 const vec4 Y34 = Add(Y14, Y24);
  278.  
  279.                 vec4 Visible = Vec4FFFFFFFF();
  280.                 uint16 y = MinY;
  281.                 do
  282.                 {
  283.                         vec4 Px = Madd(X10, dy4, Y1x);
  284.                         vec4 Py = Madd(X20, dy4, Y2x);
  285.                         vec4 Pz = Sub(Sub(Vec4One(), Py), Px);
  286.  
  287.                         vec4* pDstZ = reinterpret_cast<vec4*>(&m_ZBuffer[MinX + y * (uint16)SIZEX]);
  288.                         y++;
  289.                         uint16 x = MinX;
  290.                         do
  291.                         {
  292.                                 Prefetch<ECL_LVL1>(pDstZ);
  293.                                 x += 4;
  294.                                 vec4 Mask = Or(Or(Px, Py), Pz);
  295.                                 vec4 Z, rZ = *pDstZ;
  296. #ifdef CULL_RENDERER_MINZ
  297.                                 if (!WRITE)                       //compile time
  298.                                 {
  299.                                         Mask = Or(Mask, CmpLE(rZ, VMinZ));
  300.                                 }
  301.                                 else
  302. #endif
  303.                                 {
  304.                                         Z = Madd(Z10, Px, Madd(Z20, Py, V0z));
  305.                                         Mask = Or(Mask, CmpLE(rZ, Z));
  306.                                 }
  307.                                 Px = Add(Px, Y14);
  308.                                 Py = Add(Py, Y24);
  309.                                 Pz = Sub(Pz, Y34);
  310.                                 if (CULL)                       //compile time
  311.                                 {
  312.                                         Visible = And(Visible, Mask);
  313.                                 }
  314.                                 if (WRITE)                      //compile time
  315.                                 {
  316.                                         *pDstZ = SelectSign(Z, rZ, Mask);
  317.                                 }
  318.                                 pDstZ++;
  319.                         }
  320.                         while (x < MaxX);
  321.  
  322.                         if (!WRITE && CULL && (SignMask(Visible) & (BitX | BitY | BitZ | BitW)) != (BitX | BitY | BitZ | BitW))
  323.                         {
  324.                                 return true;
  325.                         }
  326.  
  327.                         dy4 = Add(dy4, Vec4One());
  328.                 }
  329.                 while (y < MaxY);
  330.  
  331.                 return CULL && (SignMask(Visible) & (BitX | BitY | BitZ | BitW)) != (BitX | BitY | BitZ | BitW);
  332.         }
  333.  
  334.         inline bool Quad2D(const NVMath::vec4& rV0, const NVMath::vec4& rV1, const NVMath::vec4& rV3, const NVMath::vec4& rV2)
  335.         {
  336.                 using namespace NVMath;
  337.                 const vec4 WWW = Shuffle<xzxz>(Shuffle<wwww>(rV0, rV1), Shuffle<wwww>(rV2, rV3));
  338.                 const vec4 iWWW = Rcp(WWW);
  339.  
  340.                 vec4 V0 = Mul(rV0, Splat<0>(iWWW));
  341.                 vec4 V1 = Mul(rV1, Splat<1>(iWWW));
  342.                 vec4 V2 = Mul(rV2, Splat<2>(iWWW));
  343.                 vec4 V3 = Mul(rV3, Splat<3>(iWWW));
  344.  
  345.                 vec4 V210 = Sub(Shuffle<xyxy>(V1, V2), Swizzle<xyxy>(V0));
  346.                 vec4 V213 = Sub(Shuffle<xyxy>(V1, V2), Swizzle<xyxy>(V3));
  347.                 vec4 Det = Mul(V210, Swizzle<wzwz>(V210));
  348.                 Det = Sub(Det, Splat<1>(Det));
  349.  
  350.                 vec4 VMax = Max(Max(V0, V1), Max(V2, V3));
  351.                 vec4 VMin = Min(Min(V0, V1), Min(V2, V3));
  352.                 VMax = Add(VMax, Vec4One());
  353.                 //saturate to 0 - ScreenSize cause it's assigned to uin16
  354.                 VMin = Min(VMin, m_VMaxXY);
  355.                 VMax = Min(VMax, m_VMaxXY);
  356.  
  357.                 vec4 VMinMax = floatToint32(Max(Shuffle<xyxy>(VMin, VMax), Vec4Zero()));
  358.                 uint16 MinX = Vec4int32(VMinMax, 0);
  359.                 const uint16 MinY = Vec4int32(VMinMax, 1);
  360.                 const uint16 MaxX = Vec4int32(VMinMax, 2);
  361.                 const uint16 MaxY = Vec4int32(VMinMax, 3);
  362.                 if (MinX >= MaxX || MinY >= MaxY)
  363.                 {
  364.                         return false;
  365.                 }
  366.                 MinX &= ~3;
  367.  
  368.                 const vec4 VMinZ = Splat<2>(Min(Min(rV0, rV1), Min(rV2, rV3)));
  369.                 Det = Rcp(Splat<0>(Det));
  370.                 V210 = Mul(V210, Det);
  371.                 V213 = Mul(V213, Det);
  372.                 const vec4 X20 = Splat<0>(V210);
  373.                 const vec4 Y20 = Splat<1>(V210);
  374.                 const vec4 X10 = Splat<2>(V210);
  375.                 const vec4 Y10 = Splat<3>(V210);
  376.                 const vec4 X23 = Splat<0>(V213);
  377.                 const vec4 Y23 = Splat<1>(V213);
  378.                 const vec4 X13 = Splat<2>(V213);
  379.                 const vec4 Y13 = Splat<3>(V213);
  380.  
  381.                 const vec4 dx4 = Sub(Add(NVMath::Vec4(static_cast<float>(MinX)), Vec4ZeroOneTwoThree()), Splat<0>(V0));
  382.                 const vec4 Y10x = Mul(Y10, dx4);
  383.                 const vec4 Y20x = Mul(Y20, dx4);
  384.                 const vec4 Y13x = Mul(Y13, dx4);
  385.                 const vec4 Y23x = Mul(Y23, dx4);
  386.                 vec4 dy4 = Sub(NVMath::Vec4(static_cast<float>(MinY)), Splat<1>(V0));
  387.                 const vec4 Y104 = Mul(Y10, Vec4Four());
  388.                 const vec4 Y204 = Mul(Y20, Vec4Four());
  389.                 const vec4 Y134 = Mul(Y13, Vec4Four());
  390.                 const vec4 Y234 = Mul(Y23, Vec4Four());
  391.                 const vec4 Y304 = Sub(Y104, Y204);
  392.                 const vec4 Y334 = Sub(Y134, Y234);
  393.  
  394.                 vec4 Visible = Vec4FFFFFFFF();
  395.                 uint16 y = MinY;
  396.                 do
  397.                 {
  398.                         vec4 P0x = Sub(Y10x, Mul(X10, dy4));
  399.                         vec4 P0y = Sub(Mul(X20, dy4), Y20x);
  400.                         vec4 P3x = Sub(Y13x, Mul(X13, dy4));
  401.                         vec4 P3y = Sub(Mul(X23, dy4), Y23x);
  402.                         uint16 x = MinX;
  403.                         vec4* pDstZ = reinterpret_cast<vec4*>(&m_ZBuffer[MinX + y * (uint16)SIZEX]);
  404.                         do
  405.                         {
  406.                                 Prefetch<ECL_LVL1>(pDstZ);
  407.                                 vec4 Mask = Or(Or(P0x, P0y), Or(P3x, P3y));
  408.                                 vec4 rZ = *pDstZ++;
  409.                                 Mask = Or(Mask, CmpLE(rZ, VMinZ));
  410.                                 x += 4;
  411.                                 Visible = And(Visible, Mask);
  412.                                 P0x = Add(P0x, Y104);
  413.                                 P0y = Sub(P0y, Y204);
  414.                                 P3x = Add(P3x, Y134);
  415.                                 P3y = Sub(P3y, Y234);
  416.                         }
  417.                         while (x < MaxX);
  418.  
  419.                         if (SignMask(Visible) != (BitX | BitY | BitZ | BitW))
  420.                         {
  421.                                 return true;
  422.                         }
  423.  
  424.                         y++;
  425.                         dy4 = Add(dy4, Vec4One());
  426.                 }
  427.                 while (y < MaxY);
  428.  
  429.                 return false;
  430.         }
  431.  
  432.         void Show();
  433. public:
  434.  
  435.         // Note: Arrays are not initialized for performance reasons
  436.         // cppcheck-suppress uninitMemberVar
  437.         inline CCullRenderer()
  438.         {
  439.                 m_ZBuffer = m_ZBufferMainMemory;
  440.                 m_DebugRender = 0;
  441.                 m_nNumWorker = 0;
  442.                 m_ZBufferSwap = NULL;
  443.         }
  444.  
  445.         ~CCullRenderer()
  446.         {
  447.                 for (uint32 i = 0; i < m_nNumWorker; ++i)
  448.                 {
  449.                         CryModuleMemalignFree(m_ZBufferSwap[i]);
  450.                 }
  451.                 delete[] m_ZBufferSwap;
  452.         }
  453.  
  454.         void Prepare()
  455.         {
  456.                 if (m_nNumWorker)
  457.                 {
  458.                         return;
  459.                 }
  460.  
  461.                 m_nNumWorker = gEnv->pJobManager->GetNumWorkerThreads();
  462.                 m_ZBufferSwap = new tdZexel*[m_nNumWorker];
  463.                 for (uint32 i = 0; i < m_nNumWorker; ++i)
  464.                 {
  465.                         m_ZBufferSwap[i] = (tdZexel*)CryModuleMemalign(sizeof(tdZexel) * SIZEX * SIZEY, 128);
  466.                 }
  467.         }
  468.  
  469.         inline void Clear()
  470.         {
  471.                 m_VMaxXY = NVMath::int32Tofloat(NVMath::Vec4(SIZEX, SIZEY, SIZEX, SIZEY));
  472.                 for (uint32 a = 0, S = SIZEX * SIZEY; a < S; a++)
  473.                 {
  474.                         m_ZBuffer[a] = 9999999999.f;
  475.                 }
  476.                 m_DrawCall = 0;
  477.                 m_PolyCount = 0;
  478.         }
  479.  
  480.         bool DownLoadHWDepthBuffer(float nearPlane, float farPlane, float nearestMax, float Bias)
  481.         {
  482.                 Matrix44A& Reproject = m_Reproject;
  483.  
  484.                 m_VMaxXY = NVMath::int32Tofloat(NVMath::Vec4(SIZEX, SIZEY, SIZEX, SIZEY));
  485.  
  486.                 Matrix44 Dummy;
  487.                 if (!gEnv->pRenderer->GetOcclusionBuffer((uint16*)&m_ZBuffer[0], SizeX(), SizeY(), &Dummy, reinterpret_cast<Matrix44*>(&Reproject)))
  488.                 {
  489.                         return false;
  490.                 }
  491.  
  492.                 for (uint32 i = 0; i < m_nNumWorker; ++i)
  493.                 {
  494.                         memset(m_ZBufferSwap[i], 0, SIZEX * SIZEY * sizeof(float));
  495.                 }
  496.                 memset(m_ZBufferSwapMerged, 0, SIZEX * SIZEY * sizeof(float));
  497.  
  498.                 return true;
  499.         }
  500.  
  501.         void ReprojectHWDepthBuffer(const Matrix44A& rCurrent, float nearPlane, float farPlane, float nearestMax, float Bias, int nStartLine, int nNumLines)
  502.         {
  503.                 //#define USE_W_DEPTH
  504.                 //#define SCALE_DEPTH
  505.  
  506.                 uint32 nWorkerThreadID = JobManager::GetWorkerThreadId();
  507.                 float* pZBufferSwap = m_ZBufferSwap[nWorkerThreadID];
  508.  
  509.                 int sizeX = SIZEX;
  510.                 int sizeY = SIZEY;
  511.  
  512.                 float fWidth = (float) sizeX;
  513.                 float fHeight = (float) sizeY;
  514.  
  515.                 const float a = farPlane / (farPlane - nearPlane);
  516.                 const float b = farPlane * nearPlane / (nearPlane - farPlane);
  517.  
  518.                 Matrix44A fromScreen;
  519.                 fromScreen.SetIdentity();
  520.                 fromScreen.SetTranslation(Vec3(-1.0f + 0.5f / fWidth, 1.0f - 0.5f / fHeight, 0.0f));
  521.                 fromScreen.m00 = 2.0f / fWidth;
  522.                 fromScreen.m11 = -2.0f / fHeight;  // Y flipped
  523.                 fromScreen.Transpose();
  524.  
  525.                 Matrix44A Reproject = m_Reproject;
  526.                 Reproject.Invert();
  527.                 Matrix44A mToWorld = fromScreen * Reproject;
  528.  
  529.                 {
  530.                         int x, y;
  531.                         float fY;
  532.                         using namespace NVMath;
  533.  
  534. #ifdef USE_W_DEPTH
  535.                         Matrix44A mReproject = mToWorld * rCurrent;
  536.                         const vec4 MR0 = reinterpret_cast<vec4*>(&mReproject)[0];
  537.                         const vec4 MR1 = reinterpret_cast<vec4*>(&mReproject)[1];
  538.                         const vec4 MR2 = reinterpret_cast<vec4*>(&mReproject)[2];
  539.                         const vec4 MR3 = reinterpret_cast<vec4*>(&mReproject)[3];
  540.  
  541.                         const vec4 vA = NVMath::Vec4(a);
  542.                         const vec4 vB = NVMath::Vec4(b);
  543. #else
  544.                         const vec4 MW0 = reinterpret_cast<vec4*>(&mToWorld)[0];
  545.                         const vec4 MW1 = reinterpret_cast<vec4*>(&mToWorld)[1];
  546.                         const vec4 MW2 = reinterpret_cast<vec4*>(&mToWorld)[2];
  547.                         const vec4 MW3 = reinterpret_cast<vec4*>(&mToWorld)[3];
  548.  
  549.                         const vec4 MS0 = reinterpret_cast<const vec4*>(&rCurrent)[0];
  550.                         const vec4 MS1 = reinterpret_cast<const vec4*>(&rCurrent)[1];
  551.                         const vec4 MS2 = reinterpret_cast<const vec4*>(&rCurrent)[2];
  552.                         const vec4 MS3 = reinterpret_cast<const vec4*>(&rCurrent)[3];
  553. #endif
  554.  
  555.                         const vec4 vXOffsets = NVMath::Vec4(0.0f, 1.0f, 2.0f, 3.0f);
  556.                         const vec4 vXIncrement = NVMath::Vec4(4.0f);
  557.  
  558.                         const float nearestLinear = b / (nearestMax - a);
  559.                         const vec4 vfEpsilon = NVMath::Vec4Epsilon();
  560.                         const vec4 vfOne = NVMath::Vec4One();
  561.                         const vec4 vZero = NVMath::Vec4Zero();
  562.  
  563.                         vec4* pSrcZ = reinterpret_cast<vec4*>(&m_ZBuffer[nStartLine * sizeX]);
  564.  
  565.                         for (y = nStartLine, fY = static_cast<float>(nStartLine); y < nStartLine + nNumLines; y++, fY += 1.0f)
  566.                         {
  567.                                 const vec4 vYYYY = NVMath::Vec4(fY);
  568.  
  569.                                 vec4 vXCoords = vXOffsets;
  570.  
  571.                                 for (x = 0; x < sizeX; x += 4)
  572.                                 {
  573.                                         const vec4 vNonLinearDepth = *pSrcZ;
  574.  
  575.                                         vec4 vXXXX[4];
  576.                                         vXXXX[0] = Splat<0>(vXCoords);
  577.                                         vXXXX[1] = Splat<1>(vXCoords);
  578.                                         vXXXX[2] = Splat<2>(vXCoords);
  579.                                         vXXXX[3] = Splat<3>(vXCoords);
  580.  
  581.                                         vec4 vZZZZ[4];
  582.                                         vZZZZ[0] = Splat<0>(vNonLinearDepth);
  583.                                         vZZZZ[1] = Splat<1>(vNonLinearDepth);
  584.                                         vZZZZ[2] = Splat<2>(vNonLinearDepth);
  585.                                         vZZZZ[3] = Splat<3>(vNonLinearDepth);
  586.  
  587.                                         for (int i = 0; i < 4; i++)
  588.                                         {
  589. #ifdef USE_W_DEPTH
  590.                                                 vec4 vScreenPos = Madd(MR0, vXXXX[i], Madd(MR1, vYYYY, Madd(MR2, vZZZZ[i], MR3)));
  591.  
  592.                                                 vec4 vScreenPosH = Div(vScreenPos, Splat<3>(vScreenPos));
  593.  
  594.                                                 vec4 vNewDepth = Div(vB, Sub(Splat<2>(vScreenPosH), vA));
  595.  
  596.                                                 float newDepth = Vec4float<2>(vNewDepth);
  597. #else
  598.                                                 vec4 vWorldPos = Madd(MW0, vXXXX[i], Madd(MW1, vYYYY, Madd(MW2, vZZZZ[i], MW3)));
  599.  
  600.                                                 vec4 vWorldPosH = Div(vWorldPos, Max(Splat<3>(vWorldPos), vfEpsilon));
  601.  
  602.                                                 vec4 vScreenPos = Madd(MS0, Splat<0>(vWorldPosH), Madd(MS1, Splat<1>(vWorldPosH), Madd(MS2, Splat<2>(vWorldPosH), MS3)));
  603.  
  604.                                                 vec4 vNewDepth = Splat<2>(vScreenPos);
  605.  
  606.                                                 vec4 vScreenPosH = Div(vScreenPos, Max(Splat<3>(vScreenPos), vfEpsilon));
  607.  
  608.                                                 float newDepth = Vec4float<2>(vNewDepth);
  609. #endif
  610.                                                 // It is faster to use simple non-vectorized code to write the depth in the buffer
  611.  
  612.                                                 if (newDepth > 0.f)
  613.                                                 {
  614.                                                         int X;
  615.                                                         int Y;
  616.                                                         if (Vec4float<0>(vZZZZ[i]) < nearestMax)
  617.                                                         {
  618.                                                                 X = x + i;
  619.                                                                 Y = y;
  620.                                                                 newDepth = nearestLinear;
  621.                                                         }
  622.                                                         else
  623.                                                         {
  624.                                                                 vec4 vFinalScreenPosU = floatToint32(vScreenPosH);
  625.  
  626.                                                                 X = Vec4int32<0>(vFinalScreenPosU);
  627.                                                                 Y = Vec4int32<1>(vFinalScreenPosU);
  628.                                                         }
  629.  
  630.                                                         if (X >= 0 && Y >= 0 && X < sizeX && Y < sizeY)
  631.                                                         {
  632.                                                                 float* pDstZ = &pZBufferSwap[X + (Y * sizeX)];
  633.                                                                 float depth = *pDstZ;
  634.  
  635.                                                                 depth = depth <= 0.f ? farPlane : depth;
  636.                                                                 *pDstZ = min(depth, newDepth);
  637.                                                         }
  638.                                                 }
  639.                                         }
  640.                                         vXCoords = Add(vXIncrement, vXCoords);
  641.  
  642.                                         pSrcZ++;
  643.                                 }
  644.                         }
  645.                 }
  646.         }
  647.  
  648.         void MergeReprojectHWDepthBuffer(int nStartLine, int nNumLines)
  649.         {
  650.                 const int sizeX = SIZEX;
  651.                 using namespace NVMath;
  652.  
  653.                 const vec4 zero = Vec4Zero();
  654.  
  655.                 for (uint32 i = 0; i < m_nNumWorker; ++i)
  656.                 {
  657.                         for (int y = nStartLine; y < nStartLine + nNumLines; y++)
  658.                         {
  659.                                 for (int x = 0; x < sizeX; x += 4)
  660.                                 {
  661.                                         vec4* pDstZ = reinterpret_cast<vec4*>(&m_ZBufferSwapMerged[x + (y * sizeX)]);
  662.                                         vec4 vDstZ = *pDstZ;
  663.  
  664.                                         vec4* pSrcZ = reinterpret_cast<vec4*>(&m_ZBufferSwap[i][x + (y * sizeX)]);
  665.                                         vec4 vSrcZ = *pSrcZ;
  666.  
  667.                                         // remove zeros so Min doesn't select them
  668.                                         vDstZ = Select(vDstZ, vSrcZ, CmpLE(vDstZ, zero));
  669.                                         vSrcZ = Select(vSrcZ, vDstZ, CmpLE(vSrcZ, zero));
  670.  
  671.                                         const vec4 vNewDepth = Min(vSrcZ, vDstZ);
  672.  
  673.                                         *pDstZ = vNewDepth;
  674.                                 }
  675.                         }
  676.                 }
  677.         }
  678.  
  679.         void ReprojectHWDepthBufferAfterMerge(const Matrix44A& rCurrent, float nearPlane, float farPlane, float nearestMax, float Bias, int nStartLine, int nNumLines)
  680.         {
  681.                 using namespace NVMath;
  682.                 int sizeX = SIZEX;
  683.                 int sizeY = SIZEY;
  684.                 const vec4 vFarPlane = NVMath::Vec4(farPlane);
  685.  
  686.                 float* pZBufferSwap = m_ZBufferSwapMerged;
  687.                 vec4* pSwap = reinterpret_cast<vec4*>(&pZBufferSwap[0]);
  688.                 vec4* pDst = reinterpret_cast<vec4*>(&m_ZBuffer[nStartLine * sizeX]);
  689.  
  690.                 const vec4 vBiasAdd = NVMath::Vec4(Bias < 0.f ? -Bias : 0.f);
  691.                 const vec4 vBiasMul = NVMath::Vec4(Bias > 0.f ? Bias : 0.f);
  692.                 const int pitchX = SIZEX / 4;
  693.  
  694.                 vec4 zero = Vec4Zero();
  695.  
  696.                 for (int y = nStartLine; y < nStartLine + nNumLines; y++)
  697.                 {
  698.                         int minY = max((int)0, (int)y - 1);
  699.                         int maxY = min((int)sizeY - 1, (int)y + 1);
  700.                         int maxX = min(pitchX - 1, 0 + 1);
  701.  
  702.                         vec4 src[3];
  703.                         vec4 srcMax[3];
  704.                         vec4 srcCenter;
  705.  
  706.                         // left, no data available yet
  707.                         srcMax[0] = zero;
  708.  
  709.                         // center
  710.                         src[0] = pSwap[0 + minY * pitchX];
  711.                         src[1] = pSwap[0 + y * pitchX];
  712.                         src[2] = pSwap[0 + maxY * pitchX];
  713.                         srcMax[1] = Max(Max(src[0], src[1]), src[2]);
  714.                         srcCenter = src[1];
  715.  
  716.                         // right
  717.                         src[0] = pSwap[maxX + minY * pitchX];
  718.                         src[1] = pSwap[maxX + y * pitchX];
  719.                         src[2] = pSwap[maxX + maxY * pitchX];
  720.                         srcMax[2] = Max(Max(src[0], src[1]), src[2]);
  721.  
  722.                         int vecX = 0;
  723.                         for (int x = 0; x < sizeX; x += 4) //todo, fix edge cases
  724.                         {
  725.                                 vec4 vDst;
  726.                                 vec4 vSrcIsZero = CmpLE(srcCenter, zero);
  727.  
  728.                                 // 0
  729.                                 {
  730.                                         vec4 vLeft, vCenter;
  731.                                         vLeft = SelectStatic<0x8>(zero, srcMax[0]);
  732.                                         vCenter = SelectStatic<0x3>(zero, srcMax[1]);
  733.  
  734.                                         vec4 _vMax;
  735.                                         _vMax = Max(vLeft, vCenter);
  736.                                         _vMax = Max(_vMax, Swizzle<zwxy>(_vMax));
  737.                                         _vMax = Max(_vMax, Swizzle<wzyx>(_vMax));
  738.  
  739.                                         vDst = _vMax;
  740.                                 }
  741.  
  742.                                 // 1
  743.                                 {
  744.                                         vec4 vCenter;
  745.  
  746.                                         vCenter = SelectStatic<0x7>(zero, srcMax[1]);
  747.  
  748.                                         vec4 _vMax;
  749.                                         _vMax = Max(vCenter, Swizzle<zwxy>(vCenter));
  750.                                         _vMax = Max(_vMax, Swizzle<wzyx>(_vMax));
  751.  
  752.                                         vDst = SelectStatic<0x2>(vDst, _vMax);
  753.                                 }
  754.  
  755.                                 // 2
  756.                                 {
  757.                                         vec4 vCenter;
  758.  
  759.                                         vCenter = SelectStatic<0xE>(zero, srcMax[1]);
  760.  
  761.                                         vec4 _vMax;
  762.                                         _vMax = Max(vCenter, Swizzle<zwxy>(vCenter));
  763.                                         _vMax = Max(_vMax, Swizzle<wzyx>(_vMax));
  764.  
  765.                                         vDst = SelectStatic<0x4>(vDst, _vMax);
  766.                                 }
  767.  
  768.                                 // 3
  769.                                 {
  770.                                         vec4 vRight, vCenter;
  771.  
  772.                                         vRight = SelectStatic<0x1>(zero, srcMax[2]);
  773.                                         vCenter = SelectStatic<0xC>(zero, srcMax[1]);
  774.  
  775.                                         vec4 _vMax;
  776.                                         _vMax = Max(vRight, vCenter);
  777.  
  778.                                         _vMax = Max(_vMax, Swizzle<zwxy>(_vMax));
  779.                                         _vMax = Max(_vMax, Swizzle<wzyx>(_vMax));
  780.  
  781.                                         vDst = SelectStatic<0x8>(vDst, _vMax);
  782.                                 }
  783.  
  784.                                 vec4 vDstIsZero = CmpLE(vDst, zero);
  785.                                 vDst = Select(vDst, vFarPlane, vDstIsZero);
  786.  
  787.                                 vDst = Select(srcCenter, vDst, vSrcIsZero);
  788.  
  789.                                 vDst = Add(vDst, vBiasAdd);  //linear bias
  790.                                 vDst = Add(vDst, Madd(vBiasMul, vDst, vBiasMul));// none-linear bias
  791. #ifdef SCALE_DEPTH
  792.                                 //*pDst = Mul(vDst, NVMath::Vec4(1.2f));
  793.                                 *pDst = Add(vDst, NVMath::Vec4(0.5f));
  794. #else
  795.                                 *pDst = vDst;
  796. #endif
  797.  
  798.                                 //next loop
  799.                                 ++pDst;
  800.                                 ++vecX;
  801.  
  802.                                 // shift to the left
  803.                                 srcMax[0] = srcMax[1];
  804.                                 srcMax[1] = srcMax[2];
  805.                                 srcCenter = src[1];
  806.  
  807.                                 // load right data
  808.                                 maxX = min(pitchX - 1, vecX + 1);
  809.                                 src[0] = pSwap[maxX + minY * pitchX];
  810.                                 src[1] = pSwap[maxX + y * pitchX];
  811.                                 src[2] = pSwap[maxX + maxY * pitchX];
  812.                                 srcMax[2] = Max(Max(src[0], src[1]), src[2]);
  813.                         }
  814.                 }
  815.  
  816.                 //for(int a=0;a<128;a+=16)
  817.                 //      printf("%2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f\n",
  818.                 //      m_ZBuffer[a+0],m_ZBuffer[a+1],m_ZBuffer[a+2],m_ZBuffer[a+3],
  819.                 //      m_ZBuffer[a+4],m_ZBuffer[a+5],m_ZBuffer[a+6],m_ZBuffer[a+7],
  820.                 //      m_ZBuffer[a+8],m_ZBuffer[a+9],m_ZBuffer[a+10],m_ZBuffer[a+11],
  821.                 //      m_ZBuffer[a+12],m_ZBuffer[a+13],m_ZBuffer[a+14],m_ZBuffer[a+15]);
  822.  
  823. #ifdef CULL_RENDERER_REPROJ_DEBUG
  824.                 memcpy(&pZBufferSwap[nStartLine * sizeX], &m_ZBuffer[nStartLine * sizeX], sizeX * nNumLines * sizeof(float));
  825. #endif
  826.  
  827. #ifdef SCALE_DEPTH
  828.         #undef SCALE_DEPTH
  829. #endif
  830.  
  831. #ifdef USE_W_DEPTH
  832.         #undef USE_W_DEPTH
  833. #endif
  834.  
  835.         }
  836.  
  837.         inline int AABBInFrustum(const NVMath::vec4* pViewProj, Vec3 Min, Vec3 Max, Vec3 ViewPos)
  838.         {
  839.                 using namespace NVMath;
  840.                 const NVMath::vec4 M0 = pViewProj[0];
  841.                 const NVMath::vec4 M1 = pViewProj[1];
  842.                 const NVMath::vec4 M2 = pViewProj[2];
  843.                 const NVMath::vec4 M3 = pViewProj[3];
  844.                 const NVMath::vec4 MinX = NVMath::Vec4(Min.x);
  845.                 const NVMath::vec4 MinY = NVMath::Vec4(Min.y);
  846.                 const NVMath::vec4 MinZ = NVMath::Vec4(Min.z);
  847.                 const NVMath::vec4 MaxX = NVMath::Vec4(Max.x);
  848.                 const NVMath::vec4 MaxY = NVMath::Vec4(Max.y);
  849.                 const NVMath::vec4 MaxZ = NVMath::Vec4(Max.z);
  850.  
  851.                 vec4 VB0 = Madd(MinX, M0, Madd(MinY, M1, Madd(MinZ, M2, M3)));
  852.                 vec4 VB1 = Madd(MinX, M0, Madd(MaxY, M1, Madd(MinZ, M2, M3)));
  853.                 vec4 VB2 = Madd(MaxX, M0, Madd(MinY, M1, Madd(MinZ, M2, M3)));
  854.                 vec4 VB3 = Madd(MaxX, M0, Madd(MaxY, M1, Madd(MinZ, M2, M3)));
  855.                 vec4 VB4 = Madd(MinX, M0, Madd(MinY, M1, Madd(MaxZ, M2, M3)));
  856.                 vec4 VB5 = Madd(MinX, M0, Madd(MaxY, M1, Madd(MaxZ, M2, M3)));
  857.                 vec4 VB6 = Madd(MaxX, M0, Madd(MinY, M1, Madd(MaxZ, M2, M3)));
  858.                 vec4 VB7 = Madd(MaxX, M0, Madd(MaxY, M1, Madd(MaxZ, M2, M3)));
  859.                 vec4 SMask = And(And(And(VB0, VB1), And(VB2, VB3)), And(Or(VB4, VB5), And(VB6, VB7)));
  860.                 if (SignMask(SMask) & BitZ)
  861.                 {
  862.                         return 0;
  863.                 }
  864.  
  865.                 int Visible = 3;
  866.  
  867.                 SMask = Or(Or(Or(VB0, VB1), Or(VB2, VB3)), Or(Or(VB4, VB5), Or(VB6, VB7)));
  868.                 if ((SignMask(SMask) & BitZ) == 0)
  869.                 {
  870.                         VB0 = Div(VB0, Splat<3>(VB0));
  871.                         VB1 = Div(VB1, Splat<3>(VB1));
  872.                         VB2 = Div(VB2, Splat<3>(VB2));
  873.                         VB3 = Div(VB3, Splat<3>(VB3));
  874.                         VB4 = Div(VB4, Splat<3>(VB4));
  875.                         VB5 = Div(VB5, Splat<3>(VB5));
  876.                         VB6 = Div(VB6, Splat<3>(VB6));
  877.                         VB7 = Div(VB7, Splat<3>(VB7));
  878.                         const vec4 VC0 = Madd(VB0, NVMath::Vec4(-1.f), m_VMaxXY);
  879.                         const vec4 VC1 = Madd(VB1, NVMath::Vec4(-1.f), m_VMaxXY);
  880.                         const vec4 VC2 = Madd(VB2, NVMath::Vec4(-1.f), m_VMaxXY);
  881.                         const vec4 VC3 = Madd(VB3, NVMath::Vec4(-1.f), m_VMaxXY);
  882.                         const vec4 VC4 = Madd(VB4, NVMath::Vec4(-1.f), m_VMaxXY);
  883.                         const vec4 VC5 = Madd(VB5, NVMath::Vec4(-1.f), m_VMaxXY);
  884.                         const vec4 VC6 = Madd(VB6, NVMath::Vec4(-1.f), m_VMaxXY);
  885.                         const vec4 VC7 = Madd(VB7, NVMath::Vec4(-1.f), m_VMaxXY);
  886.                         const vec4 SMaskB = And(And(And(VB0, VB1), And(VB2, VB3)), And(And(VB4, VB5), And(VB6, VB7)));
  887.                         const vec4 SMaskC = And(And(And(VC0, VC1), And(VC2, VC3)), And(And(VC4, VC5), And(VC6, VC7)));
  888.                         if ((SignMask(SMaskB) & (BitX | BitY)) || (SignMask(SMaskC) & (BitX | BitY)))
  889.                         {
  890.                                 return 0;
  891.                         }
  892.                         Visible = 1;
  893.                 }
  894.                 //return true;
  895.                 if (Max.x < ViewPos.x)
  896.                 {
  897.                         if (Triangle<false, true, true>(VB3, VB2, VB7))
  898.                         {
  899.                                 return Visible;    //MaxX
  900.                         }
  901.                         if (Triangle<false, true, true>(VB7, VB2, VB6))
  902.                         {
  903.                                 return Visible;
  904.                         }
  905.                         Visible &= ~1;
  906.                 }
  907.                 else if (Min.x > ViewPos.x)
  908.                 {
  909.                         if (Triangle<false, true, true>(VB0, VB1, VB4))
  910.                         {
  911.                                 return Visible;    //MinX
  912.                         }
  913.                         if (Triangle<false, true, true>(VB4, VB1, VB5))
  914.                         {
  915.                                 return Visible;
  916.                         }
  917.                         Visible &= ~1;
  918.                 }
  919.                 if (Max.y < ViewPos.y)
  920.                 {
  921.                         if (Triangle<false, true, true>(VB1, VB3, VB5))
  922.                         {
  923.                                 return Visible | 1;    //MaxY
  924.                         }
  925.                         if (Triangle<false, true, true>(VB5, VB3, VB7))
  926.                         {
  927.                                 return Visible | 1;
  928.                         }
  929.                         Visible &= ~1;
  930.                 }
  931.                 else if (Min.y > ViewPos.y)
  932.                 {
  933.                         if (Triangle<false, true, true>(VB2, VB0, VB6))
  934.                         {
  935.                                 return Visible | 1;    //MinY
  936.                         }
  937.                         if (Triangle<false, true, true>(VB6, VB0, VB4))
  938.                         {
  939.                                 return Visible | 1;
  940.                         }
  941.                         Visible &= ~1;
  942.                 }
  943.                 if (Max.z < ViewPos.z)
  944.                 {
  945.                         if (Triangle<false, true, true>(VB4, VB5, VB6))
  946.                         {
  947.                                 return Visible | 1;    //MaxZ
  948.                         }
  949.                         if (Triangle<false, true, true>(VB6, VB5, VB7))
  950.                         {
  951.                                 return Visible | 1;
  952.                         }
  953.                         Visible = 0;
  954.                 }
  955.                 else if (Min.z > ViewPos.z)
  956.                 {
  957.                         if (Triangle<false, true, true>(VB1, VB0, VB3))
  958.                         {
  959.                                 return Visible | 1;    //MinZ
  960.                         }
  961.                         if (Triangle<false, true, true>(VB3, VB0, VB2))
  962.                         {
  963.                                 return Visible | 1;
  964.                         }
  965.                         Visible = 0;
  966.                 }
  967.                 return Visible & (Visible << 1);
  968.         }
  969.  
  970.         inline bool TestQuad(const NVMath::vec4* pViewProj, const Vec3& vCenter, const Vec3& vAxisX, const Vec3& vAxisY)
  971.         {
  972.                 const NVMath::vec4 M0 = pViewProj[0];
  973.                 const NVMath::vec4 M1 = pViewProj[1];
  974.                 const NVMath::vec4 M2 = pViewProj[2];
  975.                 const NVMath::vec4 M3 = pViewProj[3];
  976.  
  977.                 const Vec3 v0 = vCenter - vAxisX - vAxisY;
  978.                 const Vec3 v1 = vCenter - vAxisX + vAxisY;
  979.                 const Vec3 v2 = vCenter + vAxisX + vAxisY;
  980.                 const Vec3 v3 = vCenter + vAxisX - vAxisY;
  981.  
  982.                 const NVMath::vec4 VB0 = NVMath::Madd(NVMath::Vec4(v0.x), M0, NVMath::Madd(NVMath::Vec4(v0.y), M1, NVMath::Madd(NVMath::Vec4(v0.z), M2, M3)));
  983.                 const NVMath::vec4 VB1 = NVMath::Madd(NVMath::Vec4(v1.x), M0, NVMath::Madd(NVMath::Vec4(v1.y), M1, NVMath::Madd(NVMath::Vec4(v1.z), M2, M3)));
  984.                 const NVMath::vec4 VB2 = NVMath::Madd(NVMath::Vec4(v2.x), M0, NVMath::Madd(NVMath::Vec4(v2.y), M1, NVMath::Madd(NVMath::Vec4(v2.z), M2, M3)));
  985.                 const NVMath::vec4 VB3 = NVMath::Madd(NVMath::Vec4(v3.x), M0, NVMath::Madd(NVMath::Vec4(v3.y), M1, NVMath::Madd(NVMath::Vec4(v3.z), M2, M3)));
  986.  
  987.                 // Note: Explicitly disabling backface culling here
  988.                 if (Triangle<false, true, false>(VB2, VB0, VB3))
  989.                 {
  990.                         return true;
  991.                 }
  992.                 if (Triangle<false, true, false>(VB1, VB0, VB2))
  993.                 {
  994.                         return true;
  995.                 }
  996.  
  997.                 return false;
  998.         }
  999.  
  1000.         inline bool TestAABB(const NVMath::vec4* pViewProj, Vec3 Min, Vec3 Max, Vec3 ViewPos)
  1001.         {
  1002.                 using namespace NVMath;
  1003.                 const NVMath::vec4 M0 = pViewProj[0];
  1004.                 const NVMath::vec4 M1 = pViewProj[1];
  1005.                 const NVMath::vec4 M2 = pViewProj[2];
  1006.                 const NVMath::vec4 M3 = pViewProj[3];
  1007.                 const NVMath::vec4 MinX = NVMath::Vec4(Min.x);
  1008.                 const NVMath::vec4 MinY = NVMath::Vec4(Min.y);
  1009.                 const NVMath::vec4 MinZ = NVMath::Vec4(Min.z);
  1010.                 const NVMath::vec4 MaxX = NVMath::Vec4(Max.x);
  1011.                 const NVMath::vec4 MaxY = NVMath::Vec4(Max.y);
  1012.                 const NVMath::vec4 MaxZ = NVMath::Vec4(Max.z);
  1013.  
  1014.                 const vec4 VB0 = Madd(MinX, M0, Madd(MinY, M1, Madd(MinZ, M2, M3)));
  1015.                 const vec4 VB1 = Madd(MinX, M0, Madd(MaxY, M1, Madd(MinZ, M2, M3)));
  1016.                 const vec4 VB2 = Madd(MaxX, M0, Madd(MinY, M1, Madd(MinZ, M2, M3)));
  1017.                 const vec4 VB3 = Madd(MaxX, M0, Madd(MaxY, M1, Madd(MinZ, M2, M3)));
  1018.                 const vec4 VB4 = Madd(MinX, M0, Madd(MinY, M1, Madd(MaxZ, M2, M3)));
  1019.                 const vec4 VB5 = Madd(MinX, M0, Madd(MaxY, M1, Madd(MaxZ, M2, M3)));
  1020.                 const vec4 VB6 = Madd(MaxX, M0, Madd(MinY, M1, Madd(MaxZ, M2, M3)));
  1021.                 const vec4 VB7 = Madd(MaxX, M0, Madd(MaxY, M1, Madd(MaxZ, M2, M3)));
  1022.                 vec4 SMask = Or(Or(Or(VB0, VB1), Or(VB2, VB3)), Or(Or(VB4, VB5), Or(VB6, VB7)));
  1023.  
  1024.                 if (SignMask(SMask) & BitZ)
  1025.                 {
  1026.                         if (Max.x < ViewPos.x)
  1027.                         {
  1028.                                 if (Triangle<false, true, true>(VB3, VB2, VB7))
  1029.                                 {
  1030.                                         return true;    //MaxX
  1031.                                 }
  1032.                                 if (Triangle<false, true, true>(VB7, VB2, VB6))
  1033.                                 {
  1034.                                         return true;
  1035.                                 }
  1036.                         }
  1037.                         if (Min.x > ViewPos.x)
  1038.                         {
  1039.                                 if (Triangle<false, true, true>(VB0, VB1, VB4))
  1040.                                 {
  1041.                                         return true;    //MinX
  1042.                                 }
  1043.                                 if (Triangle<false, true, true>(VB4, VB1, VB5))
  1044.                                 {
  1045.                                         return true;
  1046.                                 }
  1047.                         }
  1048.                         if (Max.y < ViewPos.y)
  1049.                         {
  1050.                                 if (Triangle<false, true, true>(VB1, VB3, VB5))
  1051.                                 {
  1052.                                         return true;    //MaxY
  1053.                                 }
  1054.                                 if (Triangle<false, true, true>(VB5, VB3, VB7))
  1055.                                 {
  1056.                                         return true;
  1057.                                 }
  1058.                         }
  1059.                         if (Min.y > ViewPos.y)
  1060.                         {
  1061.                                 if (Triangle<false, true, true>(VB2, VB0, VB6))
  1062.                                 {
  1063.                                         return true;    //MinY
  1064.                                 }
  1065.                                 if (Triangle<false, true, true>(VB6, VB0, VB4))
  1066.                                 {
  1067.                                         return true;
  1068.                                 }
  1069.                         }
  1070.                         if (Max.z < ViewPos.z)
  1071.                         {
  1072.                                 if (Triangle<false, true, true>(VB4, VB5, VB6))
  1073.                                 {
  1074.                                         return true;    //MaxZ
  1075.                                 }
  1076.                                 if (Triangle<false, true, true>(VB6, VB5, VB7))
  1077.                                 {
  1078.                                         return true;
  1079.                                 }
  1080.                         }
  1081.                         if (Min.z > ViewPos.z)
  1082.                         {
  1083.                                 if (Triangle<false, true, true>(VB1, VB0, VB3))
  1084.                                 {
  1085.                                         return true;    //MinZ
  1086.                                 }
  1087.                                 if (Triangle<false, true, true>(VB3, VB0, VB2))
  1088.                                 {
  1089.                                         return true;
  1090.                                 }
  1091.                         }
  1092.                 }
  1093.                 else
  1094.                 {
  1095.                         if (Max.x < ViewPos.x)
  1096.                         {
  1097.                                 //if(Quad2D(VB3,VB2,VB6,VB7))return true;
  1098.                                 if (Triangle2D<false, true, true, true>(VB3, VB2, VB7))
  1099.                                 {
  1100.                                         return true;
  1101.                                 }
  1102.                                 if (Triangle2D<false, true, true, true>(VB7, VB2, VB6))
  1103.                                 {
  1104.                                         return true;
  1105.                                 }
  1106.                         }
  1107.                         if (Min.x > ViewPos.x)
  1108.                         {
  1109.                                 //if(Quad2D(VB0,VB1,VB5,VB4))return true;
  1110.                                 if (Triangle2D<false, true, true, true>(VB0, VB1, VB4))
  1111.                                 {
  1112.                                         return true;
  1113.                                 }
  1114.                                 if (Triangle2D<false, true, true, true>(VB4, VB1, VB5))
  1115.                                 {
  1116.                                         return true;
  1117.                                 }
  1118.                         }
  1119.                         if (Max.y < ViewPos.y)
  1120.                         {
  1121.                                 //if(Quad2D(VB1,VB3,VB7,VB5))return true;
  1122.                                 if (Triangle2D<false, true, true, true>(VB1, VB3, VB5))
  1123.                                 {
  1124.                                         return true;
  1125.                                 }
  1126.                                 if (Triangle2D<false, true, true, true>(VB5, VB3, VB7))
  1127.                                 {
  1128.                                         return true;
  1129.                                 }
  1130.                         }
  1131.                         if (Min.y > ViewPos.y)
  1132.                         {
  1133.                                 //if(Quad2D(VB2,VB0,VB4,VB6))return true;
  1134.                                 if (Triangle2D<false, true, true, true>(VB2, VB0, VB6))
  1135.                                 {
  1136.                                         return true;
  1137.                                 }
  1138.                                 if (Triangle2D<false, true, true, true>(VB6, VB0, VB4))
  1139.                                 {
  1140.                                         return true;
  1141.                                 }
  1142.                         }
  1143.                         if (Max.z < ViewPos.z)
  1144.                         {
  1145.                                 //if(Quad2D(VB4,VB5,VB7,VB6))return true;
  1146.                                 if (Triangle2D<false, true, true, true>(VB4, VB5, VB6))
  1147.                                 {
  1148.                                         return true;
  1149.                                 }
  1150.                                 if (Triangle2D<false, true, true, true>(VB6, VB5, VB7))
  1151.                                 {
  1152.                                         return true;
  1153.                                 }
  1154.                         }
  1155.                         if (Min.z > ViewPos.z)
  1156.                         {
  1157.                                 //if(Quad2D(VB1,VB0,VB2,VB3))return true;
  1158.                                 if (Triangle2D<false, true, true, true>(VB1, VB0, VB3))
  1159.                                 {
  1160.                                         return true;
  1161.                                 }
  1162.                                 if (Triangle2D<false, true, true, true>(VB3, VB0, VB2))
  1163.                                 {
  1164.                                         return true;
  1165.                                 }
  1166.                         }
  1167.                 }
  1168.                 return false;
  1169.         }
  1170.  
  1171.         template<bool NEEDCLIPPING>
  1172.         inline void Rasterize(const NVMath::vec4* pViewProj, const NVMath::vec4* __restrict pTriangles, size_t TriCount)
  1173.         {
  1174.                 using namespace NVMath;
  1175.                 Prefetch<ECL_LVL1>(pTriangles);
  1176.                 m_DrawCall++;
  1177.                 m_PolyCount += TriCount;
  1178.  
  1179.                 const vec4 M0 = pViewProj[0];
  1180.                 const vec4 M1 = pViewProj[1];
  1181.                 const vec4 M2 = pViewProj[2];
  1182.                 const vec4 M3 = pViewProj[3];
  1183.                 const size_t VCacheCount = 48;                       //16x3 vertices
  1184.                 vec4 VTmp[VCacheCount];
  1185.                 vec4 DetTmp[VCacheCount * 2 / 3];
  1186.  
  1187.                 if (TriCount > 65535)
  1188.                 {
  1189.                         TriCount = 65535;
  1190.                 }
  1191.  
  1192.                 for (size_t a = 0, S = TriCount; a < S; a += VCacheCount)
  1193.                 {
  1194.                         vec4 ZMask = Vec4Zero();
  1195.                         const size_t VTmpCount = VCacheCount + a > TriCount ? TriCount - a : VCacheCount;
  1196.                         vec4* pVTmp = VTmp;
  1197.                         for (size_t b = 0; b < VTmpCount; b += 3, pVTmp += 3, pTriangles += 3)
  1198.                         {
  1199.                                 Prefetch<ECL_LVL1>(pTriangles + 48);
  1200.  
  1201.                                 const vec4 VA = reinterpret_cast<const vec4*>(pTriangles)[0];
  1202.                                 const vec4 VB = reinterpret_cast<const vec4*>(pTriangles)[1];
  1203.                                 const vec4 VC = reinterpret_cast<const vec4*>(pTriangles)[2];
  1204.  
  1205.                                 const vec4 V0 = Madd(Splat<0>(VA), M0, Madd(Splat<1>(VA), M1, Madd(Splat<2>(VA), M2, M3)));
  1206.                                 const vec4 V1 = Madd(Splat<0>(VB), M0, Madd(Splat<1>(VB), M1, Madd(Splat<2>(VB), M2, M3)));
  1207.                                 const vec4 V2 = Madd(Splat<0>(VC), M0, Madd(Splat<1>(VC), M1, Madd(Splat<2>(VC), M2, M3)));
  1208.  
  1209.                                 if (NEEDCLIPPING)
  1210.                                 {
  1211.                                         ZMask = Or(Or(ZMask, V0), Or(V1, V2));
  1212.                                 }
  1213.  
  1214.                                 pVTmp[0] = V0;
  1215.                                 pVTmp[1] = V1;
  1216.                                 pVTmp[2] = V2;
  1217.                         }
  1218.  
  1219.                         const uint32 Idx = SignMask(ZMask) & BitZ;
  1220.                         if (NEEDCLIPPING && Idx == BitZ)
  1221.                         {
  1222.                                 for (size_t b = 0; b < VTmpCount; b += 3)
  1223.                                 {
  1224.                                         Triangle<true, false, true>(VTmp[b], VTmp[b + 2], VTmp[b + 1]);
  1225.                                 }
  1226.                         }
  1227.                         else
  1228.                         {
  1229.                                 const vec4 M = NVMath::Vec4(~0u, ~0u, 0u, ~0u);
  1230.                                 pVTmp = VTmp;
  1231.                                 vec4* pDetTmp = DetTmp;
  1232.                                 for (size_t b = 0; b < VTmpCount; b += 12, pVTmp += 12, pDetTmp += 8)
  1233.                                 {
  1234.                                         vec4 V0 = pVTmp[0];
  1235.                                         vec4 V1 = pVTmp[1];
  1236.                                         vec4 V2 = pVTmp[2];
  1237.                                         vec4 V3 = pVTmp[3];
  1238.                                         vec4 V4 = pVTmp[4];
  1239.                                         vec4 V5 = pVTmp[5];
  1240.                                         vec4 V6 = pVTmp[6];
  1241.                                         vec4 V7 = pVTmp[7];
  1242.                                         vec4 V8 = pVTmp[8];
  1243.                                         vec4 V9 = pVTmp[9];
  1244.                                         vec4 VA = pVTmp[10];
  1245.                                         vec4 VB = pVTmp[11];
  1246.  
  1247.                                         const vec4 W0123 = Shuffle<xzxz>(Shuffle<wwww>(V0, V1), Shuffle<wwww>(V2, V3));
  1248.                                         const vec4 W4567 = Shuffle<xzxz>(Shuffle<wwww>(V4, V5), Shuffle<wwww>(V6, V7));
  1249.                                         const vec4 W89AB = Shuffle<xzxz>(Shuffle<wwww>(V8, V9), Shuffle<wwww>(VA, VB));
  1250.                                         const vec4 iW0123 = Rcp(W0123);
  1251.                                         const vec4 iW4567 = Rcp(W4567);
  1252.                                         const vec4 iW89AB = Rcp(W89AB);
  1253.                                         const vec4 V0T = Mul(V0, Splat<0>(iW0123));
  1254.                                         const vec4 V1T = Mul(V1, Splat<1>(iW0123));
  1255.                                         const vec4 V2T = Mul(V2, Splat<2>(iW0123));
  1256.                                         const vec4 V3T = Mul(V3, Splat<3>(iW0123));
  1257.                                         const vec4 V4T = Mul(V4, Splat<0>(iW4567));
  1258.                                         const vec4 V5T = Mul(V5, Splat<1>(iW4567));
  1259.                                         const vec4 V6T = Mul(V6, Splat<2>(iW4567));
  1260.                                         const vec4 V7T = Mul(V7, Splat<3>(iW4567));
  1261.                                         const vec4 V8T = Mul(V8, Splat<0>(iW89AB));
  1262.                                         const vec4 V9T = Mul(V9, Splat<1>(iW89AB));
  1263.                                         const vec4 VAT = Mul(VA, Splat<2>(iW89AB));
  1264.                                         const vec4 VBT = Mul(VB, Splat<3>(iW89AB));
  1265.  
  1266.                                         V0 = SelectBits(V0, V0T, M);
  1267.                                         V1 = SelectBits(V1, V1T, M);
  1268.                                         V2 = SelectBits(V2, V2T, M);
  1269.                                         V3 = SelectBits(V3, V3T, M);
  1270.                                         V4 = SelectBits(V4, V4T, M);
  1271.                                         V5 = SelectBits(V5, V5T, M);
  1272.                                         V6 = SelectBits(V6, V6T, M);
  1273.                                         V7 = SelectBits(V7, V7T, M);
  1274.                                         V8 = SelectBits(V8, V8T, M);
  1275.                                         V9 = SelectBits(V9, V9T, M);
  1276.                                         VA = SelectBits(VA, VAT, M);
  1277.                                         VB = SelectBits(VB, VBT, M);
  1278.  
  1279.                                         vec4 V012 = Sub(Shuffle<xyxy>(V2T, V1T), Swizzle<xyxy>(V0T));
  1280.                                         vec4 V345 = Sub(Shuffle<xyxy>(V5T, V4T), Swizzle<xyxy>(V3T));
  1281.                                         vec4 V678 = Sub(Shuffle<xyxy>(V8T, V7T), Swizzle<xyxy>(V6T));
  1282.                                         vec4 V9AB = Sub(Shuffle<xyxy>(VBT, VAT), Swizzle<xyxy>(V9T));
  1283.                                         vec4 Det012 = Mul(V012, Swizzle<wzwz>(V012));
  1284.                                         vec4 Det345 = Mul(V345, Swizzle<wzwz>(V345));
  1285.                                         vec4 Det678 = Mul(V678, Swizzle<wzwz>(V678));
  1286.                                         vec4 Det9AB = Mul(V9AB, Swizzle<wzwz>(V9AB));
  1287.  
  1288.                                         Det012 = Sub(Det012, Splat<1>(Det012));
  1289.                                         Det345 = Sub(Det345, Splat<1>(Det345));
  1290.                                         Det678 = Sub(Det678, Splat<1>(Det678));
  1291.                                         Det9AB = Sub(Det9AB, Splat<1>(Det9AB));
  1292.                                         vec4 Det = Shuffle<xzxz>(Shuffle<xxxx>(Det012, Det345), Shuffle<xxxx>(Det678, Det9AB));
  1293.  
  1294. #if !CRY_PLATFORM_LINUX && !CRY_PLATFORM_ANDROID && !CRY_PLATFORM_APPLE //to avoid DivBy0 exception on PC
  1295.                                         Det = Select(Det, NVMath::Vec4(-FLT_EPSILON), CmpEq(Det, Vec4Zero()));
  1296. #endif
  1297.                                         Det = Rcp(Det);
  1298.                                         Det012 = Splat<0>(Det);
  1299.                                         Det345 = Splat<1>(Det);
  1300.                                         Det678 = Splat<2>(Det);
  1301.                                         Det9AB = Splat<3>(Det);
  1302.  
  1303.                                         vec4 VMax012 = Max(Max(V0T, V1T), V2T);
  1304.                                         vec4 VMax345 = Max(Max(V3T, V4T), V5T);
  1305.                                         vec4 VMax678 = Max(Max(V6T, V7T), V8T);
  1306.                                         vec4 VMax9AB = Max(Max(V9T, VAT), VBT);
  1307.                                         vec4 VMin012 = Min(Min(V0T, V1T), V2T);
  1308.                                         vec4 VMin345 = Min(Min(V3T, V4T), V5T);
  1309.                                         vec4 VMin678 = Min(Min(V6T, V7T), V8T);
  1310.                                         vec4 VMin9AB = Min(Min(V9T, VAT), VBT);
  1311.                                         VMax012 = Add(VMax012, Vec4One());
  1312.                                         VMax345 = Add(VMax345, Vec4One());
  1313.                                         VMax678 = Add(VMax678, Vec4One());
  1314.                                         VMax9AB = Add(VMax9AB, Vec4One());
  1315.                                         vec4 VMinMax012 = Shuffle<xyxy>(VMin012, VMax012);
  1316.                                         vec4 VMinMax345 = Shuffle<xyxy>(VMin345, VMax345);
  1317.                                         vec4 VMinMax678 = Shuffle<xyxy>(VMin678, VMax678);
  1318.                                         vec4 VMinMax9AB = Shuffle<xyxy>(VMin9AB, VMax9AB);
  1319.                                         VMinMax012 = Max(VMinMax012, Vec4Zero());
  1320.                                         VMinMax345 = Max(VMinMax345, Vec4Zero());
  1321.                                         VMinMax678 = Max(VMinMax678, Vec4Zero());
  1322.                                         VMinMax9AB = Max(VMinMax9AB, Vec4Zero());
  1323.                                         VMinMax012 = Min(VMinMax012, m_VMaxXY);
  1324.                                         VMinMax345 = Min(VMinMax345, m_VMaxXY);
  1325.                                         VMinMax678 = Min(VMinMax678, m_VMaxXY);
  1326.                                         VMinMax9AB = Min(VMinMax9AB, m_VMaxXY);
  1327.                                         VMinMax012 = floatToint32(VMinMax012);
  1328.                                         VMinMax345 = floatToint32(VMinMax345);
  1329.                                         VMinMax678 = floatToint32(VMinMax678);
  1330.                                         VMinMax9AB = floatToint32(VMinMax9AB);
  1331.                                         VMinMax012 = Or(VMinMax012, CmpLE(Det012, Vec4Zero()));                     //backface cull
  1332.                                         VMinMax345 = Or(VMinMax345, CmpLE(Det345, Vec4Zero()));
  1333.                                         VMinMax678 = Or(VMinMax678, CmpLE(Det678, Vec4Zero()));
  1334.                                         VMinMax9AB = Or(VMinMax9AB, CmpLE(Det9AB, Vec4Zero()));
  1335.  
  1336.                                         pVTmp[0] = V0;
  1337.                                         pVTmp[1] = V1;
  1338.                                         pVTmp[2] = V2;
  1339.                                         pVTmp[3] = V3;
  1340.                                         pVTmp[4] = V4;
  1341.                                         pVTmp[5] = V5;
  1342.                                         pVTmp[6] = V6;
  1343.                                         pVTmp[7] = V7;
  1344.                                         pVTmp[8] = V8;
  1345.                                         pVTmp[9] = V9;
  1346.                                         pVTmp[10] = VA;
  1347.                                         pVTmp[11] = VB;
  1348.                                         pDetTmp[0] = VMinMax012;
  1349.                                         pDetTmp[1] = Mul(V012, Det012);
  1350.                                         pDetTmp[2] = VMinMax345;
  1351.                                         pDetTmp[3] = Mul(V345, Det345);
  1352.                                         pDetTmp[4] = VMinMax678;
  1353.                                         pDetTmp[5] = Mul(V678, Det678);
  1354.                                         pDetTmp[6] = VMinMax9AB;
  1355.                                         pDetTmp[7] = Mul(V9AB, Det9AB);
  1356.                                 }
  1357.  
  1358.                                 pDetTmp = DetTmp;
  1359.                                 for (size_t b = 0; b < VTmpCount; b += 3, pDetTmp += 2)
  1360.                                 {
  1361.                                         const uint32* pMM = reinterpret_cast<uint32*>(pDetTmp);
  1362.                                         const uint16 MinX = pMM[0];
  1363.                                         const uint16 MinY = pMM[1];
  1364.                                         const uint16 MaxX = pMM[2];
  1365.                                         const uint16 MaxY = pMM[3];
  1366.                                         if (MinX < MaxX && MinY < MaxY)
  1367.                                         {
  1368.                                                 Triangle2D<true, false, false, true>(VTmp[b], VTmp[b + 2], VTmp[b + 1], MinX, MinY, MaxX, MaxY, pDetTmp[0], pDetTmp[1]);
  1369.                                         }
  1370.                                 }
  1371.                         }
  1372.                 }
  1373.  
  1374.         }
  1375.         template<bool WRITE>
  1376.         inline bool Rasterize(const NVMath::vec4* pViewProj, tdVertexCacheArg vertexCache,
  1377.                                     const tdIndex* __restrict pIndices, const uint32 ICount,
  1378.                                     const uint8* __restrict pVertices, const uint32 VertexSize, const uint32 VCount)
  1379.         {
  1380.                 using namespace NVMath;
  1381.                 if (!VCount || !ICount)
  1382.                 {
  1383.                         return false;
  1384.                 }
  1385.  
  1386.                 m_DrawCall++;
  1387.                 m_PolyCount += VCount / 3;
  1388.  
  1389.                 const vec4 M0 = pViewProj[0];
  1390.                 const vec4 M1 = pViewProj[1];
  1391.                 const vec4 M2 = pViewProj[2];
  1392.                 const vec4 M3 = pViewProj[3];
  1393.  
  1394.                 if (VCount + 1 > vertexCache.size())
  1395.                 {
  1396.                         vertexCache.resize(VCount + 1);
  1397.                 }
  1398.  
  1399.                 vec4* pVCache = &vertexCache[0];
  1400.                 pVCache = reinterpret_cast<vec4*>(((reinterpret_cast<size_t>(pVCache) + 15) & ~15));
  1401.  
  1402.                 vec4 SMask = Vec4Zero();
  1403.                 for (uint32 a = 0, S = VCount & ~3; a < S; a += 4)
  1404.                 {
  1405.                         const float* pV0 = reinterpret_cast<const float*>(pVertices + (a + 0) * VertexSize);
  1406.                         const float* pV1 = reinterpret_cast<const float*>(pVertices + (a + 1) * VertexSize);
  1407.                         const float* pV2 = reinterpret_cast<const float*>(pVertices + (a + 2) * VertexSize);
  1408.                         const float* pV3 = reinterpret_cast<const float*>(pVertices + (a + 3) * VertexSize);
  1409.  
  1410.                         const vec4 V0 = Madd(NVMath::Vec4(pV0[0]), M0, Madd(NVMath::Vec4(pV0[1]), M1, Madd(NVMath::Vec4(pV0[2]), M2, M3)));
  1411.                         const vec4 V1 = Madd(NVMath::Vec4(pV1[0]), M0, Madd(NVMath::Vec4(pV1[1]), M1, Madd(NVMath::Vec4(pV1[2]), M2, M3)));
  1412.                         const vec4 V2 = Madd(NVMath::Vec4(pV2[0]), M0, Madd(NVMath::Vec4(pV2[1]), M1, Madd(NVMath::Vec4(pV2[2]), M2, M3)));
  1413.                         const vec4 V3 = Madd(NVMath::Vec4(pV3[0]), M0, Madd(NVMath::Vec4(pV3[1]), M1, Madd(NVMath::Vec4(pV3[2]), M2, M3)));
  1414.  
  1415.                         SMask = Or(SMask, V0);
  1416.                         SMask = Or(SMask, V1);
  1417.                         SMask = Or(SMask, V2);
  1418.                         SMask = Or(SMask, V3);
  1419.  
  1420.                         pVCache[a + 0] = V0;
  1421.                         pVCache[a + 1] = V1;
  1422.                         pVCache[a + 2] = V2;
  1423.                         pVCache[a + 3] = V3;
  1424.                 }
  1425.                 for (uint32 a = VCount & ~3, S = VCount; a < S; a++)
  1426.                 {
  1427.                         const float* pV = reinterpret_cast<const float*>(pVertices + a * VertexSize);
  1428.                         const vec4 V = Madd(NVMath::Vec4(pV[0]), M0, Madd(NVMath::Vec4(pV[1]), M1, Madd(NVMath::Vec4(pV[2]), M2, M3)));
  1429.                         SMask = Or(SMask, V);
  1430.                         pVCache[a] = V;
  1431.                 }
  1432.  
  1433.                 bool Visible = false;
  1434.                 if (SignMask(SMask) & BitZ)
  1435.                 {
  1436.                         for (uint32 a = 0; a < ICount; a += 3)
  1437.                         {
  1438.                                 vec4 Pos0 = pVCache[pIndices[a + 0]];
  1439.                                 vec4 Pos2 = pVCache[pIndices[a + 1]];
  1440.                                 vec4 Pos1 = pVCache[pIndices[a + 2]];
  1441.  
  1442.                                 Visible |= Triangle<WRITE, true>(Pos0, Pos1, Pos2);
  1443.                                 if (!WRITE && Visible)
  1444.                                 {
  1445.                                         return true;
  1446.                                 }
  1447.                         }
  1448.                 }
  1449.                 else
  1450.                 {
  1451.                         for (uint32 a = 0; a < ICount; a += 3)
  1452.                         {
  1453.                                 vec4 Pos0 = pVCache[pIndices[a + 0]];
  1454.                                 vec4 Pos2 = pVCache[pIndices[a + 1]];
  1455.                                 vec4 Pos1 = pVCache[pIndices[a + 2]];
  1456.  
  1457.                                 Visible |= Triangle2D<WRITE, true>(Pos0, Pos1, Pos2);
  1458.                                 if (!WRITE && Visible)
  1459.                                 {
  1460.                                         return true;
  1461.                                 }
  1462.                         }
  1463.                 }
  1464.  
  1465.                 return Visible;
  1466.         }
  1467.  
  1468.         int m_DebugRender;
  1469.  
  1470.         void DrawDebug(IRenderer* pRenderer, int32 nStep)
  1471.         {
  1472.                 // project buffer to the screen
  1473. #if defined(CULLING_ENABLE_DEBUG_OVERLAY)
  1474.                 nStep %= 32;
  1475.                 if (!nStep)
  1476.                 {
  1477.                         return;
  1478.                 }
  1479.  
  1480.                 //if(!m_DebugRender)
  1481.                 //      return;
  1482.  
  1483.                 const float FarPlaneInv = 255.f / pRenderer->GetCamera().GetFarPlane();
  1484.  
  1485.                 SAuxGeomRenderFlags oFlags(e_Def2DPublicRenderflags);
  1486.                 oFlags.SetDepthTestFlag(e_DepthTestOff);
  1487.                 oFlags.SetDepthWriteFlag(e_DepthWriteOff);
  1488.                 oFlags.SetCullMode(e_CullModeNone);
  1489.                 oFlags.SetAlphaBlendMode(e_AlphaNone);
  1490.                 pRenderer->GetIRenderAuxGeom()->SetRenderFlags(oFlags);
  1491.  
  1492.                 int nScreenHeight = gEnv->pRenderer->GetHeight();
  1493.                 int nScreenWidth = gEnv->pRenderer->GetWidth();
  1494.  
  1495.                 float fScreenHeight = (float)nScreenHeight;
  1496.                 float fScreenWidth = (float)nScreenWidth;
  1497.  
  1498.                 float fTopOffSet = 35.0f;
  1499.                 float fSideOffSet = 35.0f;
  1500.  
  1501.                 // draw z-buffer after reprojection (unknown parts are red)
  1502.                 fTopOffSet += 200.0f;
  1503.                 for (uint32 y = 0; y < SIZEY; y += 1)
  1504.                 {
  1505.                         const float* __restrict pVMemZ = alias_cast<float*>(&m_ZBuffer[y * SIZEX]);
  1506.                         float fY = fTopOffSet + (y * 3);
  1507.                         for (uint32 x = 0; x < SIZEX; x += 4)
  1508.                         {
  1509.                                 float fX0 = fSideOffSet + ((x + 0) * 3);
  1510.                                 float fX1 = fSideOffSet + ((x + 1) * 3);
  1511.                                 float fX2 = fSideOffSet + ((x + 2) * 3);
  1512.                                 float fX3 = fSideOffSet + ((x + 3) * 3);
  1513.  
  1514.                                 //ColorB ValueColor0  = ((ColorB*)pVMemZ)[x+0];
  1515.                                 //ColorB ValueColor1  = ((ColorB*)pVMemZ)[x+1];
  1516.                                 //ColorB ValueColor2  = ((ColorB*)pVMemZ)[x+2];
  1517.                                 //ColorB ValueColor3  = ((ColorB*)pVMemZ)[x+3];
  1518.                                 ////ColorB color0=ColorB(ValueColor0,ValueColor0,ValueColor0,222);
  1519.                                 ////ColorB color1=ColorB(ValueColor1,ValueColor1,ValueColor1,222);
  1520.                                 ////ColorB color2=ColorB(ValueColor2,ValueColor2,ValueColor2,222);
  1521.                                 ////ColorB color3=ColorB(ValueColor3,ValueColor3,ValueColor3,222);
  1522.                                 //
  1523.                                 //NAsyncCull::Debug::Draw2DBox(fX0,fY,3.0f,3.0f,ValueColor0, fScreenHeight,fScreenWidth,pRenderer->GetIRenderAuxGeom());
  1524.                                 //NAsyncCull::Debug::Draw2DBox(fX1,fY,3.0f,3.0f,ValueColor1, fScreenHeight,fScreenWidth,pRenderer->GetIRenderAuxGeom());
  1525.                                 //NAsyncCull::Debug::Draw2DBox(fX2,fY,3.0f,3.0f,ValueColor2, fScreenHeight,fScreenWidth,pRenderer->GetIRenderAuxGeom());
  1526.                                 //NAsyncCull::Debug::Draw2DBox(fX3,fY,3.0f,3.0f,ValueColor3, fScreenHeight,fScreenWidth,pRenderer->GetIRenderAuxGeom());
  1527.  
  1528.                                 uint32 ValueColor0 = (uint32)(pVMemZ[x + 0]);
  1529.                                 uint32 ValueColor1 = (uint32)(pVMemZ[x + 1]);
  1530.                                 uint32 ValueColor2 = (uint32)(pVMemZ[x + 2]);
  1531.                                 uint32 ValueColor3 = (uint32)(pVMemZ[x + 3]);
  1532.                                 ColorB Color0(ValueColor0, ValueColor0 * 16, ValueColor0 * 256, 222);
  1533.                                 ColorB Color1(ValueColor1, ValueColor1 * 16, ValueColor1 * 256, 222);
  1534.                                 ColorB Color2(ValueColor2, ValueColor2 * 16, ValueColor2 * 256, 222);
  1535.                                 ColorB Color3(ValueColor3, ValueColor3 * 16, ValueColor3 * 256, 222);
  1536.  
  1537.                                 NAsyncCull::Debug::Draw2DBox(fX0, fY, 3.0f, 3.0f, Color0, fScreenHeight, fScreenWidth, pRenderer->GetIRenderAuxGeom());
  1538.                                 NAsyncCull::Debug::Draw2DBox(fX1, fY, 3.0f, 3.0f, Color1, fScreenHeight, fScreenWidth, pRenderer->GetIRenderAuxGeom());
  1539.                                 NAsyncCull::Debug::Draw2DBox(fX2, fY, 3.0f, 3.0f, Color2, fScreenHeight, fScreenWidth, pRenderer->GetIRenderAuxGeom());
  1540.                                 NAsyncCull::Debug::Draw2DBox(fX3, fY, 3.0f, 3.0f, Color3, fScreenHeight, fScreenWidth, pRenderer->GetIRenderAuxGeom());
  1541.                         }
  1542.                 }
  1543. #endif
  1544.         }
  1545.  
  1546.         inline uint32 SizeX() const
  1547.         {
  1548.                 return SIZEX;
  1549.         }
  1550.         inline uint32 SizeY() const
  1551.         {
  1552.                 return SIZEY;
  1553.         }
  1554.  
  1555. };
  1556. }
  1557.  
  1558. #pragma warning(pop)
  1559.  
  1560. template<uint32 SIZEX, uint32 SIZEY>
  1561. CRY_ALIGN(128) float NAsyncCull::CCullRenderer<SIZEX, SIZEY>::m_ZBufferMainMemory[SIZEX * SIZEY];
  1562. #endif
  1563.  
downloadCCullRenderer.h Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top