Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
20fc2e5
Coding - Add SIMD dispatch infrastructure for BVH ray-box intersection
jijinbei Apr 19, 2026
76759cf
Coding - Add SSE2 kernel for 1-ray-vs-4-AABB BVH intersection
jijinbei Apr 19, 2026
18fddae
Coding - Add QBVH ray traversal using SIMD ray-box intersection
jijinbei Apr 19, 2026
5f72f98
Coding - Add AVX2 kernel for 1-ray-vs-4-AABB BVH intersection
jijinbei Apr 19, 2026
793f24c
Coding - Add AVX-512 kernel for 1-ray-vs-4-AABB BVH intersection
jijinbei Apr 19, 2026
f4fe588
Coding - Add microbenchmark comparing scalar/SSE2/AVX2/AVX-512 ray-bo…
jijinbei Apr 19, 2026
14244f5
Coding - Add BVH_OctTree type and CollapseToOctTree builder
jijinbei Apr 19, 2026
2b23a82
Coding - Add scalar RayBox8 kernel and BVH8 dispatch scaffolding
jijinbei Apr 19, 2026
029a763
Coding - Add SSE2 kernel for 1-ray-vs-8-AABB BVH8 traversal
jijinbei Apr 19, 2026
c53a3d9
Coding - Add AVX2 kernel for 1-ray-vs-8-AABB BVH8 traversal (genuine …
jijinbei Apr 19, 2026
30884b9
Coding - Add AVX-512 kernel for 1-ray-vs-8-AABB BVH8 traversal
jijinbei Apr 19, 2026
3dd5d7c
Coding - Add BVH8 ray traversal using SIMD ray-box intersection
jijinbei Apr 19, 2026
89d3c01
Coding - Refactor BVH8 into BVH_WideTree<W> template (BVH4 unchanged)
jijinbei Apr 24, 2026
cda2e63
Coding - Add BVH16 (CollapseToWide<16> + scalar kernel + tests)
jijinbei Apr 24, 2026
1934c0c
Coding - Add AVX-512 BVH16 kernel using __m512 (16-wide zmm)
jijinbei Apr 24, 2026
54bef07
Coding - Add BVH16 microbenchmark to RayBoxN comparison
jijinbei Apr 24, 2026
3b71504
Coding - Fix CI: ARM-safe Detect() + clang-format-18 reflow
jijinbei Apr 24, 2026
bd1085a
Coding - Fix macOS CI: [[maybe_unused]] on BVH4 test helpers
jijinbei Apr 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions src/FoundationClasses/TKMath/BVH/BVH_BinaryTree.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define _BVH_BinaryTree_Header

#include <BVH_QuadTree.hxx>
#include <BVH_WideTree.hxx>

#include <deque>
#include <tuple>
Expand Down Expand Up @@ -149,6 +150,16 @@ public: //! @name methods specific to binary BVH
//! Collapses the tree into QBVH an returns it. As a result, each
//! 2-nd level of current tree is kept and the rest are discarded.
BVH_Tree<T, N, BVH_QuadTree>* CollapseToQuadTree() const;

//! Collapses the tree into a W-wide BVH (BVH8 for W=8, BVH16 for W=16).
//! Each log2(W)-th level of the source tree is preserved while the
//! intermediate levels are flattened into a single inner node holding
//! 1..W children. Built so the matching SIMD kernel saturates its native
//! register width:
//! - W=8 -> BVH8, RayBoxN_AVX2_8 (__m256, ymm)
//! - W=16 -> BVH16, RayBoxN_AVX512_16 (__m512, zmm)
template <int W>
BVH_Tree<T, N, BVH_WideTree<W>>* CollapseToWide() const;
};

namespace BVH
Expand Down Expand Up @@ -285,4 +296,91 @@ BVH_Tree<T, N, BVH_QuadTree>* BVH_Tree<T, N, BVH_BinaryTree>::CollapseToQuadTree
return aQBVH;
}

//=================================================================================================

namespace BVH
{
//! Walks down a binary subtree at most theDepth levels and records the nodes
//! it stops at. A node is recorded if it is a leaf or if the descent depth
//! reached theDepth. Used by CollapseToWide<W> to gather up to 2^Log2W = W
//! representatives of a Log2W-level binary subtree as the children of one
//! wide-BVH inner node.
template <class T, int N>
void GatherDescendants(const BVH_Tree<T, N, BVH_BinaryTree>* theTree,
const int theNode,
const int theDepth,
NCollection_Vector<int>& theOutNodes)
{
if (theDepth == 0 || theTree->IsOuter(theNode))
{
theOutNodes.Append(theNode);
return;
}
GatherDescendants(theTree, theTree->template Child<0>(theNode), theDepth - 1, theOutNodes);
GatherDescendants(theTree, theTree->template Child<1>(theNode), theDepth - 1, theOutNodes);
}
} // namespace BVH

template <class T, int N>
template <int W>
BVH_Tree<T, N, BVH_WideTree<W>>* BVH_Tree<T, N, BVH_BinaryTree>::CollapseToWide() const
{
static_assert(W == 8 || W == 16, "CollapseToWide<W> only instantiated for W=8 or W=16");
constexpr int kLog2W = BVH_WideTree<W>::Log2W;

BVH_Tree<T, N, BVH_WideTree<W>>* aWBVH = new BVH_Tree<T, N, BVH_WideTree<W>>;

if (this->Length() == 0)
{
return aWBVH;
}

// Each queue entry pairs a source-tree node id with the level it sits at
// in the destination tree (used only for myDepth bookkeeping).
std::deque<std::pair<int, int>> aQueue(1, std::make_pair(0, 0));

for (int aNbNodes = 1; !aQueue.empty();)
{
const std::pair<int, int> aNode = aQueue.front();

BVH::Array<T, N>::Append(aWBVH->myMinPointBuffer,
BVH::Array<T, N>::Value(this->myMinPointBuffer, std::get<0>(aNode)));
BVH::Array<T, N>::Append(aWBVH->myMaxPointBuffer,
BVH::Array<T, N>::Value(this->myMaxPointBuffer, std::get<0>(aNode)));

BVH_Vec4i aNodeInfo;
if (this->IsOuter(std::get<0>(aNode)))
{
aNodeInfo = BVH_Vec4i(1 /* leaf flag */,
this->BegPrimitive(std::get<0>(aNode)),
this->EndPrimitive(std::get<0>(aNode)),
std::get<1>(aNode));
}
else
{
// Walk Log2W binary levels down (or stop early at leaves) to harvest
// up to 2^Log2W = W representatives that become the children of this
// wide-BVH inner node.
NCollection_Vector<int> aGrandChildren;
BVH::GatherDescendants(this, std::get<0>(aNode), kLog2W, aGrandChildren);

for (int aIdx = 0; aIdx < aGrandChildren.Size(); ++aIdx)
{
aQueue.push_back(std::make_pair(aGrandChildren(aIdx), std::get<1>(aNode) + 1));
}

aNodeInfo =
BVH_Vec4i(0 /* inner flag */, aNbNodes, aGrandChildren.Size() - 1, std::get<1>(aNode));

aWBVH->myDepth = (std::max)(aWBVH->myDepth, std::get<1>(aNode) + 1);
aNbNodes += aGrandChildren.Size();
}

BVH::Array<int, 4>::Append(aWBVH->myNodeInfoBuffer, aNodeInfo);
aQueue.pop_front();
}

return aWBVH;
}

#endif // _BVH_BinaryTree_Header
Loading
Loading