Path: blob/master/thirdparty/embree/kernels/bvh/bvh.h
9912 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45/* include all node types */6#include "bvh_node_aabb.h"7#include "bvh_node_aabb_mb.h"8#include "bvh_node_aabb_mb4d.h"9#include "bvh_node_obb.h"10#include "bvh_node_obb_mb.h"11#include "bvh_node_qaabb.h"1213namespace embree14{15/*! flags used to enable specific node types in intersectors */16enum BVHNodeFlags17{18BVH_FLAG_ALIGNED_NODE = 0x00001,19BVH_FLAG_ALIGNED_NODE_MB = 0x00010,20BVH_FLAG_UNALIGNED_NODE = 0x00100,21BVH_FLAG_UNALIGNED_NODE_MB = 0x01000,22BVH_FLAG_QUANTIZED_NODE = 0x100000,23BVH_FLAG_ALIGNED_NODE_MB4D = 0x1000000,2425/* short versions */26BVH_AN1 = BVH_FLAG_ALIGNED_NODE,27BVH_AN2 = BVH_FLAG_ALIGNED_NODE_MB,28BVH_AN2_AN4D = BVH_FLAG_ALIGNED_NODE_MB | BVH_FLAG_ALIGNED_NODE_MB4D,29BVH_UN1 = BVH_FLAG_UNALIGNED_NODE,30BVH_UN2 = BVH_FLAG_UNALIGNED_NODE_MB,31BVH_MB = BVH_FLAG_ALIGNED_NODE_MB | BVH_FLAG_UNALIGNED_NODE_MB | BVH_FLAG_ALIGNED_NODE_MB4D,32BVH_AN1_UN1 = BVH_FLAG_ALIGNED_NODE | BVH_FLAG_UNALIGNED_NODE,33BVH_AN2_UN2 = BVH_FLAG_ALIGNED_NODE_MB | BVH_FLAG_UNALIGNED_NODE_MB,34BVH_AN2_AN4D_UN2 = BVH_FLAG_ALIGNED_NODE_MB | BVH_FLAG_ALIGNED_NODE_MB4D | BVH_FLAG_UNALIGNED_NODE_MB,35BVH_QN1 = BVH_FLAG_QUANTIZED_NODE36};3738/*! Multi BVH with N children. Each node stores the bounding box of39* it's N children as well as N child references. */40template<int N>41class BVHN : public AccelData42{43ALIGNED_CLASS_(16);44public:4546/*! forward declaration of node ref type */47typedef NodeRefPtr<N> NodeRef;48typedef BaseNode_t<NodeRef,N> BaseNode;49typedef AABBNode_t<NodeRef,N> AABBNode;50typedef AABBNodeMB_t<NodeRef,N> AABBNodeMB;51typedef AABBNodeMB4D_t<NodeRef,N> AABBNodeMB4D;52typedef OBBNode_t<NodeRef,N> OBBNode;53typedef OBBNodeMB_t<NodeRef,N> OBBNodeMB;54typedef QuantizedBaseNode_t<N> QuantizedBaseNode;55typedef QuantizedBaseNodeMB_t<N> QuantizedBaseNodeMB;56typedef QuantizedNode_t<NodeRef,N> QuantizedNode;5758/*! Number of bytes the nodes and primitives are minimally aligned to.*/59static const size_t byteAlignment = 16;60static const size_t byteNodeAlignment = 4*N;6162/*! Empty node */63static const size_t emptyNode = NodeRef::emptyNode;6465/*! Invalid node, used as marker in traversal */66static const size_t invalidNode = NodeRef::invalidNode;67static const size_t popRay = NodeRef::popRay;6869/*! Maximum depth of the BVH. */70static const size_t maxBuildDepth = 32;71static const size_t maxBuildDepthLeaf = maxBuildDepth+8;72static const size_t maxDepth = 2*maxBuildDepthLeaf; // 2x because of two level builder7374/*! Maximum number of primitive blocks in a leaf. */75static const size_t maxLeafBlocks = NodeRef::maxLeafBlocks;7677public:7879/*! Builder interface to create allocator */80struct CreateAlloc : public FastAllocator::Create {81__forceinline CreateAlloc (BVHN* bvh) : FastAllocator::Create(&bvh->alloc) {}82};8384typedef BVHNodeRecord<NodeRef> NodeRecord;85typedef BVHNodeRecordMB<NodeRef> NodeRecordMB;86typedef BVHNodeRecordMB4D<NodeRef> NodeRecordMB4D;8788public:8990/*! BVHN default constructor. */91BVHN (const PrimitiveType& primTy, Scene* scene);9293/*! BVHN destruction */94~BVHN ();9596/*! clears the acceleration structure */97void clear();9899/*! sets BVH members after build */100void set (NodeRef root, const LBBox3fa& bounds, size_t numPrimitives);101102/*! Clears the barrier bits of a subtree. */103void clearBarrier(NodeRef& node);104105/*! lays out num large nodes of the BVH */106void layoutLargeNodes(size_t num);107NodeRef layoutLargeNodesRecursion(NodeRef& node, const FastAllocator::CachedAllocator& allocator);108109/*! called by all builders before build starts */110double preBuild(const std::string& builderName);111112/*! called by all builders after build ended */113void postBuild(double t0);114115/*! allocator class */116struct Allocator {117BVHN* bvh;118Allocator (BVHN* bvh) : bvh(bvh) {}119__forceinline void* operator() (size_t bytes) const {120return bvh->alloc._threadLocal()->malloc(&bvh->alloc,bytes);121}122};123124/*! post build cleanup */125void cleanup() {126alloc.cleanup();127}128129public:130131/*! Encodes a node */132static __forceinline NodeRef encodeNode(AABBNode* node) { return NodeRef::encodeNode(node); }133static __forceinline NodeRef encodeNode(AABBNodeMB* node) { return NodeRef::encodeNode(node); }134static __forceinline NodeRef encodeNode(AABBNodeMB4D* node) { return NodeRef::encodeNode(node); }135static __forceinline NodeRef encodeNode(OBBNode* node) { return NodeRef::encodeNode(node); }136static __forceinline NodeRef encodeNode(OBBNodeMB* node) { return NodeRef::encodeNode(node); }137static __forceinline NodeRef encodeLeaf(void* tri, size_t num) { return NodeRef::encodeLeaf(tri,num); }138static __forceinline NodeRef encodeTypedLeaf(void* ptr, size_t ty) { return NodeRef::encodeTypedLeaf(ptr,ty); }139140public:141142/*! Prefetches the node this reference points to */143__forceinline static void prefetch(const NodeRef ref, int types=0)144{145#if defined(__AVX512PF__) // MIC146if (types != BVH_FLAG_QUANTIZED_NODE) {147prefetchL2(((char*)ref.ptr)+0*64);148prefetchL2(((char*)ref.ptr)+1*64);149if ((N >= 8) || (types > BVH_FLAG_ALIGNED_NODE)) {150prefetchL2(((char*)ref.ptr)+2*64);151prefetchL2(((char*)ref.ptr)+3*64);152}153if ((N >= 8) && (types > BVH_FLAG_ALIGNED_NODE)) {154/* KNL still needs L2 prefetches for large nodes */155prefetchL2(((char*)ref.ptr)+4*64);156prefetchL2(((char*)ref.ptr)+5*64);157prefetchL2(((char*)ref.ptr)+6*64);158prefetchL2(((char*)ref.ptr)+7*64);159}160}161else162{163/* todo: reduce if 32bit offsets are enabled */164prefetchL2(((char*)ref.ptr)+0*64);165prefetchL2(((char*)ref.ptr)+1*64);166prefetchL2(((char*)ref.ptr)+2*64);167}168#else169if (types != BVH_FLAG_QUANTIZED_NODE) {170prefetchL1(((char*)ref.ptr)+0*64);171prefetchL1(((char*)ref.ptr)+1*64);172if ((N >= 8) || (types > BVH_FLAG_ALIGNED_NODE)) {173prefetchL1(((char*)ref.ptr)+2*64);174prefetchL1(((char*)ref.ptr)+3*64);175}176if ((N >= 8) && (types > BVH_FLAG_ALIGNED_NODE)) {177/* deactivate for large nodes on Xeon, as it introduces regressions */178//prefetchL1(((char*)ref.ptr)+4*64);179//prefetchL1(((char*)ref.ptr)+5*64);180//prefetchL1(((char*)ref.ptr)+6*64);181//prefetchL1(((char*)ref.ptr)+7*64);182}183}184else185{186/* todo: reduce if 32bit offsets are enabled */187prefetchL1(((char*)ref.ptr)+0*64);188prefetchL1(((char*)ref.ptr)+1*64);189prefetchL1(((char*)ref.ptr)+2*64);190}191#endif192}193194__forceinline static void prefetchW(const NodeRef ref, int types=0)195{196embree::prefetchEX(((char*)ref.ptr)+0*64);197embree::prefetchEX(((char*)ref.ptr)+1*64);198if ((N >= 8) || (types > BVH_FLAG_ALIGNED_NODE)) {199embree::prefetchEX(((char*)ref.ptr)+2*64);200embree::prefetchEX(((char*)ref.ptr)+3*64);201}202if ((N >= 8) && (types > BVH_FLAG_ALIGNED_NODE)) {203embree::prefetchEX(((char*)ref.ptr)+4*64);204embree::prefetchEX(((char*)ref.ptr)+5*64);205embree::prefetchEX(((char*)ref.ptr)+6*64);206embree::prefetchEX(((char*)ref.ptr)+7*64);207}208}209210/*! bvh type information */211public:212const PrimitiveType* primTy; //!< primitive type stored in the BVH213214/*! bvh data */215public:216Device* device; //!< device pointer217Scene* scene; //!< scene pointer218NodeRef root; //!< root node219FastAllocator alloc; //!< allocator used to allocate nodes220221/*! statistics data */222public:223size_t numPrimitives; //!< number of primitives the BVH is build over224size_t numVertices; //!< number of vertices the BVH references225226/*! data arrays for special builders */227public:228std::vector<BVHN*> objects;229vector_t<char,aligned_allocator<char,32>> subdiv_patches;230};231232typedef BVHN<4> BVH4;233typedef BVHN<8> BVH8;234}235236237