instance_stack.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "rtcore.h"
  5. namespace embree {
  6. namespace instance_id_stack {
  7. static_assert(RTC_MAX_INSTANCE_LEVEL_COUNT > 0,
  8. "RTC_MAX_INSTANCE_LEVEL_COUNT must be greater than 0.");
  9. /*******************************************************************************
  10. * Instance ID stack manipulation.
  11. * This is used from the instance intersector.
  12. ******************************************************************************/
  13. /*
  14. * Push an instance to the stack.
  15. */
  16. RTC_FORCEINLINE bool push(RTCIntersectContext* context,
  17. unsigned instanceId)
  18. {
  19. #if RTC_MAX_INSTANCE_LEVEL_COUNT > 1
  20. const bool spaceAvailable = context->instStackSize < RTC_MAX_INSTANCE_LEVEL_COUNT;
  21. /* We assert here because instances are silently dropped when the stack is full.
  22. This might be quite hard to find in production. */
  23. assert(spaceAvailable);
  24. if (likely(spaceAvailable))
  25. context->instID[context->instStackSize++] = instanceId;
  26. return spaceAvailable;
  27. #else
  28. const bool spaceAvailable = (context->instID[0] == RTC_INVALID_GEOMETRY_ID);
  29. assert(spaceAvailable);
  30. if (likely(spaceAvailable))
  31. context->instID[0] = instanceId;
  32. return spaceAvailable;
  33. #endif
  34. }
  35. /*
  36. * Pop the last instance pushed to the stack.
  37. * Do not call on an empty stack.
  38. */
  39. RTC_FORCEINLINE void pop(RTCIntersectContext* context)
  40. {
  41. assert(context);
  42. #if RTC_MAX_INSTANCE_LEVEL_COUNT > 1
  43. assert(context->instStackSize > 0);
  44. context->instID[--context->instStackSize] = RTC_INVALID_GEOMETRY_ID;
  45. #else
  46. assert(context->instID[0] != RTC_INVALID_GEOMETRY_ID);
  47. context->instID[0] = RTC_INVALID_GEOMETRY_ID;
  48. #endif
  49. }
  50. /*
  51. * Optimized instance id stack copy.
  52. * The copy() functions will either copy full
  53. * stacks or copy only until the last valid element has been copied, depending
  54. * on RTC_MAX_INSTANCE_LEVEL_COUNT.
  55. */
  56. RTC_FORCEINLINE void copy_UU(const unsigned* src, unsigned* tgt)
  57. {
  58. #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
  59. tgt[0] = src[0];
  60. #else
  61. for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
  62. tgt[l] = src[l];
  63. if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
  64. if (src[l] == RTC_INVALID_GEOMETRY_ID)
  65. break;
  66. }
  67. #endif
  68. }
  69. template <int K>
  70. RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt)
  71. {
  72. #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
  73. tgt[0] = src[0];
  74. #else
  75. for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
  76. tgt[l] = src[l];
  77. if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
  78. if (src[l] == RTC_INVALID_GEOMETRY_ID)
  79. break;
  80. }
  81. #endif
  82. }
  83. template <int K>
  84. RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, size_t j)
  85. {
  86. #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
  87. tgt[0][j] = src[0];
  88. #else
  89. for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
  90. tgt[l][j] = src[l];
  91. if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
  92. if (src[l] == RTC_INVALID_GEOMETRY_ID)
  93. break;
  94. }
  95. #endif
  96. }
  97. template <int K>
  98. RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, const vbool<K>& mask)
  99. {
  100. #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
  101. vuint<K>::store(mask, tgt, src[0]);
  102. #else
  103. for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
  104. vuint<K>::store(mask, tgt + l, src[l]);
  105. if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
  106. if (src[l] == RTC_INVALID_GEOMETRY_ID)
  107. break;
  108. }
  109. #endif
  110. }
  111. template <int K>
  112. RTC_FORCEINLINE void copy_VU(const vuint<K>* src, unsigned* tgt, size_t i)
  113. {
  114. #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
  115. tgt[0] = src[0][i];
  116. #else
  117. for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
  118. tgt[l] = src[l][i];
  119. if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
  120. if (src[l][i] == RTC_INVALID_GEOMETRY_ID)
  121. break;
  122. }
  123. #endif
  124. }
  125. template <int K>
  126. RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, size_t i, size_t j)
  127. {
  128. #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
  129. tgt[0][j] = src[0][i];
  130. #else
  131. for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
  132. tgt[l][j] = src[l][i];
  133. if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
  134. if (src[l][i] == RTC_INVALID_GEOMETRY_ID)
  135. break;
  136. }
  137. #endif
  138. }
  139. template <int K>
  140. RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, const vbool<K>& mask)
  141. {
  142. #if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
  143. vuint<K>::store(mask, tgt, src[0]);
  144. #else
  145. vbool<K> done = !mask;
  146. for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
  147. vuint<K>::store(mask, tgt + l, src[l]);
  148. if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) {
  149. done |= src[l] == RTC_INVALID_GEOMETRY_ID;
  150. if (all(done)) break;
  151. }
  152. }
  153. #endif
  154. }
  155. } // namespace instance_id_stack
  156. } // namespace embree