RavEngine
Loading...
Searching...
No Matches
GuBV4_Slabs_KajiyaOrdered.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef GU_BV4_SLABS_KAJIYA_ORDERED_H
30#define GU_BV4_SLABS_KAJIYA_ORDERED_H
31
32#include "GuBVConstants.h"
33
34#ifdef REMOVED
35 // Kajiya + PNS
36 template<const int inflateT, class LeafTestT, class ParamsT>
37 static void BV4_ProcessStreamKajiyaOrdered(const BVDataPacked* PX_RESTRICT node, PxU32 initData, ParamsT* PX_RESTRICT params)
38 {
39 const BVDataPacked* root = node;
40
41 PxU32 nb=1;
42 PxU32 stack[GU_BV4_STACK_SIZE];
43 stack[0] = initData;
44
45#ifdef BV4_SLABS_SORT
46 const PxU32* tmp = reinterpret_cast<const PxU32*>(&params->mLocalDir_Padded);
47 const PxU32 X = tmp[0]>>31;
48 const PxU32 Y = tmp[1]>>31;
49 const PxU32 Z = tmp[2]>>31;
50// const PxU32 X = PX_IR(params->mLocalDir_Padded.x)>>31;
51// const PxU32 Y = PX_IR(params->mLocalDir_Padded.y)>>31;
52// const PxU32 Z = PX_IR(params->mLocalDir_Padded.z)>>31;
53 const PxU32 bitIndex = 3+(Z|(Y<<1)|(X<<2));
54 const PxU32 dirMask = 1u<<bitIndex;
55#endif
56
57#ifdef BV4_SLABS_FIX
58 BV4_ALIGN16(float distances4[4]);
59#endif
61
62 Vec4V fattenAABBsX, fattenAABBsY, fattenAABBsZ;
63 if(inflateT)
64 {
65 Vec4V fattenAABBs4 = V4LoadU_Safe(&params->mOriginalExtents_Padded.x);
66 fattenAABBs4 = V4Add(fattenAABBs4, epsInflateFloat4); // US2385 - shapes are "closed" meaning exactly touching shapes should report overlap
67 fattenAABBsX = V4SplatElement<0>(fattenAABBs4);
68 fattenAABBsY = V4SplatElement<1>(fattenAABBs4);
69 fattenAABBsZ = V4SplatElement<2>(fattenAABBs4);
70 }
71
73
74 SLABS_INIT
75
76#ifdef GU_BV4_QUANTIZED_TREE
77 const Vec4V minCoeffV = V4LoadA_Safe(&params->mCenterOrMinCoeff_PaddedAligned.x);
78 const Vec4V maxCoeffV = V4LoadA_Safe(&params->mExtentsOrMaxCoeff_PaddedAligned.x);
79 const Vec4V minCoeffxV = V4SplatElement<0>(minCoeffV);
80 const Vec4V minCoeffyV = V4SplatElement<1>(minCoeffV);
81 const Vec4V minCoeffzV = V4SplatElement<2>(minCoeffV);
82 const Vec4V maxCoeffxV = V4SplatElement<0>(maxCoeffV);
83 const Vec4V maxCoeffyV = V4SplatElement<1>(maxCoeffV);
84 const Vec4V maxCoeffzV = V4SplatElement<2>(maxCoeffV);
85#endif
86
87 do
88 {
89 const PxU32 childData = stack[--nb];
90 node = root + getChildOffset(childData);
91
92 const BVDataSwizzled* tn = reinterpret_cast<const BVDataSwizzled*>(node);
93
94#ifdef GU_BV4_QUANTIZED_TREE
95 Vec4V minx4a;
96 Vec4V maxx4a;
97 OPC_DEQ4(maxx4a, minx4a, mX, minCoeffxV, maxCoeffxV)
98
99 Vec4V miny4a;
100 Vec4V maxy4a;
101 OPC_DEQ4(maxy4a, miny4a, mY, minCoeffyV, maxCoeffyV)
102
103 Vec4V minz4a;
104 Vec4V maxz4a;
105 OPC_DEQ4(maxz4a, minz4a, mZ, minCoeffzV, maxCoeffzV)
106#else
107 Vec4V minx4a = V4LoadA(tn->mMinX);
108 Vec4V miny4a = V4LoadA(tn->mMinY);
109 Vec4V minz4a = V4LoadA(tn->mMinZ);
110
111 Vec4V maxx4a = V4LoadA(tn->mMaxX);
112 Vec4V maxy4a = V4LoadA(tn->mMaxY);
113 Vec4V maxz4a = V4LoadA(tn->mMaxZ);
114#endif
115 if(inflateT)
116 {
117 maxx4a = V4Add(maxx4a, fattenAABBsX); maxy4a = V4Add(maxy4a, fattenAABBsY); maxz4a = V4Add(maxz4a, fattenAABBsZ);
118 minx4a = V4Sub(minx4a, fattenAABBsX); miny4a = V4Sub(miny4a, fattenAABBsY); minz4a = V4Sub(minz4a, fattenAABBsZ);
119 }
120
121 SLABS_TEST
122
123#ifdef BV4_SLABS_FIX
124 if(inflateT)
125 V4StoreA(maxOfNeasa, &distances4[0]);
126#endif
127
128 SLABS_TEST2
129
130#ifdef BV4_SLABS_SORT
131 #ifdef BV4_SLABS_FIX
132 // PT: for some unknown reason the Linux/OSX compilers fail to understand this version
133/* #define DO_LEAF_TEST(x) \
134 { \
135 if(!inflateT) \
136 { \
137 if(tn->isLeaf(x)) \
138 { \
139 LeafTestT::doLeafTest(params, tn->getPrimitive(x)); \
140 maxT4 = V4Load(params->mStabbedFace.mDistance); \
141 } \
142 else \
143 { \
144 code2 |= 1<<x; \
145 } \
146 } \
147 else \
148 { \
149 if(distances4[x]<params->mStabbedFace.mDistance) \
150 { \
151 if(tn->isLeaf(x)) \
152 { \
153 LeafTestT::doLeafTest(params, tn->getPrimitive(x)); \
154 maxT4 = V4Load(params->mStabbedFace.mDistance); \
155 } \
156 else \
157 { \
158 code2 |= 1<<x; \
159 } \
160 } \
161 } \
162 }*/
163
164 // PT: TODO: check that this version compiles to the same code as above. Redo benchmarks.
165 #define DO_LEAF_TEST(x) \
166 { \
167 if(!inflateT || distances4[x]<params->mStabbedFace.mDistance + GU_EPSILON_SAME_DISTANCE) \
168 { \
169 if(tn->isLeaf(x)) \
170 { \
171 LeafTestT::doLeafTest(params, tn->getPrimitive(x)); \
172 maxT4 = V4Load(params->mStabbedFace.mDistance); \
173 } \
174 else \
175 { \
176 code2 |= 1<<x; \
177 } \
178 } \
179 }
180
181 #else
182 #define DO_LEAF_TEST(x) \
183 { \
184 if(tn->isLeaf(x)) \
185 { \
186 LeafTestT::doLeafTest(params, tn->getPrimitive(x)); \
187 maxT4 = V4Load(params->mStabbedFace.mDistance); \
188 } \
189 else \
190 { \
191 code2 |= 1<<x; \
192 } \
193 }
194 #endif
195 PxU32 code2 = 0;
196 const PxU32 nodeType = getChildType(childData);
197
198 if(!(code&8) && nodeType>1)
199 DO_LEAF_TEST(3)
200
201 if(!(code&4) && nodeType>0)
202 DO_LEAF_TEST(2)
203
204 if(!(code&2))
205 DO_LEAF_TEST(1)
206
207 if(!(code&1))
208 DO_LEAF_TEST(0)
209
210 SLABS_PNS
211#else
212 #define DO_LEAF_TEST(x) \
213 {if(tn->isLeaf(x)) \
214 { \
215 LeafTestT::doLeafTest(params, tn->getPrimitive(x)); \
216 maxT4 = V4Load(params->mStabbedFace.mDistance); \
217 } \
218 else \
219 { \
220 stack[nb++] = tn->getChildData(x); \
221 }}
222
223
224 const PxU32 nodeType = getChildType(childData);
225 if(!(code&8) && nodeType>1)
226 DO_LEAF_TEST(3)
227
228 if(!(code&4) && nodeType>0)
229 DO_LEAF_TEST(2)
230
231 if(!(code&2))
232 DO_LEAF_TEST(1)
233
234 if(!(code&1))
235 DO_LEAF_TEST(0)
236#endif
237
238 }while(nb);
239 }
240#undef DO_LEAF_TEST
241#endif
242
243
244
245#ifdef BV4_SLABS_SORT
246 #ifdef BV4_SLABS_FIX
247 // PT: for some unknown reason the Linux/OSX compilers fail to understand this version
248/* #define DO_LEAF_TEST(x) \
249 { \
250 if(!inflateT) \
251 { \
252 if(tn->isLeaf(x)) \
253 { \
254 LeafTestT::doLeafTest(params, tn->getPrimitive(x)); \
255 maxT4 = V4Load(params->mStabbedFace.mDistance); \
256 } \
257 else \
258 { \
259 code2 |= 1<<x; \
260 } \
261 } \
262 else \
263 { \
264 if(distances4[x]<params->mStabbedFace.mDistance) \
265 { \
266 if(tn->isLeaf(x)) \
267 { \
268 LeafTestT::doLeafTest(params, tn->getPrimitive(x)); \
269 maxT4 = V4Load(params->mStabbedFace.mDistance); \
270 } \
271 else \
272 { \
273 code2 |= 1<<x; \
274 } \
275 } \
276 } \
277 }*/
278
279 // PT: TODO: check that this version compiles to the same code as above. Redo benchmarks.
280 #define DO_LEAF_TEST(x) \
281 { \
282 if(!inflateT || distances4[x]<params->mStabbedFace.mDistance + GU_EPSILON_SAME_DISTANCE) \
283 { \
284 if(tn->isLeaf(x)) \
285 { \
286 LeafTestT::doLeafTest(params, tn->getPrimitive(x)); \
287 maxT4 = V4Load(params->mStabbedFace.mDistance); \
288 } \
289 else \
290 { \
291 code2 |= 1<<x; nbHits++; \
292 } \
293 } \
294 }
295
296 #else
297 #define DO_LEAF_TEST(x) \
298 { \
299 if(tn->isLeaf(x)) \
300 { \
301 LeafTestT::doLeafTest(params, tn->getPrimitive(x)); \
302 maxT4 = V4Load(params->mStabbedFace.mDistance); \
303 } \
304 else \
305 { \
306 code2 |= 1<<x; nbHits++; \
307 } \
308 }
309 #endif
310#else
311 #define DO_LEAF_TEST(x) \
312 {if(tn->isLeaf(x)) \
313 { \
314 LeafTestT::doLeafTest(params, tn->getPrimitive(x)); \
315 maxT4 = V4Load(params->mStabbedFace.mDistance); \
316 } \
317 else \
318 { \
319 stack[nb++] = tn->getChildData(x); \
320 }}
321#endif
322
323 // Kajiya + PNS
324 template<const int inflateT, class LeafTestT, class ParamsT>
325 static void BV4_ProcessStreamKajiyaOrderedQ(const BVDataPackedQ* PX_RESTRICT node, PxU32 initData, ParamsT* PX_RESTRICT params)
326 {
327 const BVDataPackedQ* root = node;
328
329 PxU32 nb=1;
330 PxU32 stack[GU_BV4_STACK_SIZE];
331 stack[0] = initData;
332
333#ifdef BV4_SLABS_SORT
334 const PxU32* tmp = reinterpret_cast<const PxU32*>(&params->mLocalDir_Padded);
335 const PxU32 X = tmp[0]>>31;
336 const PxU32 Y = tmp[1]>>31;
337 const PxU32 Z = tmp[2]>>31;
338// const PxU32 X = PX_IR(params->mLocalDir_Padded.x)>>31;
339// const PxU32 Y = PX_IR(params->mLocalDir_Padded.y)>>31;
340// const PxU32 Z = PX_IR(params->mLocalDir_Padded.z)>>31;
341 const PxU32 bitIndex = 3+(Z|(Y<<1)|(X<<2));
342 const PxU32 dirMask = 1u<<bitIndex;
343#endif
344
345#ifdef BV4_SLABS_FIX
346 BV4_ALIGN16(float distances4[4]);
347#endif
349
350 Vec4V fattenAABBsX, fattenAABBsY, fattenAABBsZ;
351 if(inflateT)
352 {
353 Vec4V fattenAABBs4 = V4LoadU_Safe(&params->mOriginalExtents_Padded.x);
354 fattenAABBs4 = V4Add(fattenAABBs4, epsInflateFloat4); // US2385 - shapes are "closed" meaning exactly touching shapes should report overlap
355 fattenAABBsX = V4SplatElement<0>(fattenAABBs4);
356 fattenAABBsY = V4SplatElement<1>(fattenAABBs4);
357 fattenAABBsZ = V4SplatElement<2>(fattenAABBs4);
358 }
359
361
362 SLABS_INIT
363
364 const Vec4V minCoeffV = V4LoadA_Safe(&params->mCenterOrMinCoeff_PaddedAligned.x);
365 const Vec4V maxCoeffV = V4LoadA_Safe(&params->mExtentsOrMaxCoeff_PaddedAligned.x);
366 const Vec4V minCoeffxV = V4SplatElement<0>(minCoeffV);
367 const Vec4V minCoeffyV = V4SplatElement<1>(minCoeffV);
368 const Vec4V minCoeffzV = V4SplatElement<2>(minCoeffV);
369 const Vec4V maxCoeffxV = V4SplatElement<0>(maxCoeffV);
370 const Vec4V maxCoeffyV = V4SplatElement<1>(maxCoeffV);
371 const Vec4V maxCoeffzV = V4SplatElement<2>(maxCoeffV);
372
373 do
374 {
375 const PxU32 childData = stack[--nb];
376 node = root + getChildOffset(childData);
377
378 const BVDataSwizzledQ* tn = reinterpret_cast<const BVDataSwizzledQ*>(node);
379
380 Vec4V minx4a;
381 Vec4V maxx4a;
382 OPC_DEQ4(maxx4a, minx4a, mX, minCoeffxV, maxCoeffxV)
383
384 Vec4V miny4a;
385 Vec4V maxy4a;
386 OPC_DEQ4(maxy4a, miny4a, mY, minCoeffyV, maxCoeffyV)
387
388 Vec4V minz4a;
389 Vec4V maxz4a;
390 OPC_DEQ4(maxz4a, minz4a, mZ, minCoeffzV, maxCoeffzV)
391
392 if(inflateT)
393 {
394 maxx4a = V4Add(maxx4a, fattenAABBsX); maxy4a = V4Add(maxy4a, fattenAABBsY); maxz4a = V4Add(maxz4a, fattenAABBsZ);
395 minx4a = V4Sub(minx4a, fattenAABBsX); miny4a = V4Sub(miny4a, fattenAABBsY); minz4a = V4Sub(minz4a, fattenAABBsZ);
396 }
397
398 SLABS_TEST
399
400#ifdef BV4_SLABS_FIX
401 if(inflateT)
402 V4StoreA(maxOfNeasa, &distances4[0]);
403#endif
404
405 SLABS_TEST2
406
407#ifdef BV4_SLABS_SORT
408 PxU32 code2 = 0;
409 PxU32 nbHits = 0;
410 const PxU32 nodeType = getChildType(childData);
411
412 if(!(code&8) && nodeType>1)
413 DO_LEAF_TEST(3)
414
415 if(!(code&4) && nodeType>0)
416 DO_LEAF_TEST(2)
417
418 if(!(code&2))
419 DO_LEAF_TEST(1)
420
421 if(!(code&1))
422 DO_LEAF_TEST(0)
423
424 //SLABS_PNS
425
426 if(nbHits==1)
427 {
428 PNS_BLOCK3(0,1,2,3)
429 }
430 else
431 {
432 SLABS_PNS
433 }
434#else
435 const PxU32 nodeType = getChildType(childData);
436 if(!(code&8) && nodeType>1)
437 DO_LEAF_TEST(3)
438
439 if(!(code&4) && nodeType>0)
440 DO_LEAF_TEST(2)
441
442 if(!(code&2))
443 DO_LEAF_TEST(1)
444
445 if(!(code&1))
446 DO_LEAF_TEST(0)
447#endif
448
449 }while(nb);
450 }
451
452
453 // Kajiya + PNS
454 template<const int inflateT, class LeafTestT, class ParamsT>
455 static void BV4_ProcessStreamKajiyaOrderedNQ(const BVDataPackedNQ* PX_RESTRICT node, PxU32 initData, ParamsT* PX_RESTRICT params)
456 {
457 const BVDataPackedNQ* root = node;
458
459 PxU32 nb=1;
460 PxU32 stack[GU_BV4_STACK_SIZE];
461 stack[0] = initData;
462
463#ifdef BV4_SLABS_SORT
464 const PxU32* tmp = reinterpret_cast<const PxU32*>(&params->mLocalDir_Padded);
465 const PxU32 X = tmp[0]>>31;
466 const PxU32 Y = tmp[1]>>31;
467 const PxU32 Z = tmp[2]>>31;
468// const PxU32 X = PX_IR(params->mLocalDir_Padded.x)>>31;
469// const PxU32 Y = PX_IR(params->mLocalDir_Padded.y)>>31;
470// const PxU32 Z = PX_IR(params->mLocalDir_Padded.z)>>31;
471 const PxU32 bitIndex = 3+(Z|(Y<<1)|(X<<2));
472 const PxU32 dirMask = 1u<<bitIndex;
473#endif
474
475#ifdef BV4_SLABS_FIX
476 BV4_ALIGN16(float distances4[4]);
477#endif
479
480 Vec4V fattenAABBsX, fattenAABBsY, fattenAABBsZ;
481 if(inflateT)
482 {
483 Vec4V fattenAABBs4 = V4LoadU_Safe(&params->mOriginalExtents_Padded.x);
484 fattenAABBs4 = V4Add(fattenAABBs4, epsInflateFloat4); // US2385 - shapes are "closed" meaning exactly touching shapes should report overlap
485 fattenAABBsX = V4SplatElement<0>(fattenAABBs4);
486 fattenAABBsY = V4SplatElement<1>(fattenAABBs4);
487 fattenAABBsZ = V4SplatElement<2>(fattenAABBs4);
488 }
489
491
492 SLABS_INIT
493
494 do
495 {
496 const PxU32 childData = stack[--nb];
497 node = root + getChildOffset(childData);
498
499 const BVDataSwizzledNQ* tn = reinterpret_cast<const BVDataSwizzledNQ*>(node);
500
501 Vec4V minx4a = V4LoadA(tn->mMinX);
502 Vec4V miny4a = V4LoadA(tn->mMinY);
503 Vec4V minz4a = V4LoadA(tn->mMinZ);
504
505 Vec4V maxx4a = V4LoadA(tn->mMaxX);
506 Vec4V maxy4a = V4LoadA(tn->mMaxY);
507 Vec4V maxz4a = V4LoadA(tn->mMaxZ);
508
509 if(inflateT)
510 {
511 maxx4a = V4Add(maxx4a, fattenAABBsX); maxy4a = V4Add(maxy4a, fattenAABBsY); maxz4a = V4Add(maxz4a, fattenAABBsZ);
512 minx4a = V4Sub(minx4a, fattenAABBsX); miny4a = V4Sub(miny4a, fattenAABBsY); minz4a = V4Sub(minz4a, fattenAABBsZ);
513 }
514
515 SLABS_TEST
516
517#ifdef BV4_SLABS_FIX
518 if(inflateT)
519 V4StoreA(maxOfNeasa, &distances4[0]);
520#endif
521
522 SLABS_TEST2
523
524#ifdef BV4_SLABS_SORT
525 PxU32 code2 = 0;
526 PxU32 nbHits = 0;
527 const PxU32 nodeType = getChildType(childData);
528
529 if(!(code&8) && nodeType>1)
530 DO_LEAF_TEST(3)
531
532 if(!(code&4) && nodeType>0)
533 DO_LEAF_TEST(2)
534
535 if(!(code&2))
536 DO_LEAF_TEST(1)
537
538 if(!(code&1))
539 DO_LEAF_TEST(0)
540
541 //SLABS_PNS
542 if(nbHits==1)
543 {
544 PNS_BLOCK3(0,1,2,3)
545 }
546 else
547 {
548 SLABS_PNS
549 }
550#else
551 const PxU32 nodeType = getChildType(childData);
552 if(!(code&8) && nodeType>1)
553 DO_LEAF_TEST(3)
554
555 if(!(code&4) && nodeType>0)
556 DO_LEAF_TEST(2)
557
558 if(!(code&2))
559 DO_LEAF_TEST(1)
560
561 if(!(code&1))
562 DO_LEAF_TEST(0)
563#endif
564
565 }while(nb);
566 }
567
568#undef DO_LEAF_TEST
569
570#endif // GU_BV4_SLABS_KAJIYA_ORDERED_H
#define PX_RESTRICT
Definition PxPreprocessor.h:355