diff options
Diffstat (limited to 'thirdparty/embree/kernels/common/instance_stack.h')
| -rw-r--r-- | thirdparty/embree/kernels/common/instance_stack.h | 179 | 
1 files changed, 179 insertions, 0 deletions
| diff --git a/thirdparty/embree/kernels/common/instance_stack.h b/thirdparty/embree/kernels/common/instance_stack.h new file mode 100644 index 0000000000..d3c0a643f1 --- /dev/null +++ b/thirdparty/embree/kernels/common/instance_stack.h @@ -0,0 +1,179 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "rtcore.h" + +namespace embree { +namespace instance_id_stack { + +static_assert(RTC_MAX_INSTANCE_LEVEL_COUNT > 0,  +              "RTC_MAX_INSTANCE_LEVEL_COUNT must be greater than 0."); + +/******************************************************************************* + * Instance ID stack manipulation. + * This is used from the instance intersector. + ******************************************************************************/ + +/*  + * Push an instance to the stack.  + */ +RTC_FORCEINLINE bool push(RTCIntersectContext* context,  +                          unsigned instanceId) +{ +#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1 +  const bool spaceAvailable = context->instStackSize < RTC_MAX_INSTANCE_LEVEL_COUNT; +  /* We assert here because instances are silently dropped when the stack is full.  +     This might be quite hard to find in production. */ +  assert(spaceAvailable);  +  if (likely(spaceAvailable)) +    context->instID[context->instStackSize++] = instanceId; +  return spaceAvailable; +#else +  const bool spaceAvailable = (context->instID[0] == RTC_INVALID_GEOMETRY_ID); +  assert(spaceAvailable);  +  if (likely(spaceAvailable)) +    context->instID[0] = instanceId; +  return spaceAvailable; +#endif +} + + +/*  + * Pop the last instance pushed to the stack.  + * Do not call on an empty stack.  + */ +RTC_FORCEINLINE void pop(RTCIntersectContext* context) +{ +  assert(context); +#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1 +  assert(context->instStackSize > 0); +  context->instID[--context->instStackSize] = RTC_INVALID_GEOMETRY_ID; +#else +  assert(context->instID[0] != RTC_INVALID_GEOMETRY_ID); +  context->instID[0] = RTC_INVALID_GEOMETRY_ID; +#endif +} + +/* + * Optimized instance id stack copy. + * The copy() functions will either copy full + * stacks or copy only until the last valid element has been copied, depending + * on RTC_MAX_INSTANCE_LEVEL_COUNT. + */ +RTC_FORCEINLINE void copy_UU(const unsigned* src, unsigned* tgt) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) +  tgt[0] = src[0]; +   +#else +  for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { +    tgt[l] = src[l]; +    if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) +      if (src[l] == RTC_INVALID_GEOMETRY_ID) +        break; +  } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) +  tgt[0] = src[0]; + +#else +  for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { +    tgt[l] = src[l]; +    if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) +      if (src[l] == RTC_INVALID_GEOMETRY_ID) +        break; +  } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, size_t j) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) +  tgt[0][j] = src[0]; + +#else +  for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { +    tgt[l][j] = src[l]; +    if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) +      if (src[l] == RTC_INVALID_GEOMETRY_ID) +        break; +  } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, const vbool<K>& mask) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) +  vuint<K>::store(mask, tgt, src[0]); + +#else +  for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { +    vuint<K>::store(mask, tgt + l, src[l]); +    if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) +      if (src[l] == RTC_INVALID_GEOMETRY_ID) +        break; +  } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_VU(const vuint<K>* src, unsigned* tgt, size_t i) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) +  tgt[0] = src[0][i]; + +#else +  for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { +    tgt[l] = src[l][i]; +    if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) +      if (src[l][i] == RTC_INVALID_GEOMETRY_ID) +        break; +  } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, size_t i, size_t j) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) +  tgt[0][j] = src[0][i]; + +#else +  for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { +    tgt[l][j] = src[l][i]; +    if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) +      if (src[l][i] == RTC_INVALID_GEOMETRY_ID) +        break; +  } +#endif +} + +template <int K> +RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, const vbool<K>& mask) +{ +#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1) +  vuint<K>::store(mask, tgt, src[0]); + +#else +  vbool<K> done = !mask; +  for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { +    vuint<K>::store(mask, tgt + l, src[l]); +    if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) { +      done |= src[l] == RTC_INVALID_GEOMETRY_ID; +      if (all(done)) break; +    } +  } +#endif +} + +} // namespace instance_id_stack +} // namespace embree |