mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Merge topic 'bvh/remove_device_template'
b03fec9a3 bvh device adpater banishment Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !1559
This commit is contained in:
commit
5e2e0d9ff1
@ -27,7 +27,6 @@
|
||||
#include <vtkm/cont/DeviceAdapter.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
#include <vtkm/cont/AtomicArray.h>
|
||||
@ -56,7 +55,6 @@ class LinearBVHBuilder
|
||||
public:
|
||||
class CountingIterator;
|
||||
|
||||
template <typename Device>
|
||||
class GatherFloat32;
|
||||
|
||||
template <typename Device>
|
||||
@ -66,23 +64,18 @@ public:
|
||||
|
||||
class BVHData;
|
||||
|
||||
template <typename Device>
|
||||
class PropagateAABBs;
|
||||
|
||||
template <typename Device>
|
||||
class TreeBuilder;
|
||||
|
||||
VTKM_CONT
|
||||
LinearBVHBuilder() {}
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void SortAABBS(BVHData& bvh, Device vtkmNotUsed(device), bool);
|
||||
VTKM_CONT void SortAABBS(BVHData& bvh, bool);
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void BuildHierarchy(BVHData& bvh);
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void RunOnDevice(LinearBVH& linearBVH, Device device);
|
||||
VTKM_CONT void Build(LinearBVH& linearBVH);
|
||||
}; // class LinearBVHBuilder
|
||||
|
||||
class LinearBVHBuilder::CountingIterator : public vtkm::worklet::WorkletMapField
|
||||
@ -96,31 +89,21 @@ public:
|
||||
void operator()(const vtkm::Id& index, vtkm::Id& outId) const { outId = index; }
|
||||
}; //class countingIterator
|
||||
|
||||
template <typename Device>
|
||||
class LinearBVHBuilder::GatherFloat32 : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
using FloatArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Float32>;
|
||||
using PortalConst = typename FloatArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using Portal = typename FloatArrayHandle::ExecutionTypes<Device>::Portal;
|
||||
PortalConst InputPortal;
|
||||
Portal OutputPortal;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
GatherFloat32(const FloatArrayHandle& inputPortal,
|
||||
FloatArrayHandle& outputPortal,
|
||||
const vtkm::Id& size)
|
||||
: InputPortal(inputPortal.PrepareForInput(Device()))
|
||||
GatherFloat32() {}
|
||||
using ControlSignature = void(FieldIn, WholeArrayIn, WholeArrayOut);
|
||||
using ExecutionSignature = void(WorkIndex, _1, _2, _3);
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& outIndex,
|
||||
const vtkm::Id& inIndex,
|
||||
const InType& inPortal,
|
||||
OutType& outPortal) const
|
||||
{
|
||||
this->OutputPortal = outputPortal.PrepareForOutput(size, Device());
|
||||
}
|
||||
using ControlSignature = void(FieldIn);
|
||||
using ExecutionSignature = void(WorkIndex, _1);
|
||||
VTKM_EXEC
|
||||
void operator()(const vtkm::Id& outIndex, const vtkm::Id& inIndex) const
|
||||
{
|
||||
OutputPortal.Set(outIndex, InputPortal.Get(inIndex));
|
||||
outPortal.Set(outIndex, inPortal.Get(inIndex));
|
||||
}
|
||||
}; //class GatherFloat
|
||||
|
||||
@ -188,8 +171,7 @@ public:
|
||||
vtkm::cont::ArrayHandleCounting<vtkm::Id> leafOffsets;
|
||||
AABBs& AABB;
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT BVHData(vtkm::Id numPrimitives, AABBs& aabbs, Device vtkmNotUsed(device))
|
||||
VTKM_CONT BVHData(vtkm::Id numPrimitives, AABBs& aabbs)
|
||||
: leafOffsets(0, 2, numPrimitives)
|
||||
, AABB(aabbs)
|
||||
, NumPrimitives(numPrimitives)
|
||||
@ -197,11 +179,11 @@ public:
|
||||
InnerNodeCount = NumPrimitives - 1;
|
||||
vtkm::Id size = NumPrimitives + InnerNodeCount;
|
||||
|
||||
parent.PrepareForOutput(size, Device());
|
||||
leftChild.PrepareForOutput(InnerNodeCount, Device());
|
||||
rightChild.PrepareForOutput(InnerNodeCount, Device());
|
||||
innerBounds.PrepareForOutput(InnerNodeCount, Device());
|
||||
mortonCodes.PrepareForOutput(NumPrimitives, Device());
|
||||
parent.Allocate(size);
|
||||
leftChild.Allocate(InnerNodeCount);
|
||||
rightChild.Allocate(InnerNodeCount);
|
||||
innerBounds.Allocate(InnerNodeCount);
|
||||
mortonCodes.Allocate(NumPrimitives);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -218,45 +200,17 @@ private:
|
||||
|
||||
}; // class BVH
|
||||
|
||||
template <typename Device>
|
||||
class LinearBVHBuilder::PropagateAABBs : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
using IdArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using Int8Handle = typename vtkm::cont::ArrayHandle<vtkm::Int8>;
|
||||
using Float2ArrayHandle = typename vtkm::cont::ArrayHandle<Vec<vtkm::Float32, 2>>;
|
||||
using VecInt2Handle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int32, 2>>;
|
||||
using Float4ArrayHandle = typename vtkm::cont::ArrayHandle<Vec<vtkm::Float32, 4>>;
|
||||
|
||||
using IdConstPortal = typename IdArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using Float2ArrayPortal = typename Float2ArrayHandle::ExecutionTypes<Device>::Portal;
|
||||
using Int2ArrayPortal = typename VecInt2Handle::ExecutionTypes<Device>::Portal;
|
||||
using Int8ArrayPortal = typename Int8Handle::ExecutionTypes<Device>::Portal;
|
||||
using Float4ArrayPortal = typename Float4ArrayHandle::ExecutionTypes<Device>::Portal;
|
||||
|
||||
Float4ArrayPortal FlatBVH;
|
||||
IdConstPortal Parents;
|
||||
IdConstPortal LeftChildren;
|
||||
IdConstPortal RightChildren;
|
||||
vtkm::Int32 LeafCount;
|
||||
vtkm::exec::AtomicArrayExecutionObject<vtkm::Int32, Device> Counters;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
PropagateAABBs(IdArrayHandle& parents,
|
||||
IdArrayHandle& leftChildren,
|
||||
IdArrayHandle& rightChildren,
|
||||
vtkm::Int32 leafCount,
|
||||
Float4ArrayHandle flatBVH,
|
||||
const vtkm::cont::AtomicArray<vtkm::Int32>& counters)
|
||||
: Parents(parents.PrepareForInput(Device()))
|
||||
, LeftChildren(leftChildren.PrepareForInput(Device()))
|
||||
, RightChildren(rightChildren.PrepareForInput(Device()))
|
||||
, LeafCount(leafCount)
|
||||
, Counters(counters.PrepareForExecution(Device()))
|
||||
PropagateAABBs(vtkm::Int32 leafCount)
|
||||
: LeafCount(leafCount)
|
||||
|
||||
{
|
||||
this->FlatBVH = flatBVH.PrepareForOutput((LeafCount - 1) * 4, Device());
|
||||
}
|
||||
using ControlSignature = void(WholeArrayIn,
|
||||
WholeArrayIn,
|
||||
@ -264,10 +218,20 @@ public:
|
||||
WholeArrayIn,
|
||||
WholeArrayIn,
|
||||
WholeArrayIn,
|
||||
WholeArrayIn);
|
||||
using ExecutionSignature = void(WorkIndex, _1, _2, _3, _4, _5, _6, _7);
|
||||
WholeArrayIn,
|
||||
WholeArrayIn, //Parents
|
||||
WholeArrayIn, //lchild
|
||||
WholeArrayIn, //rchild
|
||||
AtomicArrayInOut, //counters
|
||||
WholeArrayInOut // flatbvh
|
||||
);
|
||||
using ExecutionSignature = void(WorkIndex, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12);
|
||||
|
||||
template <typename InputPortalType, typename OffsetPortalType>
|
||||
template <typename InputPortalType,
|
||||
typename OffsetPortalType,
|
||||
typename IdPortalType,
|
||||
typename AtomicType,
|
||||
typename BVHType>
|
||||
VTKM_EXEC_CONT void operator()(const vtkm::Id workIndex,
|
||||
const InputPortalType& xmin,
|
||||
const InputPortalType& ymin,
|
||||
@ -275,21 +239,28 @@ public:
|
||||
const InputPortalType& xmax,
|
||||
const InputPortalType& ymax,
|
||||
const InputPortalType& zmax,
|
||||
const OffsetPortalType& leafOffsets) const
|
||||
const OffsetPortalType& leafOffsets,
|
||||
const IdPortalType& parents,
|
||||
const IdPortalType& leftChildren,
|
||||
const IdPortalType& rightChildren,
|
||||
AtomicType& counters,
|
||||
BVHType& flatBVH) const
|
||||
|
||||
{
|
||||
//move up into the inner nodes
|
||||
vtkm::Id currentNode = LeafCount - 1 + workIndex;
|
||||
vtkm::Vec<vtkm::Id, 2> childVector;
|
||||
while (currentNode != 0)
|
||||
{
|
||||
currentNode = Parents.Get(currentNode);
|
||||
|
||||
vtkm::Int32 oldCount = Counters.Add(currentNode, 1);
|
||||
currentNode = parents.Get(currentNode);
|
||||
vtkm::Int32 oldCount = counters.Add(currentNode, 1);
|
||||
if (oldCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
vtkm::Id currentNodeOffset = currentNode * 4;
|
||||
childVector[0] = LeftChildren.Get(currentNode);
|
||||
childVector[1] = RightChildren.Get(currentNode);
|
||||
childVector[0] = leftChildren.Get(currentNode);
|
||||
childVector[1] = rightChildren.Get(currentNode);
|
||||
if (childVector[0] > (LeafCount - 2))
|
||||
{
|
||||
//our left child is a leaf, so just grab the AABB
|
||||
@ -303,12 +274,12 @@ public:
|
||||
first4Vec[1] = ymin.Get(childVector[0]);
|
||||
first4Vec[2] = zmin.Get(childVector[0]);
|
||||
first4Vec[3] = xmax.Get(childVector[0]);
|
||||
FlatBVH.Set(currentNodeOffset, first4Vec);
|
||||
flatBVH.Set(currentNodeOffset, first4Vec);
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> second4Vec = FlatBVH.Get(currentNodeOffset + 1);
|
||||
vtkm::Vec<vtkm::Float32, 4> second4Vec = flatBVH.Get(currentNodeOffset + 1);
|
||||
second4Vec[0] = ymax.Get(childVector[0]);
|
||||
second4Vec[1] = zmax.Get(childVector[0]);
|
||||
FlatBVH.Set(currentNodeOffset + 1, second4Vec);
|
||||
flatBVH.Set(currentNodeOffset + 1, second4Vec);
|
||||
// set index to leaf
|
||||
vtkm::Id leafIndex = leafOffsets.Get(childVector[0]);
|
||||
childVector[0] = -(leafIndex + 1);
|
||||
@ -320,21 +291,21 @@ public:
|
||||
//the current node left AABB.
|
||||
vtkm::Id child = childVector[0] * 4;
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> cFirst4Vec = FlatBVH.Get(child);
|
||||
vtkm::Vec<vtkm::Float32, 4> cSecond4Vec = FlatBVH.Get(child + 1);
|
||||
vtkm::Vec<vtkm::Float32, 4> cThird4Vec = FlatBVH.Get(child + 2);
|
||||
vtkm::Vec<vtkm::Float32, 4> cFirst4Vec = flatBVH.Get(child);
|
||||
vtkm::Vec<vtkm::Float32, 4> cSecond4Vec = flatBVH.Get(child + 1);
|
||||
vtkm::Vec<vtkm::Float32, 4> cThird4Vec = flatBVH.Get(child + 2);
|
||||
|
||||
cFirst4Vec[0] = vtkm::Min(cFirst4Vec[0], cSecond4Vec[2]);
|
||||
cFirst4Vec[1] = vtkm::Min(cFirst4Vec[1], cSecond4Vec[3]);
|
||||
cFirst4Vec[2] = vtkm::Min(cFirst4Vec[2], cThird4Vec[0]);
|
||||
cFirst4Vec[3] = vtkm::Max(cFirst4Vec[3], cThird4Vec[1]);
|
||||
FlatBVH.Set(currentNodeOffset, cFirst4Vec);
|
||||
flatBVH.Set(currentNodeOffset, cFirst4Vec);
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> second4Vec = FlatBVH.Get(currentNodeOffset + 1);
|
||||
vtkm::Vec<vtkm::Float32, 4> second4Vec = flatBVH.Get(currentNodeOffset + 1);
|
||||
second4Vec[0] = vtkm::Max(cSecond4Vec[0], cThird4Vec[2]);
|
||||
second4Vec[1] = vtkm::Max(cSecond4Vec[1], cThird4Vec[3]);
|
||||
|
||||
FlatBVH.Set(currentNodeOffset + 1, second4Vec);
|
||||
flatBVH.Set(currentNodeOffset + 1, second4Vec);
|
||||
}
|
||||
|
||||
if (childVector[1] > (LeafCount - 2))
|
||||
@ -344,18 +315,18 @@ public:
|
||||
childVector[1] = childVector[1] - LeafCount + 1;
|
||||
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> second4Vec = FlatBVH.Get(currentNodeOffset + 1);
|
||||
vtkm::Vec<vtkm::Float32, 4> second4Vec = flatBVH.Get(currentNodeOffset + 1);
|
||||
|
||||
second4Vec[2] = xmin.Get(childVector[1]);
|
||||
second4Vec[3] = ymin.Get(childVector[1]);
|
||||
FlatBVH.Set(currentNodeOffset + 1, second4Vec);
|
||||
flatBVH.Set(currentNodeOffset + 1, second4Vec);
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> third4Vec;
|
||||
third4Vec[0] = zmin.Get(childVector[1]);
|
||||
third4Vec[1] = xmax.Get(childVector[1]);
|
||||
third4Vec[2] = ymax.Get(childVector[1]);
|
||||
third4Vec[3] = zmax.Get(childVector[1]);
|
||||
FlatBVH.Set(currentNodeOffset + 2, third4Vec);
|
||||
flatBVH.Set(currentNodeOffset + 2, third4Vec);
|
||||
|
||||
// set index to leaf
|
||||
vtkm::Id leafIndex = leafOffsets.Get(childVector[1]);
|
||||
@ -368,20 +339,20 @@ public:
|
||||
//the current node left AABB.
|
||||
vtkm::Id child = childVector[1] * 4;
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> cFirst4Vec = FlatBVH.Get(child);
|
||||
vtkm::Vec<vtkm::Float32, 4> cSecond4Vec = FlatBVH.Get(child + 1);
|
||||
vtkm::Vec<vtkm::Float32, 4> cThird4Vec = FlatBVH.Get(child + 2);
|
||||
vtkm::Vec<vtkm::Float32, 4> cFirst4Vec = flatBVH.Get(child);
|
||||
vtkm::Vec<vtkm::Float32, 4> cSecond4Vec = flatBVH.Get(child + 1);
|
||||
vtkm::Vec<vtkm::Float32, 4> cThird4Vec = flatBVH.Get(child + 2);
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 4> second4Vec = FlatBVH.Get(currentNodeOffset + 1);
|
||||
vtkm::Vec<vtkm::Float32, 4> second4Vec = flatBVH.Get(currentNodeOffset + 1);
|
||||
second4Vec[2] = vtkm::Min(cFirst4Vec[0], cSecond4Vec[2]);
|
||||
second4Vec[3] = vtkm::Min(cFirst4Vec[1], cSecond4Vec[3]);
|
||||
FlatBVH.Set(currentNodeOffset + 1, second4Vec);
|
||||
flatBVH.Set(currentNodeOffset + 1, second4Vec);
|
||||
|
||||
cThird4Vec[0] = vtkm::Min(cFirst4Vec[2], cThird4Vec[0]);
|
||||
cThird4Vec[1] = vtkm::Max(cFirst4Vec[3], cThird4Vec[1]);
|
||||
cThird4Vec[2] = vtkm::Max(cSecond4Vec[0], cThird4Vec[2]);
|
||||
cThird4Vec[3] = vtkm::Max(cSecond4Vec[1], cThird4Vec[3]);
|
||||
FlatBVH.Set(currentNodeOffset + 2, cThird4Vec);
|
||||
flatBVH.Set(currentNodeOffset + 2, cThird4Vec);
|
||||
}
|
||||
vtkm::Vec<vtkm::Float32, 4> fourth4Vec;
|
||||
vtkm::Int32 leftChild =
|
||||
@ -390,23 +361,14 @@ public:
|
||||
vtkm::Int32 rightChild =
|
||||
static_cast<vtkm::Int32>((childVector[1] >= 0) ? childVector[1] * 4 : childVector[1]);
|
||||
memcpy(&fourth4Vec[1], &rightChild, 4);
|
||||
FlatBVH.Set(currentNodeOffset + 3, fourth4Vec);
|
||||
flatBVH.Set(currentNodeOffset + 3, fourth4Vec);
|
||||
}
|
||||
}
|
||||
}; //class PropagateAABBs
|
||||
|
||||
template <typename Device>
|
||||
class LinearBVHBuilder::TreeBuilder : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using UIntArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::UInt32>;
|
||||
using IdArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
using UIntPortalType = typename UIntArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using IdPortalType = typename IdArrayHandle::ExecutionTypes<Device>::Portal;
|
||||
|
||||
private:
|
||||
UIntPortalType MortonCodePortal;
|
||||
IdPortalType ParentPortal;
|
||||
vtkm::Id LeafCount;
|
||||
vtkm::Id InnerCount;
|
||||
//TODO: get intrinsic support
|
||||
@ -451,15 +413,17 @@ private:
|
||||
//
|
||||
// returns count of the largest binary prefix
|
||||
|
||||
VTKM_EXEC
|
||||
inline vtkm::Int32 delta(const vtkm::Int32& a, const vtkm::Int32& b) const
|
||||
template <typename MortonType>
|
||||
VTKM_EXEC inline vtkm::Int32 delta(const vtkm::Int32& a,
|
||||
const vtkm::Int32& b,
|
||||
const MortonType& mortonCodePortal) const
|
||||
{
|
||||
bool tie = false;
|
||||
bool outOfRange = (b < 0 || b > LeafCount - 1);
|
||||
//still make the call but with a valid adderss
|
||||
vtkm::Int32 bb = (outOfRange) ? 0 : b;
|
||||
vtkm::UInt32 aCode = MortonCodePortal.Get(a);
|
||||
vtkm::UInt32 bCode = MortonCodePortal.Get(bb);
|
||||
vtkm::UInt32 aCode = mortonCodePortal.Get(a);
|
||||
vtkm::UInt32 bCode = mortonCodePortal.Get(bb);
|
||||
//use xor to find where they differ
|
||||
vtkm::UInt32 exOr = aCode ^ bCode;
|
||||
tie = (exOr == 0);
|
||||
@ -474,48 +438,49 @@ private:
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
TreeBuilder(const UIntArrayHandle& mortonCodesHandle,
|
||||
IdArrayHandle& parentHandle,
|
||||
const vtkm::Id& leafCount)
|
||||
: MortonCodePortal(mortonCodesHandle.PrepareForInput(Device()))
|
||||
, LeafCount(leafCount)
|
||||
TreeBuilder(const vtkm::Id& leafCount)
|
||||
: LeafCount(leafCount)
|
||||
, InnerCount(leafCount - 1)
|
||||
{
|
||||
InnerCount = LeafCount - 1;
|
||||
this->ParentPortal = parentHandle.PrepareForOutput(InnerCount + LeafCount, Device());
|
||||
}
|
||||
using ControlSignature = void(FieldOut, FieldOut);
|
||||
using ExecutionSignature = void(WorkIndex, _1, _2);
|
||||
VTKM_EXEC
|
||||
void operator()(const vtkm::Id& index, vtkm::Id& leftChild, vtkm::Id& rightChild) const
|
||||
using ControlSignature = void(FieldOut, FieldOut, WholeArrayIn, WholeArrayOut);
|
||||
using ExecutionSignature = void(WorkIndex, _1, _2, _3, _4);
|
||||
|
||||
template <typename MortonType, typename ParentType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& index,
|
||||
vtkm::Id& leftChild,
|
||||
vtkm::Id& rightChild,
|
||||
const MortonType& mortonCodePortal,
|
||||
ParentType& parentPortal) const
|
||||
{
|
||||
vtkm::Int32 idx = vtkm::Int32(index);
|
||||
//something = MortonCodePortal.Get(index) + 1;
|
||||
//determine range direction
|
||||
vtkm::Int32 d = 0 > (delta(idx, idx + 1) - delta(idx, idx - 1)) ? -1 : 1;
|
||||
vtkm::Int32 d =
|
||||
0 > (delta(idx, idx + 1, mortonCodePortal) - delta(idx, idx - 1, mortonCodePortal)) ? -1 : 1;
|
||||
|
||||
//find upper bound for the length of the range
|
||||
vtkm::Int32 minDelta = delta(idx, idx - d);
|
||||
vtkm::Int32 minDelta = delta(idx, idx - d, mortonCodePortal);
|
||||
vtkm::Int32 lMax = 2;
|
||||
while (delta(idx, idx + lMax * d) > minDelta)
|
||||
while (delta(idx, idx + lMax * d, mortonCodePortal) > minDelta)
|
||||
lMax *= 2;
|
||||
|
||||
//binary search to find the lower bound
|
||||
vtkm::Int32 l = 0;
|
||||
for (int t = lMax / 2; t >= 1; t /= 2)
|
||||
{
|
||||
if (delta(idx, idx + (l + t) * d) > minDelta)
|
||||
if (delta(idx, idx + (l + t) * d, mortonCodePortal) > minDelta)
|
||||
l += t;
|
||||
}
|
||||
|
||||
vtkm::Int32 j = idx + l * d;
|
||||
vtkm::Int32 deltaNode = delta(idx, j);
|
||||
vtkm::Int32 deltaNode = delta(idx, j, mortonCodePortal);
|
||||
vtkm::Int32 s = 0;
|
||||
vtkm::Float32 divFactor = 2.f;
|
||||
//find the split position using a binary search
|
||||
for (vtkm::Int32 t = (vtkm::Int32)ceil(vtkm::Float32(l) / divFactor);;
|
||||
divFactor *= 2, t = (vtkm::Int32)ceil(vtkm::Float32(l) / divFactor))
|
||||
{
|
||||
if (delta(idx, idx + (s + t) * d) > deltaNode)
|
||||
if (delta(idx, idx + (s + t) * d, mortonCodePortal) > deltaNode)
|
||||
{
|
||||
s += t;
|
||||
}
|
||||
@ -529,13 +494,13 @@ public:
|
||||
if (vtkm::Min(idx, j) == split)
|
||||
{
|
||||
//leaf
|
||||
ParentPortal.Set(split + InnerCount, idx);
|
||||
parentPortal.Set(split + InnerCount, idx);
|
||||
leftChild = split + InnerCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
//inner node
|
||||
ParentPortal.Set(split, idx);
|
||||
parentPortal.Set(split, idx);
|
||||
leftChild = split;
|
||||
}
|
||||
|
||||
@ -543,77 +508,76 @@ public:
|
||||
if (vtkm::Max(idx, j) == split + 1)
|
||||
{
|
||||
//leaf
|
||||
ParentPortal.Set(split + InnerCount + 1, idx);
|
||||
parentPortal.Set(split + InnerCount + 1, idx);
|
||||
rightChild = split + InnerCount + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParentPortal.Set(split + 1, idx);
|
||||
parentPortal.Set(split + 1, idx);
|
||||
rightChild = split + 1;
|
||||
}
|
||||
}
|
||||
}; // class TreeBuilder
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void LinearBVHBuilder::SortAABBS(BVHData& bvh, Device device, bool singleAABB)
|
||||
VTKM_CONT void LinearBVHBuilder::SortAABBS(BVHData& bvh, bool singleAABB)
|
||||
{
|
||||
vtkm::worklet::Invoker invoke(device);
|
||||
|
||||
//create array of indexes to be sorted with morton codes
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> iterator;
|
||||
iterator.PrepareForOutput(bvh.GetNumberOfPrimitives(), device);
|
||||
invoke(CountingIterator{}, iterator);
|
||||
iterator.Allocate(bvh.GetNumberOfPrimitives());
|
||||
|
||||
vtkm::worklet::DispatcherMapField<CountingIterator> iterDispatcher;
|
||||
iterDispatcher.Invoke(iterator);
|
||||
|
||||
//sort the morton codes
|
||||
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::SortByKey(bvh.mortonCodes, iterator);
|
||||
vtkm::cont::Algorithm::SortByKey(bvh.mortonCodes, iterator);
|
||||
|
||||
vtkm::Id arraySize = bvh.GetNumberOfPrimitives();
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> temp1;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> temp2;
|
||||
temp1.Allocate(arraySize);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<GatherFloat32> gatherDispatcher;
|
||||
|
||||
//tempStorage = new vtkm::cont::ArrayHandle<vtkm::Float32>();
|
||||
//xmins
|
||||
invoke(GatherFloat32<Device>{ bvh.AABB.xmins, temp1, arraySize }, iterator);
|
||||
gatherDispatcher.Invoke(iterator, bvh.AABB.xmins, temp1);
|
||||
|
||||
temp2 = bvh.AABB.xmins;
|
||||
bvh.AABB.xmins = temp1;
|
||||
temp1 = temp2;
|
||||
//ymins
|
||||
invoke(GatherFloat32<Device>{ bvh.AABB.ymins, temp1, arraySize }, iterator);
|
||||
gatherDispatcher.Invoke(iterator, bvh.AABB.ymins, temp1);
|
||||
|
||||
temp2 = bvh.AABB.ymins;
|
||||
bvh.AABB.ymins = temp1;
|
||||
temp1 = temp2;
|
||||
//zmins
|
||||
invoke(GatherFloat32<Device>{ bvh.AABB.zmins, temp1, arraySize }, iterator);
|
||||
gatherDispatcher.Invoke(iterator, bvh.AABB.zmins, temp1);
|
||||
|
||||
temp2 = bvh.AABB.zmins;
|
||||
bvh.AABB.zmins = temp1;
|
||||
temp1 = temp2;
|
||||
//xmaxs
|
||||
invoke(GatherFloat32<Device>{ bvh.AABB.xmaxs, temp1, arraySize }, iterator);
|
||||
gatherDispatcher.Invoke(iterator, bvh.AABB.xmaxs, temp1);
|
||||
|
||||
temp2 = bvh.AABB.xmaxs;
|
||||
bvh.AABB.xmaxs = temp1;
|
||||
temp1 = temp2;
|
||||
//ymaxs
|
||||
invoke(GatherFloat32<Device>{ bvh.AABB.ymaxs, temp1, arraySize }, iterator);
|
||||
gatherDispatcher.Invoke(iterator, bvh.AABB.ymaxs, temp1);
|
||||
|
||||
temp2 = bvh.AABB.ymaxs;
|
||||
bvh.AABB.ymaxs = temp1;
|
||||
temp1 = temp2;
|
||||
//zmaxs
|
||||
invoke(GatherFloat32<Device>{ bvh.AABB.zmaxs, temp1, arraySize }, iterator);
|
||||
gatherDispatcher.Invoke(iterator, bvh.AABB.zmaxs, temp1);
|
||||
|
||||
temp2 = bvh.AABB.zmaxs;
|
||||
bvh.AABB.zmaxs = temp1;
|
||||
temp1 = temp2;
|
||||
|
||||
// Create the leaf references
|
||||
bvh.leafs.PrepareForOutput(arraySize * 2, Device());
|
||||
bvh.leafs.Allocate(arraySize * 2);
|
||||
// we only actually have a single primitive, but the algorithm
|
||||
// requires 2. Make sure they both point to the original
|
||||
// primitive
|
||||
@ -625,24 +589,15 @@ VTKM_CONT void LinearBVHBuilder::SortAABBS(BVHData& bvh, Device device, bool sin
|
||||
iterPortal.Set(i, 0);
|
||||
}
|
||||
}
|
||||
invoke(CreateLeafs{}, iterator, bvh.leafs);
|
||||
|
||||
vtkm::worklet::DispatcherMapField<CreateLeafs> leafDispatcher;
|
||||
leafDispatcher.Invoke(iterator, bvh.leafs);
|
||||
|
||||
} // method SortAABB
|
||||
|
||||
// Adding this as a template parameter to allow restricted types and
|
||||
// storage for dynamic coordinate system to limit crazy code bloat and
|
||||
// compile times.
|
||||
//
|
||||
template <typename Device>
|
||||
VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device)
|
||||
VTKM_CONT void LinearBVHBuilder::Build(LinearBVH& linearBVH)
|
||||
{
|
||||
vtkm::worklet::Invoker invoke(device);
|
||||
|
||||
Logger* logger = Logger::GetInstance();
|
||||
logger->OpenLogEntry("bvh_constuct");
|
||||
|
||||
vtkm::cont::Timer constructTimer{ Device() };
|
||||
constructTimer.Start();
|
||||
//
|
||||
//
|
||||
// This algorithm needs at least 2 AABBs
|
||||
@ -678,30 +633,20 @@ VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device
|
||||
}
|
||||
|
||||
|
||||
logger->AddLogData("bvh_num_aabbs", numberOfAABBs);
|
||||
|
||||
const vtkm::Id numBBoxes = numberOfAABBs;
|
||||
BVHData bvh(numBBoxes, linearBVH.GetAABBs(), device);
|
||||
BVHData bvh(numBBoxes, linearBVH.GetAABBs());
|
||||
|
||||
|
||||
vtkm::cont::Timer timer{ Device() };
|
||||
timer.Start();
|
||||
// Find the extent of all bounding boxes to generate normalization for morton codes
|
||||
vtkm::Vec<vtkm::Float32, 3> minExtent(vtkm::Infinity32(), vtkm::Infinity32(), vtkm::Infinity32());
|
||||
vtkm::Vec<vtkm::Float32, 3> maxExtent(
|
||||
vtkm::NegativeInfinity32(), vtkm::NegativeInfinity32(), vtkm::NegativeInfinity32());
|
||||
maxExtent[0] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.xmaxs, maxExtent[0], MaxValue());
|
||||
maxExtent[1] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.ymaxs, maxExtent[1], MaxValue());
|
||||
maxExtent[2] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.zmaxs, maxExtent[2], MaxValue());
|
||||
minExtent[0] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.xmins, minExtent[0], MinValue());
|
||||
minExtent[1] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.ymins, minExtent[1], MinValue());
|
||||
minExtent[2] =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(bvh.AABB.zmins, minExtent[2], MinValue());
|
||||
maxExtent[0] = vtkm::cont::Algorithm::Reduce(bvh.AABB.xmaxs, maxExtent[0], MaxValue());
|
||||
maxExtent[1] = vtkm::cont::Algorithm::Reduce(bvh.AABB.ymaxs, maxExtent[1], MaxValue());
|
||||
maxExtent[2] = vtkm::cont::Algorithm::Reduce(bvh.AABB.zmaxs, maxExtent[2], MaxValue());
|
||||
minExtent[0] = vtkm::cont::Algorithm::Reduce(bvh.AABB.xmins, minExtent[0], MinValue());
|
||||
minExtent[1] = vtkm::cont::Algorithm::Reduce(bvh.AABB.ymins, minExtent[1], MinValue());
|
||||
minExtent[2] = vtkm::cont::Algorithm::Reduce(bvh.AABB.zmins, minExtent[2], MinValue());
|
||||
|
||||
linearBVH.TotalBounds.X.Min = minExtent[0];
|
||||
linearBVH.TotalBounds.X.Max = maxExtent[0];
|
||||
@ -710,10 +655,6 @@ VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device
|
||||
linearBVH.TotalBounds.Z.Min = minExtent[2];
|
||||
linearBVH.TotalBounds.Z.Max = maxExtent[2];
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->AddLogData("calc_extents", time);
|
||||
timer.Start();
|
||||
|
||||
vtkm::Vec<vtkm::Float32, 3> deltaExtent = maxExtent - minExtent;
|
||||
vtkm::Vec<vtkm::Float32, 3> inverseExtent;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
@ -722,82 +663,50 @@ VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device
|
||||
}
|
||||
|
||||
//Generate the morton codes
|
||||
invoke(MortonCodeAABB{ inverseExtent, minExtent },
|
||||
bvh.AABB.xmins,
|
||||
bvh.AABB.ymins,
|
||||
bvh.AABB.zmins,
|
||||
bvh.AABB.xmaxs,
|
||||
bvh.AABB.ymaxs,
|
||||
bvh.AABB.zmaxs,
|
||||
bvh.mortonCodes);
|
||||
vtkm::worklet::DispatcherMapField<MortonCodeAABB> mortonDispatch(
|
||||
MortonCodeAABB(inverseExtent, minExtent));
|
||||
mortonDispatch.Invoke(bvh.AABB.xmins,
|
||||
bvh.AABB.ymins,
|
||||
bvh.AABB.zmins,
|
||||
bvh.AABB.xmaxs,
|
||||
bvh.AABB.ymaxs,
|
||||
bvh.AABB.zmaxs,
|
||||
bvh.mortonCodes);
|
||||
linearBVH.Allocate(bvh.GetNumberOfPrimitives());
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("morton_codes", time);
|
||||
timer.Start();
|
||||
SortAABBS(bvh, singleAABB);
|
||||
|
||||
linearBVH.Allocate(bvh.GetNumberOfPrimitives(), device);
|
||||
|
||||
SortAABBS(bvh, device, singleAABB);
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("sort_aabbs", time);
|
||||
timer.Start();
|
||||
|
||||
invoke(TreeBuilder<Device>{ bvh.mortonCodes, bvh.parent, bvh.GetNumberOfPrimitives() },
|
||||
bvh.leftChild,
|
||||
bvh.rightChild);
|
||||
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("build_tree", time);
|
||||
timer.Start();
|
||||
vtkm::worklet::DispatcherMapField<TreeBuilder> treeDispatch(
|
||||
TreeBuilder(bvh.GetNumberOfPrimitives()));
|
||||
treeDispatch.Invoke(bvh.leftChild, bvh.rightChild, bvh.mortonCodes, bvh.parent);
|
||||
|
||||
const vtkm::Int32 primitiveCount = vtkm::Int32(bvh.GetNumberOfPrimitives());
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Int32> counters;
|
||||
counters.PrepareForOutput(bvh.GetNumberOfPrimitives() - 1, device);
|
||||
counters.Allocate(bvh.GetNumberOfPrimitives() - 1);
|
||||
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Int32> zero(0, bvh.GetNumberOfPrimitives() - 1);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Copy(zero, counters);
|
||||
vtkm::cont::Algorithm::Copy(zero, counters);
|
||||
|
||||
vtkm::cont::AtomicArray<vtkm::Int32> atomicCounters(counters);
|
||||
vtkm::worklet::DispatcherMapField<PropagateAABBs> propDispatch(PropagateAABBs{ primitiveCount });
|
||||
|
||||
|
||||
PropagateAABBs<Device> propagateWorklet(
|
||||
bvh.parent, bvh.leftChild, bvh.rightChild, primitiveCount, linearBVH.FlatBVH, atomicCounters);
|
||||
invoke(propagateWorklet,
|
||||
bvh.AABB.xmins,
|
||||
bvh.AABB.ymins,
|
||||
bvh.AABB.zmins,
|
||||
bvh.AABB.xmaxs,
|
||||
bvh.AABB.ymaxs,
|
||||
bvh.AABB.zmaxs,
|
||||
bvh.leafOffsets);
|
||||
propDispatch.Invoke(bvh.AABB.xmins,
|
||||
bvh.AABB.ymins,
|
||||
bvh.AABB.zmins,
|
||||
bvh.AABB.xmaxs,
|
||||
bvh.AABB.ymaxs,
|
||||
bvh.AABB.zmaxs,
|
||||
bvh.leafOffsets,
|
||||
bvh.parent,
|
||||
bvh.leftChild,
|
||||
bvh.rightChild,
|
||||
counters,
|
||||
linearBVH.FlatBVH);
|
||||
|
||||
linearBVH.Leafs = bvh.leafs;
|
||||
time = timer.GetElapsedTime();
|
||||
logger->AddLogData("propagate_aabbs", time);
|
||||
|
||||
time = constructTimer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
}
|
||||
} //namespace detail
|
||||
|
||||
struct LinearBVH::ConstructFunctor
|
||||
{
|
||||
LinearBVH* Self;
|
||||
VTKM_CONT
|
||||
ConstructFunctor(LinearBVH* self)
|
||||
: Self(self)
|
||||
{
|
||||
}
|
||||
template <typename Device>
|
||||
bool operator()(Device)
|
||||
{
|
||||
Self->ConstructOnDevice(Device());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
LinearBVH::LinearBVH()
|
||||
: IsConstructed(false)
|
||||
, CanConstruct(false){};
|
||||
@ -820,11 +729,11 @@ LinearBVH::LinearBVH(const LinearBVH& other)
|
||||
, CanConstruct(other.CanConstruct)
|
||||
{
|
||||
}
|
||||
template <typename Device>
|
||||
VTKM_CONT void LinearBVH::Allocate(const vtkm::Id& leafCount, Device deviceAdapter)
|
||||
|
||||
VTKM_CONT void LinearBVH::Allocate(const vtkm::Id& leafCount)
|
||||
{
|
||||
LeafCount = leafCount;
|
||||
FlatBVH.PrepareForOutput((leafCount - 1) * 4, deviceAdapter);
|
||||
FlatBVH.Allocate((leafCount - 1) * 4);
|
||||
}
|
||||
|
||||
void LinearBVH::Construct()
|
||||
@ -835,9 +744,8 @@ void LinearBVH::Construct()
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Linear BVH: coordinates and triangles must be set before calling construct!");
|
||||
|
||||
ConstructFunctor functor(this);
|
||||
vtkm::cont::TryExecute(functor);
|
||||
IsConstructed = true;
|
||||
detail::LinearBVHBuilder builder;
|
||||
builder.Build(*this);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -848,43 +756,22 @@ void LinearBVH::SetData(AABBs& aabbs)
|
||||
CanConstruct = true;
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
void LinearBVH::ConstructOnDevice(Device device)
|
||||
{
|
||||
Logger* logger = Logger::GetInstance();
|
||||
vtkm::cont::Timer timer{ Device() };
|
||||
timer.Start();
|
||||
logger->OpenLogEntry("bvh");
|
||||
if (!CanConstruct)
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Linear BVH: coordinates and triangles must be set before calling construct!");
|
||||
if (!IsConstructed)
|
||||
{
|
||||
detail::LinearBVHBuilder builder;
|
||||
builder.RunOnDevice(*this, device);
|
||||
IsConstructed = true;
|
||||
}
|
||||
|
||||
vtkm::Float64 time = timer.GetElapsedTime();
|
||||
logger->CloseLogEntry(time);
|
||||
}
|
||||
|
||||
// explicitly export
|
||||
template VTKM_RENDERING_EXPORT void LinearBVH::ConstructOnDevice<
|
||||
vtkm::cont::DeviceAdapterTagSerial>(vtkm::cont::DeviceAdapterTagSerial);
|
||||
#ifdef VTKM_ENABLE_TBB
|
||||
template VTKM_RENDERING_EXPORT void LinearBVH::ConstructOnDevice<vtkm::cont::DeviceAdapterTagTBB>(
|
||||
vtkm::cont::DeviceAdapterTagTBB);
|
||||
#endif
|
||||
#ifdef VTKM_ENABLE_OPENMP
|
||||
template VTKM_CONT_EXPORT void LinearBVH::ConstructOnDevice<vtkm::cont::DeviceAdapterTagOpenMP>(
|
||||
vtkm::cont::DeviceAdapterTagOpenMP);
|
||||
#endif
|
||||
#ifdef VTKM_ENABLE_CUDA
|
||||
template VTKM_RENDERING_EXPORT void LinearBVH::ConstructOnDevice<vtkm::cont::DeviceAdapterTagCuda>(
|
||||
vtkm::cont::DeviceAdapterTagCuda);
|
||||
#endif
|
||||
|
||||
//template VTKM_RENDERING_EXPORT void LinearBVH::ConstructOnDevice<
|
||||
// vtkm::cont::DeviceAdapterTagSerial>(vtkm::cont::DeviceAdapterTagSerial);
|
||||
//#ifdef VTKM_ENABLE_TBB
|
||||
//template VTKM_RENDERING_EXPORT void LinearBVH::ConstructOnDevice<vtkm::cont::DeviceAdapterTagTBB>(
|
||||
// vtkm::cont::DeviceAdapterTagTBB);
|
||||
//#endif
|
||||
//#ifdef VTKM_ENABLE_OPENMP
|
||||
//template VTKM_CONT_EXPORT void LinearBVH::ConstructOnDevice<vtkm::cont::DeviceAdapterTagOpenMP>(
|
||||
// vtkm::cont::DeviceAdapterTagOpenMP);
|
||||
//#endif
|
||||
//#ifdef VTKM_ENABLE_CUDA
|
||||
//template VTKM_RENDERING_EXPORT void LinearBVH::ConstructOnDevice<vtkm::cont::DeviceAdapterTagCuda>(
|
||||
// vtkm::cont::DeviceAdapterTagCuda);
|
||||
//#endif
|
||||
//
|
||||
VTKM_CONT
|
||||
bool LinearBVH::GetIsConstructed() const
|
||||
{
|
||||
@ -893,7 +780,7 @@ bool LinearBVH::GetIsConstructed() const
|
||||
|
||||
vtkm::Id LinearBVH::GetNumberOfAABBs() const
|
||||
{
|
||||
return AABB.xmins.GetPortalConstControl().GetNumberOfValues();
|
||||
return AABB.xmins.GetNumberOfValues();
|
||||
}
|
||||
|
||||
AABBs& LinearBVH::GetAABBs()
|
||||
|
@ -53,7 +53,6 @@ public:
|
||||
InnerNodesHandle FlatBVH;
|
||||
LeafNodesHandle Leafs;
|
||||
vtkm::Bounds TotalBounds;
|
||||
struct ConstructFunctor;
|
||||
vtkm::Id LeafCount;
|
||||
|
||||
protected:
|
||||
@ -69,8 +68,7 @@ public:
|
||||
VTKM_CONT
|
||||
LinearBVH(const LinearBVH& other);
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
VTKM_CONT void Allocate(const vtkm::Id& leafCount, DeviceAdapter deviceAdapter);
|
||||
VTKM_CONT void Allocate(const vtkm::Id& leafCount);
|
||||
|
||||
VTKM_CONT
|
||||
void Construct();
|
||||
@ -81,9 +79,6 @@ public:
|
||||
VTKM_CONT
|
||||
AABBs& GetAABBs();
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT void ConstructOnDevice(Device device);
|
||||
|
||||
VTKM_CONT
|
||||
bool GetIsConstructed() const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user