Skip to content

Commit f065d7c

Browse files
author
devsh
committed
start going through the implementation
1 parent 1e3f5dd commit f065d7c

File tree

1 file changed

+196
-4
lines changed

1 file changed

+196
-4
lines changed

src/nbl/video/utilities/CAssetConverter.cpp

Lines changed: 196 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ bool CAssetConverter::patch_impl_t<ICPUSampler>::valid(const ILogicalDevice* dev
4040
return true;
4141
}
4242

43+
4344
CAssetConverter::patch_impl_t<ICPUShader>::patch_impl_t(const ICPUShader* shader) : stage(shader->getStage()) {}
4445
bool CAssetConverter::patch_impl_t<ICPUShader>::valid(const ILogicalDevice* device)
4546
{
@@ -99,6 +100,67 @@ bool CAssetConverter::patch_impl_t<ICPUBuffer>::valid(const ILogicalDevice* devi
99100
return true;
100101
}
101102

103+
bool CAssetConverter::acceleration_structure_patch_base::valid(const ILogicalDevice* device)
104+
{
105+
// note that we don't check the validity of things we don't patch, all the instance and geometry data, but it will be checked by the driver anyway during creation/build
106+
if (preference==BuildPreference::Invalid) // unititialized or just wrong
107+
return false;
108+
// just make the flags agree/canonicalize
109+
allowCompaction = allowCompaction || compactAfterBuild;
110+
// don't make invalid, just soft fail
111+
const auto& limits = device->getPhysicalDevice()->getLimits();
112+
if (allowDataAccess) // TODO: && !limits.rayTracingPositionFetch)
113+
allowDataAccess = false;
114+
const auto& features = device->getEnabledFeatures();
115+
if (hostBuild && !features.accelerationStructureHostCommands)
116+
hostBuild = false;
117+
return true;
118+
}
119+
CAssetConverter::patch_impl_t<ICPUBottomLevelAccelerationStructure>::patch_impl_t(const ICPUBottomLevelAccelerationStructure* blas)
120+
{
121+
const auto flags = blas->getBuildFlags();
122+
// straight up invalid
123+
if (flags.hasFlags(build_flags_t::PREFER_FAST_TRACE_BIT | build_flags_t::PREFER_FAST_BUILD_BIT))
124+
return;
125+
126+
allowUpdate = flags.hasFlags(build_flags_t::ALLOW_UPDATE_BIT);
127+
allowCompaction = flags.hasFlags(build_flags_t::ALLOW_COMPACTION_BIT);
128+
allowDataAccess = flags.hasFlags(build_flags_t::ALLOW_DATA_ACCESS_KHR);
129+
if (flags.hasFlags(build_flags_t::PREFER_FAST_TRACE_BIT))
130+
preference = BuildPreference::FastTrace;
131+
else if (flags.hasFlags(build_flags_t::PREFER_FAST_BUILD_BIT))
132+
preference = BuildPreference::FastBuild;
133+
else
134+
preference = BuildPreference::None;
135+
lowMemory = flags.hasFlags(build_flags_t::LOW_MEMORY_BIT);
136+
}
137+
bool CAssetConverter::patch_impl_t<ICPUBottomLevelAccelerationStructure>::valid(const ILogicalDevice* device)
138+
{
139+
return acceleration_structure_patch_base::valid(device);
140+
}
141+
CAssetConverter::patch_impl_t<ICPUTopLevelAccelerationStructure>::patch_impl_t(const ICPUTopLevelAccelerationStructure* blas)
142+
{
143+
const auto flags = blas->getBuildFlags();
144+
// straight up invalid
145+
if (flags.hasFlags(build_flags_t::PREFER_FAST_TRACE_BIT|build_flags_t::PREFER_FAST_BUILD_BIT))
146+
return;
147+
148+
allowUpdate = flags.hasFlags(build_flags_t::ALLOW_UPDATE_BIT);
149+
allowCompaction = flags.hasFlags(build_flags_t::ALLOW_COMPACTION_BIT);
150+
allowDataAccess = false;
151+
if (flags.hasFlags(build_flags_t::PREFER_FAST_TRACE_BIT))
152+
preference = BuildPreference::FastTrace;
153+
else if (flags.hasFlags(build_flags_t::PREFER_FAST_BUILD_BIT))
154+
preference = BuildPreference::FastBuild;
155+
else
156+
preference = BuildPreference::None;
157+
lowMemory = flags.hasFlags(build_flags_t::LOW_MEMORY_BIT);
158+
}
159+
bool CAssetConverter::patch_impl_t<ICPUTopLevelAccelerationStructure>::valid(const ILogicalDevice* device)
160+
{
161+
return acceleration_structure_patch_base::valid(device);
162+
}
163+
102164
// smol utility function
103165
template<typename Patch>
104166
void deduceMetaUsages(Patch& patch, const core::bitflag<IGPUImage::E_USAGE_FLAGS> usages, const E_FORMAT originalFormat, const bool hasDepthAspect=true)
@@ -330,6 +392,24 @@ class AssetVisitor : public CRTP
330392
patch.usage |= IGPUBuffer::E_USAGE_FLAGS::EUF_STORAGE_TEXEL_BUFFER_BIT;
331393
return descend<ICPUBuffer>(dep,std::move(patch));
332394
}
395+
inline bool impl(const instance_t<ICPUTopLevelAccelerationStructure>& instance, const CAssetConverter::patch_t<ICPUTopLevelAccelerationStructure>& userPatch)
396+
{
397+
const auto blasInstances = instance.asset->getInstances();
398+
if (blasInstances.empty()) // TODO: is it valid to have a BLASless TLAS?
399+
return false;
400+
for (size_t i=0; i<blasInstances.size(); i++)
401+
{
402+
const auto* blas = blasInstances[i].getBase().blas.get();
403+
if (!blas)
404+
return false;
405+
CAssetConverter::patch_t<ICPUBottomLevelAccelerationStructure> patch = {blas};
406+
if (userPatch.allowDataAccess) // TODO: check if all BLAS within TLAS need to have the flag ON vs OFF or only some
407+
patch.allowDataAccess = true;
408+
if (!descend(blas,std::move(patch),i))
409+
return false;
410+
}
411+
return true;
412+
}
333413
inline bool impl(const instance_t<ICPUImageView>& instance, const CAssetConverter::patch_t<ICPUImageView>& userPatch)
334414
{
335415
const auto& params = instance.asset->getCreationParameters();
@@ -556,8 +636,10 @@ class AssetVisitor : public CRTP
556636
}
557637
case IDescriptor::EC_ACCELERATION_STRUCTURE:
558638
{
559-
_NBL_TODO();
560-
[[fallthrough]];
639+
auto tlas = static_cast<const ICPUTopLevelAccelerationStructure*>(untypedDesc);
640+
if (!descend(tlas,{tlas},type,binding,el))
641+
return false;
642+
break;
561643
}
562644
default:
563645
assert(false);
@@ -845,6 +927,8 @@ class PatchOverride final : public CAssetConverter::CHashCache::IPatchOverride
845927
inline const patch_t<ICPUSampler>* operator()(const lookup_t<ICPUSampler>& lookup) const override {return impl(lookup);}
846928
inline const patch_t<ICPUShader>* operator()(const lookup_t<ICPUShader>& lookup) const override {return impl(lookup);}
847929
inline const patch_t<ICPUBuffer>* operator()(const lookup_t<ICPUBuffer>& lookup) const override {return impl(lookup);}
930+
inline const patch_t<ICPUBottomLevelAccelerationStructure>* operator()(const lookup_t<ICPUBottomLevelAccelerationStructure>& lookup) const override {return impl(lookup);}
931+
inline const patch_t<ICPUTopLevelAccelerationStructure>* operator()(const lookup_t<ICPUTopLevelAccelerationStructure>& lookup) const override {return impl(lookup);}
848932
inline const patch_t<ICPUImage>* operator()(const lookup_t<ICPUImage>& lookup) const override {return impl(lookup);}
849933
inline const patch_t<ICPUBufferView>* operator()(const lookup_t<ICPUBufferView>& lookup) const override {return impl(lookup);}
850934
inline const patch_t<ICPUImageView>* operator()(const lookup_t<ICPUImageView>& lookup) const override {return impl(lookup);}
@@ -955,6 +1039,68 @@ bool CAssetConverter::CHashCache::hash_impl::operator()(lookup_t<ICPUBuffer> loo
9551039
hasher.update(&patchedParams,sizeof(patchedParams)) << lookup.asset->getContentHash();
9561040
return true;
9571041
}
1042+
bool CAssetConverter::CHashCache::hash_impl::operator()(lookup_t<ICPUBottomLevelAccelerationStructure> lookup)
1043+
{
1044+
// extras from the patch
1045+
hasher << lookup.patch->hostBuild;
1046+
hasher << lookup.patch->compactAfterBuild;
1047+
// overriden flags
1048+
using build_flags_t = ICPUBottomLevelAccelerationStructure::BUILD_FLAGS;
1049+
constexpr build_flags_t OverridableMask = build_flags_t::LOW_MEMORY_BIT|build_flags_t::PREFER_FAST_TRACE_BIT|build_flags_t::PREFER_FAST_BUILD_BIT|build_flags_t::ALLOW_COMPACTION_BIT|build_flags_t::ALLOW_UPDATE_BIT|build_flags_t::ALLOW_DATA_ACCESS_KHR;
1050+
auto patchedBuildFlags = lookup.asset->getBuildFlags()&(~OverridableMask);
1051+
if (lookup.patch->lowMemory)
1052+
patchedBuildFlags |= build_flags_t::LOW_MEMORY_BIT;
1053+
if (lookup.patch->allowDataAccess)
1054+
patchedBuildFlags |= build_flags_t::ALLOW_DATA_ACCESS_KHR;
1055+
if (lookup.patch->allowCompaction)
1056+
patchedBuildFlags |= build_flags_t::ALLOW_COMPACTION_BIT;
1057+
if (lookup.patch->allowUpdate)
1058+
patchedBuildFlags |= build_flags_t::ALLOW_UPDATE_BIT;
1059+
switch (lookup.patch->preference)
1060+
{
1061+
case acceleration_structure_patch_base::BuildPreference::FastTrace:
1062+
patchedBuildFlags |= build_flags_t::PREFER_FAST_TRACE_BIT;
1063+
break;
1064+
case acceleration_structure_patch_base::BuildPreference::FastBuild:
1065+
patchedBuildFlags |= build_flags_t::PREFER_FAST_BUILD_BIT;
1066+
break;
1067+
default:
1068+
break;
1069+
}
1070+
hasher << patchedBuildFlags;
1071+
// TODO: hash the geometry metadata thats not already in the dependents (c.f. Renderpass, Descriptor Set)
1072+
return true;
1073+
}
1074+
bool CAssetConverter::CHashCache::hash_impl::operator()(lookup_t<ICPUTopLevelAccelerationStructure> lookup)
1075+
{
1076+
// extras from the patch
1077+
hasher << lookup.patch->hostBuild;
1078+
hasher << lookup.patch->compactAfterBuild;
1079+
// overriden flags
1080+
using build_flags_t = ICPUTopLevelAccelerationStructure::BUILD_FLAGS;
1081+
constexpr build_flags_t OverridableMask = build_flags_t::LOW_MEMORY_BIT|build_flags_t::PREFER_FAST_TRACE_BIT|build_flags_t::PREFER_FAST_BUILD_BIT|build_flags_t::ALLOW_COMPACTION_BIT|build_flags_t::ALLOW_UPDATE_BIT;
1082+
auto patchedBuildFlags = lookup.asset->getBuildFlags()&(~OverridableMask);
1083+
if (lookup.patch->lowMemory)
1084+
patchedBuildFlags |= build_flags_t::LOW_MEMORY_BIT;
1085+
if (lookup.patch->allowCompaction)
1086+
patchedBuildFlags |= build_flags_t::ALLOW_COMPACTION_BIT;
1087+
if (lookup.patch->allowUpdate)
1088+
patchedBuildFlags |= build_flags_t::ALLOW_UPDATE_BIT;
1089+
switch (lookup.patch->preference)
1090+
{
1091+
case acceleration_structure_patch_base::BuildPreference::FastTrace:
1092+
patchedBuildFlags |= build_flags_t::PREFER_FAST_TRACE_BIT;
1093+
break;
1094+
case acceleration_structure_patch_base::BuildPreference::FastBuild:
1095+
patchedBuildFlags |= build_flags_t::PREFER_FAST_BUILD_BIT;
1096+
break;
1097+
default:
1098+
break;
1099+
}
1100+
hasher << patchedBuildFlags;
1101+
// TODO: hash the instance metadata thats not already in the dependents (c.f. Renderpass, Descriptor Set)
1102+
return true;
1103+
}
9581104
bool CAssetConverter::CHashCache::hash_impl::operator()(lookup_t<ICPUImage> lookup)
9591105
{
9601106
// failed promotion
@@ -1366,8 +1512,8 @@ void CAssetConverter::CHashCache::eraseStale(const IPatchOverride* patchOverride
13661512
rehash.operator()<ICPUBufferView>();
13671513
rehash.operator()<ICPUImage>();
13681514
rehash.operator()<ICPUImageView>();
1369-
// rehash.operator()<ICPUBottomLevelAccelerationStructure>();
1370-
// rehash.operator()<ICPUTopLevelAccelerationStructure>();
1515+
rehash.operator()<ICPUBottomLevelAccelerationStructure>();
1516+
rehash.operator()<ICPUTopLevelAccelerationStructure>();
13711517
// only once all the descriptor types have been hashed, we can hash sets
13721518
rehash.operator()<ICPUDescriptorSet>();
13731519
// naturally any pipeline depends on shaders and pipeline cache
@@ -1417,6 +1563,52 @@ class GetDependantVisitBase
14171563
template<Asset AssetType>
14181564
class GetDependantVisit;
14191565

1566+
template<>
1567+
class GetDependantVisit<ICPUBottomLevelAccelerationStructure> : public GetDependantVisitBase<ICPUBottomLevelAccelerationStructure>
1568+
{
1569+
public:
1570+
SBufferRange<IGPUBuffer> underlying = {};
1571+
1572+
protected:
1573+
bool descend_impl(
1574+
const instance_t<AssetType>& user, const CAssetConverter::patch_t<AssetType>& userPatch,
1575+
const instance_t<ICPUBuffer>& dep, const CAssetConverter::patch_t<ICPUBuffer>& soloPatch
1576+
)
1577+
{
1578+
auto depObj = getDependant<ICPUBuffer>(dep,soloPatch);
1579+
if (!depObj)
1580+
return false;
1581+
underlying = {
1582+
.offset = user.asset->getOffsetInBuffer(),
1583+
.size = user.asset->getByteSize(),
1584+
.buffer = std::move(depObj)
1585+
};
1586+
return underlying.isValid();
1587+
}
1588+
};
1589+
template<>
1590+
class GetDependantVisit<ICPUTopLevelAccelerationStructure> : public GetDependantVisitBase<ICPUTopLevelAccelerationStructure>
1591+
{
1592+
public:
1593+
SBufferRange<IGPUBuffer> underlying = {};
1594+
1595+
protected:
1596+
bool descend_impl(
1597+
const instance_t<AssetType>& user, const CAssetConverter::patch_t<AssetType>& userPatch,
1598+
const instance_t<ICPUBuffer>& dep, const CAssetConverter::patch_t<ICPUBuffer>& soloPatch
1599+
)
1600+
{
1601+
auto depObj = getDependant<ICPUBuffer>(dep,soloPatch);
1602+
if (!depObj)
1603+
return false;
1604+
underlying = {
1605+
.offset = user.asset->getOffsetInBuffer(),
1606+
.size = user.asset->getByteSize(),
1607+
.buffer = std::move(depObj)
1608+
};
1609+
return underlying.isValid();
1610+
}
1611+
};
14201612
template<>
14211613
class GetDependantVisit<ICPUBufferView> : public GetDependantVisitBase<ICPUBufferView>
14221614
{

0 commit comments

Comments
 (0)