summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2020-11-12 15:19:35 +0000
committerazhirnov <zh1dron@gmail.com>2020-11-12 15:19:35 +0000
commit0f5eaa1eb5bf6cd85146a29bd988903e22084832 (patch)
tree6698b73bbafec6d0b7843b9af3964738dec48522 /Graphics/GraphicsEngine
parentMerge branch 'master' into ray_tracing (diff)
downloadDiligentCore-0f5eaa1eb5bf6cd85146a29bd988903e22084832.tar.gz
DiligentCore-0f5eaa1eb5bf6cd85146a29bd988903e22084832.zip
fixed and improved shader binding
Diffstat (limited to 'Graphics/GraphicsEngine')
-rw-r--r--Graphics/GraphicsEngine/include/BottomLevelASBase.hpp5
-rw-r--r--Graphics/GraphicsEngine/include/DeviceContextBase.hpp6
-rw-r--r--Graphics/GraphicsEngine/include/ShaderBindingTableBase.hpp136
-rw-r--r--Graphics/GraphicsEngine/include/TopLevelASBase.hpp104
-rw-r--r--Graphics/GraphicsEngine/interface/BottomLevelAS.h2
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h43
-rw-r--r--Graphics/GraphicsEngine/interface/ShaderBindingTable.h75
-rw-r--r--Graphics/GraphicsEngine/interface/TopLevelAS.h74
-rw-r--r--Graphics/GraphicsEngine/src/DeviceContextBase.cpp20
9 files changed, 254 insertions, 211 deletions
diff --git a/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp b/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp
index 4c09607b..d95595d6 100644
--- a/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp
+++ b/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp
@@ -216,6 +216,11 @@ public:
return m_GeometryCount;
}
+ Uint32 GetMaxGeometryCount() const
+ {
+ return this->m_Desc.TriangleCount + this->m_Desc.BoxCount;
+ }
+
private:
void CopyGeometryDescriptionUnsafe(const BottomLevelASDesc& SrcDesc, const BLASNameToIndex* pSrcNameToIndex) noexcept(false)
{
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
index fbdb8d8f..9735bce2 100644
--- a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
+++ b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
@@ -66,7 +66,7 @@ bool VerifyBeginRenderPassAttribs(const BeginRenderPassAttribs& Attribs);
bool VerifyStateTransitionDesc(const IRenderDevice* pDevice, const StateTransitionDesc& Barrier);
bool VerifyBuildBLASAttribs(const BuildBLASAttribs& Attribs);
-bool VerifyBuildTLASAttribs(const BuildTLASAttribs& Attribs, Uint32 PrevInstanceCount);
+bool VerifyBuildTLASAttribs(const BuildTLASAttribs& Attribs);
bool VerifyCopyBLASAttribs(const IRenderDevice* pDevice, const CopyBLASAttribs& Attribs);
bool VerifyCopyTLASAttribs(const CopyTLASAttribs& Attribs);
bool VerifyWriteBLASCompactedSizeAttribs(const IRenderDevice* pDevice, const WriteBLASCompactedSizeAttribs& Attribs);
@@ -1482,9 +1482,7 @@ bool DeviceContextBase<BaseInterface, ImplementationTraits>::BuildTLAS(const Bui
return false;
}
- const Uint32 InstCount = Attribs.pTLAS ? ValidatedCast<TopLevelASType>(Attribs.pTLAS)->GetInstanceCount() : 0;
-
- if (!VerifyBuildTLASAttribs(Attribs, InstCount))
+ if (!VerifyBuildTLASAttribs(Attribs))
return false;
#endif
diff --git a/Graphics/GraphicsEngine/include/ShaderBindingTableBase.hpp b/Graphics/GraphicsEngine/include/ShaderBindingTableBase.hpp
index d21d0094..9ac643c4 100644
--- a/Graphics/GraphicsEngine/include/ShaderBindingTableBase.hpp
+++ b/Graphics/GraphicsEngine/include/ShaderBindingTableBase.hpp
@@ -123,12 +123,6 @@ public:
}
- void DILIGENT_CALL_TYPE BindAll(const BindAllAttribs& Attribs) override final
- {
- // AZ TODO
- }
-
-
void DILIGENT_CALL_TYPE BindRayGenShader(const char* pShaderGroupName, const void* pData, Uint32 DataSize) override final
{
VERIFY_EXPR((pData == nullptr) == (DataSize == 0));
@@ -159,6 +153,30 @@ public:
}
+ void DILIGENT_CALL_TYPE BindHitGroupByIndex(Uint32 BindingIndex,
+ const char* pShaderGroupName,
+ const void* pData,
+ Uint32 DataSize) override final
+ {
+ VERIFY_EXPR((pData == nullptr) == (DataSize == 0));
+ VERIFY_EXPR((pData == nullptr) || (DataSize == this->m_ShaderRecordSize));
+
+ const size_t Stride = this->m_ShaderRecordStride;
+ const Uint32 GroupSize = this->m_pDevice->GetProperties().ShaderGroupHandleSize;
+ const size_t Offset = BindingIndex * Stride;
+
+ this->m_HitGroupsRecord.resize(std::max(this->m_HitGroupsRecord.size(), Offset + Stride), Uint8{EmptyElem});
+
+ this->m_pPSO->CopyShaderHandle(pShaderGroupName, this->m_HitGroupsRecord.data() + Offset, Stride);
+ std::memcpy(this->m_HitGroupsRecord.data() + Offset + GroupSize, pData, DataSize);
+ this->m_Changed = true;
+
+#ifdef DILIGENT_DEVELOPMENT
+ OnBindHitGroup(nullptr, BindingIndex);
+#endif
+ }
+
+
void DILIGENT_CALL_TYPE BindHitGroup(ITopLevelAS* pTLAS,
const char* pInstanceName,
const char* pGeometryName,
@@ -172,20 +190,22 @@ public:
VERIFY_EXPR(pTLAS != nullptr);
auto* const pTLASImpl = ValidatedCast<TopLevelASImplType>(pTLAS);
- const auto& Desc = pTLASImpl->GetInstanceDesc(pInstanceName);
+ const auto Info = pTLASImpl->GetBuildInfo();
+ const auto Desc = pTLASImpl->GetInstanceDesc(pInstanceName);
- VERIFY_EXPR(pTLASImpl->GetBindingMode() == SHADER_BINDING_MODE_PER_GEOMETRY);
- VERIFY_EXPR(RayOffsetInHitGroupIndex < pTLASImpl->GetHitShadersPerInstance());
- VERIFY_EXPR(Desc.ContributionToHitGroupIndex != INVALID_INDEX);
+ VERIFY_EXPR(Info.BindingMode == HIT_GROUP_BINDING_MODE_PER_GEOMETRY ||
+ Info.BindingMode == HIT_GROUP_BINDING_MODE_PER_MAX_GEOMETRY);
+ VERIFY_EXPR(RayOffsetInHitGroupIndex < Info.HitGroupStride);
+ VERIFY_EXPR(Desc.ContributionToHitGroupIndex != ~0u);
if (Desc.pBLAS == nullptr)
return; // this is a disabled instance
- const Uint32 InstanceIndex = Desc.ContributionToHitGroupIndex;
- const Uint32 GeometryIndex = Desc.pBLAS->GetGeometryIndex(pGeometryName);
+ const Uint32 InstanceOffset = Desc.ContributionToHitGroupIndex;
+ const Uint32 GeometryIndex = Desc.pBLAS->GetGeometryIndex(pGeometryName);
VERIFY_EXPR(GeometryIndex != INVALID_INDEX);
- const Uint32 Index = InstanceIndex + GeometryIndex * pTLASImpl->GetHitShadersPerInstance() + RayOffsetInHitGroupIndex;
+ const Uint32 Index = InstanceOffset + GeometryIndex * Info.HitGroupStride + RayOffsetInHitGroupIndex;
const size_t Stride = this->m_ShaderRecordStride;
const Uint32 GroupSize = this->m_pDevice->GetProperties().ShaderGroupHandleSize;
const size_t Offset = Index * Stride;
@@ -197,6 +217,7 @@ public:
this->m_Changed = true;
#ifdef DILIGENT_DEVELOPMENT
+ VERIFY_EXPR(Index >= Info.FirstContributionToHitGroupIndex && Index <= Info.LastContributionToHitGroupIndex);
OnBindHitGroup(pTLASImpl, Index);
#endif
}
@@ -210,51 +231,53 @@ public:
Uint32 DataSize) override final
{
VERIFY_EXPR((pData == nullptr) == (DataSize == 0));
+ VERIFY_EXPR((pData == nullptr) || (DataSize == this->m_ShaderRecordSize));
VERIFY_EXPR(pTLAS != nullptr);
auto* const pTLASImpl = ValidatedCast<TopLevelASImplType>(pTLAS);
- const auto& Desc = pTLASImpl->GetInstanceDesc(pInstanceName);
+ const auto Info = pTLASImpl->GetBuildInfo();
+ const auto Desc = pTLASImpl->GetInstanceDesc(pInstanceName);
- VERIFY_EXPR(pTLASImpl->GetBindingMode() == SHADER_BINDING_MODE_PER_GEOMETRY ||
- pTLASImpl->GetBindingMode() == SHADER_BINDING_MODE_PER_INSTANCE);
- VERIFY_EXPR(RayOffsetInHitGroupIndex < pTLASImpl->GetHitShadersPerInstance());
+ VERIFY_EXPR(Info.BindingMode == HIT_GROUP_BINDING_MODE_PER_GEOMETRY ||
+ Info.BindingMode == HIT_GROUP_BINDING_MODE_PER_MAX_GEOMETRY ||
+ Info.BindingMode == HIT_GROUP_BINDING_MODE_PER_INSTANCE);
+ VERIFY_EXPR(RayOffsetInHitGroupIndex < Info.HitGroupStride);
VERIFY_EXPR(Desc.ContributionToHitGroupIndex != INVALID_INDEX);
- const Uint32 InstanceIndex = Desc.ContributionToHitGroupIndex;
- Uint32 GeometryCount = 0;
+ const Uint32 InstanceOffset = Desc.ContributionToHitGroupIndex;
+ Uint32 GeometryCount = 0;
- switch (pTLASImpl->GetBindingMode())
+ switch (Info.BindingMode)
{
// clang-format off
- case SHADER_BINDING_MODE_PER_GEOMETRY: GeometryCount = Desc.pBLAS ? Desc.pBLAS->GetActualGeometryCount() : 0; break;
- case SHADER_BINDING_MODE_PER_INSTANCE: GeometryCount = 1; break;
- default: UNEXPECTED("unknown binding mode");
+ case HIT_GROUP_BINDING_MODE_PER_GEOMETRY: GeometryCount = Desc.pBLAS ? Desc.pBLAS->GetActualGeometryCount() : 0; break;
+ case HIT_GROUP_BINDING_MODE_PER_MAX_GEOMETRY: GeometryCount = Desc.pBLAS ? Desc.pBLAS->GetDesc().TriangleCount + Desc.pBLAS->GetDesc().BoxCount: 0; break;
+ case HIT_GROUP_BINDING_MODE_PER_INSTANCE: GeometryCount = 1; break;
+ default: UNEXPECTED("unknown binding mode");
// clang-format on
}
- VERIFY_EXPR((pData == nullptr) || (DataSize == this->m_ShaderRecordSize * GeometryCount));
-
- const Uint32 BeginIndex = InstanceIndex + RayOffsetInHitGroupIndex;
- const size_t EndIndex = InstanceIndex + GeometryCount * pTLASImpl->GetHitShadersPerInstance() + RayOffsetInHitGroupIndex;
+ const Uint32 BeginIndex = InstanceOffset;
+ const size_t EndIndex = InstanceOffset + GeometryCount * Info.HitGroupStride;
const Uint32 GroupSize = this->m_pDevice->GetProperties().ShaderGroupHandleSize;
const size_t Stride = this->m_ShaderRecordStride;
- const auto* DataPtr = static_cast<const Uint8*>(pData);
this->m_HitGroupsRecord.resize(std::max(this->m_HitGroupsRecord.size(), EndIndex * Stride), Uint8{EmptyElem});
+ this->m_Changed = true;
for (Uint32 i = 0; i < GeometryCount; ++i)
{
- size_t Offset = (BeginIndex + i) * Stride;
+ Uint32 Index = BeginIndex + i * Info.HitGroupStride + RayOffsetInHitGroupIndex;
+ size_t Offset = Index * Stride;
this->m_pPSO->CopyShaderHandle(pShaderGroupName, this->m_HitGroupsRecord.data() + Offset, Stride);
- std::memcpy(this->m_HitGroupsRecord.data() + Offset + GroupSize, DataPtr, this->m_ShaderRecordSize);
- DataPtr += this->m_ShaderRecordSize;
+ std::memcpy(this->m_HitGroupsRecord.data() + Offset + GroupSize, pData, DataSize);
#ifdef DILIGENT_DEVELOPMENT
+ VERIFY_EXPR(Index >= Info.FirstContributionToHitGroupIndex && Index <= Info.LastContributionToHitGroupIndex);
OnBindHitGroup(pTLASImpl, BeginIndex + i);
#endif
}
- this->m_Changed = true;
}
@@ -268,21 +291,22 @@ public:
VERIFY_EXPR((pData == nullptr) || (DataSize == this->m_ShaderRecordSize));
VERIFY_EXPR(pTLAS != nullptr);
- auto* pTLASImpl = ValidatedCast<TopLevelASImplType>(pTLAS);
- VERIFY_EXPR(pTLASImpl->GetBindingMode() == SHADER_BINDING_MODE_PER_GEOMETRY ||
- pTLASImpl->GetBindingMode() == SHADER_BINDING_MODE_PER_INSTANCE ||
- pTLASImpl->GetBindingMode() == SHADER_BINDING_MODE_PER_ACCEL_STRUCT);
- VERIFY_EXPR(RayOffsetInHitGroupIndex < pTLASImpl->GetHitShadersPerInstance());
-
- Uint32 FirstContributionToHitGroupIndex, LastContributionToHitGroupIndex;
- pTLASImpl->GetContributionToHitGroupIndex(FirstContributionToHitGroupIndex, LastContributionToHitGroupIndex);
+ auto* pTLASImpl = ValidatedCast<TopLevelASImplType>(pTLAS);
+ const auto Info = pTLASImpl->GetBuildInfo();
+ VERIFY_EXPR(Info.BindingMode == HIT_GROUP_BINDING_MODE_PER_GEOMETRY ||
+ Info.BindingMode == HIT_GROUP_BINDING_MODE_PER_MAX_GEOMETRY ||
+ Info.BindingMode == HIT_GROUP_BINDING_MODE_PER_INSTANCE ||
+ Info.BindingMode == HIT_GROUP_BINDING_MODE_PER_ACCEL_STRUCT);
+ VERIFY_EXPR(RayOffsetInHitGroupIndex < Info.HitGroupStride);
const Uint32 GroupSize = this->m_pDevice->GetProperties().ShaderGroupHandleSize;
const size_t Stride = this->m_ShaderRecordStride;
- this->m_HitGroupsRecord.resize(std::max(this->m_HitGroupsRecord.size(), (LastContributionToHitGroupIndex + 1) * Stride), Uint8{EmptyElem});
+ this->m_HitGroupsRecord.resize(std::max(this->m_HitGroupsRecord.size(), (Info.LastContributionToHitGroupIndex + 1) * Stride), Uint8{EmptyElem});
this->m_Changed = true;
- for (Uint32 Index = FirstContributionToHitGroupIndex; Index <= LastContributionToHitGroupIndex; ++Index)
+ for (Uint32 Index = RayOffsetInHitGroupIndex + Info.FirstContributionToHitGroupIndex;
+ Index <= Info.LastContributionToHitGroupIndex;
+ Index += Info.HitGroupStride)
{
const size_t Offset = Index * Stride;
this->m_pPSO->CopyShaderHandle(pShaderGroupName, this->m_HitGroupsRecord.data() + Offset, Stride);
@@ -315,6 +339,9 @@ public:
Bool DILIGENT_CALL_TYPE Verify(SHADER_BINDING_VALIDATION_FLAGS Flags) const override final
{
+#ifdef DILIGENT_DEVELOPMENT
+ static_assert(EmptyElem != 0, "must not be zero");
+
const auto Stride = this->m_ShaderRecordStride;
const auto ShSize = this->m_pDevice->GetProperties().ShaderGroupHandleSize;
const auto FindPattern = [&](const std::vector<Uint8>& Data, const char* GroupName) -> bool //
@@ -357,13 +384,17 @@ public:
return false;
}
-#ifdef DILIGENT_DEVELOPMENT
if (Flags & SHADER_BINDING_VALIDATION_TLAS)
{
for (size_t i = 0; i < m_DbgHitGroupBindings.size(); ++i)
{
auto& Binding = m_DbgHitGroupBindings[i];
auto pTLAS = Binding.pTLAS.Lock();
+ if (!Binding.IsBound)
+ {
+ LOG_INFO_MESSAGE("Shader binding table '", this->m_Desc.Name, "' is not valid: hit group at index (", i, ") is not bound");
+ return false;
+ }
if (!pTLAS)
{
LOG_INFO_MESSAGE("Shader binding table '", this->m_Desc.Name, "' is not valid: TLAS that was used to bind hit group at index (", i, ") was deleted");
@@ -377,7 +408,6 @@ public:
}
}
}
-#endif
bool valid = true;
valid = valid && FindPattern(m_RayGenShaderRecord, "ray generation");
@@ -385,6 +415,10 @@ public:
valid = valid && FindPattern(m_CallableShadersRecord, "callable");
valid = valid && FindPattern(m_HitGroupsRecord, "hit groups");
return valid;
+#else
+ return true;
+
+#endif // DILIGENT_DEVELOPMENT
}
@@ -486,7 +520,13 @@ protected:
Uint32 m_ShaderRecordStride = 0;
bool m_Changed = true;
+#ifdef DILIGENT_DEVELOPMENT
static constexpr Uint8 EmptyElem = 0xA7;
+#else
+ // In release mode clear uninitialized data by zeros.
+ // This makes shader inactive, wich hides errors but prevents crashes.
+ static constexpr Uint8 EmptyElem = 0;
+#endif
private:
#ifdef DILIGENT_DEVELOPMENT
@@ -494,16 +534,18 @@ private:
{
RefCntWeakPtr<TopLevelASImplType> pTLAS;
Uint32 Version = ~0u;
+ bool IsBound = false;
};
mutable std::vector<HitGroupBinding> m_DbgHitGroupBindings;
- void OnBindHitGroup(TopLevelASImplType* pTLAS, Uint32 Index)
+ void OnBindHitGroup(TopLevelASImplType* pTLAS, size_t Index)
{
- this->m_DbgHitGroupBindings.resize(Index + 1);
+ this->m_DbgHitGroupBindings.resize(std::max(this->m_DbgHitGroupBindings.size(), Index + 1));
auto& Binding = this->m_DbgHitGroupBindings[Index];
Binding.pTLAS = pTLAS;
- Binding.Version = pTLAS->GetVersion();
+ Binding.Version = pTLAS ? pTLAS->GetVersion() : ~0u;
+ Binding.IsBound = true;
}
#endif
};
diff --git a/Graphics/GraphicsEngine/include/TopLevelASBase.hpp b/Graphics/GraphicsEngine/include/TopLevelASBase.hpp
index 92182b60..006d876a 100644
--- a/Graphics/GraphicsEngine/include/TopLevelASBase.hpp
+++ b/Graphics/GraphicsEngine/include/TopLevelASBase.hpp
@@ -92,8 +92,8 @@ public:
bool SetInstanceData(const TLASBuildInstanceData* pInstances,
const Uint32 InstanceCount,
const Uint32 BaseContributionToHitGroupIndex,
- const Uint32 HitShadersPerInstance,
- const SHADER_BINDING_MODE BindingMode) noexcept
+ const Uint32 HitGroupStride,
+ const HIT_GROUP_BINDING_MODE BindingMode) noexcept
{
try
{
@@ -119,7 +119,7 @@ public:
Desc.pBLAS = ValidatedCast<BottomLevelASType>(Inst.pBLAS);
Desc.ContributionToHitGroupIndex = Inst.ContributionToHitGroupIndex;
Desc.InstanceIndex = i;
- CalculateHitGroupIndex(Desc, InstanceOffset, HitShadersPerInstance, BindingMode);
+ CalculateHitGroupIndex(Desc, InstanceOffset, HitGroupStride, BindingMode);
#ifdef DILIGENT_DEVELOPMENT
Desc.Version = Desc.pBLAS ? Desc.pBLAS->GetVersion() : ~0u;
@@ -131,10 +131,13 @@ public:
VERIFY_EXPR(this->m_StringPool.GetRemainingSize() == 0);
- this->m_HitShadersPerInstance = HitShadersPerInstance;
- this->m_FirstContributionToHitGroupIndex = BaseContributionToHitGroupIndex;
- this->m_LastContributionToHitGroupIndex = InstanceOffset;
- this->m_BindingMode = BindingMode;
+ InstanceOffset = InstanceOffset + (BindingMode == HIT_GROUP_BINDING_MODE_PER_ACCEL_STRUCT ? HitGroupStride : 0) - 1;
+
+ this->m_BuildInfo.HitGroupStride = HitGroupStride;
+ this->m_BuildInfo.FirstContributionToHitGroupIndex = BaseContributionToHitGroupIndex;
+ this->m_BuildInfo.LastContributionToHitGroupIndex = InstanceOffset;
+ this->m_BuildInfo.BindingMode = BindingMode;
+ this->m_BuildInfo.InstanceCount = InstanceCount;
#ifdef DILIGENT_DEVELOPMENT
this->m_DbgVersion.fetch_add(1);
@@ -154,9 +157,10 @@ public:
bool UpdateInstances(const TLASBuildInstanceData* pInstances,
const Uint32 InstanceCount,
const Uint32 BaseContributionToHitGroupIndex,
- const Uint32 HitShadersPerInstance,
- const SHADER_BINDING_MODE BindingMode) noexcept
+ const Uint32 HitGroupStride,
+ const HIT_GROUP_BINDING_MODE BindingMode) noexcept
{
+ VERIFY_EXPR(this->m_BuildInfo.InstanceCount == InstanceCount);
#ifdef DILIGENT_DEVELOPMENT
bool Changed = false;
#endif
@@ -180,7 +184,7 @@ public:
Desc.pBLAS = ValidatedCast<BottomLevelASType>(Inst.pBLAS);
Desc.ContributionToHitGroupIndex = Inst.ContributionToHitGroupIndex;
//Desc.InstanceIndex = i; // keep Desc.InstanceIndex unmodified
- CalculateHitGroupIndex(Desc, InstanceOffset, HitShadersPerInstance, BindingMode);
+ CalculateHitGroupIndex(Desc, InstanceOffset, HitGroupStride, BindingMode);
#ifdef DILIGENT_DEVELOPMENT
Changed = Changed || (pPrevBLAS != Inst.pBLAS);
@@ -190,18 +194,20 @@ public:
#endif
}
+ InstanceOffset = InstanceOffset + (BindingMode == HIT_GROUP_BINDING_MODE_PER_ACCEL_STRUCT ? HitGroupStride : 0) - 1;
+
#ifdef DILIGENT_DEVELOPMENT
- Changed = Changed || (this->m_HitShadersPerInstance != HitShadersPerInstance);
- Changed = Changed || (this->m_FirstContributionToHitGroupIndex != BaseContributionToHitGroupIndex);
- Changed = Changed || (this->m_LastContributionToHitGroupIndex != InstanceOffset);
- Changed = Changed || (this->m_BindingMode != BindingMode);
+ Changed = Changed || (this->m_BuildInfo.HitGroupStride != HitGroupStride);
+ Changed = Changed || (this->m_BuildInfo.FirstContributionToHitGroupIndex != BaseContributionToHitGroupIndex);
+ Changed = Changed || (this->m_BuildInfo.LastContributionToHitGroupIndex != InstanceOffset);
+ Changed = Changed || (this->m_BuildInfo.BindingMode != BindingMode);
if (Changed)
this->m_DbgVersion.fetch_add(1);
#endif
- this->m_HitShadersPerInstance = HitShadersPerInstance;
- this->m_FirstContributionToHitGroupIndex = BaseContributionToHitGroupIndex;
- this->m_LastContributionToHitGroupIndex = InstanceOffset;
- this->m_BindingMode = BindingMode;
+ this->m_BuildInfo.HitGroupStride = HitGroupStride;
+ this->m_BuildInfo.FirstContributionToHitGroupIndex = BaseContributionToHitGroupIndex;
+ this->m_BuildInfo.LastContributionToHitGroupIndex = InstanceOffset;
+ this->m_BuildInfo.BindingMode = BindingMode;
return true;
}
@@ -211,10 +217,7 @@ public:
ClearInstanceData();
this->m_StringPool.Reserve(Src.m_StringPool.GetReservedSize(), GetRawAllocator());
- this->m_HitShadersPerInstance = Src.m_HitShadersPerInstance;
- this->m_FirstContributionToHitGroupIndex = Src.m_FirstContributionToHitGroupIndex;
- this->m_LastContributionToHitGroupIndex = Src.m_LastContributionToHitGroupIndex;
- this->m_BindingMode = Src.m_BindingMode;
+ this->m_BuildInfo = Src.m_BuildInfo;
for (auto& SrcInst : Src.m_Instances)
{
@@ -229,21 +232,6 @@ public:
#endif
}
- Uint32 GetInstanceCount() const
- {
- return static_cast<Uint32>(this->m_Instances.size());
- }
-
- Uint32 GetHitShadersPerInstance() const
- {
- return this->m_HitShadersPerInstance;
- }
-
- SHADER_BINDING_MODE GetBindingMode() const
- {
- return this->m_BindingMode;
- }
-
virtual TLASInstanceDesc DILIGENT_CALL_TYPE GetInstanceDesc(const char* Name) const override final
{
VERIFY_EXPR(Name != nullptr && Name[0] != '\0');
@@ -268,13 +256,9 @@ public:
return Result;
}
- virtual void DILIGENT_CALL_TYPE GetContributionToHitGroupIndex(Uint32& FirstContributionToHitGroupIndex,
- Uint32& LastContributionToHitGroupIndex) const override final
+ virtual TLASBuildInfo DILIGENT_CALL_TYPE GetBuildInfo() const override final
{
- FirstContributionToHitGroupIndex = this->m_FirstContributionToHitGroupIndex;
- LastContributionToHitGroupIndex = this->m_LastContributionToHitGroupIndex;
-
- VERIFY_EXPR(FirstContributionToHitGroupIndex <= LastContributionToHitGroupIndex);
+ return m_BuildInfo;
}
virtual void DILIGENT_CALL_TYPE SetState(RESOURCE_STATE State) override final
@@ -356,15 +340,15 @@ private:
this->m_Instances.clear();
this->m_StringPool.Clear();
- this->m_BindingMode = SHADER_BINDING_MODE_LAST;
- this->m_HitShadersPerInstance = 0;
- this->m_FirstContributionToHitGroupIndex = INVALID_INDEX;
- this->m_LastContributionToHitGroupIndex = INVALID_INDEX;
+ this->m_BuildInfo.BindingMode = HIT_GROUP_BINDING_MODE_LAST;
+ this->m_BuildInfo.HitGroupStride = 0;
+ this->m_BuildInfo.FirstContributionToHitGroupIndex = INVALID_INDEX;
+ this->m_BuildInfo.LastContributionToHitGroupIndex = INVALID_INDEX;
}
- static void CalculateHitGroupIndex(InstanceDesc& Desc, Uint32& InstanceOffset, const Uint32 HitShadersPerInstance, const SHADER_BINDING_MODE BindingMode)
+ static void CalculateHitGroupIndex(InstanceDesc& Desc, Uint32& InstanceOffset, const Uint32 HitGroupStride, const HIT_GROUP_BINDING_MODE BindingMode)
{
- static_assert(SHADER_BINDING_MODE_LAST == SHADER_BINDING_USER_DEFINED, "Please update the switch below to handle the new shader binding mode");
+ static_assert(HIT_GROUP_BINDING_MODE_LAST == HIT_GROUP_BINDING_MODE_USER_DEFINED, "Please update the switch below to handle the new shader binding mode");
if (Desc.ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO)
{
@@ -372,17 +356,18 @@ private:
switch (BindingMode)
{
// clang-format off
- case SHADER_BINDING_MODE_PER_GEOMETRY: InstanceOffset += Desc.pBLAS ? Desc.pBLAS->GetActualGeometryCount() * HitShadersPerInstance : 0; break;
- case SHADER_BINDING_MODE_PER_INSTANCE: InstanceOffset += HitShadersPerInstance; break;
- case SHADER_BINDING_MODE_PER_ACCEL_STRUCT: /* InstanceOffset is a constant */ break;
- case SHADER_BINDING_USER_DEFINED: UNEXPECTED("TLAS_INSTANCE_OFFSET_AUTO is not compatible with SHADER_BINDING_USER_DEFINED"); break;
- default: UNEXPECTED("Unknown ray tracing shader binding mode");
+ case HIT_GROUP_BINDING_MODE_PER_GEOMETRY: InstanceOffset += Desc.pBLAS ? Desc.pBLAS->GetActualGeometryCount() * HitGroupStride : 0; break;
+ case HIT_GROUP_BINDING_MODE_PER_MAX_GEOMETRY: InstanceOffset += Desc.pBLAS ? Desc.pBLAS->GetMaxGeometryCount() * HitGroupStride : 0; break;
+ case HIT_GROUP_BINDING_MODE_PER_INSTANCE: InstanceOffset += HitGroupStride; break;
+ case HIT_GROUP_BINDING_MODE_PER_ACCEL_STRUCT: /* InstanceOffset is a constant */ break;
+ case HIT_GROUP_BINDING_MODE_USER_DEFINED: UNEXPECTED("TLAS_INSTANCE_OFFSET_AUTO is not compatible with HIT_GROUP_BINDING_MODE_USER_DEFINED"); break;
+ default: UNEXPECTED("Unknown ray tracing shader binding mode");
// clang-format on
}
}
else
{
- VERIFY(BindingMode == SHADER_BINDING_USER_DEFINED, "BindingMode must be SHADER_BINDING_USER_DEFINED");
+ VERIFY(BindingMode == HIT_GROUP_BINDING_MODE_USER_DEFINED, "BindingMode must be HIT_GROUP_BINDING_MODE_USER_DEFINED");
}
constexpr Uint32 MaxIndex = (1u << 24);
@@ -390,12 +375,9 @@ private:
}
protected:
- RESOURCE_STATE m_State = RESOURCE_STATE_UNKNOWN;
- SHADER_BINDING_MODE m_BindingMode = SHADER_BINDING_MODE_LAST;
- Uint32 m_HitShadersPerInstance = 0;
- Uint32 m_FirstContributionToHitGroupIndex = INVALID_INDEX;
- Uint32 m_LastContributionToHitGroupIndex = INVALID_INDEX;
- ScratchBufferSizes m_ScratchSize;
+ RESOURCE_STATE m_State = RESOURCE_STATE_UNKNOWN;
+ TLASBuildInfo m_BuildInfo;
+ ScratchBufferSizes m_ScratchSize;
std::unordered_map<HashMapStringKey, InstanceDesc, HashMapStringKey::Hasher> m_Instances;
StringPool m_StringPool;
diff --git a/Graphics/GraphicsEngine/interface/BottomLevelAS.h b/Graphics/GraphicsEngine/interface/BottomLevelAS.h
index 00c759e4..f7190c93 100644
--- a/Graphics/GraphicsEngine/interface/BottomLevelAS.h
+++ b/Graphics/GraphicsEngine/interface/BottomLevelAS.h
@@ -178,7 +178,7 @@ struct ScratchBufferSizes
{
/// Scratch buffer size for acceleration structure building,
/// see IDeviceContext::BuildBLAS(), IDeviceContext::BuildTLAS().
- /// May be zero if the structure was created with non-zero CompactedSize.
+ /// May be zero if the acceleration structure was created with non-zero CompactedSize.
Uint32 Build DEFAULT_INITIALIZER(0);
/// Scratch buffer size for acceleration structure updating,
diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h
index b8d95244..833c1dad 100644
--- a/Graphics/GraphicsEngine/interface/DeviceContext.h
+++ b/Graphics/GraphicsEngine/interface/DeviceContext.h
@@ -947,8 +947,8 @@ typedef struct BuildBLASAttribs BuildBLASAttribs;
/// For each instance in TLAS
/// if (Instance.ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO)
/// Instance.ContributionToHitGroupIndex = InstanceOffset;
-/// if (BindingMode == SHADER_BINDING_MODE_PER_GEOMETRY) InstanceOffset += Instance.pBLAS->GeometryCount() * HitShadersPerInstance;
-/// if (BindingMode == SHADER_BINDING_MODE_PER_INSTANCE) InstanceOffset += HitShadersPerInstance;
+/// if (BindingMode == HIT_GROUP_BINDING_MODE_PER_GEOMETRY) InstanceOffset += Instance.pBLAS->GeometryCount() * HitGroupStride;
+/// if (BindingMode == HIT_GROUP_BINDING_MODE_PER_INSTANCE) InstanceOffset += HitGroupStride;
static const Uint32 TLAS_INSTANCE_OFFSET_AUTO = ~0u;
@@ -1001,6 +1001,7 @@ struct TLASBuildInstanceData
/// Bottom-level AS that represents instance geometry.
/// Once built, TLAS will hold strong reference to pBLAS until next build or copy operation.
+ /// Can be null to disable instance.
/// Access to the BLAS must be externally synchronized.
IBottomLevelAS* pBLAS DEFAULT_INITIALIZER(nullptr);
@@ -1035,28 +1036,6 @@ typedef struct TLASBuildInstanceData TLASBuildInstanceData;
static const Uint32 TLAS_INSTANCE_DATA_SIZE = 64;
-/// Defines shader binding mode.
-DILIGENT_TYPED_ENUM(SHADER_BINDING_MODE, Uint8)
-{
- /// Each geometry in each instance can have a unique hit shader.
- /// See IShaderBindingTable::BindHitGroup().
- SHADER_BINDING_MODE_PER_GEOMETRY = 0,
-
- /// Each instance can have a unique hit shader. In this mode SBT buffer will use less memory.
- /// See IShaderBindingTable::BindHitGroups().
- SHADER_BINDING_MODE_PER_INSTANCE,
-
- /// Single hit shader for top-level acceleration structure.
- /// See IShaderBindingTable::BindHitGroupForAll().
- SHADER_BINDING_MODE_PER_ACCEL_STRUCT,
-
- /// The user must specify TLASBuildInstanceData::ContributionToHitGroupIndex and only use IShaderBindingTable::BindAll().
- SHADER_BINDING_USER_DEFINED,
-
- SHADER_BINDING_MODE_LAST = SHADER_BINDING_USER_DEFINED,
-};
-
-
/// This structure is used by IDeviceContext::BuildTLAS().
struct BuildTLASAttribs
{
@@ -1097,7 +1076,7 @@ struct BuildTLASAttribs
/// - Ignored if BindingMode is SHADER_BINDING_USER_DEFINED.
/// You should use the same value in a shader:
/// 'MultiplierForGeometryContributionToHitGroupIndex' argument in TraceRay() in HLSL, 'sbtRecordStride' argument in traceRay() in GLSL.
- Uint32 HitShadersPerInstance DEFAULT_INITIALIZER(1);
+ Uint32 HitGroupStride DEFAULT_INITIALIZER(1);
/// Base offset for hit group location.
/// Can be used to bind hit shaders for multiple acceleration structures, see IShaderBindingTable::BindHitGroup().
@@ -1107,7 +1086,7 @@ struct BuildTLASAttribs
/// Hit shader binding mode, see Diligent::SHADER_BINDING_MODE.
/// Used to calculate TLASBuildInstanceData::ContributionToHitGroupIndex.
- SHADER_BINDING_MODE BindingMode DEFAULT_INITIALIZER(SHADER_BINDING_MODE_PER_GEOMETRY);
+ HIT_GROUP_BINDING_MODE BindingMode DEFAULT_INITIALIZER(HIT_GROUP_BINDING_MODE_PER_GEOMETRY);
/// Buffer that is used for acceleration structure building.
/// Must be created with BIND_RAY_TRACING.
@@ -2160,6 +2139,9 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContext, IObject)
/// Builds a bottom-level acceleration structure with the specified geometries.
/// \param [in] Attribs - Structure describing build BLAS command attributes, see Diligent::BuildBLASAttribs for details.
+ ///
+ /// \note Don't call build or copy operation on the same BLAS in a different contexts, because BLAS has CPU-side data
+ /// that will not match with GPU-side, so shader binding were incorrect.
VIRTUAL void METHOD(BuildBLAS)(THIS_
const BuildBLASAttribs REF Attribs) PURE;
@@ -2167,6 +2149,9 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContext, IObject)
/// Builds a top-level acceleration structure with the specified instances.
/// \param [in] Attribs - Structure describing build TLAS command attributes, see Diligent::BuildTLASAttribs for details.
+ ///
+ /// \note Don't call build or copy operation on the same TLAS in a different contexts, because TLAS has CPU-side data
+ /// that will not match with GPU-side, so shader binding were incorrect.
VIRTUAL void METHOD(BuildTLAS)(THIS_
const BuildTLASAttribs REF Attribs) PURE;
@@ -2174,6 +2159,9 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContext, IObject)
/// Copies data from one acceleration structure to another.
/// \param [in] Attribs - Structure describing copy BLAS command attributes, see Diligent::CopyBLASAttribs for details.
+ ///
+ /// \note Don't call build or copy operation on the same BLAS in a different contexts, because BLAS has CPU-side data
+ /// that will not match with GPU-side, so shader binding were incorrect.
VIRTUAL void METHOD(CopyBLAS)(THIS_
const CopyBLASAttribs REF Attribs) PURE;
@@ -2181,6 +2169,9 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContext, IObject)
/// Copies data from one acceleration structure to another.
/// \param [in] Attribs - Structure describing copy TLAS command attributes, see Diligent::CopyTLASAttribs for details.
+ ///
+ /// \note Don't call build or copy operation on the same TLAS in a different contexts, because TLAS has CPU-side data
+ /// that will not match with GPU-side, so shader binding were incorrect.
VIRTUAL void METHOD(CopyTLAS)(THIS_
const CopyTLASAttribs REF Attribs) PURE;
diff --git a/Graphics/GraphicsEngine/interface/ShaderBindingTable.h b/Graphics/GraphicsEngine/interface/ShaderBindingTable.h
index 6ec8e210..e79cb62a 100644
--- a/Graphics/GraphicsEngine/interface/ShaderBindingTable.h
+++ b/Graphics/GraphicsEngine/interface/ShaderBindingTable.h
@@ -78,38 +78,6 @@ DILIGENT_TYPED_ENUM(SHADER_BINDING_VALIDATION_FLAGS, Uint8)
DEFINE_FLAG_ENUM_OPERATORS(SHADER_BINDING_VALIDATION_FLAGS)
-/// AZ TODO
-struct BindAllAttribs
-{
- /// AZ TODO
- Uint32 RayGenShader DEFAULT_INITIALIZER(~0u);
- const void* RayGenSRData DEFAULT_INITIALIZER(nullptr); // optional, can be null
- Uint32 RayGenSRDataSize DEFAULT_INITIALIZER(0);
-
- /// AZ TODO
- const Uint32* MissShaders DEFAULT_INITIALIZER(nullptr);
- Uint32 MissShaderCount DEFAULT_INITIALIZER(0);
- const void* MissSRData DEFAULT_INITIALIZER(nullptr); // optional, can be null
- Uint32 MissSRDataSize DEFAULT_INITIALIZER(0); // stride will be calculated as (MissSRDataSize / MissShaderCount)
-
- /// AZ TODO
- const Uint32* CallableShaders DEFAULT_INITIALIZER(nullptr);
- Uint32 CallableShaderCount DEFAULT_INITIALIZER(0);
- const void* CallableSRData DEFAULT_INITIALIZER(nullptr); // optional, can be null
- Uint32 CallableSRDataSize DEFAULT_INITIALIZER(0); // stride will be calculated as (CallableSRDataSize / CallableShaderCount)
-
- /// AZ TODO
- const Uint32* HitGroups DEFAULT_INITIALIZER(nullptr); // optional, can be null
- Uint32 HitGroupCount DEFAULT_INITIALIZER(0);
- const void* HitSRData DEFAULT_INITIALIZER(nullptr); // optional, can be null
- Uint32 HitSRDataSize DEFAULT_INITIALIZER(0); // stride will be calculated as (HitSRDataSize / HitGroupCount)
-
-#if DILIGENT_CPP_INTERFACE
- BindAllAttribs() noexcept {}
-#endif
-};
-typedef struct BindAllAttribs BindAllAttribs;
-
#define DILIGENT_INTERFACE_NAME IShaderBindingTable
#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
@@ -207,6 +175,24 @@ DILIGENT_BEGIN_INTERFACE(IShaderBindingTable, IDeviceObject)
Uint32 DataSize DEFAULT_INITIALIZER(0)) PURE;
+ /// Bind hit group to specified location.
+
+ /// \param [in] BindingIndex - location of the hit group.
+ /// \param [in] pShaderGroupName - hit group name that specified in RayTracingTriangleHitShaderGroup::Name and RayTracingProceduralHitShaderGroup::Name,
+ /// can be null to make shader inactive.
+ /// \param [in] pData - shader record data, can be null.
+ /// \param [in] DataSize - shader record data size, should equal to RayTracingPipelineDesc::ShaderRecordSize.
+ ///
+ /// \note Access to the SBT must be externally synchronized.
+ ///
+ /// \remarks Use IBottomLevelAS::GetGeometryIndex(), ITopLevelAS::GetBuildInfo(), ITopLevelAS::GetInstanceDesc().ContributionToHitGroupIndex to calculate binding index.
+ VIRTUAL void METHOD(BindHitGroupByIndex)(THIS_
+ Uint32 BindingIndex,
+ const char* pShaderGroupName,
+ const void* pData DEFAULT_INITIALIZER(nullptr),
+ Uint32 DataSize DEFAULT_INITIALIZER(0)) PURE;
+
+
/// Bind hit group for each geometries in specified instance.
/// \param [in] pTLAS - Top-level AS, used to calculate offset for instance.
@@ -266,11 +252,6 @@ DILIGENT_BEGIN_INTERFACE(IShaderBindingTable, IDeviceObject)
Uint32 CallableIndex,
const void* pData DEFAULT_INITIALIZER(nullptr),
Uint32 DataSize DEFAULT_INITIALIZER(0)) PURE;
-
-
- /// AZ TODO
- VIRTUAL void METHOD(BindAll)(THIS_
- const BindAllAttribs REF Attribs) PURE;
};
DILIGENT_END_INTERFACE
@@ -280,16 +261,16 @@ DILIGENT_END_INTERFACE
// clang-format off
-# define IShaderBindingTable_Verify(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, Verify, This, __VA_ARGS__)
-# define IShaderBindingTable_Reset(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, Reset, This, __VA_ARGS__)
-# define IShaderBindingTable_ResetHitGroups(This) CALL_IFACE_METHOD(ShaderBindingTable, ResetHitGroups, This)
-# define IShaderBindingTable_BindRayGenShader(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindRayGenShader, This, __VA_ARGS__)
-# define IShaderBindingTable_BindMissShader(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindMissShader, This, __VA_ARGS__)
-# define IShaderBindingTable_BindHitGroup(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindHitGroup, This, __VA_ARGS__)
-# define IShaderBindingTable_BindHitGroups(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindHitGroups, This, __VA_ARGS__)
-# define IShaderBindingTable_BindHitGroupForAll(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindHitGroupForAll, This, __VA_ARGS__)
-# define IShaderBindingTable_BindCallableShader(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindCallableShader, This, __VA_ARGS__)
-# define IShaderBindingTable_BindAll(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindAll, This, __VA_ARGS__)
+# define IShaderBindingTable_Verify(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, Verify, This, __VA_ARGS__)
+# define IShaderBindingTable_Reset(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, Reset, This, __VA_ARGS__)
+# define IShaderBindingTable_ResetHitGroups(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, ResetHitGroups, This, __VA_ARGS__)
+# define IShaderBindingTable_BindRayGenShader(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindRayGenShader, This, __VA_ARGS__)
+# define IShaderBindingTable_BindMissShader(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindMissShader, This, __VA_ARGS__)
+# define IShaderBindingTable_BindHitGroupByIndex(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindHitGroupByIndex, This, __VA_ARGS__)
+# define IShaderBindingTable_BindHitGroup(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindHitGroup, This, __VA_ARGS__)
+# define IShaderBindingTable_BindHitGroups(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindHitGroups, This, __VA_ARGS__)
+# define IShaderBindingTable_BindHitGroupForAll(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindHitGroupForAll, This, __VA_ARGS__)
+# define IShaderBindingTable_BindCallableShader(This, ...) CALL_IFACE_METHOD(ShaderBindingTable, BindCallableShader, This, __VA_ARGS__)
// clang-format on
diff --git a/Graphics/GraphicsEngine/interface/TopLevelAS.h b/Graphics/GraphicsEngine/interface/TopLevelAS.h
index 802c2777..f5ced5ed 100644
--- a/Graphics/GraphicsEngine/interface/TopLevelAS.h
+++ b/Graphics/GraphicsEngine/interface/TopLevelAS.h
@@ -68,6 +68,56 @@ struct TopLevelASDesc DILIGENT_DERIVE(DeviceObjectAttribs)
typedef struct TopLevelASDesc TopLevelASDesc;
+/// Defines shader binding mode.
+DILIGENT_TYPED_ENUM(HIT_GROUP_BINDING_MODE, Uint8)
+{
+ /// Reserve space for actual geometry count for each instance in TLAS.
+ /// Each geometry can have unique hit shader group.
+ /// See IShaderBindingTable::BindHitGroup().
+ HIT_GROUP_BINDING_MODE_PER_GEOMETRY = 0,
+
+ /// Same as HIT_GROUP_BINDING_MODE_PER_GEOMETRY but space reserved for maximum number of geometries in instance.
+ /// This may be useful if you update instance with new BLAS with different number of geometries but with
+ /// same maximum geometry count that defined in BottomLevelASDesc::TriangleCount or BottomLevelASDesc::BoxCount.
+ /// See IShaderBindingTable::BindHitGroup().
+ HIT_GROUP_BINDING_MODE_PER_MAX_GEOMETRY,
+
+ /// Reserve space for each instance in TLAS so each instance can have a unique hit shader group.
+ /// In this mode SBT buffer will use less memory. See IShaderBindingTable::BindHitGroups().
+ HIT_GROUP_BINDING_MODE_PER_INSTANCE,
+
+ /// Reserve space for single hit group for each TLAS.
+ /// See IShaderBindingTable::BindHitGroupForAll().
+ HIT_GROUP_BINDING_MODE_PER_ACCEL_STRUCT,
+
+ /// The user must specify TLASBuildInstanceData::ContributionToHitGroupIndex and only use IShaderBindingTable::BindHitGroupByIndex().
+ HIT_GROUP_BINDING_MODE_USER_DEFINED,
+
+ HIT_GROUP_BINDING_MODE_LAST = HIT_GROUP_BINDING_MODE_USER_DEFINED,
+};
+
+
+/// Defines TLAS state that was used in the last build.
+struct TLASBuildInfo
+{
+ /// The number of instances, same as BuildTLASAttribs::InstanceCount.
+ Uint32 InstanceCount DEFAULT_INITIALIZER(0);
+
+ /// The number of hit shader groups, same as BuildTLASAttribs::HitGroupStride.
+ Uint32 HitGroupStride DEFAULT_INITIALIZER(0);
+
+ /// Hit shader binding mode, same as BuildTLASAttribs::BindingMode.
+ HIT_GROUP_BINDING_MODE BindingMode DEFAULT_INITIALIZER(HIT_GROUP_BINDING_MODE_PER_GEOMETRY);
+
+ /// First hit group location, same as BuildTLASAttribs::BaseContributionToHitGroupIndex.
+ Uint32 FirstContributionToHitGroupIndex DEFAULT_INITIALIZER(0);
+
+ /// Last hit group location.
+ Uint32 LastContributionToHitGroupIndex DEFAULT_INITIALIZER(0);
+};
+typedef struct TLASBuildInfo TLASBuildInfo;
+
+
/// Top-level AS instance description.
struct TLASInstanceDesc
{
@@ -117,17 +167,12 @@ DILIGENT_BEGIN_INTERFACE(ITopLevelAS, IDeviceObject)
const char* Name) CONST PURE;
- /// Returns the first and last hit group location that is calculated during build or update operation,
- /// see IDeviceContext::BuildTLAS().
+ /// Returns TLAS state after the last build or update operation.
- /// \param [out] FirstContributionToHitGroupIndex - Returns the BuildTLASAttribs::BaseContributionToHitGroupIndex value
- /// as used in last build or copy operation.
- /// \param [out] LastContributionToHitGroupIndex - Returns the maximum value that used in hit group shader location calculation.
+ /// \return TLASBuildInfo object, see Diligent::TLASBuildInfo.
///
/// \note Access to the TLAS must be externally synchronized.
- VIRTUAL void METHOD(GetContributionToHitGroupIndex)(THIS_
- Uint32 REF FirstContributionToHitGroupIndex,
- Uint32 REF LastContributionToHitGroupIndex) CONST PURE;
+ VIRTUAL TLASBuildInfo METHOD(GetBuildInfo)(THIS) CONST PURE;
/// Returns scratch buffer info for the current acceleration structure.
@@ -135,6 +180,7 @@ DILIGENT_BEGIN_INTERFACE(ITopLevelAS, IDeviceObject)
/// \return ScratchBufferSizes object, see Diligent::ScratchBufferSizes.
VIRTUAL ScratchBufferSizes METHOD(GetScratchBufferSizes)(THIS) CONST PURE;
+
/// Returns native acceleration structure handle specific to the underlying graphics API
/// \return pointer to ID3D12Resource interface, for D3D12 implementation\n
@@ -164,12 +210,12 @@ DILIGENT_END_INTERFACE
// clang-format off
-# define ITopLevelAS_GetInstanceDesc(This, ...) CALL_IFACE_METHOD(TopLevelAS, GetInstanceDesc, This, __VA_ARGS__)
-# define ITopLevelAS_GetContributionToHitGroupIndex(This, ...) CALL_IFACE_METHOD(TopLevelAS, GetContributionToHitGroupIndex, This, __VA_ARGS__)
-# define ITopLevelAS_GetScratchBufferSizes(This) CALL_IFACE_METHOD(TopLevelAS, GetScratchBufferSizes, This)
-# define ITopLevelAS_GetNativeHandle(This) CALL_IFACE_METHOD(TopLevelAS, GetNativeHandle, This)
-# define ITopLevelAS_SetState(This, ...) CALL_IFACE_METHOD(TopLevelAS, SetState, This, __VA_ARGS__)
-# define ITopLevelAS_GetState(This) CALL_IFACE_METHOD(TopLevelAS, GetState, This)
+# define ITopLevelAS_GetInstanceDesc(This, ...) CALL_IFACE_METHOD(TopLevelAS, GetInstanceDesc, This, __VA_ARGS__)
+# define ITopLevelAS_GetBuildInfo(This) CALL_IFACE_METHOD(TopLevelAS, GetBuildInfo, This)
+# define ITopLevelAS_GetScratchBufferSizes(This) CALL_IFACE_METHOD(TopLevelAS, GetScratchBufferSizes, This)
+# define ITopLevelAS_GetNativeHandle(This) CALL_IFACE_METHOD(TopLevelAS, GetNativeHandle, This)
+# define ITopLevelAS_SetState(This, ...) CALL_IFACE_METHOD(TopLevelAS, SetState, This, __VA_ARGS__)
+# define ITopLevelAS_GetState(This) CALL_IFACE_METHOD(TopLevelAS, GetState, This)
// clang-format on
diff --git a/Graphics/GraphicsEngine/src/DeviceContextBase.cpp b/Graphics/GraphicsEngine/src/DeviceContextBase.cpp
index c1ae6cf7..9a4f137f 100644
--- a/Graphics/GraphicsEngine/src/DeviceContextBase.cpp
+++ b/Graphics/GraphicsEngine/src/DeviceContextBase.cpp
@@ -484,7 +484,7 @@ bool VerifyBuildBLASAttribs(const BuildBLASAttribs& Attribs)
}
-bool VerifyBuildTLASAttribs(const BuildTLASAttribs& Attribs, Uint32 PrevInstanceCount)
+bool VerifyBuildTLASAttribs(const BuildTLASAttribs& Attribs)
{
#define CHECK_BUILD_TLAS_ATTRIBS(Expr, ...) CHECK_PARAMETER(Expr, "Build TLAS attribs are invalid: ", __VA_ARGS__)
@@ -493,8 +493,8 @@ bool VerifyBuildTLASAttribs(const BuildTLASAttribs& Attribs, Uint32 PrevInstance
CHECK_BUILD_TLAS_ATTRIBS(Attribs.pInstances != nullptr, "pInstances must not be null");
CHECK_BUILD_TLAS_ATTRIBS(Attribs.pInstanceBuffer != nullptr, "pInstanceBuffer must not be null");
- CHECK_BUILD_TLAS_ATTRIBS(Attribs.BindingMode == SHADER_BINDING_USER_DEFINED || Attribs.HitShadersPerInstance != 0,
- "HitShadersPerInstance must be greater than 0, if BindingMode is not SHADER_BINDING_USER_DEFINED");
+ CHECK_BUILD_TLAS_ATTRIBS(Attribs.BindingMode == HIT_GROUP_BINDING_MODE_USER_DEFINED || Attribs.HitGroupStride != 0,
+ "HitGroupStride must be greater than 0 if BindingMode is not HIT_GROUP_BINDING_MODE_USER_DEFINED");
const auto& TLASDesc = Attribs.pTLAS->GetDesc();
@@ -505,9 +505,11 @@ bool VerifyBuildTLASAttribs(const BuildTLASAttribs& Attribs, Uint32 PrevInstance
if (Attribs.Update)
{
CHECK_BUILD_TLAS_ATTRIBS((TLASDesc.Flags & RAYTRACING_BUILD_AS_ALLOW_UPDATE) == RAYTRACING_BUILD_AS_ALLOW_UPDATE,
- "Update is true, but TLAS was created without RAYTRACING_BUILD_AS_ALLOW_UPDATE flag");
+ "Update is true, but TLAS created without RAYTRACING_BUILD_AS_ALLOW_UPDATE flag");
+
+ const Uint32 PrevInstanceCount = Attribs.pTLAS->GetBuildInfo().InstanceCount;
CHECK_BUILD_TLAS_ATTRIBS(PrevInstanceCount == Attribs.InstanceCount,
- "Update is true, but InstanceCount (", Attribs.InstanceCount, ") does not match the previous value (", PrevInstanceCount, ")");
+ "Update is true, but InstanceCount (", Attribs.InstanceCount, ") does not match with the previous value (", PrevInstanceCount, ")");
}
const auto& InstDesc = Attribs.pInstanceBuffer->GetDesc();
@@ -533,18 +535,14 @@ bool VerifyBuildTLASAttribs(const BuildTLASAttribs& Attribs, Uint32 PrevInstance
const TLASInstanceDesc IDesc = Attribs.pTLAS->GetInstanceDesc(Inst.InstanceName);
CHECK_BUILD_TLAS_ATTRIBS(IDesc.InstanceIndex != INVALID_INDEX, "Update is true, but pInstances[", i, "].InstanceName does not exists");
}
- else
- {
- CHECK_BUILD_TLAS_ATTRIBS(Inst.pBLAS != nullptr, "pInstances[", i, "].pBLAS must not be null");
- }
if (Inst.ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO)
++AutoOffsetCounter;
- CHECK_BUILD_TLAS_ATTRIBS(Attribs.BindingMode == SHADER_BINDING_USER_DEFINED || Inst.ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO,
+ CHECK_BUILD_TLAS_ATTRIBS(Attribs.BindingMode == HIT_GROUP_BINDING_MODE_USER_DEFINED || Inst.ContributionToHitGroupIndex == TLAS_INSTANCE_OFFSET_AUTO,
"pInstances[", i,
"].ContributionToHitGroupIndex must be TLAS_INSTANCE_OFFSET_AUTO "
- "if BindingMode is not SHADER_BINDING_USER_DEFINED");
+ "if BindingMode is not HIT_GROUP_BINDING_MODE_USER_DEFINED");
}
CHECK_BUILD_TLAS_ATTRIBS(AutoOffsetCounter == 0 || AutoOffsetCounter == Attribs.InstanceCount,