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/GraphicsEngineD3D12 | |
| 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/GraphicsEngineD3D12')
14 files changed, 336 insertions, 252 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp index 511f1a03..1d1f0082 100644 --- a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp +++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp @@ -383,11 +383,10 @@ public: } void EmitRaytracingAccelerationStructurePostbuildInfo(const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC& Desc, - UINT NumSourceAccelerationStructures, - const D3D12_GPU_VIRTUAL_ADDRESS* pSourceAccelerationStructureData) + D3D12_GPU_VIRTUAL_ADDRESS SourceAccelerationStructureAddress) { FlushResourceBarriers(); - static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->EmitRaytracingAccelerationStructurePostbuildInfo(&Desc, NumSourceAccelerationStructures, pSourceAccelerationStructureData); + static_cast<ID3D12GraphicsCommandList4*>(m_pCommandList.p)->EmitRaytracingAccelerationStructurePostbuildInfo(&Desc, 1, &SourceAccelerationStructureAddress); } void CopyRaytracingAccelerationStructure(D3D12_GPU_VIRTUAL_ADDRESS DestAccelerationStructureData, diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp index 389b76a1..8b1818f2 100644 --- a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp +++ b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp @@ -83,4 +83,7 @@ DXGI_FORMAT ValueTypeToIndexType(VALUE_TYPE Type); D3D12_RAYTRACING_GEOMETRY_FLAGS GeometryFlagsToD3D12RTGeometryFlags(RAYTRACING_GEOMETRY_FLAGS Flags); D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_INSTANCE_FLAGS Flags); +D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS BuildASFlagsToD3D12ASBuildFlags(RAYTRACING_BUILD_AS_FLAGS Flags); +D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE CopyASModeToD3D12ASCopyMode(COPY_AS_MODE Mode); + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp index 3ac65274..a112b90e 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp @@ -273,6 +273,12 @@ public: /// Implementation of IDeviceContext::CopyTLAS() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE CopyTLAS(const CopyTLASAttribs& Attribs) override final; + /// Implementation of IDeviceContext::WriteBLASCompactedSize() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs) override final; + + /// Implementation of IDeviceContext::WriteTLASCompactedSize() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs) override final; + /// Implementation of IDeviceContext::TraceRays() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final; diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 636175d5..619368fd 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -180,6 +180,9 @@ public: static Uint32 GetShaderGroupHandleSize() { return D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; } static Uint32 GetMaxShaderRecordStride() { return D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE; } + static Uint32 GetShaderGroupBaseAlignment() { return D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT; } + + static Uint32 GetMaxDrawMeshTasksCount() { return 64000; } private: template <typename PSOCreateInfoType> diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp index daf84d14..537f240a 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp @@ -57,16 +57,6 @@ 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 GetD3D12AddressRangeAndStride(IDeviceContextD3D12* pContext, - RESOURCE_STATE_TRANSITION_MODE TransitionMode, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE& RaygenShaderBindingTable, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& MissShaderBindingTable, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& HitShaderBindingTable, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& CallableShaderBindingTable) override; - -private: - RefCntAutoPtr<IBuffer> m_pBuffer; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h index aa50251a..18ebd984 100644 --- a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h @@ -50,14 +50,6 @@ static const INTERFACE_ID IID_ShaderBindingTableD3D12 = /// Exposes Direct3D12-specific functionality of a shader binding table object. DILIGENT_BEGIN_INTERFACE(IShaderBindingTableD3D12, IShaderBindingTable) { - /// AZ TODO - VIRTUAL void METHOD(GetD3D12AddressRangeAndStride)(THIS_ - IDeviceContextD3D12* pContext, - RESOURCE_STATE_TRANSITION_MODE TransitionMode, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE REF RaygenShaderBindingTable, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE REF MissShaderBindingTable, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE REF HitShaderBindingTable, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE REF CallableShaderBindingTable) PURE; }; DILIGENT_END_INTERFACE @@ -65,8 +57,6 @@ DILIGENT_END_INTERFACE #if DILIGENT_C_INTERFACE -# define IShaderBindingTableD3D12_GetD3D12AddressRangeAndStride(This, ...) CALL_IFACE_METHOD(ShaderBindingTableD3D12, GetD3D12AddressRangeAndStride, This, __VA_ARGS__) - #endif DILIGENT_END_NAMESPACE // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp index 31f0e6a3..1fc9f876 100644 --- a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp @@ -44,67 +44,84 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef bool bIsDeviceInternal) : TBottomLevelASBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal} { - D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO BottomLevelPrebuildInfo = {}; - D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS BottomLevelInputs = {}; - std::vector<D3D12_RAYTRACING_GEOMETRY_DESC> Geometries; + auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + UINT64 ResultDataMaxSizeInBytes = 0; - if (m_Desc.pTriangles != nullptr) + if (m_Desc.CompactedSize) { - Geometries.resize(m_Desc.TriangleCount); - Uint32 MaxPrimitiveCount = 0; - for (uint32_t i = 0; i < m_Desc.TriangleCount; ++i) - { - auto& src = m_Desc.pTriangles[i]; - auto& dst = Geometries[i]; - - dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; - dst.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; - dst.Triangles.VertexBuffer.StartAddress = 0; - dst.Triangles.VertexBuffer.StrideInBytes = 0; - dst.Triangles.VertexFormat = TypeToDXGI_Format(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); - dst.Triangles.VertexCount = src.MaxVertexCount; - dst.Triangles.IndexCount = src.MaxIndexCount; - dst.Triangles.IndexFormat = ValueTypeToIndexType(src.IndexType); - dst.Triangles.IndexBuffer = 0; - dst.Triangles.Transform3x4 = 0; - - MaxPrimitiveCount += src.MaxIndexCount ? src.MaxIndexCount / 3 : src.MaxVertexCount / 3; - } - VERIFY_EXPR(MaxPrimitiveCount <= D3D12_RAYTRACING_MAX_PRIMITIVES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE); + ResultDataMaxSizeInBytes = m_Desc.CompactedSize; } - else if (m_Desc.pBoxes != nullptr) + else { - Geometries.resize(m_Desc.BoxCount); - Uint32 MaxBoxCount = 0; - for (uint32_t i = 0; i < m_Desc.BoxCount; ++i) - { - auto& src = m_Desc.pBoxes[i]; - auto& dst = Geometries[i]; - - dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS; - dst.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; - dst.AABBs.AABBCount = src.MaxBoxCount; - dst.AABBs.AABBs.StartAddress = 0; - dst.AABBs.AABBs.StrideInBytes = 0; + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO d3d12BottomLevelPrebuildInfo = {}; + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS d3d12BottomLevelInputs = {}; + std::vector<D3D12_RAYTRACING_GEOMETRY_DESC> Geometries; - MaxBoxCount += src.MaxBoxCount; + if (m_Desc.pTriangles != nullptr) + { + Geometries.resize(m_Desc.TriangleCount); + Uint32 MaxPrimitiveCount = 0; + for (uint32_t i = 0; i < m_Desc.TriangleCount; ++i) + { + auto& src = m_Desc.pTriangles[i]; + auto& dst = Geometries[i]; + + dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; + dst.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; + dst.Triangles.VertexBuffer.StartAddress = 0; + dst.Triangles.VertexBuffer.StrideInBytes = 0; + dst.Triangles.VertexFormat = TypeToDXGI_Format(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); + dst.Triangles.VertexCount = src.MaxVertexCount; + dst.Triangles.IndexCount = src.IndexType == VT_UNDEFINED ? 0 : src.MaxPrimitiveCount * 3; + dst.Triangles.IndexFormat = ValueTypeToIndexType(src.IndexType); + dst.Triangles.IndexBuffer = 0; + dst.Triangles.Transform3x4 = 0; + + MaxPrimitiveCount += src.MaxPrimitiveCount; + } + VERIFY_EXPR(MaxPrimitiveCount <= D3D12_RAYTRACING_MAX_PRIMITIVES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE); + } + else if (m_Desc.pBoxes != nullptr) + { + Geometries.resize(m_Desc.BoxCount); + Uint32 MaxBoxCount = 0; + for (uint32_t i = 0; i < m_Desc.BoxCount; ++i) + { + auto& src = m_Desc.pBoxes[i]; + auto& dst = Geometries[i]; + + dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS; + dst.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; + dst.AABBs.AABBCount = src.MaxBoxCount; + dst.AABBs.AABBs.StartAddress = 0; + dst.AABBs.AABBs.StrideInBytes = 0; + + MaxBoxCount += src.MaxBoxCount; + } + VERIFY_EXPR(MaxBoxCount <= D3D12_RAYTRACING_MAX_PRIMITIVES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE); + } + else + { + UNEXPECTED("Either pTriangles or pBoxes must not be null"); } - VERIFY_EXPR(MaxBoxCount <= D3D12_RAYTRACING_MAX_PRIMITIVES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE); - } - VERIFY_EXPR(Geometries.size() <= D3D12_RAYTRACING_MAX_GEOMETRIES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE); + VERIFY_EXPR(Geometries.size() <= D3D12_RAYTRACING_MAX_GEOMETRIES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE); - BottomLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; - BottomLevelInputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE; - BottomLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; - BottomLevelInputs.pGeometryDescs = Geometries.data(); - BottomLevelInputs.NumDescs = static_cast<UINT>(Geometries.size()); + d3d12BottomLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + d3d12BottomLevelInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(m_Desc.Flags); + d3d12BottomLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + d3d12BottomLevelInputs.pGeometryDescs = Geometries.data(); + d3d12BottomLevelInputs.NumDescs = static_cast<UINT>(Geometries.size()); - auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&d3d12BottomLevelInputs, &d3d12BottomLevelPrebuildInfo); + if (d3d12BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0) + LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info"); - pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&BottomLevelInputs, &BottomLevelPrebuildInfo); - if (BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0) - LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info"); + ResultDataMaxSizeInBytes = d3d12BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes; + + m_ScratchSize.Build = static_cast<Uint32>(d3d12BottomLevelPrebuildInfo.ScratchDataSizeInBytes); + m_ScratchSize.Update = static_cast<Uint32>(d3d12BottomLevelPrebuildInfo.UpdateScratchDataSizeInBytes); + } D3D12_HEAP_PROPERTIES HeapProps; HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; @@ -116,7 +133,7 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef D3D12_RESOURCE_DESC ASDesc = {}; ASDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; ASDesc.Alignment = 0; - ASDesc.Width = BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes; + ASDesc.Width = ResultDataMaxSizeInBytes; ASDesc.Height = 1; ASDesc.DepthOrArraySize = 1; ASDesc.MipLevels = 1; @@ -136,8 +153,9 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef if (*m_Desc.Name != 0) m_pd3d12Resource->SetName(WidenString(m_Desc.Name).c_str()); - m_ScratchSize.Build = static_cast<Uint32>(BottomLevelPrebuildInfo.ScratchDataSizeInBytes); - m_ScratchSize.Update = static_cast<Uint32>(BottomLevelPrebuildInfo.UpdateScratchDataSizeInBytes); + VERIFY_EXPR(GetGPUAddress() % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0); + + SetState(RESOURCE_STATE_BUILD_AS_READ); } BottomLevelASD3D12Impl::~BottomLevelASD3D12Impl() diff --git a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp index 4285e11a..1e301bb2 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp @@ -224,6 +224,12 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier) "RESOURCE_STATE_UNKNOWN to make the engine use current resource state"); } + // RESOURCE_STATE_UNORDERED_ACCESS and RESOURCE_STATE_BUILD_AS_WRITE converted to D3D12_RESOURCE_STATE_UNORDERED_ACCESS. + // UAV barrier must be inserted between D3D12_RESOURCE_STATE_UNORDERED_ACCESS resource usage. + bool RequireUAVBarrier = + (OldState == RESOURCE_STATE_UNORDERED_ACCESS || OldState == RESOURCE_STATE_BUILD_AS_WRITE) && + (Barrier.NewState == RESOURCE_STATE_UNORDERED_ACCESS || Barrier.NewState == RESOURCE_STATE_BUILD_AS_WRITE); + // Check if required state is already set if ((OldState & Barrier.NewState) != Barrier.NewState) { @@ -306,26 +312,34 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier) } else if (pBLASD3D12Impl) { - VERIFY(!Barrier.UpdateResourceState || (Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE || Barrier.TransitionType == STATE_TRANSITION_TYPE_END), - "Bottom-level acceleration structure state can't be updated in begin-split barrier"); if (Barrier.UpdateResourceState) { pBLASD3D12Impl->SetState(NewState); } + + // acceleration structure is always in D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE but requires UAV barrier instead of state transition. + RequireUAVBarrier |= (OldState == RESOURCE_STATE_BUILD_AS_WRITE); } else if (pTLASD3D12Impl) { - VERIFY(!Barrier.UpdateResourceState || (Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE || Barrier.TransitionType == STATE_TRANSITION_TYPE_END), - "Top-level acceleration structure state can't be updated in begin-split barrier"); if (Barrier.UpdateResourceState) { pTLASD3D12Impl->SetState(NewState); } + + // acceleration structure is always in D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE but requires UAV barrier instead of state transition. + RequireUAVBarrier |= (OldState == RESOURCE_STATE_BUILD_AS_WRITE); + +#ifdef DILIGENT_DEVELOPMENT + if (Barrier.NewState & RESOURCE_STATE_RAY_TRACING) + { + pTLASD3D12Impl->ValidateContent(); + } +#endif } } - if ((OldState == RESOURCE_STATE_UNORDERED_ACCESS || OldState == RESOURCE_STATE_BUILD_AS_WRITE) && - (Barrier.NewState == RESOURCE_STATE_UNORDERED_ACCESS || Barrier.NewState == RESOURCE_STATE_BUILD_AS_WRITE)) + if (RequireUAVBarrier) { DEV_CHECK_ERR(Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE, "UAV barriers must not be split"); InsertUAVBarrier(pd3d12Resource); diff --git a/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp index 74e65559..63d19ce4 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp @@ -94,6 +94,8 @@ Uint64 CommandQueueD3D12Impl::WaitForIdle() Uint64 CommandQueueD3D12Impl::GetCompletedFenceValue() { auto CompletedFenceValue = m_d3d12Fence->GetCompletedValue(); + VERIFY(CompletedFenceValue != UINT64_MAX, "If the device has been removed, the return value will be UINT64_MAX"); + if (CompletedFenceValue > m_LastCompletedFenceValue) m_LastCompletedFenceValue = CompletedFenceValue; return m_LastCompletedFenceValue; diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index a6d6963e..1f1f621c 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -367,7 +367,7 @@ public: StateFlagBitPosToD3D12ResourceState() { 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 < FlagBitPosToResStateMap.size(); ++bit) { FlagBitPosToResStateMap[bit] = ResourceStateFlagToD3D12ResourceState(static_cast<RESOURCE_STATE>(1 << bit)); } @@ -436,7 +436,7 @@ class D3D12StateFlagBitPosToResourceState public: D3D12StateFlagBitPosToResourceState() { - for (Uint32 bit = 0; bit <= MaxFlagBitPos; ++bit) + for (Uint32 bit = 0; bit < FlagBitPosToResStateMap.size(); ++bit) { FlagBitPosToResStateMap[bit] = D3D12ResourceStateToResourceStateFlags(static_cast<D3D12_RESOURCE_STATES>(1 << bit)); } @@ -653,4 +653,46 @@ D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_I return Result; } +D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS BuildASFlagsToD3D12ASBuildFlags(RAYTRACING_BUILD_AS_FLAGS Flags) +{ + static_assert(RAYTRACING_BUILD_AS_FLAGS_LAST == RAYTRACING_BUILD_AS_LOW_MEMORY, + "Please update the switch below to handle the new acceleration structure build flag"); + + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS Result = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE; + while (Flags != RAYTRACING_BUILD_AS_NONE) + { + auto FlagBit = static_cast<RAYTRACING_BUILD_AS_FLAGS>(1 << PlatformMisc::GetLSB(Uint32{Flags})); + switch (FlagBit) + { + // clang-format off + case RAYTRACING_BUILD_AS_ALLOW_UPDATE: Result |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE; break; + case RAYTRACING_BUILD_AS_ALLOW_COMPACTION: Result |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_COMPACTION; break; + case RAYTRACING_BUILD_AS_PREFER_FAST_TRACE: Result |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE; break; + case RAYTRACING_BUILD_AS_PREFER_FAST_BUILD: Result |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_BUILD; break; + case RAYTRACING_BUILD_AS_LOW_MEMORY: Result |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_MINIMIZE_MEMORY; break; + // clang-format on + default: UNEXPECTED("unknown build AS flag"); + } + Flags &= ~FlagBit; + } + return Result; +} + +D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE CopyASModeToD3D12ASCopyMode(COPY_AS_MODE Mode) +{ + 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 D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE; + case COPY_AS_MODE_COMPACT: return D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT; + // clang-format on + default: + UNEXPECTED("unknown AS copy mode"); + return static_cast<D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE>(~0u); + } +} + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 0adcaa59..41de3a47 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2143,7 +2143,7 @@ void DeviceContextD3D12Impl::TransitionOrVerifyBufferState(CommandContext& { if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) { - if (Buffer.IsInKnownState() && !Buffer.CheckState(RequiredState)) + if (Buffer.IsInKnownState()) CmdCtx.TransitionResource(&Buffer, RequiredState); } #ifdef DILIGENT_DEVELOPMENT @@ -2162,7 +2162,7 @@ void DeviceContextD3D12Impl::TransitionOrVerifyTextureState(CommandContext& { if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) { - if (Texture.IsInKnownState() && !Texture.CheckState(RequiredState)) + if (Texture.IsInKnownState()) CmdCtx.TransitionResource(&Texture, RequiredState); } #ifdef DILIGENT_DEVELOPMENT @@ -2181,7 +2181,7 @@ void DeviceContextD3D12Impl::TransitionOrVerifyBLASState(CommandContext& { if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) { - if (BLAS.IsInKnownState() && !BLAS.CheckState(RequiredState)) + if (BLAS.IsInKnownState()) CmdCtx.TransitionResource(&BLAS, RequiredState); } #ifdef DILIGENT_DEVELOPMENT @@ -2200,7 +2200,7 @@ void DeviceContextD3D12Impl::TransitionOrVerifyTLASState(CommandContext& { if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) { - if (TLAS.IsInKnownState() && !TLAS.CheckState(RequiredState)) + if (TLAS.IsInKnownState()) CmdCtx.TransitionResource(&TLAS, RequiredState); } #ifdef DILIGENT_DEVELOPMENT @@ -2208,11 +2208,6 @@ void DeviceContextD3D12Impl::TransitionOrVerifyTLASState(CommandContext& { DvpVerifyTLASState(TLAS, RequiredState, OperationName); } - - if (RequiredState & RESOURCE_STATE_RAY_TRACING) - { - TLAS.CheckBLASVersion(); - } #endif } @@ -2291,8 +2286,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) TransitionOrVerifyBLASState(CmdCtx, *pBLASD12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); TransitionOrVerifyBufferState(CmdCtx, *pScratchD12, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); - D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC Desc = {}; - D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS& Inputs = Desc.Inputs; + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC d3d12BuildASDesc = {}; + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS& d3d12BuildASInputs = d3d12BuildASDesc.Inputs; std::vector<D3D12_RAYTRACING_GEOMETRY_DESC> Geometries; if (Attribs.pTriangleData != nullptr) @@ -2301,10 +2296,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i) { - const auto& SrcTris = Attribs.pTriangleData[i]; - Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcTris.GeometryName); - auto& d3d12Geo = Geometries[GeoIdx]; - auto& d3d12Tris = d3d12Geo.Triangles; + const auto& SrcTris = Attribs.pTriangleData[i]; + Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcTris.GeometryName); if (GeoIdx >= Geometries.size()) { @@ -2312,11 +2305,17 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) continue; } + auto& d3d12Geo = Geometries[GeoIdx]; + auto& d3d12Tris = d3d12Geo.Triangles; + const auto& TriDesc = BLASDesc.pTriangles[GeoIdx]; + d3d12Geo.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; d3d12Geo.Flags = GeometryFlagsToD3D12RTGeometryFlags(SrcTris.Flags); - auto* const pVB = ValidatedCast<BufferD3D12Impl>(SrcTris.pVertexBuffer); - d3d12Tris.VertexFormat = TypeToDXGI_Format(SrcTris.VertexValueType, SrcTris.VertexComponentCount, SrcTris.VertexValueType < VT_FLOAT16); + auto* const pVB = ValidatedCast<BufferD3D12Impl>(SrcTris.pVertexBuffer); + + // vertex format in SrcTris may be undefined, so use vertex format from description + d3d12Tris.VertexFormat = TypeToDXGI_Format(TriDesc.VertexValueType, TriDesc.VertexComponentCount, TriDesc.VertexValueType < VT_FLOAT16); d3d12Tris.VertexCount = SrcTris.VertexCount; d3d12Tris.VertexBuffer.StartAddress = pVB->GetGPUAddress() + SrcTris.VertexOffset; d3d12Tris.VertexBuffer.StrideInBytes = SrcTris.VertexStride; @@ -2325,10 +2324,12 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) if (SrcTris.pIndexBuffer) { - auto* const pIB = ValidatedCast<BufferD3D12Impl>(SrcTris.pIndexBuffer); + auto* const pIB = ValidatedCast<BufferD3D12Impl>(SrcTris.pIndexBuffer); + + // index type in SrcTris may be undefined, so use index type from description + d3d12Tris.IndexFormat = ValueTypeToIndexType(TriDesc.IndexType); d3d12Tris.IndexBuffer = pIB->GetGPUAddress() + SrcTris.IndexOffset; - d3d12Tris.IndexCount = SrcTris.IndexCount; - d3d12Tris.IndexFormat = ValueTypeToIndexType(SrcTris.IndexType); + d3d12Tris.IndexCount = SrcTris.PrimitiveCount * 3; TransitionOrVerifyBufferState(CmdCtx, *pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } @@ -2340,8 +2341,6 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) if (SrcTris.pTransformBuffer) { - VERIFY_EXPR(BLASDesc.pTriangles[GeoIdx].AllowsTransforms); - auto* const pTB = ValidatedCast<BufferD3D12Impl>(SrcTris.pTransformBuffer); d3d12Tris.Transform3x4 = pTB->GetGPUAddress() + SrcTris.TransformBufferOffset; @@ -2349,7 +2348,6 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) } else { - VERIFY_EXPR(!BLASDesc.pTriangles[GeoIdx].AllowsTransforms); d3d12Tris.Transform3x4 = 0; } } @@ -2360,10 +2358,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i) { - const auto& SrcBoxes = Attribs.pBoxData[i]; - Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcBoxes.GeometryName); - auto& d3d12Geo = Geometries[GeoIdx]; - auto& d3d12AABs = d3d12Geo.AABBs; + const auto& SrcBoxes = Attribs.pBoxData[i]; + Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcBoxes.GeometryName); if (GeoIdx >= Geometries.size()) { @@ -2371,6 +2367,9 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) continue; } + auto& d3d12Geo = Geometries[GeoIdx]; + auto& d3d12AABs = d3d12Geo.AABBs; + d3d12Geo.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS; d3d12Geo.Flags = GeometryFlagsToD3D12RTGeometryFlags(SrcBoxes.Flags); @@ -2383,16 +2382,17 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) } } - Inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; - Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; - Inputs.NumDescs = static_cast<UINT>(Geometries.size()); - Inputs.pGeometryDescs = Geometries.data(); + d3d12BuildASInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + d3d12BuildASInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(BLASDesc.Flags); + d3d12BuildASInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + d3d12BuildASInputs.NumDescs = static_cast<UINT>(Geometries.size()); + d3d12BuildASInputs.pGeometryDescs = Geometries.data(); - Desc.DestAccelerationStructureData = pBLASD12->GetGPUAddress(); - Desc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress(); - Desc.SourceAccelerationStructureData = 0; + d3d12BuildASDesc.DestAccelerationStructureData = pBLASD12->GetGPUAddress(); + d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress(); + d3d12BuildASDesc.SourceAccelerationStructureData = 0; - CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(Desc, 0, nullptr); + CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr); ++m_State.NumCommands; #ifdef DILIGENT_DEVELOPMENT @@ -2420,21 +2420,20 @@ void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) // copy instance data into instance buffer { - size_t Size = Attribs.InstanceCount * sizeof(D3D12_RAYTRACING_INSTANCE_DESC); - auto TmpSpace = m_DynamicHeap.Allocate(Size, 16, m_ContextFrameNumber); - void* pMappedInstances = TmpSpace.CPUAddress; + size_t Size = Attribs.InstanceCount * sizeof(D3D12_RAYTRACING_INSTANCE_DESC); + auto TmpSpace = m_DynamicHeap.Allocate(Size, 16, m_ContextFrameNumber); for (Uint32 i = 0; i < Attribs.InstanceCount; ++i) { const auto& Inst = Attribs.pInstances[i]; - auto& d3d12Inst = static_cast<D3D12_RAYTRACING_INSTANCE_DESC*>(pMappedInstances)[i]; + auto& d3d12Inst = static_cast<D3D12_RAYTRACING_INSTANCE_DESC*>(TmpSpace.CPUAddress)[i]; auto* const pBLASD12 = ValidatedCast<BottomLevelASD3D12Impl>(Inst.pBLAS); static_assert(sizeof(d3d12Inst.Transform) == sizeof(Inst.Transform), "size mismatch"); std::memcpy(&d3d12Inst.Transform, Inst.Transform.data, sizeof(d3d12Inst.Transform)); d3d12Inst.InstanceID = Inst.CustomId; - d3d12Inst.InstanceContributionToHitGroupIndex = pTLASD12->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize + d3d12Inst.InstanceContributionToHitGroupIndex = pTLASD12->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex; d3d12Inst.InstanceMask = Inst.Mask; d3d12Inst.Flags = InstanceFlagsToD3D12RTInstanceFlags(Inst.Flags); d3d12Inst.AccelerationStructure = pBLASD12->GetGPUAddress(); @@ -2449,6 +2448,7 @@ void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS& d3d12BuildASInputs = d3d12BuildASDesc.Inputs; d3d12BuildASInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + d3d12BuildASInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(pTLASD12->GetDesc().Flags); d3d12BuildASInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; d3d12BuildASInputs.NumDescs = Attribs.InstanceCount; d3d12BuildASInputs.InstanceDescs = pInstancesD12->GetGPUAddress(); @@ -2469,12 +2469,17 @@ void DeviceContextD3D12Impl::CopyBLAS(const CopyBLASAttribs& Attribs) auto* pSrcD3D12 = ValidatedCast<BottomLevelASD3D12Impl>(Attribs.pSrc); auto* pDstD3D12 = ValidatedCast<BottomLevelASD3D12Impl>(Attribs.pDst); auto& CmdCtx = GetCmdContext(); + auto Mode = CopyASModeToD3D12ASCopyMode(Attribs.Mode); + + // 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. + pDstD3D12->CopyDescription(*pSrcD3D12); const char* OpName = "Copy BottomLevelAS (DeviceContextD3D12Impl::CopyBLAS)"; - TransitionOrVerifyBLASState(CmdCtx, *pSrcD3D12, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); - TransitionOrVerifyBLASState(CmdCtx, *pDstD3D12, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); + TransitionOrVerifyBLASState(CmdCtx, *pSrcD3D12, Attribs.SrcTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + TransitionOrVerifyBLASState(CmdCtx, *pDstD3D12, Attribs.DstTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); - CmdCtx.AsGraphicsContext4().CopyRaytracingAccelerationStructure(pSrcD3D12->GetGPUAddress(), pDstD3D12->GetGPUAddress(), D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE); + CmdCtx.AsGraphicsContext4().CopyRaytracingAccelerationStructure(pDstD3D12->GetGPUAddress(), pSrcD3D12->GetGPUAddress(), Mode); ++m_State.NumCommands; #ifdef DILIGENT_DEVELOPMENT @@ -2490,14 +2495,67 @@ void DeviceContextD3D12Impl::CopyTLAS(const CopyTLASAttribs& Attribs) auto* pSrcD3D12 = ValidatedCast<TopLevelASD3D12Impl>(Attribs.pSrc); auto* pDstD3D12 = ValidatedCast<TopLevelASD3D12Impl>(Attribs.pDst); auto& CmdCtx = GetCmdContext(); + auto Mode = CopyASModeToD3D12ASCopyMode(Attribs.Mode); + // Instances specified in BuildTLAS command. + // We should copy instances because it required for SBT to map instance name to hit group. pDstD3D12->CopyInstancceData(*pSrcD3D12); const char* OpName = "Copy BottomLevelAS (DeviceContextD3D12Impl::CopyTLAS)"; - TransitionOrVerifyTLASState(CmdCtx, *pSrcD3D12, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); - TransitionOrVerifyTLASState(CmdCtx, *pDstD3D12, Attribs.TransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); + TransitionOrVerifyTLASState(CmdCtx, *pSrcD3D12, Attribs.SrcTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + TransitionOrVerifyTLASState(CmdCtx, *pDstD3D12, Attribs.DstTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); - CmdCtx.AsGraphicsContext4().CopyRaytracingAccelerationStructure(pSrcD3D12->GetGPUAddress(), pDstD3D12->GetGPUAddress(), D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE); + CmdCtx.AsGraphicsContext4().CopyRaytracingAccelerationStructure(pDstD3D12->GetGPUAddress(), pSrcD3D12->GetGPUAddress(), Mode); + ++m_State.NumCommands; +} + +void DeviceContextD3D12Impl::WriteBLASCompactedSize(const WriteBLASCompactedSizeAttribs& Attribs) +{ + if (!TDeviceContextBase::WriteBLASCompactedSize(Attribs, 0)) + return; + + static_assert(sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC) == sizeof(Uint64), + "Engine api specifies that compacted size is 64 bits"); + + auto* pBLASD3D12 = ValidatedCast<BottomLevelASD3D12Impl>(Attribs.pBLAS); + auto* pDestBuffD3D12 = ValidatedCast<BufferD3D12Impl>(Attribs.pDestBuffer); + auto& CmdCtx = GetCmdContext(); + + const char* OpName = "Write AS compacted size (DeviceContextD3D12Impl::WriteBLASCompactedSize)"; + TransitionOrVerifyBLASState(CmdCtx, *pBLASD3D12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + TransitionOrVerifyBufferState(CmdCtx, *pDestBuffD3D12, Attribs.BufferTransitionMode, RESOURCE_STATE_UNORDERED_ACCESS, OpName); + + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC d3d12Desc = {}; + + d3d12Desc.DestBuffer = pDestBuffD3D12->GetGPUAddress() + Attribs.DestBufferOffset; + d3d12Desc.InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE; + + CmdCtx.AsGraphicsContext4().EmitRaytracingAccelerationStructurePostbuildInfo(d3d12Desc, pBLASD3D12->GetGPUAddress()); + ++m_State.NumCommands; +} + +void DeviceContextD3D12Impl::WriteTLASCompactedSize(const WriteTLASCompactedSizeAttribs& Attribs) +{ + if (!TDeviceContextBase::WriteTLASCompactedSize(Attribs, 0)) + return; + + static_assert(sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC) == sizeof(Uint64), + "Engine api specifies that compacted size is 64 bits"); + + auto* pTLASD3D12 = ValidatedCast<TopLevelASD3D12Impl>(Attribs.pTLAS); + auto* pDestBuffD3D12 = ValidatedCast<BufferD3D12Impl>(Attribs.pDestBuffer); + auto& CmdCtx = GetCmdContext(); + + const char* OpName = "Write AS compacted size (DeviceContextD3D12Impl::WriteTLASCompactedSize)"; + TransitionOrVerifyTLASState(CmdCtx, *pTLASD3D12, Attribs.TLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + TransitionOrVerifyBufferState(CmdCtx, *pDestBuffD3D12, Attribs.BufferTransitionMode, RESOURCE_STATE_UNORDERED_ACCESS, OpName); + + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC d3d12Desc = {}; + + d3d12Desc.DestBuffer = pDestBuffD3D12->GetGPUAddress() + Attribs.DestBufferOffset; + d3d12Desc.InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE; + + CmdCtx.AsGraphicsContext4().EmitRaytracingAccelerationStructurePostbuildInfo(d3d12Desc, pTLASD3D12->GetGPUAddress()); ++m_State.NumCommands; } @@ -2506,20 +2564,60 @@ void DeviceContextD3D12Impl::TraceRays(const TraceRaysAttribs& Attribs) if (!TDeviceContextBase::TraceRays(Attribs, 0)) return; + VERIFY_EXPR((Attribs.DimensionX * Attribs.DimensionY * Attribs.DimensionZ) <= D3D12_RAYTRACING_MAX_RAY_GENERATION_SHADER_THREADS); + + auto& CmdCtx = GetCmdContext().AsGraphicsContext4(); + auto* pSBTD12 = ValidatedCast<ShaderBindingTableD3D12Impl>(Attribs.pSBT); + IBuffer* pBuffer = nullptr; + + ShaderBindingTableD3D12Impl::BindingTable RayGenShaderRecord = {}; + ShaderBindingTableD3D12Impl::BindingTable MissShaderTable = {}; + ShaderBindingTableD3D12Impl::BindingTable HitGroupTable = {}; + ShaderBindingTableD3D12Impl::BindingTable CallableShaderTable = {}; + + pSBTD12->GetData(pBuffer, RayGenShaderRecord, MissShaderTable, HitGroupTable, CallableShaderTable); + + auto* pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(pBuffer); + + const char* OpName = "Trace rays (DeviceContextD3D12Impl::TraceRays)"; + TransitionOrVerifyBufferState(CmdCtx, *pBufferD3D12, Attribs.SBTTransitionMode, RESOURCE_STATE_COPY_DEST, OpName); + + // buffer ranges are not intersected, so we don't need to add barriers between them + if (RayGenShaderRecord.pData) + UpdateBuffer(pBufferD3D12, RayGenShaderRecord.Offset, RayGenShaderRecord.Size, RayGenShaderRecord.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY); + + if (MissShaderTable.pData) + UpdateBuffer(pBufferD3D12, MissShaderTable.Offset, MissShaderTable.Size, MissShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY); + + if (HitGroupTable.pData) + UpdateBuffer(pBufferD3D12, HitGroupTable.Offset, HitGroupTable.Size, HitGroupTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY); + + if (CallableShaderTable.pData) + UpdateBuffer(pBufferD3D12, CallableShaderTable.Offset, CallableShaderTable.Size, CallableShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY); + + TransitionOrVerifyBufferState(CmdCtx, *pBufferD3D12, Attribs.SBTTransitionMode, RESOURCE_STATE_RAY_TRACING, OpName); + D3D12_DISPATCH_RAYS_DESC d3d12DispatchDesc = {}; d3d12DispatchDesc.Width = Attribs.DimensionX; d3d12DispatchDesc.Height = Attribs.DimensionY; d3d12DispatchDesc.Depth = Attribs.DimensionZ; - auto* pSBTD12 = ValidatedCast<ShaderBindingTableD3D12Impl>(Attribs.pSBT); - pSBTD12->GetD3D12AddressRangeAndStride(this, Attribs.TransitionMode, - d3d12DispatchDesc.RayGenerationShaderRecord, - d3d12DispatchDesc.MissShaderTable, - d3d12DispatchDesc.HitGroupTable, - d3d12DispatchDesc.CallableShaderTable); + d3d12DispatchDesc.RayGenerationShaderRecord.StartAddress = pBufferD3D12->GetGPUAddress() + RayGenShaderRecord.Offset; + d3d12DispatchDesc.RayGenerationShaderRecord.SizeInBytes = RayGenShaderRecord.Size; + + d3d12DispatchDesc.MissShaderTable.StartAddress = pBufferD3D12->GetGPUAddress() + MissShaderTable.Offset; + d3d12DispatchDesc.MissShaderTable.SizeInBytes = MissShaderTable.Size; + d3d12DispatchDesc.MissShaderTable.StrideInBytes = MissShaderTable.Stride; + + d3d12DispatchDesc.HitGroupTable.StartAddress = pBufferD3D12->GetGPUAddress() + HitGroupTable.Offset; + d3d12DispatchDesc.HitGroupTable.SizeInBytes = HitGroupTable.Size; + d3d12DispatchDesc.HitGroupTable.StrideInBytes = HitGroupTable.Stride; + + d3d12DispatchDesc.CallableShaderTable.StartAddress = pBufferD3D12->GetGPUAddress() + CallableShaderTable.Offset; + d3d12DispatchDesc.CallableShaderTable.SizeInBytes = CallableShaderTable.Size; + d3d12DispatchDesc.CallableShaderTable.StrideInBytes = CallableShaderTable.Stride; - auto& CmdCtx = GetCmdContext().AsGraphicsContext4(); PrepareForDispatchRays(CmdCtx); CmdCtx.DispatchRays(d3d12DispatchDesc); diff --git a/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp index a9e1c7d8..02308ca0 100644 --- a/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp @@ -51,7 +51,9 @@ FenceD3D12Impl::~FenceD3D12Impl() Uint64 FenceD3D12Impl::GetCompletedValue() { - return m_pd3d12Fence->GetCompletedValue(); + Uint64 Result = m_pd3d12Fence->GetCompletedValue(); + VERIFY(Result != UINT64_MAX, "If the device has been removed, the return value will be UINT64_MAX"); + return Result; } void FenceD3D12Impl::Reset(Uint64 Value) @@ -61,7 +63,7 @@ void FenceD3D12Impl::Reset(Uint64 Value) void FenceD3D12Impl::WaitForCompletion(Uint64 Value) { - while (m_pd3d12Fence->GetCompletedValue() < Value) + while (GetCompletedValue() < Value) std::this_thread::yield(); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp index d71d98b7..ac67ba57 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp @@ -62,101 +62,4 @@ void ShaderBindingTableD3D12Impl::BindAll(const BindAllAttribs& Attribs) // AZ TODO } -void ShaderBindingTableD3D12Impl::GetD3D12AddressRangeAndStride(IDeviceContextD3D12* pContext, - RESOURCE_STATE_TRANSITION_MODE TransitionMode, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE& RaygenShaderBindingTable, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& MissShaderBindingTable, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& HitShaderBindingTable, - D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& CallableShaderBindingTable) -{ - const auto AlignToLarger = [](size_t offset) -> Uint32 { - return Align(static_cast<Uint32>(offset), Uint32{D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT}); - }; - - 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 - - const D3D12_GPU_VIRTUAL_ADDRESS BuffHandle = m_pBuffer.RawPtr<BufferD3D12Impl>()->GetGPUAddress(0, ValidatedCast<DeviceContextD3D12Impl>(pContext)); - - if (m_RayGenShaderRecord.size()) - { - RaygenShaderBindingTable.StartAddress = BuffHandle + RayGenOffset; - RaygenShaderBindingTable.SizeInBytes = m_RayGenShaderRecord.size(); - } - - if (m_MissShadersRecord.size()) - { - MissShaderBindingTable.StartAddress = BuffHandle + MissShaderOffset; - MissShaderBindingTable.SizeInBytes = m_MissShadersRecord.size(); - MissShaderBindingTable.StrideInBytes = m_ShaderRecordStride; - } - - if (m_HitGroupsRecord.size()) - { - HitShaderBindingTable.StartAddress = BuffHandle + HitGroupOffset; - HitShaderBindingTable.SizeInBytes = m_HitGroupsRecord.size(); - HitShaderBindingTable.StrideInBytes = m_ShaderRecordStride; - } - - if (m_CallableShadersRecord.size()) - { - CallableShaderBindingTable.StartAddress = BuffHandle + CallableShadersOffset; - CallableShaderBindingTable.SizeInBytes = m_CallableShadersRecord.size(); - CallableShaderBindingTable.StrideInBytes = 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/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp index 3bbf3308..2d087d08 100644 --- a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp @@ -44,21 +44,34 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte bool bIsDeviceInternal) : TTopLevelASBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal} { - D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO d3d12TopLevelPrebuildInfo = {}; - D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS d3d12TopLevelInputs = {}; + auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + UINT64 ResultDataMaxSizeInBytes = 0; - d3d12TopLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; - d3d12TopLevelInputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE; - d3d12TopLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; - d3d12TopLevelInputs.NumDescs = Desc.MaxInstanceCount; + if (m_Desc.CompactedSize > 0) + { + ResultDataMaxSizeInBytes = m_Desc.CompactedSize; + } + else + { + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO d3d12TopLevelPrebuildInfo = {}; + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS d3d12TopLevelInputs = {}; - VERIFY_EXPR(Desc.MaxInstanceCount <= D3D12_RAYTRACING_MAX_INSTANCES_PER_TOP_LEVEL_ACCELERATION_STRUCTURE); + d3d12TopLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + d3d12TopLevelInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(m_Desc.Flags); + d3d12TopLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + d3d12TopLevelInputs.NumDescs = m_Desc.MaxInstanceCount; - auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + VERIFY_EXPR(m_Desc.MaxInstanceCount <= D3D12_RAYTRACING_MAX_INSTANCES_PER_TOP_LEVEL_ACCELERATION_STRUCTURE); - pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&d3d12TopLevelInputs, &d3d12TopLevelPrebuildInfo); - if (d3d12TopLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0) - LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info"); + pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&d3d12TopLevelInputs, &d3d12TopLevelPrebuildInfo); + if (d3d12TopLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0) + LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info"); + + ResultDataMaxSizeInBytes = d3d12TopLevelPrebuildInfo.ResultDataMaxSizeInBytes; + + m_ScratchSize.Build = static_cast<Uint32>(d3d12TopLevelPrebuildInfo.ScratchDataSizeInBytes); + m_ScratchSize.Update = static_cast<Uint32>(d3d12TopLevelPrebuildInfo.UpdateScratchDataSizeInBytes); + } D3D12_HEAP_PROPERTIES HeapProps; HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; @@ -70,7 +83,7 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte D3D12_RESOURCE_DESC d3d12ASDesc = {}; d3d12ASDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; d3d12ASDesc.Alignment = 0; - d3d12ASDesc.Width = d3d12TopLevelPrebuildInfo.ResultDataMaxSizeInBytes; + d3d12ASDesc.Width = ResultDataMaxSizeInBytes; d3d12ASDesc.Height = 1; d3d12ASDesc.DepthOrArraySize = 1; d3d12ASDesc.MipLevels = 1; @@ -90,9 +103,6 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte if (*m_Desc.Name != 0) m_pd3d12Resource->SetName(WidenString(m_Desc.Name).c_str()); - m_ScratchSize.Build = static_cast<Uint32>(d3d12TopLevelPrebuildInfo.ScratchDataSizeInBytes); - m_ScratchSize.Update = static_cast<Uint32>(d3d12TopLevelPrebuildInfo.UpdateScratchDataSizeInBytes); - m_DescriptorHandle = pDeviceD3D12->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); D3D12_SHADER_RESOURCE_VIEW_DESC d3d12SRVDesc; @@ -101,6 +111,10 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte d3d12SRVDesc.Format = DXGI_FORMAT_UNKNOWN; d3d12SRVDesc.RaytracingAccelerationStructure.Location = GetGPUAddress(); pd3d12Device->CreateShaderResourceView(nullptr, &d3d12SRVDesc, m_DescriptorHandle.GetCpuHandle()); + + VERIFY_EXPR(GetGPUAddress() % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0); + + SetState(RESOURCE_STATE_BUILD_AS_READ); } TopLevelASD3D12Impl::~TopLevelASD3D12Impl() |
