Imported Upstream version 2.81
[platform/upstream/libbullet.git] / src / BulletMultiThreaded / GpuSoftBodySolvers / DX11 / HLSL / ComputeBounds.hlsl
1 MSTRINGIFY(\r
2 \r
3 cbuffer ComputeBoundsCB : register( b0 )\r
4 {\r
5         int numNodes;\r
6         int numSoftBodies;\r
7         int padding1;\r
8         int padding2;\r
9 };\r
10 \r
11 // Node indices for each link\r
12 StructuredBuffer<int> g_vertexClothIdentifier : register( t0 );\r
13 StructuredBuffer<float4> g_vertexPositions : register( t1 );\r
14 \r
15 RWStructuredBuffer<uint4> g_clothMinBounds : register( u0 );\r
16 RWStructuredBuffer<uint4> g_clothMaxBounds : register( u1 );\r
17 \r
18 groupshared uint4 clothMinBounds[256];\r
19 groupshared uint4 clothMaxBounds[256];\r
20 \r
21 [numthreads(128, 1, 1)]\r
22 void \r
23 ComputeBoundsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )\r
24 {\r
25         const unsigned int UINT_MAX = 0xffffffff;\r
26 \r
27         // Init min and max bounds arrays\r
28         if( GTid.x < numSoftBodies )\r
29         {\r
30                 clothMinBounds[GTid.x] = uint4(UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX);\r
31                 clothMaxBounds[GTid.x] = uint4(0,0,0,0);\r
32         }\r
33 \r
34         AllMemoryBarrierWithGroupSync();\r
35 \r
36         int nodeID = DTid.x;\r
37         if( nodeID < numNodes )\r
38         {       \r
39                 int clothIdentifier = g_vertexClothIdentifier[nodeID];\r
40                 if( clothIdentifier >= 0 )\r
41                 {\r
42                         float3 position = g_vertexPositions[nodeID].xyz;\r
43 \r
44                         // Reinterpret position as uint\r
45                         uint3 positionUInt = uint3(asuint(position.x), asuint(position.y), asuint(position.z));\r
46                 \r
47                         // Invert sign bit of positives and whole of negatives to allow comparison as unsigned ints\r
48                         //positionUInt.x ^= uint((-int(positionUInt.x >> 31) | 0x80000000));\r
49                         //positionUInt.y ^= uint((-int(positionUInt.y >> 31) | 0x80000000));\r
50                         //positionUInt.z ^= uint((-int(positionUInt.z >> 31) | 0x80000000));\r
51                         positionUInt.x ^= (1+~(positionUInt.x >> 31) | 0x80000000);\r
52                         positionUInt.y ^= (1+~(positionUInt.y >> 31) | 0x80000000);             \r
53                         positionUInt.z ^= (1+~(positionUInt.z >> 31) | 0x80000000);\r
54                 \r
55                         // Min/max with the LDS values\r
56                         InterlockedMin(clothMinBounds[clothIdentifier].x, positionUInt.x);\r
57                         InterlockedMin(clothMinBounds[clothIdentifier].y, positionUInt.y);\r
58                         InterlockedMin(clothMinBounds[clothIdentifier].z, positionUInt.z);\r
59 \r
60                         InterlockedMax(clothMaxBounds[clothIdentifier].x, positionUInt.x);\r
61                         InterlockedMax(clothMaxBounds[clothIdentifier].y, positionUInt.y);\r
62                         InterlockedMax(clothMaxBounds[clothIdentifier].z, positionUInt.z);\r
63                 }\r
64         }\r
65         \r
66         AllMemoryBarrierWithGroupSync();\r
67 \r
68 \r
69         // Use global atomics to update the global versions of the data\r
70         if( GTid.x < numSoftBodies )\r
71         {\r
72                 InterlockedMin(g_clothMinBounds[GTid.x].x, clothMinBounds[GTid.x].x);\r
73                 InterlockedMin(g_clothMinBounds[GTid.x].y, clothMinBounds[GTid.x].y);\r
74                 InterlockedMin(g_clothMinBounds[GTid.x].z, clothMinBounds[GTid.x].z);\r
75 \r
76                 InterlockedMax(g_clothMaxBounds[GTid.x].x, clothMaxBounds[GTid.x].x);           \r
77                 InterlockedMax(g_clothMaxBounds[GTid.x].y, clothMaxBounds[GTid.x].y);\r
78                 InterlockedMax(g_clothMaxBounds[GTid.x].z, clothMaxBounds[GTid.x].z);\r
79         }\r
80 }\r
81 \r
82 \r
83 );