diff options
| author | azhirnov <zh1dron@gmail.com> | 2020-11-07 19:34:49 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-11-10 03:43:28 +0000 |
| commit | 0f35896a60c4de02ccfc91ace18bcef4450fa4d9 (patch) | |
| tree | 86a772a36c6c2258949231b756970a621b69f82b /Graphics/GraphicsEngineVulkan | |
| parent | Corrected ray rtacing vertex format handling in D3D12 (diff) | |
| download | DiligentCore-0f35896a60c4de02ccfc91ace18bcef4450fa4d9.tar.gz DiligentCore-0f35896a60c4de02ccfc91ace18bcef4450fa4d9.zip | |
Added ability to update AS.
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
16 files changed, 259 insertions, 79 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp index 1a4eb2c1..85665f2c 100644 --- a/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/BottomLevelASVkImpl.hpp @@ -46,8 +46,12 @@ public: BottomLevelASVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, - const BottomLevelASDesc& Desc, - bool bIsDeviceInternal = false); + const BottomLevelASDesc& Desc); + BottomLevelASVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pRenderDeviceVk, + const BottomLevelASDesc& Desc, + RESOURCE_STATE InitialState, + VkAccelerationStructureKHR vkBLAS); ~BottomLevelASVkImpl(); /// Implementation of IBottomLevelAS::GetNativeHandle() in Vulkan backend. diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp index 8680b819..2aaf4c69 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp @@ -151,6 +151,18 @@ public: RESOURCE_STATE InitialState, IBuffer** ppBuffer) override final; + /// Implementation of IRenderDeviceVk::CreateBLASFromVulkanResource(). + virtual void DILIGENT_CALL_TYPE CreateBLASFromVulkanResource(VkAccelerationStructureKHR vkBLAS, + const BottomLevelASDesc& Desc, + RESOURCE_STATE InitialState, + IBottomLevelAS** ppBLAS) override final; + + /// Implementation of IRenderDeviceVk::CreateTLASFromVulkanResource(). + virtual void DILIGENT_CALL_TYPE CreateTLASFromVulkanResource(VkAccelerationStructureKHR vkTLAS, + const TopLevelASDesc& Desc, + RESOURCE_STATE InitialState, + ITopLevelAS** ppTLAS) override final; + /// Implementation of IRenderDevice::IdleGPU() in Vulkan backend. virtual void DILIGENT_CALL_TYPE IdleGPU() override final; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp index ab43ab80..6adc1677 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp @@ -34,16 +34,17 @@ #include "RenderDeviceVkImpl.hpp" #include "ShaderBindingTableVk.h" #include "ShaderBindingTableBase.hpp" +#include "TopLevelASVkImpl.hpp" #include "PipelineStateVkImpl.hpp" #include "VulkanUtilities/VulkanObjectWrappers.hpp" namespace Diligent { -class ShaderBindingTableVkImpl final : public ShaderBindingTableBase<IShaderBindingTableVk, PipelineStateVkImpl, RenderDeviceVkImpl> +class ShaderBindingTableVkImpl final : public ShaderBindingTableBase<IShaderBindingTableVk, PipelineStateVkImpl, TopLevelASVkImpl, RenderDeviceVkImpl> { public: - using TShaderBindingTableBase = ShaderBindingTableBase<IShaderBindingTableVk, PipelineStateVkImpl, RenderDeviceVkImpl>; + using TShaderBindingTableBase = ShaderBindingTableBase<IShaderBindingTableVk, PipelineStateVkImpl, TopLevelASVkImpl, RenderDeviceVkImpl>; ShaderBindingTableVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, @@ -51,9 +52,6 @@ public: bool bIsDeviceInternal = false); ~ShaderBindingTableVkImpl(); - virtual void DILIGENT_CALL_TYPE ResetHitGroups(Uint32 HitShadersPerInstance) override; - virtual void DILIGENT_CALL_TYPE BindAll(const BindAllAttribs& Attribs) override; - IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderBindingTableVk, TShaderBindingTableBase); }; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp index 44a377fd..97e3dead 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -396,6 +396,8 @@ public: bool IsUsingSeparateSamplers() const { return m_IsUsingSeparateSamplers; } + bool IsCompatibleWith(const ShaderResourceLayoutVk& ResLayout) const; + private: Uint32 GetResourceOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const { diff --git a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp index b55223df..a318085e 100644 --- a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp @@ -47,8 +47,12 @@ public: TopLevelASVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, - const TopLevelASDesc& Desc, - bool bIsDeviceInternal = false); + const TopLevelASDesc& Desc); + TopLevelASVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pRenderDeviceVk, + const TopLevelASDesc& Desc, + RESOURCE_STATE InitialState, + VkAccelerationStructureKHR vkTLAS); ~TopLevelASVkImpl(); IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_TopLevelASVk, TTopLevelASBase); diff --git a/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h b/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h index dfded94f..0d566e70 100644 --- a/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h +++ b/Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h @@ -112,6 +112,44 @@ DILIGENT_BEGIN_INTERFACE(IRenderDeviceVk, IRenderDevice) const BufferDesc REF BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer) PURE; + + /// Creates a bottom-level AS object from native Vulkan resource + + /// \param [in] vkBLAS - Vulkan acceleration structure handle. + /// \param [in] Desc - Bottom-level AS description. + /// \param [in] InitialState - Initial BLAS state. Can be RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_BUILD_AS_READ, RESOURCE_STATE_BUILD_AS_WRITE. + /// See Diligent::RESOURCE_STATE. + /// \param [out] ppBLAS - Address of the memory location where the pointer to the + /// bottom-level AS interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one reference. + /// \note Created bottom-level AS object does not take ownership of the Vulkan acceleration structure and will not + /// destroy it once released. The application must not destroy Vulkan acceleration structure while it is + /// in use by the engine. + VIRTUAL void METHOD(CreateBLASFromVulkanResource)(THIS_ + VkAccelerationStructureKHR vkBLAS, + const BottomLevelASDesc REF Desc, + RESOURCE_STATE InitialState, + IBottomLevelAS** ppBLAS) PURE; + + /// Creates a top-level AS object from native Vulkan resource + + /// \param [in] vkTLAS - Vulkan acceleration structure handle. + /// \param [in] Desc - Bottom-level AS description. + /// \param [in] InitialState - Initial TLAS state. Can be RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_BUILD_AS_READ, RESOURCE_STATE_BUILD_AS_WRITE, RESOURCE_STATE_RAY_TRACING. + /// See Diligent::RESOURCE_STATE. + /// \param [out] ppTLAS - Address of the memory location where the pointer to the + /// top-level AS interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one reference. + /// \note Created top-level AS object does not take ownership of the Vulkan acceleration structure and will not + /// destroy it once released. The application must not destroy Vulkan acceleration structure while it is + /// in use by the engine. + VIRTUAL void METHOD(CreateTLASFromVulkanResource)(THIS_ + VkAccelerationStructureKHR vkTLAS, + const TopLevelASDesc REF Desc, + RESOURCE_STATE InitialState, + ITopLevelAS** ppTLAS) PURE; }; DILIGENT_END_INTERFACE @@ -129,6 +167,8 @@ DILIGENT_END_INTERFACE # define IRenderDeviceVk_IsFenceSignaled(This, ...) CALL_IFACE_METHOD(RenderDeviceVk, IsFenceSignaled, This, __VA_ARGS__) # define IRenderDeviceVk_CreateTextureFromVulkanImage(This, ...) CALL_IFACE_METHOD(RenderDeviceVk, CreateTextureFromVulkanImage, This, __VA_ARGS__) # define IRenderDeviceVk_CreateBufferFromVulkanResource(This, ...) CALL_IFACE_METHOD(RenderDeviceVk, CreateBufferFromVulkanResource, This, __VA_ARGS__) +# define IRenderDeviceVk_CreateBLASFromVulkanResource(This, ...) CALL_IFACE_METHOD(RenderDeviceVk, CreateBLASFromVulkanResource, This, __VA_ARGS__) +# define IRenderDeviceVk_CreateTLASFromVulkanResource(This, ...) CALL_IFACE_METHOD(RenderDeviceVk, CreateTLASFromVulkanResource, This, __VA_ARGS__) // clang-format on diff --git a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp index 092da523..4e23a13a 100644 --- a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp @@ -34,9 +34,8 @@ namespace Diligent BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, - const BottomLevelASDesc& Desc, - bool bIsDeviceInternal) : - TBottomLevelASBase{pRefCounters, pRenderDeviceVk, Desc, bIsDeviceInternal} + const BottomLevelASDesc& Desc) : + TBottomLevelASBase{pRefCounters, pRenderDeviceVk, Desc} { const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice(); const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice(); @@ -152,6 +151,18 @@ BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters, SetState(RESOURCE_STATE_BUILD_AS_READ); } +BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pRenderDeviceVk, + const BottomLevelASDesc& Desc, + RESOURCE_STATE InitialState, + VkAccelerationStructureKHR vkBLAS) : + TBottomLevelASBase{pRefCounters, pRenderDeviceVk, Desc}, + m_VulkanBLAS{vkBLAS} +{ + SetState(InitialState); + m_DeviceAddress = pRenderDeviceVk->GetLogicalDevice().GetAccelerationStructureDeviceAddress(m_VulkanBLAS); +} + BottomLevelASVkImpl::~BottomLevelASVkImpl() { // Vk object can only be destroyed when it is no longer used by the GPU diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index ce9c639c..1b8b3e83 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -2815,21 +2815,23 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) { Geometries.resize(Attribs.TriangleDataCount); Offsets.resize(Attribs.TriangleDataCount); + pBLASVk->SetActualGeometryCount(Attribs.TriangleDataCount); for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i) { const auto& SrcTris = Attribs.pTriangleData[i]; - Uint32 GeoIdx = pBLASVk->GetGeometryIndex(SrcTris.GeometryName); + Uint32 Idx = i; + Uint32 GeoIdx = pBLASVk->UpdateGeometryIndex(SrcTris.GeometryName, Idx, Attribs.Update); - if (GeoIdx >= Geometries.size()) + if (GeoIdx == INVALID_INDEX || Idx == INVALID_INDEX) { UNEXPECTED("Failed to find geometry by name"); continue; } - auto& vkGeo = Geometries[GeoIdx]; + auto& vkGeo = Geometries[Idx]; auto& vkTris = vkGeo.geometry.triangles; - auto& off = Offsets[GeoIdx]; + auto& off = Offsets[Idx]; const auto& TriDesc = BLASDesc.pTriangles[GeoIdx]; vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; @@ -2886,21 +2888,23 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) { Geometries.resize(Attribs.BoxDataCount); Offsets.resize(Attribs.BoxDataCount); + pBLASVk->SetActualGeometryCount(Attribs.BoxDataCount); for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i) { const auto& SrcBoxes = Attribs.pBoxData[i]; - Uint32 GeoIdx = pBLASVk->GetGeometryIndex(SrcBoxes.GeometryName); + Uint32 Idx = i; + Uint32 GeoIdx = pBLASVk->UpdateGeometryIndex(SrcBoxes.GeometryName, Idx, Attribs.Update); - if (GeoIdx >= Geometries.size()) + if (GeoIdx == INVALID_INDEX || Idx == INVALID_INDEX) { UNEXPECTED("Failed to find geometry by name"); continue; } - auto& vkGeo = Geometries[GeoIdx]; + auto& vkGeo = Geometries[Idx]; auto& vkAABBs = vkGeo.geometry.aabbs; - auto& off = Offsets[GeoIdx]; + auto& off = Offsets[Idx]; vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; vkGeo.pNext = nullptr; @@ -2928,8 +2932,8 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) Info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; Info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; // type must be compatible with create info Info.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(BLASDesc.Flags); // flags must be compatible with create info - Info.update = VK_FALSE; - Info.srcAccelerationStructure = VK_NULL_HANDLE; + Info.update = Attribs.Update; + Info.srcAccelerationStructure = Attribs.Update ? pBLASVk->GetVkBLAS() : VK_NULL_HANDLE; Info.dstAccelerationStructure = pBLASVk->GetVkBLAS(); Info.geometryArrayOfPointers = VK_FALSE; Info.geometryCount = static_cast<uint32_t>(Geometries.size()); @@ -2963,7 +2967,16 @@ void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs) TransitionOrVerifyTLASState(*pTLASVk, Attribs.TLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); TransitionOrVerifyBufferState(*pScratchVk, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, OpName); - pTLASVk->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount, Attribs.HitShadersPerInstance); + if (Attribs.Update) + { + if (!pTLASVk->UpdateInstances(Attribs.pInstances, Attribs.InstanceCount, Attribs.BaseContributionToHitGroupIndex, Attribs.HitShadersPerInstance, Attribs.BindingMode)) + return; + } + else + { + if (!pTLASVk->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount, Attribs.BaseContributionToHitGroupIndex, Attribs.HitShadersPerInstance, Attribs.BindingMode)) + return; + } // copy instance data into instance buffer { @@ -2973,14 +2986,22 @@ void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs) for (Uint32 i = 0; i < Attribs.InstanceCount; ++i) { const auto& Inst = Attribs.pInstances[i]; - auto& vkASInst = static_cast<VkAccelerationStructureInstanceKHR*>(TmpSpace.CPUAddress)[i]; - auto* const pBLASVk = ValidatedCast<BottomLevelASVkImpl>(Inst.pBLAS); + const auto InstDesc = pTLASVk->GetInstanceDesc(Inst.InstanceName); + + if (InstDesc.InstanceIndex >= Attribs.InstanceCount) + { + UNEXPECTED("Failed to find instance by name"); + return; + } + + auto& vkASInst = static_cast<VkAccelerationStructureInstanceKHR*>(TmpSpace.CPUAddress)[InstDesc.InstanceIndex]; + auto* pBLASVk = ValidatedCast<BottomLevelASVkImpl>(Inst.pBLAS); static_assert(sizeof(vkASInst.transform) == sizeof(Inst.Transform), "size mismatch"); std::memcpy(&vkASInst.transform, Inst.Transform.data, sizeof(vkASInst.transform)); vkASInst.instanceCustomIndex = Inst.CustomId; - vkASInst.instanceShaderBindingTableRecordOffset = pTLASVk->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex; + vkASInst.instanceShaderBindingTableRecordOffset = InstDesc.ContributionToHitGroupIndex; vkASInst.mask = Inst.Mask; vkASInst.flags = InstanceFlagsToVkGeometryInstanceFlags(Inst.Flags); vkASInst.accelerationStructureReference = pBLASVk->GetVkDeviceAddress(); @@ -3014,8 +3035,8 @@ void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs) vkASBuildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; vkASBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; // type must be compatible with create info vkASBuildInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(TLASDesc.Flags); // flags must be compatible with create info - vkASBuildInfo.update = VK_FALSE; - vkASBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE; + vkASBuildInfo.update = Attribs.Update; + vkASBuildInfo.srcAccelerationStructure = Attribs.Update ? pTLASVk->GetVkTLAS() : VK_NULL_HANDLE; vkASBuildInfo.dstAccelerationStructure = pTLASVk->GetVkTLAS(); vkASBuildInfo.geometryArrayOfPointers = VK_FALSE; vkASBuildInfo.geometryCount = 1; @@ -3036,7 +3057,8 @@ void DeviceContextVkImpl::CopyBLAS(const CopyBLASAttribs& Attribs) // Dst BLAS description has specified CompactedSize, but doesn't have specified pTriangles and pBoxes. // We should copy geometries because it required for SBT to map geometry name to hit group. - pDstVk->CopyDescription(*pSrcVk); + pDstVk->CopyGeometryDescription(*pSrcVk); + pDstVk->SetActualGeometryCount(pSrcVk->GetActualGeometryCount()); VkCopyAccelerationStructureInfoKHR Info = {}; diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp index 189b1073..44cf52e3 100644 --- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -137,8 +137,12 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E try { + Uint32 Version = VK_API_VERSION_1_0; + if (EngineCI.Features.RayTracing != DEVICE_FEATURE_STATE_DISABLED) + Version = VK_API_VERSION_1_2; + auto Instance = VulkanUtilities::VulkanInstance::Create( - VK_API_VERSION_1_2, // AZ TODO: use 1.2 only for ray tracing, wave ops extensions + Version, EngineCI.EnableValidation, EngineCI.GlobalExtensionCount, EngineCI.ppGlobalExtensionNames, diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 6bfd4eeb..cfde6479 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -851,7 +851,7 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const return false; auto IsSamePipelineLayout = m_PipelineLayout.IsSameAs(pPSOVk->m_PipelineLayout); -#if 0 //def DILIGENT_DEBUG // AZ TODO +#ifdef DILIGENT_DEBUG { bool IsCompatibleShaders = true; if (GetNumShaderStages() != pPSOVk->GetNumShaderStages()) @@ -867,8 +867,8 @@ bool PipelineStateVkImpl::IsCompatibleWith(const IPipelineState* pPSO) const break; } - const auto& Res0 = GetShaderResLayout(s).GetResources(); - const auto& Res1 = pPSOVk->GetShaderResLayout(s).GetResources(); + const auto& Res0 = GetShaderResLayout(s); + const auto& Res1 = pPSOVk->GetShaderResLayout(s); if (!Res0.IsCompatibleWith(Res1)) { IsCompatibleShaders = false; diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index addf3440..620d29e9 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -754,6 +754,22 @@ void RenderDeviceVkImpl::CreateFramebuffer(const FramebufferDesc& Desc, IFramebu }); } +void RenderDeviceVkImpl::CreateBLASFromVulkanResource(VkAccelerationStructureKHR vkBLAS, + const BottomLevelASDesc& Desc, + RESOURCE_STATE InitialState, + IBottomLevelAS** ppBLAS) +{ + CreateDeviceObject( + "BottomLevelAS", Desc, ppBLAS, + [&]() // + { + BottomLevelASVkImpl* pBottomLevelASVk(NEW_RC_OBJ(m_BLASAllocator, "BottomLevelASVkImpl instance", BottomLevelASVkImpl)(this, Desc, InitialState, vkBLAS)); + pBottomLevelASVk->QueryInterface(IID_BottomLevelAS, reinterpret_cast<IObject**>(ppBLAS)); + OnCreateDeviceObject(pBottomLevelASVk); + } // + ); +} + void RenderDeviceVkImpl::CreateBLAS(const BottomLevelASDesc& Desc, IBottomLevelAS** ppBLAS) { @@ -766,6 +782,22 @@ void RenderDeviceVkImpl::CreateBLAS(const BottomLevelASDesc& Desc, }); } +void RenderDeviceVkImpl::CreateTLASFromVulkanResource(VkAccelerationStructureKHR vkTLAS, + const TopLevelASDesc& Desc, + RESOURCE_STATE InitialState, + ITopLevelAS** ppTLAS) +{ + CreateDeviceObject( + "TopLevelAS", Desc, ppTLAS, + [&]() // + { + TopLevelASVkImpl* pTopLevelASVk(NEW_RC_OBJ(m_BLASAllocator, "TopLevelASVkImpl instance", TopLevelASVkImpl)(this, Desc, InitialState, vkTLAS)); + pTopLevelASVk->QueryInterface(IID_TopLevelAS, reinterpret_cast<IObject**>(ppTLAS)); + OnCreateDeviceObject(pTopLevelASVk); + } // + ); +} + void RenderDeviceVkImpl::CreateTLAS(const TopLevelASDesc& Desc, ITopLevelAS** ppTLAS) { diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp index c0228146..194d15f4 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp @@ -45,16 +45,4 @@ ShaderBindingTableVkImpl::~ShaderBindingTableVkImpl() { } -void ShaderBindingTableVkImpl::ResetHitGroups(Uint32 HitShadersPerInstance) -{ - // AZ TODO - - m_Changed = true; -} - -void ShaderBindingTableVkImpl::BindAll(const BindAllAttribs& Attribs) -{ - // AZ TODO -} - } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp index 2e1039ba..26516695 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp @@ -166,9 +166,10 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl) { constexpr RESOURCE_STATE RequiredState = RESOURCE_STATE_CONSTANT_BUFFER; VERIFY_EXPR((ResourceStateFlagsToVkAccessFlags(RequiredState) & VK_ACCESS_UNIFORM_READ_BIT) == VK_ACCESS_UNIFORM_READ_BIT); + const bool IsInRequiredState = pBufferVk->CheckState(RequiredState); if (VerifyOnly) { - if (!pBufferVk->CheckState(RequiredState)) + if (!IsInRequiredState) { LOG_ERROR_MESSAGE("State of buffer '", pBufferVk->GetDesc().Name, "' is incorrect. Required state: ", GetResourceStateString(RequiredState), ". Actual state: ", @@ -180,7 +181,10 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl) } else { - pCtxVkImpl->TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RequiredState, true); + if (!IsInRequiredState) + { + pCtxVkImpl->TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RequiredState, true); + } VERIFY_EXPR(pBufferVk->CheckAccessFlags(VK_ACCESS_UNIFORM_READ_BIT)); } } @@ -207,10 +211,11 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl) (VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT); VERIFY_EXPR((ResourceStateFlagsToVkAccessFlags(RequiredState) & RequiredAccessFlags) == RequiredAccessFlags); #endif + const bool IsInRequiredState = pBufferVk->CheckState(RequiredState); if (VerifyOnly) { - if (!pBufferVk->CheckState(RequiredState)) + if (!IsInRequiredState) { LOG_ERROR_MESSAGE("State of buffer '", pBufferVk->GetDesc().Name, "' is incorrect. Required state: ", GetResourceStateString(RequiredState), ". Actual state: ", @@ -222,7 +227,12 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl) } else { - pCtxVkImpl->TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RequiredState, true); + // When both old and new states are RESOURCE_STATE_UNORDERED_ACCESS, we need to execute UAV barrier + // to make sure that all UAV writes are complete and visible. + if (!IsInRequiredState || RequiredState == RESOURCE_STATE_UNORDERED_ACCESS) + { + pCtxVkImpl->TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RequiredState, true); + } VERIFY_EXPR(pBufferVk->CheckAccessFlags(RequiredAccessFlags)); } } @@ -265,10 +275,11 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl) VERIFY_EXPR(ResourceStateToVkImageLayout(RequiredState) == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } } + const bool IsInRequiredState = pTextureVk->CheckState(RequiredState); if (VerifyOnly) { - if (!pTextureVk->CheckState(RequiredState)) + if (!IsInRequiredState) { LOG_ERROR_MESSAGE("State of texture '", pTextureVk->GetDesc().Name, "' is incorrect. Required state: ", GetResourceStateString(RequiredState), ". Actual state: ", @@ -280,7 +291,12 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl) } else { - pCtxVkImpl->TransitionTextureState(*pTextureVk, RESOURCE_STATE_UNKNOWN, RequiredState, true); + // When both old and new states are RESOURCE_STATE_UNORDERED_ACCESS, we need to execute UAV barrier + // to make sure that all UAV writes are complete and visible. + if (!IsInRequiredState || RequiredState == RESOURCE_STATE_UNORDERED_ACCESS) + { + pCtxVkImpl->TransitionTextureState(*pTextureVk, RESOURCE_STATE_UNKNOWN, RequiredState, true); + } } } } @@ -311,10 +327,11 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl) auto* pTLASVk = Res.pObject.RawPtr<TopLevelASVkImpl>(); if (pTLASVk != nullptr && pTLASVk->IsInKnownState()) { - constexpr RESOURCE_STATE RequiredState = RESOURCE_STATE_RAY_TRACING; + constexpr RESOURCE_STATE RequiredState = RESOURCE_STATE_RAY_TRACING; + const bool IsInRequiredState = pTLASVk->CheckState(RequiredState); if (VerifyOnly) { - if (!pTLASVk->CheckState(RequiredState)) + if (!IsInRequiredState) { LOG_ERROR_MESSAGE("State of TLAS '", pTLASVk->GetDesc().Name, "' is incorrect. Required state: ", GetResourceStateString(RequiredState), ". Actual state: ", @@ -323,15 +340,18 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl) "when calling IDeviceContext::CommitShaderResources() or explicitly transition the TLAS state " "with IDeviceContext::TransitionResourceStates()."); } - -#ifdef DILIGENT_DEVELOPMENT - pTLASVk->ValidateContent(); -#endif } else { - pCtxVkImpl->TransitionTLASState(*pTLASVk, RESOURCE_STATE_UNKNOWN, RequiredState, true); + if (!IsInRequiredState) + { + pCtxVkImpl->TransitionTLASState(*pTLASVk, RESOURCE_STATE_UNKNOWN, RequiredState, true); + } } + +#ifdef DILIGENT_DEVELOPMENT + pTLASVk->ValidateContent(); +#endif } } break; diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index ba8d567a..f45749e2 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -374,27 +374,26 @@ void ShaderResourceLayoutVk::dvpVerifyResourceLayoutDesc(const TShaderStages& std::string ShadersStr; while (Stages != SHADER_TYPE_UNKNOWN) { - const auto ShaderType = Stages & static_cast<SHADER_TYPE>(~(static_cast<Uint32>(Stages) - 1)); - const char* ShaderName = nullptr; + const auto ShaderType = Stages & static_cast<SHADER_TYPE>(~(static_cast<Uint32>(Stages) - 1)); + String ShaderName; - // AZ TODO - /*for (const auto& StageInfo : ShaderStages) + for (const auto& StageInfo : ShaderStages) { if ((Stages & StageInfo.Type) != 0) { - ShaderName = StageInfo.pShader->GetDesc().Name; + ShaderName = GetShaderGroupName(StageInfo.Shaders); break; } - }*/ + } if (!ShadersStr.empty()) ShadersStr.append(", "); ShadersStr.append(GetShaderTypeLiteralName(ShaderType)); ShadersStr.append(" ("); - if (ShaderName) + if (ShaderName.size()) { ShadersStr.push_back('\''); - ShadersStr.append(ShaderName ? ShaderName : "<Not enabled in PSO>"); + ShadersStr.append(ShaderName); ShadersStr.push_back('\''); } else @@ -829,10 +828,10 @@ void ShaderResourceLayoutVk::VkResource::CacheUniformBuffer(IDeviceObject* if (pBufferVk->GetDesc().uiSizeInBytes < BufferStaticSize) { - std::stringstream ss; - ss << "The size of buffer '" << pBufferVk->GetDesc().Name << "' (" << pBufferVk->GetDesc().uiSizeInBytes - << ") is not large enough for what the shader expects (" << BufferStaticSize << ")"; - LOG_ERROR_MESSAGE(ss.str()); + // It is OK if enabled robustBufferAccess feature, otherwise access outside of buffer range may lead to crash or undefined behavior. + LOG_WARNING_MESSAGE("Error binding uniform buffer '", pBufferVk->GetDesc().Name, "' to shader variable '", + Name, "' in shader '", ParentResLayout.GetShaderName(), "': buffer size in the shader (", + BufferStaticSize, ") is incompatible with the actual buffer size (", pBufferVk->GetDesc().uiSizeInBytes, ")."); } #endif @@ -888,11 +887,22 @@ void ShaderResourceLayoutVk::VkResource::CacheStorageBuffer(IDeviceObject* Name, "' in shader '", ParentResLayout.GetShaderName(), "': structured buffer view is expected."); } - if (ViewDesc.ByteWidth < BufferStaticSize || (ViewDesc.ByteWidth - BufferStaticSize) % BufferStride != 0) + if (BufferStride == 0 && ViewDesc.ByteWidth < BufferStaticSize) { - LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", - Name, "' in shader '", ParentResLayout.GetShaderName(), "': static buffer size in the shader (", - BufferStaticSize, ") and array element stride (", BufferStride, ") are incompatible with the actual buffer size (", ViewDesc.ByteWidth, ")."); + // It is OK if enabled robustBufferAccess feature, otherwise access outside of buffer range may lead to crash or undefined behavior. + LOG_WARNING_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", + Name, "' in shader '", ParentResLayout.GetShaderName(), "': buffer size in the shader (", + BufferStaticSize, ") is incompatible with the actual buffer view size (", ViewDesc.ByteWidth, ")."); + } + + if (BufferStride > 0 && (ViewDesc.ByteWidth < BufferStaticSize || (ViewDesc.ByteWidth - BufferStaticSize) % BufferStride != 0)) + { + // For buffers with dynamic arrays we know only static part size and array element stride. + // Element stride in shader may be differ than in code. Here we check that buffer size is exactly match to the array with N elements. + LOG_WARNING_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", + Name, "' in shader '", ParentResLayout.GetShaderName(), "': static buffer size in the shader (", + BufferStaticSize, ") and array element stride (", BufferStride, ") are incompatible with the actual buffer view size (", ViewDesc.ByteWidth, "),", + " this may be result of array element size mismatch."); } } } @@ -1117,7 +1127,7 @@ void ShaderResourceLayoutVk::VkResource::CacheAccelerationStructure(IDeviceObjec VERIFY(Type == SPIRVShaderResourceAttribs::ResourceType::AccelerationStructure, "Acceleration Structure resource is expected"); RefCntAutoPtr<TopLevelASVkImpl> pTLASVk{pTLAS, IID_TopLevelASVk}; #ifdef DILIGENT_DEVELOPMENT - // AZ TODO + VerifyTLASResourceBinding(*this, GetVariableType(), ArrayInd, pTLASVk.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); #endif if (UpdateCachedResource(DstRes, std::move(pTLASVk), [](const TopLevelASVkImpl*, const TopLevelASVkImpl*) {})) { @@ -1536,4 +1546,28 @@ void ShaderResourceLayoutVk::CommitDynamicResources(const ShaderResourceCacheVk& } } +bool ShaderResourceLayoutVk::IsCompatibleWith(const ShaderResourceLayoutVk& ResLayout) const +{ + if (m_NumResources != ResLayout.m_NumResources) + return false; + + bool IsCompatible = true; + for (Uint32 i = 0, Cnt = GetTotalResourceCount(); i < Cnt; ++i) + { + const auto& lhs = this->GetResource(i); + const auto& rhs = ResLayout.GetResource(i); + + // clang-format off + if (lhs.ArraySize != rhs.ArraySize || + lhs.Type != rhs.Type || + lhs.SamplerInd != rhs.SamplerInd) + // clang-format on + { + IsCompatible = false; + } + } + + return IsCompatible; +} + } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp index fbef736c..bfde3aa6 100644 --- a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp @@ -34,9 +34,8 @@ namespace Diligent TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, - const TopLevelASDesc& Desc, - bool bIsDeviceInternal) : - TTopLevelASBase{pRefCounters, pRenderDeviceVk, Desc, bIsDeviceInternal} + const TopLevelASDesc& Desc) : + TTopLevelASBase{pRefCounters, pRenderDeviceVk, Desc} { const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice(); const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice(); @@ -104,6 +103,17 @@ TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters, SetState(RESOURCE_STATE_BUILD_AS_READ); } +TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pRenderDeviceVk, + const TopLevelASDesc& Desc, + RESOURCE_STATE InitialState, + VkAccelerationStructureKHR vkTLAS) : + TTopLevelASBase{pRefCounters, pRenderDeviceVk, Desc}, + m_VulkanTLAS{vkTLAS} +{ + SetState(InitialState); +} + TopLevelASVkImpl::~TopLevelASVkImpl() { // Vk object can only be destroyed when it is no longer used by the GPU diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp index a80d7f73..fd81dcfb 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp @@ -189,7 +189,6 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice, // Emulate KHR extension if (m_ExtFeatures.RayTracingNV) { - //m_ExtFeatures.RayTracing.rayTracingPrimitiveCulling = true; // AZ TODO m_ExtFeatures.RayTracing.rayTracing = VK_TRUE; m_ExtProperties.RayTracing.shaderGroupHandleSize = RayTracingNV.shaderGroupHandleSize; |
