bvh_traverser_stream.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "bvh.h"
  5. #include "../common/ray.h"
  6. #include "../common/stack_item.h"
  7. namespace embree
  8. {
  9. namespace isa
  10. {
  11. template<int N, int types>
  12. class BVHNNodeTraverserStreamHitCoherent
  13. {
  14. typedef BVHN<N> BVH;
  15. typedef typename BVH::NodeRef NodeRef;
  16. typedef typename BVH::BaseNode BaseNode;
  17. public:
  18. template<class T>
  19. static __forceinline void traverseClosestHit(NodeRef& cur,
  20. size_t& m_trav_active,
  21. const vbool<N>& vmask,
  22. const vfloat<N>& tNear,
  23. const T* const tMask,
  24. StackItemMaskCoherent*& stackPtr)
  25. {
  26. const NodeRef parent = cur;
  27. size_t mask = movemask(vmask);
  28. assert(mask != 0);
  29. const BaseNode* node = cur.baseNode();
  30. /*! one child is hit, continue with that child */
  31. const size_t r0 = bscf(mask);
  32. assert(r0 < 8);
  33. cur = node->child(r0);
  34. BVHN<N>::prefetch(cur,types);
  35. m_trav_active = tMask[r0];
  36. assert(cur != BVH::emptyNode);
  37. if (unlikely(mask == 0)) return;
  38. const unsigned int* const tNear_i = (unsigned int*)&tNear;
  39. /*! two children are hit, push far child, and continue with closer child */
  40. NodeRef c0 = cur;
  41. unsigned int d0 = tNear_i[r0];
  42. const size_t r1 = bscf(mask);
  43. assert(r1 < 8);
  44. NodeRef c1 = node->child(r1);
  45. BVHN<N>::prefetch(c1,types);
  46. unsigned int d1 = tNear_i[r1];
  47. assert(c0 != BVH::emptyNode);
  48. assert(c1 != BVH::emptyNode);
  49. if (likely(mask == 0)) {
  50. if (d0 < d1) {
  51. assert(tNear[r1] >= 0.0f);
  52. stackPtr->mask = tMask[r1];
  53. stackPtr->parent = parent;
  54. stackPtr->child = c1;
  55. stackPtr++;
  56. cur = c0;
  57. m_trav_active = tMask[r0];
  58. return;
  59. }
  60. else {
  61. assert(tNear[r0] >= 0.0f);
  62. stackPtr->mask = tMask[r0];
  63. stackPtr->parent = parent;
  64. stackPtr->child = c0;
  65. stackPtr++;
  66. cur = c1;
  67. m_trav_active = tMask[r1];
  68. return;
  69. }
  70. }
  71. /*! slow path for more than two hits */
  72. size_t hits = movemask(vmask);
  73. const vint<N> dist_i = select(vmask, (asInt(tNear) & 0xfffffff8) | vint<N>(step), 0);
  74. const vint<N> dist_i_sorted = usort_descending(dist_i);
  75. const vint<N> sorted_index = dist_i_sorted & 7;
  76. size_t i = 0;
  77. for (;;)
  78. {
  79. const unsigned int index = sorted_index[i];
  80. assert(index < 8);
  81. cur = node->child(index);
  82. m_trav_active = tMask[index];
  83. assert(m_trav_active);
  84. BVHN<N>::prefetch(cur,types);
  85. bscf(hits);
  86. if (unlikely(hits==0)) break;
  87. i++;
  88. assert(cur != BVH::emptyNode);
  89. assert(tNear[index] >= 0.0f);
  90. stackPtr->mask = m_trav_active;
  91. stackPtr->parent = parent;
  92. stackPtr->child = cur;
  93. stackPtr++;
  94. }
  95. }
  96. template<class T>
  97. static __forceinline void traverseAnyHit(NodeRef& cur,
  98. size_t& m_trav_active,
  99. const vbool<N>& vmask,
  100. const T* const tMask,
  101. StackItemMaskCoherent*& stackPtr)
  102. {
  103. const NodeRef parent = cur;
  104. size_t mask = movemask(vmask);
  105. assert(mask != 0);
  106. const BaseNode* node = cur.baseNode();
  107. /*! one child is hit, continue with that child */
  108. size_t r = bscf(mask);
  109. cur = node->child(r);
  110. BVHN<N>::prefetch(cur,types);
  111. m_trav_active = tMask[r];
  112. /* simple in order sequence */
  113. assert(cur != BVH::emptyNode);
  114. if (likely(mask == 0)) return;
  115. stackPtr->mask = m_trav_active;
  116. stackPtr->parent = parent;
  117. stackPtr->child = cur;
  118. stackPtr++;
  119. for (; ;)
  120. {
  121. r = bscf(mask);
  122. cur = node->child(r);
  123. BVHN<N>::prefetch(cur,types);
  124. m_trav_active = tMask[r];
  125. assert(cur != BVH::emptyNode);
  126. if (likely(mask == 0)) return;
  127. stackPtr->mask = m_trav_active;
  128. stackPtr->parent = parent;
  129. stackPtr->child = cur;
  130. stackPtr++;
  131. }
  132. }
  133. };
  134. }
  135. }