Path: blob/master/thirdparty/embree/kernels/common/instance_stack.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "rtcore.h"67namespace embree {8namespace instance_id_stack {910static_assert(RTC_MAX_INSTANCE_LEVEL_COUNT > 0,11"RTC_MAX_INSTANCE_LEVEL_COUNT must be greater than 0.");1213/*******************************************************************************14* Instance ID stack manipulation.15* This is used from the instance intersector.16******************************************************************************/1718/*19* Push an instance to the stack.20*/21template<typename Context>22RTC_FORCEINLINE bool push(Context context,23unsigned instanceId,24unsigned instancePrimId)25{26#if RTC_MAX_INSTANCE_LEVEL_COUNT > 127const bool spaceAvailable = context->instStackSize < RTC_MAX_INSTANCE_LEVEL_COUNT;28/* We assert here because instances are silently dropped when the stack is full.29This might be quite hard to find in production. */30assert(spaceAvailable);31if (likely(spaceAvailable)) {32context->instID[context->instStackSize] = instanceId;33#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)34context->instPrimID[context->instStackSize] = instancePrimId;35#endif36context->instStackSize++;37}38return spaceAvailable;39#else40const bool spaceAvailable = (context->instID[0] == RTC_INVALID_GEOMETRY_ID);41assert(spaceAvailable);42if (likely(spaceAvailable)) {43context->instID[0] = instanceId;44#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)45context->instPrimID[0] = instancePrimId;46#endif47}48return spaceAvailable;49#endif50}5152/*53* Pop the last instance pushed to the stack.54* Do not call on an empty stack.55*/56template<typename Context>57RTC_FORCEINLINE void pop(Context context)58{59assert(context);60#if RTC_MAX_INSTANCE_LEVEL_COUNT > 161assert(context->instStackSize > 0);62--context->instStackSize;63context->instID[context->instStackSize] = RTC_INVALID_GEOMETRY_ID;64#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)65context->instPrimID[context->instStackSize] = RTC_INVALID_GEOMETRY_ID;66#endif67#else68assert(context->instID[0] != RTC_INVALID_GEOMETRY_ID);69context->instID[0] = RTC_INVALID_GEOMETRY_ID;70#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)71context->instPrimID[0] = RTC_INVALID_GEOMETRY_ID;72#endif73#endif74}757677/* Push an instance to the stack. Used for point queries*/78RTC_FORCEINLINE bool push(RTCPointQueryContext* context,79unsigned int instanceId,80unsigned int instancePrimId,81AffineSpace3fa const& w2i,82AffineSpace3fa const& i2w)83{84assert(context);85const size_t stackSize = context->instStackSize;86assert(stackSize < RTC_MAX_INSTANCE_LEVEL_COUNT);87context->instID[stackSize] = instanceId;88#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)89context->instPrimID[stackSize] = instancePrimId;90#endif9192AffineSpace3fa_store_unaligned(w2i,(AffineSpace3fa*)context->world2inst[stackSize]);93AffineSpace3fa_store_unaligned(i2w,(AffineSpace3fa*)context->inst2world[stackSize]);9495#if RTC_MAX_INSTANCE_LEVEL_COUNT > 196if (unlikely(stackSize > 0))97{98const AffineSpace3fa world2inst = AffineSpace3fa_load_unaligned((AffineSpace3fa*)context->world2inst[stackSize ])99* AffineSpace3fa_load_unaligned((AffineSpace3fa*)context->world2inst[stackSize-1]);100const AffineSpace3fa inst2world = AffineSpace3fa_load_unaligned((AffineSpace3fa*)context->inst2world[stackSize-1])101* AffineSpace3fa_load_unaligned((AffineSpace3fa*)context->inst2world[stackSize ]);102AffineSpace3fa_store_unaligned(world2inst,(AffineSpace3fa*)context->world2inst[stackSize]);103AffineSpace3fa_store_unaligned(inst2world,(AffineSpace3fa*)context->inst2world[stackSize]);104}105#endif106context->instStackSize++;107return true;108}109110template<>111RTC_FORCEINLINE void pop(RTCPointQueryContext* context)112{113assert(context);114#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1115assert(context->instStackSize > 0);116#else117assert(context->instID[0] != RTC_INVALID_GEOMETRY_ID);118#endif119--context->instStackSize;120context->instID[context->instStackSize] = RTC_INVALID_GEOMETRY_ID;121#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)122context->instPrimID[context->instStackSize] = RTC_INVALID_GEOMETRY_ID;123#endif124}125126/*127* Optimized instance id stack copy.128* The copy() functions will either copy full129* stacks or copy only until the last valid element has been copied, depending130* on RTC_MAX_INSTANCE_LEVEL_COUNT.131*/132RTC_FORCEINLINE void copy_UU(const unsigned* src, unsigned* tgt)133{134#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)135tgt[0] = src[0];136137#else138for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {139tgt[l] = src[l];140if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)141if (src[l] == RTC_INVALID_GEOMETRY_ID)142break;143}144#endif145}146147RTC_FORCEINLINE void copy_UU(const RTCRayQueryContext* context, const unsigned* src, unsigned* tgt)148{149#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)150tgt[0] = src[0];151152#else153154unsigned int depth = context->instStackSize;155156for (unsigned l = 0; l < depth; ++l)157tgt[l] = src[l];158159for (unsigned l = depth; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l)160tgt[l] = RTC_INVALID_GEOMETRY_ID;161162#endif163}164165template <int K>166RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt)167{168#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)169tgt[0] = src[0];170171#else172for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {173tgt[l] = src[l];174if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)175if (src[l] == RTC_INVALID_GEOMETRY_ID)176break;177}178#endif179}180181template <int K>182RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, size_t j)183{184#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)185tgt[0][j] = src[0];186187#else188for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {189tgt[l][j] = src[l];190if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)191if (src[l] == RTC_INVALID_GEOMETRY_ID)192break;193}194#endif195}196197template <int K>198RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, const vbool<K>& mask)199{200#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)201vuint<K>::store(mask, tgt, src[0]);202203#else204for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {205vuint<K>::store(mask, tgt + l, src[l]);206if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)207if (src[l] == RTC_INVALID_GEOMETRY_ID)208break;209}210#endif211}212213template <int K>214RTC_FORCEINLINE void copy_VU(const vuint<K>* src, unsigned* tgt, size_t i)215{216#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)217tgt[0] = src[0][i];218219#else220for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {221tgt[l] = src[l][i];222if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)223if (src[l][i] == RTC_INVALID_GEOMETRY_ID)224break;225}226#endif227}228229template <int K>230RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, size_t i, size_t j)231{232#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)233tgt[0][j] = src[0][i];234235#else236for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {237tgt[l][j] = src[l][i];238if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)239if (src[l][i] == RTC_INVALID_GEOMETRY_ID)240break;241}242#endif243}244245template <int K>246RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, const vbool<K>& mask)247{248#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)249vuint<K>::store(mask, tgt, src[0]);250251#else252vbool<K> done = !mask;253for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {254vuint<K>::store(mask, tgt + l, src[l]);255if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) {256done |= src[l] == RTC_INVALID_GEOMETRY_ID;257if (all(done)) break;258}259}260#endif261}262263} // namespace instance_id_stack264} // namespace embree265266267