From 0f5eaa1eb5bf6cd85146a29bd988903e22084832 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 12 Nov 2020 18:19:35 +0300 Subject: fixed and improved shader binding --- .../GraphicsEngine/include/BottomLevelASBase.hpp | 5 + .../GraphicsEngine/include/DeviceContextBase.hpp | 6 +- .../include/ShaderBindingTableBase.hpp | 136 ++++++++++++++------- Graphics/GraphicsEngine/include/TopLevelASBase.hpp | 104 +++++++--------- Graphics/GraphicsEngine/interface/BottomLevelAS.h | 2 +- Graphics/GraphicsEngine/interface/DeviceContext.h | 43 +++---- .../GraphicsEngine/interface/ShaderBindingTable.h | 75 +++++------- Graphics/GraphicsEngine/interface/TopLevelAS.h | 74 ++++++++--- Graphics/GraphicsEngine/src/DeviceContextBase.cpp | 20 ++- 9 files changed, 254 insertions(+), 211 deletions(-) (limited to 'Graphics/GraphicsEngine') 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::BuildTLAS(const Bui return false; } - const Uint32 InstCount = Attribs.pTLAS ? ValidatedCast(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(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(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(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(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(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& 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 pTLAS; Uint32 Version = ~0u; + bool IsBound = false; }; mutable std::vector 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(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(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(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 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, -- cgit v1.2.3