diff options
| author | azhirnov <zh1dron@gmail.com> | 2020-11-05 00:43:05 +0000 |
|---|---|---|
| committer | azhirnov <zh1dron@gmail.com> | 2020-11-05 00:53:36 +0000 |
| commit | 5e81b867be771dc7f2add0d7b403af4aeaa744db (patch) | |
| tree | 0f1f3835149f8887d80d558203956fcdbb233f60 /Graphics/GraphicsEngineVulkan | |
| parent | fixed compilation (diff) | |
| download | DiligentCore-5e81b867be771dc7f2add0d7b403af4aeaa744db.tar.gz DiligentCore-5e81b867be771dc7f2add0d7b403af4aeaa744db.zip | |
Added AS copy with compacting.
Added UB & SB size checks for Vulkan.
Some improvements for ray tracing & tests.
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
15 files changed, 303 insertions, 293 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp index 40e19d80..39dca08d 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp @@ -266,6 +266,12 @@ public: /// Implementation of IDeviceContext::CopyTLAS() in Vulkan backend. virtual void DILIGENT_CALL_TYPE CopyTLAS(const CopyTLASAttribs& Attribs) override final; + /// Implementation of IDeviceContext::WriteBLASCompactedSize() in Vulkan backend. + virtual void DILIGENT_CALL_TYPE WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs) override final; + + /// Implementation of IDeviceContext::WriteTLASCompactedSize() in Vulkan backend. + virtual void DILIGENT_CALL_TYPE WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs) override final; + /// Implementation of IDeviceContext::TraceRays() in Vulkan backend. virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final; @@ -470,6 +476,8 @@ private: void DvpLogRenderPass_PSOMismatch(); + void CreateASCompactedSizeQueryPool(); + VulkanUtilities::VulkanCommandBuffer m_CommandBuffer; const Uint32 m_NumCommandsToFlush = 192; @@ -551,6 +559,8 @@ private: Int32 m_ActiveQueriesCounter = 0; std::vector<VkClearValue> m_vkClearValues; + + VulkanUtilities::QueryPoolWrapper m_ASQueryPool; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp index 5440a6c8..556e3aa5 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp @@ -205,6 +205,15 @@ public: { return GetPhysicalDevice().GetExtProperties().RayTracing.maxShaderGroupStride; } + Uint32 GetShaderGroupBaseAlignment() const + { + return GetPhysicalDevice().GetExtProperties().RayTracing.shaderGroupBaseAlignment; + } + + Uint32 GetMaxDrawMeshTasksCount() const + { + return GetPhysicalDevice().GetExtProperties().MeshShader.maxDrawMeshTasksCount; + } private: template <typename PSOCreateInfoType> diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp index cef50a4e..ab43ab80 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderBindingTableVkImpl.hpp @@ -54,17 +54,7 @@ public: virtual void DILIGENT_CALL_TYPE ResetHitGroups(Uint32 HitShadersPerInstance) override; virtual void DILIGENT_CALL_TYPE BindAll(const BindAllAttribs& Attribs) override; - virtual void DILIGENT_CALL_TYPE GetVkStridedBufferRegions(IDeviceContextVk* pContext, - RESOURCE_STATE_TRANSITION_MODE TransitionMode, - VkStridedBufferRegionKHR& RaygenShaderBindingTable, - VkStridedBufferRegionKHR& MissShaderBindingTable, - VkStridedBufferRegionKHR& HitShaderBindingTable, - VkStridedBufferRegionKHR& CallableShaderBindingTable) override; - IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderBindingTableVk, TShaderBindingTableBase); - -private: - RefCntAutoPtr<IBuffer> m_pBuffer; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp index 44b75187..bee3de1f 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -197,6 +197,11 @@ public: /* 16 */ const char* const Name; /* 24 */ const ShaderResourceLayoutVk& ParentResLayout; + +#ifdef DILIGENT_DEBUG +/* 32 */ const Uint32 BufferStaticSize; +/* 36 */ const Uint32 BufferStride; +#endif // clang-format on VkResource(const ShaderResourceLayoutVk& _ParentLayout, @@ -210,7 +215,9 @@ public: uint32_t _DescriptorSet, Uint32 _CacheOffset, Uint32 _SamplerInd, - bool _ImmutableSamplerAssigned = false) noexcept : + bool _ImmutableSamplerAssigned, + Uint32 _BufferStaticSize, + Uint32 _BufferStride) noexcept : // clang-format off Binding {static_cast<decltype(Binding)>(_Binding) }, DescriptorSet {static_cast<decltype(DescriptorSet)>(_DescriptorSet)}, @@ -222,11 +229,15 @@ public: Type {_Type }, ResourceDim {_ResourceDim }, IsMS {_IsMS ? Uint8{1} : Uint8{0}}, - Name {_Name }, - ParentResLayout {_ParentLayout } +#ifdef DILIGENT_DEBUG + BufferStaticSize {_BufferStaticSize}, + BufferStride {_BufferStride }, +#endif + Name {_Name }, + ParentResLayout {_ParentLayout } // clang-format on { -#if defined(_MSC_VER) && defined(_WIN64) +#if defined(_MSC_VER) && defined(_WIN64) && !defined(DILIGENT_DEBUG) static_assert(sizeof(*this) == 32, "Unexpected sizeof(VkResource)"); #endif // clang-format off diff --git a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp index 0f8a94c8..8f2b42ab 100644 --- a/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/TopLevelASVkImpl.hpp @@ -58,7 +58,7 @@ public: virtual void* DILIGENT_CALL_TYPE GetNativeHandle() override final { auto Handle = GetVkTLAS(); - return reinterpret_cast<void*>(Handle); + return reinterpret_cast<void*>(Handle); // AZ TODO: fix for 32 bit platform } /// Implementation of ITopLevelASVk::GetVkTLAS(). diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp index 50a4c99f..8a21fb17 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp @@ -637,6 +637,21 @@ public: #endif } + __forceinline void WriteAccelerationStructuresProperties(VkAccelerationStructureKHR accelerationStructure, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery) + { +#if DILIGENT_USE_VOLK + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + if (m_State.RenderPass != VK_NULL_HANDLE) + { + // Write AS properties operations must be performed outside of render pass. + EndRenderPass(); + } + vkCmdWriteAccelerationStructuresPropertiesKHR(m_VkCmdBuffer, 1, &accelerationStructure, queryType, queryPool, firstQuery); +#else + UNSUPPORTED("Ray tracing is not supported when vulkan library is linked statically"); +#endif + } + __forceinline void TraceRays(const VkStridedBufferRegionKHR& RaygenShaderBindingTable, const VkStridedBufferRegionKHR& MissShaderBindingTable, const VkStridedBufferRegionKHR& HitShaderBindingTable, diff --git a/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h b/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h index d879faac..ee4ea3c8 100644 --- a/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h +++ b/Graphics/GraphicsEngineVulkan/interface/ShaderBindingTableVk.h @@ -50,14 +50,6 @@ static const INTERFACE_ID IID_ShaderBindingTableVk = /// Exposes Vulkan-specific functionality of a Shader binding table object. DILIGENT_BEGIN_INTERFACE(IShaderBindingTableVk, IShaderBindingTable) { - /// AZ TODO - VIRTUAL void METHOD(GetVkStridedBufferRegions)(THIS_ - IDeviceContextVk* pContext, - RESOURCE_STATE_TRANSITION_MODE TransitionMode, - VkStridedBufferRegionKHR REF RaygenShaderBindingTable, - VkStridedBufferRegionKHR REF MissShaderBindingTable, - VkStridedBufferRegionKHR REF HitShaderBindingTable, - VkStridedBufferRegionKHR REF CallableShaderBindingTable) PURE; }; DILIGENT_END_INTERFACE // clang-format on @@ -66,8 +58,6 @@ DILIGENT_END_INTERFACE #if DILIGENT_C_INTERFACE -# define IShaderBindingTableVk_GetVkStridedBufferRegions(This, ...) CALL_IFACE_METHOD(ShaderBindingTableVk, GetVkStridedBufferRegions, This, __VA_ARGS__) - #endif DILIGENT_END_NAMESPACE // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp index a1172130..cc16c9e4 100644 --- a/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/BottomLevelASVkImpl.cpp @@ -45,63 +45,69 @@ BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters, VkAccelerationStructureCreateInfoKHR CreateInfo = {}; std::vector<VkAccelerationStructureCreateGeometryTypeInfoKHR> Geometries; - CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR; - CreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; - CreateInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags); - CreateInfo.maxGeometryCount = std::max(m_Desc.BoxCount, m_Desc.TriangleCount); - CreateInfo.compactedSize = 0; // AZ TODO + CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR; + CreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; + CreateInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags); - VERIFY_EXPR(CreateInfo.maxGeometryCount <= Limits.maxGeometryCount); + if (m_Desc.CompactedSize > 0) + { + CreateInfo.compactedSize = m_Desc.CompactedSize; + } + else + { + CreateInfo.maxGeometryCount = m_Desc.TriangleCount + m_Desc.BoxCount; + Geometries.resize(CreateInfo.maxGeometryCount); + CreateInfo.pGeometryInfos = Geometries.data(); - Geometries.resize(CreateInfo.maxGeometryCount); - CreateInfo.pGeometryInfos = Geometries.data(); + VERIFY_EXPR(CreateInfo.maxGeometryCount <= Limits.maxGeometryCount); - // Specs says: the geometryType member of each geometry in pGeometries must be the same. - if (m_Desc.pTriangles != nullptr) - { - Uint32 MaxPrimitiveCount = 0; - for (uint32_t i = 0; i < m_Desc.TriangleCount; ++i) + if (m_Desc.pTriangles != nullptr) { - auto& src = m_Desc.pTriangles[i]; - auto& dst = Geometries[i]; - - dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; - dst.pNext = nullptr; - dst.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; - dst.maxPrimitiveCount = (src.IndexType == VT_UNDEFINED ? src.MaxVertexCount : src.MaxIndexCount) / 3; - dst.indexType = TypeToVkIndexType(src.IndexType); - dst.maxVertexCount = src.MaxVertexCount; - dst.vertexFormat = TypeToVkFormat(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); - dst.allowsTransforms = src.AllowsTransforms; - - MaxPrimitiveCount += dst.maxPrimitiveCount; + + Uint32 MaxPrimitiveCount = 0; + for (uint32_t i = 0; i < m_Desc.TriangleCount; ++i) + { + auto& src = m_Desc.pTriangles[i]; + auto& dst = Geometries[i]; + + dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; + dst.pNext = nullptr; + dst.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; + dst.maxPrimitiveCount = src.MaxPrimitiveCount; + dst.indexType = TypeToVkIndexType(src.IndexType); + dst.maxVertexCount = src.MaxVertexCount; + dst.vertexFormat = TypeToVkFormat(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); + dst.allowsTransforms = src.AllowsTransforms; + + MaxPrimitiveCount += dst.maxPrimitiveCount; + } + VERIFY_EXPR(MaxPrimitiveCount <= Limits.maxPrimitiveCount); } - VERIFY_EXPR(MaxPrimitiveCount <= Limits.maxPrimitiveCount); - } - else if (m_Desc.pBoxes != nullptr) - { - Uint32 MaxBoxCount = 0; - for (uint32_t i = 0; i < m_Desc.BoxCount; ++i) + else if (m_Desc.pBoxes != nullptr) { - auto& src = m_Desc.pBoxes[i]; - auto& dst = Geometries[i]; - - dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; - dst.pNext = nullptr; - dst.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR; - dst.maxPrimitiveCount = src.MaxBoxCount; - dst.indexType = VK_INDEX_TYPE_NONE_KHR; - dst.maxVertexCount = 0; - dst.vertexFormat = VK_FORMAT_UNDEFINED; - dst.allowsTransforms = VK_FALSE; - - MaxBoxCount += dst.maxPrimitiveCount; + Uint32 MaxBoxCount = 0; + for (uint32_t i = 0; i < m_Desc.BoxCount; ++i) + { + auto& src = m_Desc.pBoxes[i]; + auto& dst = Geometries[i]; + + dst.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; + dst.pNext = nullptr; + dst.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR; + dst.maxPrimitiveCount = src.MaxBoxCount; + dst.indexType = VK_INDEX_TYPE_NONE_KHR; + dst.maxVertexCount = 0; + dst.vertexFormat = VK_FORMAT_UNDEFINED; + dst.allowsTransforms = VK_FALSE; + + MaxBoxCount += dst.maxPrimitiveCount; + } + VERIFY_EXPR(MaxBoxCount <= Limits.maxPrimitiveCount); + } + else + { + UNEXPECTED("Either pTriangles or pBoxes must not be null"); } - VERIFY_EXPR(MaxBoxCount <= Limits.maxPrimitiveCount); - } - else - { - UNEXPECTED("Either pTriangles or pBoxes must not be null"); } m_VulkanBLAS = LogicalDevice.CreateAccelStruct(CreateInfo, m_Desc.Name); @@ -132,13 +138,18 @@ BottomLevelASVkImpl::BottomLevelASVkImpl(IReferenceCounters* pRefCounters, m_DeviceAddress = LogicalDevice.GetAccelerationStructureDeviceAddress(m_VulkanBLAS); - MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR; - MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); - m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size); + if (m_Desc.CompactedSize == 0) + { + MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR; + MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); + m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size); + + MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR; + MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); + m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size); + } - MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR; - MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); - m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size); + SetState(RESOURCE_STATE_BUILD_AS_READ); } BottomLevelASVkImpl::~BottomLevelASVkImpl() diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index a77fb96d..a76a901e 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -117,6 +117,8 @@ DeviceContextVkImpl::DeviceContextVkImpl(IReferenceCounters* p m_DummyVB = pDummyVB.RawPtr<BufferVkImpl>(); m_vkClearValues.reserve(16); + + CreateASCompactedSizeQueryPool(); } DeviceContextVkImpl::~DeviceContextVkImpl() @@ -592,16 +594,6 @@ void DeviceContextVkImpl::DrawMesh(const DrawMeshAttribs& Attribs) if (!DvpVerifyDrawMeshArguments(Attribs)) return; -#ifdef DILIGENT_DEBUG - { - const auto& PhysicalDevice = m_pDevice->GetPhysicalDevice(); - const auto& LogicalDevice = m_pDevice->GetLogicalDevice(); - const auto& MeshShaderFeats = LogicalDevice.GetEnabledExtFeatures().MeshShader; - VERIFY_EXPR(MeshShaderFeats.meshShader != VK_FALSE && MeshShaderFeats.taskShader != VK_FALSE); - VERIFY_EXPR(Attribs.ThreadGroupCount <= PhysicalDevice.GetExtProperties().MeshShader.maxDrawMeshTasksCount); - } -#endif - PrepareForDraw(Attribs.Flags); m_CommandBuffer.DrawMesh(Attribs.ThreadGroupCount, 0); @@ -613,13 +605,6 @@ void DeviceContextVkImpl::DrawMeshIndirect(const DrawMeshIndirectAttribs& Attrib if (!DvpVerifyDrawMeshIndirectArguments(Attribs, pAttribsBuffer)) return; -#ifdef DILIGENT_DEBUG - { - const auto& MeshShaderFeats = m_pDevice->GetLogicalDevice().GetEnabledExtFeatures().MeshShader; - VERIFY_EXPR(MeshShaderFeats.meshShader != VK_FALSE && MeshShaderFeats.taskShader != VK_FALSE); - } -#endif - // We must prepare indirect draw attribs buffer first because state transitions must // be performed outside of render pass, and PrepareForDraw commits render pass BufferVkImpl* pIndirectDrawAttribsVk = PrepareIndirectDrawAttribsBuffer(pAttribsBuffer, Attribs.IndirectAttribsBufferStateTransitionMode); @@ -2684,9 +2669,9 @@ void DeviceContextVkImpl::TransitionOrVerifyTLASState(TopLevelASVkImpl& DvpVerifyTLASState(TLAS, RequiredState, OperationName); } - if (RequiredState & RESOURCE_STATE_RAY_TRACING) + if (RequiredState & (RESOURCE_STATE_RAY_TRACING | RESOURCE_STATE_BUILD_AS_READ)) { - TLAS.CheckBLASVersion(); + TLAS.ValidateContent(); } #endif } @@ -2812,13 +2797,6 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) if (!TDeviceContextBase::BuildBLAS(Attribs, 0)) return; -#ifdef DILIGENT_DEBUG - { - const auto& LogicalDevice = m_pDevice->GetLogicalDevice(); - VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing != VK_FALSE); - } -#endif - auto* pBLASVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pBLAS); auto* pScratchVk = ValidatedCast<BufferVkImpl>(Attribs.pScratchBuffer); auto& BLASDesc = pBLASVk->GetDesc(); @@ -2842,9 +2820,6 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) { const auto& SrcTris = Attribs.pTriangleData[i]; Uint32 GeoIdx = pBLASVk->GetGeometryIndex(SrcTris.GeometryName); - auto& vkGeo = Geometries[GeoIdx]; - auto& vkTris = vkGeo.geometry.triangles; - auto& off = Offsets[GeoIdx]; if (GeoIdx >= Geometries.size()) { @@ -2852,6 +2827,11 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) continue; } + auto& vkGeo = Geometries[GeoIdx]; + auto& vkTris = vkGeo.geometry.triangles; + auto& off = Offsets[GeoIdx]; + const auto& TriDesc = BLASDesc.pTriangles[GeoIdx]; + vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; vkGeo.pNext = nullptr; vkGeo.flags = GeometryFlagsToVkGeometryFlags(SrcTris.Flags); @@ -2859,8 +2839,10 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) vkTris.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR; vkTris.pNext = nullptr; - auto* const pVB = ValidatedCast<BufferVkImpl>(SrcTris.pVertexBuffer); - vkTris.vertexFormat = TypeToVkFormat(SrcTris.VertexValueType, SrcTris.VertexComponentCount, SrcTris.VertexValueType < VT_FLOAT16); + auto* const pVB = ValidatedCast<BufferVkImpl>(SrcTris.pVertexBuffer); + + // vertex format in SrcTris may be undefined, so use vertex format from description + vkTris.vertexFormat = TypeToVkFormat(TriDesc.VertexValueType, TriDesc.VertexComponentCount, TriDesc.VertexValueType < VT_FLOAT16); vkTris.vertexStride = SrcTris.VertexStride; vkTris.vertexData.deviceAddress = pVB->GetVkDeviceAddress() + SrcTris.VertexOffset; @@ -2868,10 +2850,11 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) if (SrcTris.pIndexBuffer) { - auto* const pIB = ValidatedCast<BufferVkImpl>(SrcTris.pIndexBuffer); - vkTris.indexType = TypeToVkIndexType(SrcTris.IndexType); + auto* const pIB = ValidatedCast<BufferVkImpl>(SrcTris.pIndexBuffer); + + // index type in SrcTris may be undefined, so use index type from description + vkTris.indexType = TypeToVkIndexType(TriDesc.IndexType); vkTris.indexData.deviceAddress = pIB->GetVkDeviceAddress() + SrcTris.IndexOffset; - off.primitiveCount = SrcTris.IndexCount / 3; TransitionOrVerifyBufferState(*pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, OpName); } @@ -2879,13 +2862,10 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) { vkTris.indexType = VK_INDEX_TYPE_NONE_KHR; vkTris.indexData.deviceAddress = 0; - off.primitiveCount = SrcTris.VertexCount / 3; } if (SrcTris.pTransformBuffer) { - VERIFY_EXPR(BLASDesc.pTriangles[GeoIdx].AllowsTransforms); - auto* const pTB = ValidatedCast<BufferVkImpl>(SrcTris.pTransformBuffer); vkTris.transformData.deviceAddress = pTB->GetVkDeviceAddress() + SrcTris.TransformBufferOffset; @@ -2893,10 +2873,10 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) } else { - VERIFY_EXPR(!BLASDesc.pTriangles[GeoIdx].AllowsTransforms); vkTris.transformData.deviceAddress = 0; } + off.primitiveCount = SrcTris.PrimitiveCount; off.firstVertex = 0; off.primitiveOffset = 0; off.transformOffset = 0; @@ -2911,9 +2891,6 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) { const auto& SrcBoxes = Attribs.pBoxData[i]; Uint32 GeoIdx = pBLASVk->GetGeometryIndex(SrcBoxes.GeometryName); - auto& vkGeo = Geometries[GeoIdx]; - auto& vkAABBs = vkGeo.geometry.aabbs; - auto& off = Offsets[GeoIdx]; if (GeoIdx >= Geometries.size()) { @@ -2921,6 +2898,10 @@ void DeviceContextVkImpl::BuildBLAS(const BLASBuildAttribs& Attribs) continue; } + auto& vkGeo = Geometries[GeoIdx]; + auto& vkAABBs = vkGeo.geometry.aabbs; + auto& off = Offsets[GeoIdx]; + vkGeo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; vkGeo.pNext = nullptr; vkGeo.flags = GeometryFlagsToVkGeometryFlags(SrcBoxes.Flags); @@ -2971,13 +2952,6 @@ void DeviceContextVkImpl::BuildTLAS(const TLASBuildAttribs& Attribs) static_assert(TLAS_INSTANCE_DATA_SIZE == sizeof(VkAccelerationStructureInstanceKHR), "Value in TLAS_INSTANCE_DATA_SIZE doesn't match the actual instance description size"); -#ifdef DILIGENT_DEBUG - { - const auto& LogicalDevice = m_pDevice->GetLogicalDevice(); - VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing != VK_FALSE); - } -#endif - auto* pTLASVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pTLAS); auto* pScratchVk = ValidatedCast<BufferVkImpl>(Attribs.pScratchBuffer); auto* pInstancesVk = ValidatedCast<BufferVkImpl>(Attribs.pInstanceBuffer); @@ -3007,7 +2981,7 @@ void DeviceContextVkImpl::BuildTLAS(const TLASBuildAttribs& Attribs) std::memcpy(&vkASInst.transform, Inst.Transform.data, sizeof(vkASInst.transform)); vkASInst.instanceCustomIndex = Inst.CustomId; - vkASInst.instanceShaderBindingTableRecordOffset = pTLASVk->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize + vkASInst.instanceShaderBindingTableRecordOffset = pTLASVk->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex; vkASInst.mask = Inst.Mask; vkASInst.flags = InstanceFlagsToVkGeometryInstanceFlags(Inst.Flags); vkASInst.accelerationStructureReference = pBLASVk->GetVkDeviceAddress(); @@ -3058,16 +3032,13 @@ void DeviceContextVkImpl::CopyBLAS(const CopyBLASAttribs& Attribs) if (!TDeviceContextBase::CopyBLAS(Attribs, 0)) return; -#ifdef DILIGENT_DEBUG - { - const auto& LogicalDevice = m_pDevice->GetLogicalDevice(); - VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing != VK_FALSE); - } -#endif - auto* pSrcVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pSrc); auto* pDstVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pDst); + // 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); + VkCopyAccelerationStructureInfoKHR Info = {}; Info.sType = VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR; @@ -3078,8 +3049,8 @@ void DeviceContextVkImpl::CopyBLAS(const CopyBLASAttribs& Attribs) EnsureVkCmdBuffer(); const char* OpName = "Copy BottomLevelAS (DeviceContextVkImpl::CopyBLAS)"; - TransitionOrVerifyBLASState(*pSrcVk, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); - TransitionOrVerifyBLASState(*pDstVk, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); + TransitionOrVerifyBLASState(*pSrcVk, Attribs.SrcTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + TransitionOrVerifyBLASState(*pDstVk, Attribs.DstTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); m_CommandBuffer.CopyAccelerationStructure(Info); ++m_State.NumCommands; @@ -3094,16 +3065,11 @@ void DeviceContextVkImpl::CopyTLAS(const CopyTLASAttribs& Attribs) if (!TDeviceContextBase::CopyTLAS(Attribs, 0)) return; -#ifdef DILIGENT_DEBUG - { - const auto& LogicalDevice = m_pDevice->GetLogicalDevice(); - VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing != VK_FALSE); - } -#endif - auto* pSrcVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pSrc); auto* pDstVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pDst); + // Instances specified in BuildTLAS command. + // We should copy instances because it required for SBT to map instance name to hit group. pDstVk->CopyInstancceData(*pSrcVk); VkCopyAccelerationStructureInfoKHR Info = {}; @@ -3116,32 +3082,111 @@ void DeviceContextVkImpl::CopyTLAS(const CopyTLASAttribs& Attribs) EnsureVkCmdBuffer(); const char* OpName = "Copy TopLevelAS (DeviceContextVkImpl::CopyTLAS)"; - TransitionOrVerifyTLASState(*pSrcVk, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); - TransitionOrVerifyTLASState(*pDstVk, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); + TransitionOrVerifyTLASState(*pSrcVk, Attribs.SrcTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + TransitionOrVerifyTLASState(*pDstVk, Attribs.DstTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); m_CommandBuffer.CopyAccelerationStructure(Info); ++m_State.NumCommands; } -void DeviceContextVkImpl::TraceRays(const TraceRaysAttribs& Attribs) +void DeviceContextVkImpl::WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs) { - if (!TDeviceContextBase::TraceRays(Attribs, 0)) + if (!TDeviceContextBase::WriteBLASCompactedSize(Attribs, 0)) return; -#ifdef DILIGENT_DEBUG + const Uint32 QueryIndex = 0; + auto* pBLASVk = ValidatedCast<BottomLevelASVkImpl>(Attribs.pBLAS); + auto* pDestBuffVk = ValidatedCast<BufferVkImpl>(Attribs.pDestBuffer); + + EnsureVkCmdBuffer(); + + const char* OpName = "Write AS compacted size (DeviceContextVkImpl::WriteBLASCompactedSize)"; + TransitionOrVerifyBLASState(*pBLASVk, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + TransitionOrVerifyBufferState(*pDestBuffVk, Attribs.BufferTransitionMode, RESOURCE_STATE_COPY_DEST, VK_ACCESS_TRANSFER_WRITE_BIT, OpName); + + m_CommandBuffer.WriteAccelerationStructuresProperties(pBLASVk->GetVkBLAS(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, m_ASQueryPool, QueryIndex); + m_CommandBuffer.CopyQueryPoolResults(m_ASQueryPool, QueryIndex, 1, pDestBuffVk->GetVkBuffer(), Attribs.DestBufferOffset, sizeof(Uint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT); + m_CommandBuffer.ResetQueryPool(m_ASQueryPool, QueryIndex, 1); + ++m_State.NumCommands; +} + +void DeviceContextVkImpl::WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs) +{ + if (!TDeviceContextBase::WriteTLASCompactedSize(Attribs, 0)) + return; + + const Uint32 QueryIndex = 0; + auto* pTLASVk = ValidatedCast<TopLevelASVkImpl>(Attribs.pTLAS); + auto* pDestBuffVk = ValidatedCast<BufferVkImpl>(Attribs.pDestBuffer); + + EnsureVkCmdBuffer(); + + const char* OpName = "Write AS compacted size (DeviceContextVkImpl::WriteTLASCompactedSize)"; + TransitionOrVerifyTLASState(*pTLASVk, Attribs.TLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + TransitionOrVerifyBufferState(*pDestBuffVk, Attribs.BufferTransitionMode, RESOURCE_STATE_COPY_DEST, VK_ACCESS_TRANSFER_WRITE_BIT, OpName); + + m_CommandBuffer.WriteAccelerationStructuresProperties(pTLASVk->GetVkTLAS(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, m_ASQueryPool, QueryIndex); + m_CommandBuffer.CopyQueryPoolResults(m_ASQueryPool, QueryIndex, 1, pDestBuffVk->GetVkBuffer(), Attribs.DestBufferOffset, sizeof(Uint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT); + m_CommandBuffer.ResetQueryPool(m_ASQueryPool, QueryIndex, 1); + ++m_State.NumCommands; +} + +void DeviceContextVkImpl::CreateASCompactedSizeQueryPool() +{ + if (m_pDevice->GetDeviceCaps().Features.RayTracing == DEVICE_FEATURE_STATE_ENABLED) { - const auto& LogicalDevice = m_pDevice->GetLogicalDevice(); - VERIFY_EXPR(LogicalDevice.GetEnabledExtFeatures().RayTracing.rayTracing != VK_FALSE); + const auto& LogicalDevice = m_pDevice->GetLogicalDevice(); + VkQueryPoolCreateInfo Info = {}; + + Info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; + Info.queryCount = 1; + Info.queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR; + + m_ASQueryPool = LogicalDevice.CreateQueryPool(Info); } -#endif +} + +void DeviceContextVkImpl::TraceRays(const TraceRaysAttribs& Attribs) +{ + if (!TDeviceContextBase::TraceRays(Attribs, 0)) + return; + + auto* pSBTVk = ValidatedCast<ShaderBindingTableVkImpl>(Attribs.pSBT); + IBuffer* pBuffer = nullptr; - VkStridedBufferRegionKHR RaygenShaderBindingTable = {}; - VkStridedBufferRegionKHR MissShaderBindingTable = {}; - VkStridedBufferRegionKHR HitShaderBindingTable = {}; - VkStridedBufferRegionKHR CallableShaderBindingTable = {}; + ShaderBindingTableVkImpl::BindingTable RayGenShaderRecord = {}; + ShaderBindingTableVkImpl::BindingTable MissShaderTable = {}; + ShaderBindingTableVkImpl::BindingTable HitGroupTable = {}; + ShaderBindingTableVkImpl::BindingTable CallableShaderTable = {}; - auto* pSBTVk = ValidatedCast<ShaderBindingTableVkImpl>(Attribs.pSBT); - pSBTVk->GetVkStridedBufferRegions(this, Attribs.TransitionMode, RaygenShaderBindingTable, MissShaderBindingTable, HitShaderBindingTable, CallableShaderBindingTable); + pSBTVk->GetData(pBuffer, RayGenShaderRecord, MissShaderTable, HitGroupTable, CallableShaderTable); + + auto* pBufferVk = ValidatedCast<BufferVkImpl>(pBuffer); + + const char* OpName = "Trace rays (DeviceContextVkImpl::TraceRays)"; + TransitionOrVerifyBufferState(*pBufferVk, Attribs.SBTTransitionMode, RESOURCE_STATE_COPY_DEST, VK_ACCESS_TRANSFER_WRITE_BIT, OpName); + + // buffer ranges are not intersected, so we don't need to add barriers between them + if (RayGenShaderRecord.pData) + UpdateBuffer(pBuffer, RayGenShaderRecord.Offset, RayGenShaderRecord.Size, RayGenShaderRecord.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY); + + if (MissShaderTable.pData) + UpdateBuffer(pBuffer, MissShaderTable.Offset, MissShaderTable.Size, MissShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY); + + if (HitGroupTable.pData) + UpdateBuffer(pBuffer, HitGroupTable.Offset, HitGroupTable.Size, HitGroupTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY); + + if (CallableShaderTable.pData) + UpdateBuffer(pBuffer, CallableShaderTable.Offset, CallableShaderTable.Size, CallableShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY); + + TransitionOrVerifyBufferState(*pBufferVk, Attribs.SBTTransitionMode, RESOURCE_STATE_RAY_TRACING, VK_ACCESS_SHADER_READ_BIT, OpName); + + // clang-format off + VkStridedBufferRegionKHR RaygenShaderBindingTable = {pBufferVk->GetVkBuffer(), RayGenShaderRecord.Offset, RayGenShaderRecord.Stride, RayGenShaderRecord.Size }; + VkStridedBufferRegionKHR MissShaderBindingTable = {pBufferVk->GetVkBuffer(), MissShaderTable.Offset, MissShaderTable.Stride, MissShaderTable.Size }; + VkStridedBufferRegionKHR HitShaderBindingTable = {pBufferVk->GetVkBuffer(), HitGroupTable.Offset, HitGroupTable.Stride, HitGroupTable.Size }; + VkStridedBufferRegionKHR CallableShaderBindingTable = {pBufferVk->GetVkBuffer(), CallableShaderTable.Offset, CallableShaderTable.Stride, CallableShaderTable.Size}; + // clang-format on PrepareForRayTracing(); m_CommandBuffer.TraceRays(RaygenShaderBindingTable, MissShaderBindingTable, HitShaderBindingTable, CallableShaderBindingTable, diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp index 3940769f..c0228146 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderBindingTableVkImpl.cpp @@ -57,108 +57,4 @@ void ShaderBindingTableVkImpl::BindAll(const BindAllAttribs& Attribs) // AZ TODO } -void ShaderBindingTableVkImpl::GetVkStridedBufferRegions(IDeviceContextVk* pContext, - RESOURCE_STATE_TRANSITION_MODE TransitionMode, - VkStridedBufferRegionKHR& RaygenShaderBindingTable, - VkStridedBufferRegionKHR& MissShaderBindingTable, - VkStridedBufferRegionKHR& HitShaderBindingTable, - VkStridedBufferRegionKHR& CallableShaderBindingTable) -{ - const auto ShaderGroupBaseAlignment = GetDevice()->GetPhysicalDevice().GetExtProperties().RayTracing.shaderGroupBaseAlignment; - - const auto AlignToLarger = [ShaderGroupBaseAlignment](size_t offset) -> Uint32 { - return Align(static_cast<Uint32>(offset), ShaderGroupBaseAlignment); - }; - - const Uint32 RayGenOffset = 0; - const Uint32 MissShaderOffset = AlignToLarger(m_RayGenShaderRecord.size()); - const Uint32 HitGroupOffset = AlignToLarger(MissShaderOffset + m_MissShadersRecord.size()); - const Uint32 CallableShadersOffset = AlignToLarger(HitGroupOffset + m_HitGroupsRecord.size()); - const Uint32 BufSize = AlignToLarger(CallableShadersOffset + m_CallableShadersRecord.size()); - - // recreate buffer - if (m_pBuffer == nullptr || m_pBuffer->GetDesc().uiSizeInBytes < BufSize) - { - m_pBuffer = nullptr; - - String BuffName = String{GetDesc().Name} + " - internal buffer"; - BufferDesc BuffDesc; - BuffDesc.Name = BuffName.c_str(); - BuffDesc.Usage = USAGE_DEFAULT; - BuffDesc.BindFlags = BIND_RAY_TRACING; - BuffDesc.uiSizeInBytes = BufSize; - - GetDevice()->CreateBuffer(BuffDesc, nullptr, &m_pBuffer); - VERIFY_EXPR(m_pBuffer != nullptr); - } - - if (m_pBuffer == nullptr) - return; // something goes wrong - - VkBuffer BuffHandle = m_pBuffer.RawPtr<BufferVkImpl>()->GetVkBuffer(); - - if (m_RayGenShaderRecord.size()) - { - RaygenShaderBindingTable.buffer = BuffHandle; - RaygenShaderBindingTable.offset = RayGenOffset; - RaygenShaderBindingTable.size = m_RayGenShaderRecord.size(); - RaygenShaderBindingTable.stride = m_ShaderRecordStride; - } - - if (m_MissShadersRecord.size()) - { - MissShaderBindingTable.buffer = BuffHandle; - MissShaderBindingTable.offset = MissShaderOffset; - MissShaderBindingTable.size = m_MissShadersRecord.size(); - MissShaderBindingTable.stride = m_ShaderRecordStride; - } - - if (m_HitGroupsRecord.size()) - { - HitShaderBindingTable.buffer = BuffHandle; - HitShaderBindingTable.offset = HitGroupOffset; - HitShaderBindingTable.size = m_HitGroupsRecord.size(); - HitShaderBindingTable.stride = m_ShaderRecordStride; - } - - if (m_CallableShadersRecord.size()) - { - CallableShaderBindingTable.buffer = BuffHandle; - CallableShaderBindingTable.offset = CallableShadersOffset; - CallableShaderBindingTable.size = m_CallableShadersRecord.size(); - CallableShaderBindingTable.stride = m_ShaderRecordStride; - } - - if (!m_Changed) - return; - - m_Changed = false; - - // update buffer data - if (m_RayGenShaderRecord.size()) - pContext->UpdateBuffer(m_pBuffer, RayGenOffset, static_cast<Uint32>(m_RayGenShaderRecord.size()), m_RayGenShaderRecord.data(), TransitionMode); - - if (m_MissShadersRecord.size()) - pContext->UpdateBuffer(m_pBuffer, MissShaderOffset, static_cast<Uint32>(m_MissShadersRecord.size()), m_MissShadersRecord.data(), TransitionMode); - - if (m_HitGroupsRecord.size()) - pContext->UpdateBuffer(m_pBuffer, HitGroupOffset, static_cast<Uint32>(m_HitGroupsRecord.size()), m_HitGroupsRecord.data(), TransitionMode); - - if (m_CallableShadersRecord.size()) - pContext->UpdateBuffer(m_pBuffer, CallableShadersOffset, static_cast<Uint32>(m_CallableShadersRecord.size()), m_CallableShadersRecord.data(), TransitionMode); - - if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) - { - StateTransitionDesc Barrier; - Barrier.pResource = m_pBuffer; - Barrier.NewState = RESOURCE_STATE_RAY_TRACING; - Barrier.UpdateResourceState = true; - pContext->TransitionResourceStates(1, &Barrier); - } - else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) - { - VERIFY_EXPR(m_pBuffer->GetState() == RESOURCE_STATE_RAY_TRACING); - } -} - } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp index 27e5ee72..0054315f 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp @@ -324,7 +324,9 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl* pCtxVkImpl) "with IDeviceContext::TransitionResourceStates()."); } - pTLASVk->CheckBLASVersion(); +#ifdef DILIGENT_DEVELOPMENT + pTLASVk->ValidateContent(); +#endif } else { diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index f1e8b726..cab26f83 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -328,7 +328,9 @@ void ShaderResourceLayoutVk::InitializeStaticResourceLayout(const std::vector<co DescriptorSet, CacheOffset, SamplerInd, - SrcImmutableSamplerInd >= 0 // + SrcImmutableSamplerInd >= 0, + Attribs.BufferStaticSize, + Attribs.BufferStride // }; } else @@ -618,7 +620,9 @@ void ShaderResourceLayoutVk::Initialize(IRenderDevice* pRende DescriptorSet, CacheOffset, SamplerInd, - vkImmutableSampler != VK_NULL_HANDLE // + vkImmutableSampler != VK_NULL_HANDLE, + Attribs.BufferStaticSize, + Attribs.BufferStride // }; } else @@ -822,6 +826,14 @@ void ShaderResourceLayoutVk::VkResource::CacheUniformBuffer(IDeviceObject* RefCntAutoPtr<BufferVkImpl> pBufferVk{pBuffer, IID_BufferVk}; #ifdef DILIGENT_DEVELOPMENT VerifyConstantBufferBinding(*this, GetVariableType(), ArrayInd, pBuffer, pBufferVk.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); + + if (pBufferVk->GetDesc().uiSizeInBytes != BufferStaticSize) + { + std::stringstream ss; + ss << "binding buffer '" << pBufferVk->GetDesc().Name << "' size (" << pBufferVk->GetDesc().uiSizeInBytes + << ") doesn't match buffer size in shader (" << BufferStaticSize << ")"; + LOG_INFO_MESSAGE(ss.str()); + } #endif auto UpdateDynamicBuffersCounter = [&DynamicBuffersCounter](const BufferVkImpl* pOldBuffer, const BufferVkImpl* pNewBuffer) { @@ -875,6 +887,13 @@ void ShaderResourceLayoutVk::VkResource::CacheStorageBuffer(IDeviceObject* LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", Name, "' in shader '", ParentResLayout.GetShaderName(), "': structured buffer view is expected."); } + + if (ViewDesc.ByteWidth < BufferStaticSize || (ViewDesc.ByteWidth - BufferStaticSize) % BufferStride != 0) + { + LOG_INFO_MESSAGE("binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", + Name, "' in shader '", ParentResLayout.GetShaderName(), "': size mismatch, in shader buffer has static size (", + BufferStaticSize, ") and array stride (", BufferStride, "), but actual size is (", ViewDesc.ByteWidth, ")."); + } } } #endif diff --git a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp index ae10b74b..fbef736c 100644 --- a/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/TopLevelASVkImpl.cpp @@ -40,23 +40,29 @@ TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters, { const auto& LogicalDevice = pRenderDeviceVk->GetLogicalDevice(); const auto& PhysicalDevice = pRenderDeviceVk->GetPhysicalDevice(); - const auto& Limits = PhysicalDevice.GetExtProperties().RayTracing; - - VERIFY_EXPR(m_Desc.MaxInstanceCount <= Limits.maxInstanceCount); + const auto& RTLimits = PhysicalDevice.GetExtProperties().RayTracing; VkAccelerationStructureCreateInfoKHR CreateInfo = {}; VkAccelerationStructureCreateGeometryTypeInfoKHR InstanceInfo = {}; - CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR; - CreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; - CreateInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags); - CreateInfo.maxGeometryCount = 1; - CreateInfo.pGeometryInfos = &InstanceInfo; - CreateInfo.compactedSize = 0; // AZ TODO - - InstanceInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; - InstanceInfo.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR; - InstanceInfo.maxPrimitiveCount = m_Desc.MaxInstanceCount; + CreateInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR; + CreateInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; + CreateInfo.flags = BuildASFlagsToVkBuildAccelerationStructureFlags(m_Desc.Flags); + + if (m_Desc.CompactedSize > 0) + { + CreateInfo.compactedSize = m_Desc.CompactedSize; + } + else if (m_Desc.MaxInstanceCount > 0) + { + InstanceInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; + InstanceInfo.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR; + InstanceInfo.maxPrimitiveCount = m_Desc.MaxInstanceCount; + + VERIFY_EXPR(m_Desc.MaxInstanceCount <= RTLimits.maxInstanceCount); + CreateInfo.pGeometryInfos = &InstanceInfo; + CreateInfo.maxGeometryCount = 1; + } m_VulkanTLAS = LogicalDevice.CreateAccelStruct(CreateInfo, m_Desc.Name); @@ -84,13 +90,18 @@ TopLevelASVkImpl::TopLevelASVkImpl(IReferenceCounters* pRefCounters, auto err = LogicalDevice.BindASMemory(m_VulkanTLAS, Memory, m_MemoryAlignedOffset); CHECK_VK_ERROR_AND_THROW(err, "Failed to bind AS memory"); - MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR; - MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); - m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size); + if (m_Desc.CompactedSize == 0) + { + MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR; + MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); + m_ScratchSize.Build = static_cast<Uint32>(MemReqs.size); + + MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR; + MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); + m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size); + } - MemInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR; - MemReqs = LogicalDevice.GetASMemoryRequirements(MemInfo); - m_ScratchSize.Update = static_cast<Uint32>(MemReqs.size); + SetState(RESOURCE_STATE_BUILD_AS_READ); } TopLevelASVkImpl::~TopLevelASVkImpl() diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index e039311b..53719439 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -1241,7 +1241,7 @@ static VkAccessFlags ResourceStateFlagToVkAccessFlags(RESOURCE_STATE StateFlag) case RESOURCE_STATE_PRESENT: return 0; case RESOURCE_STATE_BUILD_AS_READ: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; case RESOURCE_STATE_BUILD_AS_WRITE: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR; - case RESOURCE_STATE_RAY_TRACING: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; + case RESOURCE_STATE_RAY_TRACING: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_SHADER_READ_BIT; // for TLAS & SBT // clang-format on default: @@ -1256,7 +1256,7 @@ public: StateFlagBitPosToVkAccessFlags() { static_assert((1 << MaxFlagBitPos) == RESOURCE_STATE_MAX_BIT, "This function must be updated to handle new resource state flag"); - for (Uint32 bit = 0; bit < MaxFlagBitPos; ++bit) + for (Uint32 bit = 0; bit < FlagBitPosToVkAccessFlagsMap.size(); ++bit) { FlagBitPosToVkAccessFlagsMap[bit] = ResourceStateFlagToVkAccessFlags(static_cast<RESOURCE_STATE>(1 << bit)); } @@ -1335,7 +1335,7 @@ class VkAccessFlagBitPosToResourceState public: VkAccessFlagBitPosToResourceState() { - for (Uint32 bit = 0; bit < MaxFlagBitPos; ++bit) + for (Uint32 bit = 0; bit < FlagBitPosToResourceState.size(); ++bit) { FlagBitPosToResourceState[bit] = VkAccessFlagToResourceStates(static_cast<VkAccessFlagBits>(1 << bit)); } @@ -1680,13 +1680,14 @@ VkGeometryInstanceFlagsKHR InstanceFlagsToVkGeometryInstanceFlags(RAYTRACING_INS VkCopyAccelerationStructureModeKHR CopyASModeToVkCopyAccelerationStructureMode(COPY_AS_MODE Mode) { - static_assert(COPY_AS_MODE_LAST == COPY_AS_MODE_CLONE, + static_assert(COPY_AS_MODE_LAST == COPY_AS_MODE_COMPACT, "Please update the switch below to handle the new copy AS mode"); switch (Mode) { // clang-format off - case COPY_AS_MODE_CLONE: return VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR; + case COPY_AS_MODE_CLONE: return VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR; + case COPY_AS_MODE_COMPACT: return VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR; // clang-format on default: UNEXPECTED("unknown AS copy mode"); diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp index 4d47ca3e..1f81c872 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp @@ -134,12 +134,12 @@ static VkPipelineStageFlags PipelineStageFromAccessFlags(VkAccessFlags case VK_ACCESS_MEMORY_WRITE_BIT: break; - // AZ TODO: comment + // Read access to acceleration structure or vertex/index/instance buffer in a build AS or trace rays operations. case VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR: Stages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR; break; - // AZ TODO: comment + // Write access to acceleration structure or scratch buffer in a build AS operations. case VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR: Stages |= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR; break; |
