From 9e567836f3e63c541cde7b0a02fd2fc7916402c8 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Sun, 4 Oct 2020 23:22:16 +0300 Subject: Added dummy implementation for D3D11, D3D12, OpenGL --- .../include/DeviceContextD3D12Impl.hpp | 15 +++++++++++++++ .../include/RenderDeviceD3D12Impl.hpp | 12 ++++++++++++ .../src/D3D12TypeConversions.cpp | 9 ++++++--- .../src/DeviceContextD3D12Impl.cpp | 21 +++++++++++++++++++++ .../src/RenderDeviceD3D12Impl.cpp | 22 +++++++++++++++++++++- 5 files changed, 75 insertions(+), 4 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp index 91c1610a..39a354dd 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp @@ -257,6 +257,21 @@ public: /// Implementation of IDeviceContext::TransitionBufferState() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE TransitionBufferState(IBuffer* pBuffer, D3D12_RESOURCE_STATES State) override final; + /// Implementation of IDeviceContext::BuildBLAS() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE BuildBLAS(const BLASBuildAttribs& Attribs) override final; + + /// Implementation of IDeviceContext::BuildTLAS() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE BuildTLAS(const TLASBuildAttribs& Attribs) override final; + + /// Implementation of IDeviceContext::CopyBLAS() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE CopyBLAS(const CopyBLASAttribs& Attribs) override final; + + /// Implementation of IDeviceContext::CopyTLAS() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE CopyTLAS(const CopyTLASAttribs& Attribs) override final; + + /// Implementation of IDeviceContext::TraceRays() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE TraceRays(const TraceRaysAttribs& Attribs) override final; + /// Implementation of IDeviceContextD3D12::ID3D12GraphicsCommandList() in Direct3D12 backend. virtual ID3D12GraphicsCommandList* DILIGENT_CALL_TYPE GetD3D12CommandList() override final; diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 0dc4201e..4dfc86c7 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -101,6 +101,18 @@ public: virtual void DILIGENT_CALL_TYPE CreateFramebuffer(const FramebufferDesc& Desc, IFramebuffer** ppFramebuffer) override final; + /// Implementation of IRenderDevice::CreateBLAS() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE CreateBLAS(const BottomLevelASDesc& Desc, + IBottomLevelAS** ppBLAS) override final; + + /// Implementation of IRenderDevice::CreateTLAS() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE CreateTLAS(const TopLevelASDesc& Desc, + ITopLevelAS** ppTLAS) override final; + + /// Implementation of IRenderDevice::CreateSBT() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE CreateSBT(const ShaderBindingTableDesc& Desc, + IShaderBindingTable** ppSBT) override final; + /// Implementation of IRenderDeviceD3D12::GetD3D12Device(). virtual ID3D12Device* DILIGENT_CALL_TYPE GetD3D12Device() override final { return m_pd3d12Device; } diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 23652519..2ce314c4 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -329,7 +329,7 @@ D3D12_STATIC_BORDER_COLOR BorderColorToD3D12StaticBorderColor(const Float32 Bord static D3D12_RESOURCE_STATES ResourceStateFlagToD3D12ResourceState(RESOURCE_STATE StateFlag) { - static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == 0x40000, "This function must be updated to handle new resource state flag"); VERIFY((StateFlag & (StateFlag - 1)) == 0, "Only single bit must be set"); switch (StateFlag) { @@ -351,6 +351,8 @@ static D3D12_RESOURCE_STATES ResourceStateFlagToD3D12ResourceState(RESOURCE_STAT case RESOURCE_STATE_RESOLVE_SOURCE: return D3D12_RESOURCE_STATE_RESOLVE_SOURCE; case RESOURCE_STATE_INPUT_ATTACHMENT: return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; case RESOURCE_STATE_PRESENT: return D3D12_RESOURCE_STATE_PRESENT; + case RESOURCE_STATE_BUILD_AS: return D3D12_RESOURCE_STATES(0); + case RESOURCE_STATE_RAY_TRACING: return D3D12_RESOURCE_STATES(0); // AZ TODO // clang-format on default: UNEXPECTED("Unexpected resource state flag"); @@ -377,7 +379,7 @@ public: } private: - static constexpr Uint32 MaxFlagBitPos = 16; + static constexpr Uint32 MaxFlagBitPos = 18; std::array FlagBitPosToResStateMap; }; @@ -399,7 +401,7 @@ D3D12_RESOURCE_STATES ResourceStateFlagsToD3D12ResourceStates(RESOURCE_STATE Sta static RESOURCE_STATE D3D12ResourceStateToResourceStateFlags(D3D12_RESOURCE_STATES state) { - static_assert(RESOURCE_STATE_MAX_BIT == 0x10000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == 0x40000, "This function must be updated to handle new resource state flag"); VERIFY((state & (state - 1)) == 0, "Only single state must be set"); switch (state) { @@ -420,6 +422,7 @@ static RESOURCE_STATE D3D12ResourceStateToResourceStateFlags(D3D12_RESOURCE_STAT case D3D12_RESOURCE_STATE_COPY_SOURCE: return RESOURCE_STATE_COPY_SOURCE; case D3D12_RESOURCE_STATE_RESOLVE_DEST: return RESOURCE_STATE_RESOLVE_DEST; case D3D12_RESOURCE_STATE_RESOLVE_SOURCE: return RESOURCE_STATE_RESOLVE_SOURCE; + // AZ TODO // clang-format on default: UNEXPECTED("Unexpected D3D12 resource state"); diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 546c9de8..af0b1113 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2185,4 +2185,25 @@ void DeviceContextD3D12Impl::ResolveTextureSubresource(ITexture* CmdCtx.ResolveSubresource(pDstTexD3D12->GetD3D12Resource(), DstSubresIndex, pSrcTexD3D12->GetD3D12Resource(), SrcSubresIndex, DXGIFmt); } + +void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) +{ +} + +void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) +{ +} + +void DeviceContextD3D12Impl::CopyBLAS(const CopyBLASAttribs& Attribs) +{ +} + +void DeviceContextD3D12Impl::CopyTLAS(const CopyTLASAttribs& Attribs) +{ +} + +void DeviceContextD3D12Impl::TraceRays(const TraceRaysAttribs& Attribs) +{ +} + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index db86d662..6e4b828e 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -251,6 +251,7 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo m_DeviceCaps.Features.MeshShaders = MeshShadersSupported ? DEVICE_FEATURE_STATE_ENABLED : DEVICE_FEATURE_STATE_DISABLED; + // AZ TODO: ray tracing { D3D12_FEATURE_DATA_D3D12_OPTIONS d3d12Features = {}; @@ -297,7 +298,7 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo #undef CHECK_REQUIRED_FEATURE #if defined(_MSC_VER) && defined(_WIN64) - static_assert(sizeof(DeviceFeatures) == 30, "Did you add a new feature to DeviceFeatures? Please handle its satus here."); + static_assert(sizeof(DeviceFeatures) == 31, "Did you add a new feature to DeviceFeatures? Please handle its satus here."); #endif auto& TexCaps = m_DeviceCaps.TexCaps; @@ -680,6 +681,25 @@ void RenderDeviceD3D12Impl::CreateFramebuffer(const FramebufferDesc& Desc, IFram }); } + +void RenderDeviceD3D12Impl::CreateBLAS(const BottomLevelASDesc& Desc, + IBottomLevelAS** ppBLAS) +{ + // AZ TODO +} + +void RenderDeviceD3D12Impl::CreateTLAS(const TopLevelASDesc& Desc, + ITopLevelAS** ppTLAS) +{ + // AZ TODO +} + +void RenderDeviceD3D12Impl::CreateSBT(const ShaderBindingTableDesc& Desc, + IShaderBindingTable** ppSBT) +{ + // AZ TODO +} + DescriptorHeapAllocation RenderDeviceD3D12Impl::AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count /*= 1*/) { VERIFY(Type >= D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && Type < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES, "Invalid heap type"); -- cgit v1.2.3 From 73fd82a29d3175e156754010f5de261d6f561f16 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 4 Oct 2020 16:59:33 -0700 Subject: A few random fixes to ray tracing API and implementation --- Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 2ce314c4..c833f68e 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -329,7 +329,7 @@ D3D12_STATIC_BORDER_COLOR BorderColorToD3D12StaticBorderColor(const Float32 Bord static D3D12_RESOURCE_STATES ResourceStateFlagToD3D12ResourceState(RESOURCE_STATE StateFlag) { - static_assert(RESOURCE_STATE_MAX_BIT == 0x40000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == RESOURCE_STATE_RAY_TRACING, "This function must be updated to handle new resource state flag"); VERIFY((StateFlag & (StateFlag - 1)) == 0, "Only single bit must be set"); switch (StateFlag) { @@ -401,7 +401,7 @@ D3D12_RESOURCE_STATES ResourceStateFlagsToD3D12ResourceStates(RESOURCE_STATE Sta static RESOURCE_STATE D3D12ResourceStateToResourceStateFlags(D3D12_RESOURCE_STATES state) { - static_assert(RESOURCE_STATE_MAX_BIT == 0x40000, "This function must be updated to handle new resource state flag"); + static_assert(RESOURCE_STATE_MAX_BIT == RESOURCE_STATE_RAY_TRACING, "This function must be updated to handle new resource state flag"); VERIFY((state & (state - 1)) == 0, "Only single state must be set"); switch (state) { -- cgit v1.2.3 From 7f26e40e0898391a32e6a05d91ef1a217d885668 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Sun, 25 Oct 2020 15:53:05 +0300 Subject: PSO refactoring for ray tracing --- .../GraphicsEngineD3D12/include/CommandContext.hpp | 5 +- .../include/PipelineStateD3D12Impl.hpp | 36 +- .../include/RenderDeviceD3D12Impl.hpp | 9 +- .../GraphicsEngineD3D12/include/RootSignature.hpp | 11 +- .../include/ShaderD3D12Impl.hpp | 8 +- .../include/ShaderResourceBindingD3D12Impl.hpp | 2 +- .../include/ShaderResourceCacheD3D12.hpp | 3 +- .../include/ShaderResourceLayoutD3D12.hpp | 99 +++- .../include/ShaderVariableD3D12.hpp | 4 +- .../interface/PipelineStateD3D12.h | 6 + .../src/DeviceContextD3D12Impl.cpp | 11 +- .../src/PipelineStateD3D12Impl.cpp | 391 +++++++++++-- .../src/RenderDeviceD3D12Impl.cpp | 35 +- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 111 ++-- .../GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp | 3 +- .../src/ShaderResourceLayoutD3D12.cpp | 632 +++++++++++++-------- .../src/ShaderResourcesD3D12.cpp | 13 +- .../src/ShaderVariableD3D12.cpp | 8 +- 18 files changed, 956 insertions(+), 431 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp index d6477b79..94f74933 100644 --- a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp +++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp @@ -183,7 +183,8 @@ public: { if (pPSO != m_pCurPipelineState) { - m_pCommandList->SetPipelineState(m_pCurPipelineState = pPSO); + m_pCommandList->SetPipelineState(pPSO); + m_pCurPipelineState = pPSO; } } @@ -218,7 +219,7 @@ protected: CComPtr m_pCommandList; CComPtr m_pCurrentAllocator; - ID3D12PipelineState* m_pCurPipelineState = nullptr; + void* m_pCurPipelineState = nullptr; ID3D12RootSignature* m_pCurGraphicsRootSignature = nullptr; ID3D12RootSignature* m_pCurComputeRootSignature = nullptr; diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index fa761fc7..4bdeb08c 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -53,6 +53,7 @@ public: PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const GraphicsPipelineStateCreateInfo& CreateInfo); PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const ComputePipelineStateCreateInfo& CreateInfo); + PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const RayTracingPipelineStateCreateInfo& CreateInfo); ~PipelineStateD3D12Impl(); virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; @@ -76,7 +77,10 @@ public: virtual bool DILIGENT_CALL_TYPE IsCompatibleWith(const IPipelineState* pPSO) const override final; /// Implementation of IPipelineStateD3D12::GetD3D12PipelineState(). - virtual ID3D12PipelineState* DILIGENT_CALL_TYPE GetD3D12PipelineState() const override final { return m_pd3d12PSO; } + virtual ID3D12PipelineState* DILIGENT_CALL_TYPE GetD3D12PipelineState() const override final { return static_cast(m_pd3d12PSO.p); } + + /// Implementation of IPipelineStateD3D12::GetD3D12StateObject(). + virtual ID3D12StateObject* DILIGENT_CALL_TYPE GetD3D12StateObject() const override final { return static_cast(m_pd3d12PSO.p); } /// Implementation of IPipelineStateD3D12::GetD3D12RootSignature(). virtual ID3D12RootSignature* DILIGENT_CALL_TYPE GetD3D12RootSignature() const override final { return m_RootSig.GetD3D12RootSignature(); } @@ -121,27 +125,27 @@ public: } private: - struct D3D12PipelineShaderStageInfo + struct ShaderStageInfo { - const SHADER_TYPE Type; - ShaderD3D12Impl* const pShader; - D3D12PipelineShaderStageInfo(SHADER_TYPE _Type, - ShaderD3D12Impl* _pShader) : - Type{_Type}, - pShader{_pShader} - {} + ShaderStageInfo() {} + ShaderStageInfo(SHADER_TYPE _Type, ShaderD3D12Impl* _pShader); + + void Append(ShaderD3D12Impl* pShader); + size_t Count() const; + + SHADER_TYPE Type; + std::vector Shaders; }; + using TShaderStages = std::vector; template - void InitInternalObjects(const PSOCreateInfoType& CreateInfo, std::vector& ShaderStages); - - void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, - std::vector& ShaderStages); + void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages); + void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages); void Destruct(); - CComPtr m_pd3d12PSO; - RootSignature m_RootSig; + CComPtr m_pd3d12PSO; + RootSignature m_RootSig; // Must be defined before default SRB SRBMemoryAllocator m_SRBMemAllocator; @@ -152,7 +156,7 @@ private: // Resource layout index in m_pShaderResourceLayouts array for every shader stage, // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex) - std::array m_ResourceLayoutIndex = {-1, -1, -1, -1, -1}; + std::array m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1}; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 7bdc7801..2bc13c31 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -68,6 +68,9 @@ public: /// Implementation of IRenderDevice::CreateComputePipelineState() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; + /// Implementation of IRenderDevice::CreateRayTracingPipelineState() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; + /// Implementation of IRenderDevice::CreateBuffer() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, @@ -169,9 +172,8 @@ public: IDXCompiler* GetDxCompiler() const { return m_pDxCompiler.get(); } -#ifdef D3D12_H_HAS_MESH_SHADER ID3D12Device2* GetD3D12Device2(); -#endif + ID3D12Device5* GetD3D12Device5(); ShaderVersion GetMaxShaderModel() const; D3D_FEATURE_LEVEL GetD3DFeatureLevel() const; @@ -185,9 +187,8 @@ private: CComPtr m_pd3d12Device; -#ifdef D3D12_H_HAS_MESH_SHADER CComPtr m_pd3d12Device2; -#endif + CComPtr m_pd3d12Device5; EngineD3D12CreateInfo m_EngineAttribs; diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index 232bce65..6deac5f0 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -36,7 +36,6 @@ namespace Diligent { -SHADER_TYPE ShaderTypeFromShaderVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility); D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType); D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType); @@ -514,6 +513,10 @@ private: class CommandContext& Ctx, bool IsCompute, bool ValidateStates) const; + +#ifdef DILIGENT_DEBUG + SHADER_TYPE m_DbgShaderStages = SHADER_TYPE_UNKNOWN; +#endif }; void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, @@ -534,11 +537,7 @@ void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; #ifdef DILIGENT_DEBUG - { - auto& Param = static_cast(RootView); - VERIFY_EXPR(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV); - dbgShaderType = ShaderTypeFromShaderVisibility(Param.ShaderVisibility); - } + dbgShaderType = m_DbgShaderStages; #endif auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType); diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.hpp index b2143b76..0b9b6fee 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.hpp @@ -34,9 +34,8 @@ #include "ShaderD3D12.h" #include "ShaderBase.hpp" #include "ShaderD3DBase.hpp" -#include "ShaderResourceLayoutD3D12.hpp" #include "RenderDeviceD3D12Impl.hpp" -#include "ShaderVariableD3D12.hpp" +#include "ShaderResourcesD3D12.hpp" namespace Diligent { @@ -74,7 +73,8 @@ public: ResourceDesc = m_pShaderResources->GetHLSLShaderResourceDesc(Index); } - ID3DBlob* GetShaderByteCode() { return m_pShaderByteCode; } + ID3DBlob* GetShaderByteCode() { return m_pShaderByteCode; } + const Char* GetEntryPoint() const { return m_EntryPoint.c_str(); } const std::shared_ptr& GetShaderResources() const { return m_pShaderResources; } @@ -82,6 +82,8 @@ private: // ShaderResources class instance must be referenced through the shared pointer, because // it is referenced by ShaderResourceLayoutD3D12 class instances std::shared_ptr m_pShaderResources; + + String m_EntryPoint; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp index 7be3372d..ac16cf9f 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp @@ -85,7 +85,7 @@ private: // Resource layout index in m_ShaderResourceCache array for every shader stage, // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex) - std::array m_ResourceLayoutIndex = {-1, -1, -1, -1, -1}; + std::array m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1}; bool m_bStaticResourcesInitialized = false; const Uint8 m_NumShaders = 0; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp index 8a8f7b25..cf69793a 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp @@ -97,6 +97,7 @@ enum class CachedResourceType : Int32 TexUAV, BufUAV, Sampler, + AccelStruct, NumTypes }; @@ -166,7 +167,7 @@ public: const SHADER_TYPE dbgRefShaderType) const { VERIFY(m_dbgHeapType == dbgDescriptorHeapType, "Incosistent descriptor heap type"); - VERIFY(m_dbgShaderType == dbgRefShaderType, "Incosistent shader type"); + VERIFY((m_dbgShaderType & dbgRefShaderType) == dbgRefShaderType, "Incosistent shader type"); VERIFY(OffsetFromTableStart < m_NumResources, "Root table is not large enough to store descriptor at offset ", OffsetFromTableStart); return m_pResources[OffsetFromTableStart]; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index 719345fc..bd581101 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -103,6 +103,7 @@ #include "ShaderBase.hpp" #include "ShaderResourcesD3D12.hpp" #include "ShaderResourceCacheD3D12.hpp" +#include "ShaderD3D12Impl.hpp" namespace Diligent { @@ -121,15 +122,15 @@ public: // - initialize reference layouts that address all types of resources (static, mutable, dynamic). // Root indices and descriptor table offsets are assigned during the initialization; // no shader resource cache is provided - void Initialize(ID3D12Device* pd3d12Device, - PIPELINE_TYPE PipelineType, - const PipelineResourceLayoutDesc& ResourceLayout, - std::shared_ptr pSrcResources, - IMemoryAllocator& LayoutDataAllocator, - const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheD3D12* pResourceCache, - class RootSignature* pRootSig); + void Initialize(ID3D12Device* pd3d12Device, + PIPELINE_TYPE PipelineType, + const PipelineResourceLayoutDesc& ResourceLayout, + const std::vector& Shaders, + IMemoryAllocator& LayoutDataAllocator, + const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheD3D12* pResourceCache, + class RootSignature* pRootSig); // clang-format off ShaderResourceLayoutD3D12 (const ShaderResourceLayoutD3D12&) = delete; @@ -165,31 +166,43 @@ public: static_assert( static_cast(CachedResourceType::NumTypes) < (1 << ResourceTypeBits), "3 bits is not enough to store CachedResourceType"); /* 0 */ const ShaderResourceLayoutD3D12& ParentResLayout; -/* 8 */ const D3DShaderResourceAttribs& Attribs; /*16 */ const Uint32 OffsetFromTableStart; /*20.0*/ const Uint16 ResourceType : ResourceTypeBits; // | 0 1 2 | /*20.3*/ const Uint16 VariableType : VariableTypeBits; // | 3 4 | /*20.5*/ const Uint16 RootIndex : RootIndexBits; // | 5 6 7 ... 15 | /*22 */ const Uint16 SamplerId; -/*24 */ // End of data +/* */ const char* const Name; +/* */ const Uint16 BindCount; +/* */ const Uint16 BindPoint; +/* */ const Uint8 InputType; +/* */ const Uint8 SRVDimension; +/* */ // End of data // clang-format on D3D12Resource(const ShaderResourceLayoutD3D12& _ParentLayout, - const D3DShaderResourceAttribs& _Attribs, SHADER_RESOURCE_VARIABLE_TYPE _VariableType, CachedResourceType _ResType, Uint32 _RootIndex, Uint32 _OffsetFromTableStart, - Uint32 _SamplerId) noexcept : + Uint32 _SamplerId, + const char* _Name, + Uint32 _BindCount, + Uint32 _BindPoint, + D3D_SHADER_INPUT_TYPE _InputType, + D3D_SRV_DIMENSION _SRVDimension) noexcept : // clang-format off ParentResLayout {_ParentLayout }, - Attribs {_Attribs }, ResourceType {static_cast(_ResType) }, VariableType {static_cast(_VariableType)}, RootIndex {static_cast(_RootIndex) }, SamplerId {static_cast(_SamplerId) }, - OffsetFromTableStart{ _OffsetFromTableStart } + OffsetFromTableStart{ _OffsetFromTableStart }, + Name {_Name}, + BindCount {static_cast(_BindCount) }, + BindPoint {static_cast(_BindPoint) }, + InputType {static_cast(_InputType) }, + SRVDimension {static_cast(_SRVDimension) } // clang-format on { VERIFY(IsValidOffset(), "Offset must be valid"); @@ -198,6 +211,10 @@ public: VERIFY(_VariableType < (1 << VariableTypeBits), "Variable type is out of representable range"); VERIFY(_SamplerId == InvalidSamplerId || _SamplerId <= MaxSamplerId, "Sampler id (", _SamplerId, ") exceeds max allowed value (", MaxSamplerId, ")"); VERIFY(_SamplerId == InvalidSamplerId || GetResType() == CachedResourceType::TexSRV, "A sampler can only be assigned to a Texture SRV"); + VERIFY(_BindCount <= std::numeric_limits::max(), "BindCount (", _BindCount, ") exceeds max representable value ", std::numeric_limits::max()); + VERIFY(_BindPoint <= std::numeric_limits::max(), "BindPoint (", _BindPoint, ") exceeds max representable value ", std::numeric_limits::max()); + VERIFY(_InputType <= std::numeric_limits::max(), "InputType (", _InputType, ") exceeds max representable value ", std::numeric_limits::max()); + VERIFY(_SRVDimension <= std::numeric_limits::max(), "SRVDimension (", _SRVDimension, ") exceeds max representable value ", std::numeric_limits::max()); } bool IsBound(Uint32 ArrayIndex, @@ -215,6 +232,35 @@ public: CachedResourceType GetResType() const { return static_cast(ResourceType); } SHADER_RESOURCE_VARIABLE_TYPE GetVariableType() const { return static_cast(VariableType); } + HLSLShaderResourceDesc GetHLSLResourceDesc() const; + + bool IsValidBindPoint() const + { + return BindPoint != D3DShaderResourceAttribs::InvalidBindPoint; + } + + String GetPrintName(Uint32 ArrayInd) const + { + VERIFY_EXPR(ArrayInd < BindCount); + if (BindCount > 1) + return String(Name) + '[' + std::to_string(ArrayInd) + ']'; + else + return Name; + } + + D3D_SHADER_INPUT_TYPE GetInputType() const + { + return static_cast(InputType); + } + + D3D_SRV_DIMENSION GetSRVDimension() const + { + return static_cast(SRVDimension); + } + + RESOURCE_DIMENSION GetResourceDimension() const; + + bool IsMultisample() const; private: void CacheCB(IDeviceObject* pBuffer, @@ -237,6 +283,11 @@ public: ShaderResourceCacheD3D12::Resource& DstSam, Uint32 ArrayIndex, D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const; + + void CacheAccelStruct(IDeviceObject* pTLAS, + ShaderResourceCacheD3D12::Resource& DstRes, + Uint32 ArrayIndex, + D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const; }; void CopyStaticResourceDesriptorHandles(const ShaderResourceCacheD3D12& SrcCache, @@ -272,11 +323,9 @@ public: return GetResource(GetSamplerOffset(VarType, s)); } - const bool IsUsingSeparateSamplers() const { return !m_pResources->IsUsingCombinedTextureSamplers(); } - - SHADER_TYPE GetShaderType() const { return m_pResources->GetShaderType(); } + const bool IsUsingSeparateSamplers() const { return m_IsUsingSeparateSamplers; } - const ShaderResourcesD3D12& GetResources() const { return *m_pResources; } + SHADER_TYPE GetShaderType() const { return m_ShaderType; } private: const D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv) const; @@ -284,7 +333,7 @@ private: const Char* GetShaderName() const { - return m_pResources->GetShaderName(); + return ""; // AZ TODO } @@ -353,11 +402,11 @@ private: /* 16 */ std::array m_CbvSrvUavOffsets = {}; /* 24 */ std::array m_SamplersOffsets = {}; -/* 32 */ IObject& m_Owner; -/* 48 */ CComPtr m_pd3d12Device; - // We must use shared_ptr to reference ShaderResources instance, because - // there may be multiple objects referencing the same set of resources -/* 48 */ std::shared_ptr m_pResources; +/* 24 */ StringPool m_StringPool; +/* 32 */ IObject& m_Owner; +/* 48 */ CComPtr m_pd3d12Device; +/* */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; +/* */ bool m_IsUsingSeparateSamplers = false; /* 64 */ // End of data // clang-format on diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp index c30d8296..1e60ecd8 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp @@ -186,7 +186,7 @@ public: virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final { - VerifyAndCorrectSetArrayArguments(m_Resource.Attribs.Name, m_Resource.Attribs.BindCount, FirstElement, NumElements); + VerifyAndCorrectSetArrayArguments(m_Resource.Name, m_Resource.BindCount, FirstElement, NumElements); for (Uint32 Elem = 0; Elem < NumElements; ++Elem) m_Resource.BindResource(ppObjects[Elem], FirstElement + Elem, m_ParentManager.m_ResourceCache); } @@ -198,7 +198,7 @@ public: virtual HLSLShaderResourceDesc DILIGENT_CALL_TYPE GetHLSLResourceDesc() const override final { - return m_Resource.Attribs.GetHLSLResourceDesc(); + return m_Resource.GetHLSLResourceDesc(); } virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final diff --git a/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h b/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h index fd219b95..cd315d3e 100644 --- a/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h @@ -54,6 +54,12 @@ DILIGENT_BEGIN_INTERFACE(IPipelineStateD3D12, IPipelineState) /// so Release() must not be called. VIRTUAL ID3D12PipelineState* METHOD(GetD3D12PipelineState)(THIS) CONST PURE; + /// Returns ID3D12StateObject interface of the internal D3D12 state object for ray tracing. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + VIRTUAL ID3D12StateObject* METHOD(GetD3D12StateObject)(THIS) CONST PURE; + /// Returns a pointer to the root signature object associated with this pipeline state. /// The method does *NOT* call AddRef() on the returned interface, diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index b89b226c..6ca74c27 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -219,8 +219,7 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) TDeviceContextBase::SetPipelineState(pPipelineStateD3D12, 0 /*Dummy*/); - auto& CmdCtx = GetCmdContext(); - auto* pd3d12PSO = pPipelineStateD3D12->GetD3D12PipelineState(); + auto& CmdCtx = GetCmdContext(); switch (PSODesc.PipelineType) { @@ -229,6 +228,7 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) { auto& GraphicsPipeline = pPipelineStateD3D12->GetGraphicsPipelineDesc(); auto& GraphicsCtx = CmdCtx.AsGraphicsContext(); + auto* pd3d12PSO = pPipelineStateD3D12->GetD3D12PipelineState(); GraphicsCtx.SetPipelineState(pd3d12PSO); if (PSODesc.PipelineType == PIPELINE_TYPE_GRAPHICS) @@ -254,13 +254,16 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) } break; } - case PIPELINE_TYPE_COMPUTE: { + auto* pd3d12PSO = pPipelineStateD3D12->GetD3D12PipelineState(); CmdCtx.AsComputeContext().SetPipelineState(pd3d12PSO); break; } - + case PIPELINE_TYPE_RAY_TRACING: + { + break; + } default: UNEXPECTED("unknown pipeline type"); } diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 2d31e70d..6efa4acc 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -37,6 +37,7 @@ #include "EngineMemory.h" #include "StringTools.hpp" #include "ShaderVariableD3D12.hpp" +#include "DynamicLinearAllocator.hpp" namespace Diligent { @@ -70,7 +71,6 @@ struct alignas(void*) PSS_SubObject # pragma warning(pop) #endif -} // namespace class PrimitiveTopology_To_D3D12_PRIMITIVE_TOPOLOGY_TYPE { @@ -98,9 +98,211 @@ private: std::array m_Map; }; + +template +void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateInfo, + TNameToGroupIndexMap& NameToGroupIndex, + std::vector& Subobjects, + DynamicLinearAllocator& TempPool, + LinearAllocator& MemPool) +{ +#define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ray tracing PSO '", CreateInfo.PSODesc.Name, "' is invalid: ", ##__VA_ARGS__) + + Uint32 ShaderIndex = 0; + Uint32 GroupIndex = 0; + std::unordered_map UniqueShaders; + + const auto ShaderIndexToStr = [&TempPool](Uint32 Index) -> LPCWSTR { + const Uint32 Len = sizeof(Index) * 2; + auto* Dst = TempPool.Allocate(Len + 1); + for (Uint32 i = 0; i < Len; ++i) + { + Uint32 c = Index & 0xF; + Dst[i] = static_cast(c < 10 ? '0' + c : 'A' + c - 10); + Index >>= 4; + } + Dst[Len] = 0; + return Dst; + }; + + const auto AddDxilLib = [&](IShader* pShader, const char* Name) -> LPCWSTR { + if (pShader != nullptr) + { + auto Result = UniqueShaders.emplace(pShader, nullptr); + if (Result.second) + { + auto& LibDesc = *TempPool.Allocate(); + auto& ExportDesc = *TempPool.Allocate(); + auto* pShaderD3D12 = ValidatedCast(pShader); + + LibDesc.DXILLibrary.BytecodeLength = pShaderD3D12->GetShaderByteCode()->GetBufferSize(); + LibDesc.DXILLibrary.pShaderBytecode = pShaderD3D12->GetShaderByteCode()->GetBufferPointer(); + LibDesc.NumExports = 1; + LibDesc.pExports = &ExportDesc; + + ExportDesc.Flags = D3D12_EXPORT_FLAG_NONE; + ExportDesc.ExportToRename = TempPool.CopyWString(pShaderD3D12->GetEntryPoint()); + + if (Name != nullptr) + ExportDesc.Name = TempPool.CopyWString(Name); + else + ExportDesc.Name = ShaderIndexToStr(++ShaderIndex); + + Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY, &LibDesc}); + + Result.first->second = ExportDesc.Name; + return ExportDesc.Name; + } + else + return Result.first->second; + } + return nullptr; + }; + + for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i) + { + AddDxilLib(CreateInfo.pGeneralShaders[i].pShader, CreateInfo.pGeneralShaders[i].Name); + + bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pGeneralShaders[i].Name)}, GroupIndex++).second; + if (!IsUniqueName) + LOG_PSO_ERROR_AND_THROW("pGeneralShaders[", i, "].Name must be unique"); + } + + for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i) + { + auto& HitGroupDesc = *TempPool.Allocate(); + HitGroupDesc.HitGroupExport = TempPool.CopyWString(CreateInfo.pTriangleHitShaders[i].Name); + HitGroupDesc.Type = D3D12_HIT_GROUP_TYPE_TRIANGLES; + HitGroupDesc.ClosestHitShaderImport = AddDxilLib(CreateInfo.pTriangleHitShaders[i].pClosestHitShader, nullptr); + HitGroupDesc.AnyHitShaderImport = AddDxilLib(CreateInfo.pTriangleHitShaders[i].pAnyHitShader, nullptr); + HitGroupDesc.IntersectionShaderImport = nullptr; + + Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); + + bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pTriangleHitShaders[i].Name)}, GroupIndex++).second; + if (!IsUniqueName) + LOG_PSO_ERROR_AND_THROW("pTriangleHitShaders[", i, "].Name must be unique"); + } + + for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i) + { + auto& HitGroupDesc = *TempPool.Allocate(); + HitGroupDesc.HitGroupExport = TempPool.CopyWString(CreateInfo.pProceduralHitShaders[i].Name); + HitGroupDesc.Type = D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE; + HitGroupDesc.ClosestHitShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pClosestHitShader, nullptr); + HitGroupDesc.AnyHitShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pAnyHitShader, nullptr); + HitGroupDesc.IntersectionShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pIntersectionShader, nullptr); + + Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); + + bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pProceduralHitShaders[i].Name)}, GroupIndex++).second; + if (!IsUniqueName) + LOG_PSO_ERROR_AND_THROW("pProceduralHitShaders[", i, "].Name must be unique"); + } + + VERIFY_EXPR(Uint32(CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount) == GroupIndex); + + if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH) + LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than equal to ", D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH); + + auto& PipelineConfig = *TempPool.Allocate(); + // for compatibility with Vulkan set minimal recursion depth to 1 + PipelineConfig.MaxTraceRecursionDepth = std::max(1, CreateInfo.RayTracingPipeline.MaxRecursionDepth); + Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG, &PipelineConfig}); + + auto& ShaderConfig = *TempPool.Allocate(); + ShaderConfig.MaxAttributeSizeInBytes = D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES; + ShaderConfig.MaxPayloadSizeInBytes = 32; // AZ TODO + Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &ShaderConfig}); +#undef LOG_PSO_ERROR_AND_THROW +} + +template +void GetShaderIdentifiers(ID3D12StateObject* pSO, + const RayTracingPipelineStateCreateInfo& CreateInfo, + const TNameToGroupIndexMap& NameToGroupIndex, + Uint8* ShaderData) +{ + const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; + + WCHAR TempName[256] = {}; + auto ConvertWStr = [&TempName](const char* Src) { + Uint32 i = 0; + for (; i < _countof(TempName) && Src[i] != 0; ++i) + TempName[i] = static_cast(Src[i]); + TempName[i] = 0; + return TempName; + }; + + CComPtr pStateObjectProperties; + auto hr = pSO->QueryInterface(IID_PPV_ARGS(&pStateObjectProperties)); + if (FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to get state object properties"); + + for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i) + { + auto iter = NameToGroupIndex.find(CreateInfo.pGeneralShaders[i].Name); + if (iter == NameToGroupIndex.end()) + LOG_ERROR_AND_THROW("Failed to get shader group index by name"); + + WCHAR* ShaderName = ConvertWStr(CreateInfo.pGeneralShaders[i].Name); + const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName); + if (ShaderID == nullptr) + LOG_ERROR_AND_THROW("Failed to get shader identifier"); + + std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize); + } + for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i) + { + auto iter = NameToGroupIndex.find(CreateInfo.pTriangleHitShaders[i].Name); + if (iter == NameToGroupIndex.end()) + LOG_ERROR_AND_THROW("Failed to get shader group index by name"); + + WCHAR* ShaderName = ConvertWStr(CreateInfo.pTriangleHitShaders[i].Name); + const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName); + if (ShaderID == nullptr) + LOG_ERROR_AND_THROW("Failed to get shader identifier"); + + std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize); + } + for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i) + { + auto iter = NameToGroupIndex.find(CreateInfo.pProceduralHitShaders[i].Name); + if (iter == NameToGroupIndex.end()) + LOG_ERROR_AND_THROW("Failed to get shader group index by name"); + + WCHAR* ShaderName = ConvertWStr(CreateInfo.pProceduralHitShaders[i].Name); + const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName); + if (ShaderID == nullptr) + LOG_ERROR_AND_THROW("Failed to get shader identifier"); + + std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize); + } +} + +} // namespace + + +PipelineStateD3D12Impl::ShaderStageInfo::ShaderStageInfo(SHADER_TYPE _Type, ShaderD3D12Impl* _pShader) : + Type{_Type} +{ + Shaders.push_back(_pShader); +} + +void PipelineStateD3D12Impl::ShaderStageInfo::Append(ShaderD3D12Impl* pShader) +{ + Shaders.push_back(pShader); +} + +size_t PipelineStateD3D12Impl::ShaderStageInfo::Count() const +{ + return Shaders.size(); +} + + template -void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, - std::vector& ShaderStages) +void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, + TShaderStages& ShaderStages) { m_ResourceLayoutIndex.fill(-1); @@ -151,8 +353,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { - std::vector ShaderStages; - + TShaderStages ShaderStages; InitInternalObjects(CreateInfo, ShaderStages); auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); @@ -164,19 +365,20 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* for (const auto& Stage : ShaderStages) { - auto* pShaderD3D12 = Stage.pShader; + VERIFY_EXPR(Stage.Shaders.size() == 1); + auto* pShaderD3D12 = Stage.Shaders[0]; auto ShaderType = pShaderD3D12->GetDesc().ShaderType; VERIFY_EXPR(ShaderType == Stage.Type); D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr; switch (ShaderType) { - // clang-format off - case SHADER_TYPE_VERTEX: pd3d12ShaderBytecode = &d3d12PSODesc.VS; break; - case SHADER_TYPE_PIXEL: pd3d12ShaderBytecode = &d3d12PSODesc.PS; break; - case SHADER_TYPE_GEOMETRY: pd3d12ShaderBytecode = &d3d12PSODesc.GS; break; - case SHADER_TYPE_HULL: pd3d12ShaderBytecode = &d3d12PSODesc.HS; break; - case SHADER_TYPE_DOMAIN: pd3d12ShaderBytecode = &d3d12PSODesc.DS; break; + // clang-format off + case SHADER_TYPE_VERTEX: pd3d12ShaderBytecode = &d3d12PSODesc.VS; break; + case SHADER_TYPE_PIXEL: pd3d12ShaderBytecode = &d3d12PSODesc.PS; break; + case SHADER_TYPE_GEOMETRY: pd3d12ShaderBytecode = &d3d12PSODesc.GS; break; + case SHADER_TYPE_HULL: pd3d12ShaderBytecode = &d3d12PSODesc.HS; break; + case SHADER_TYPE_DOMAIN: pd3d12ShaderBytecode = &d3d12PSODesc.DS; break; // clang-format on default: UNEXPECTED("Unexpected shader type"); } @@ -237,9 +439,12 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices. d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; - HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast(static_cast(&m_pd3d12PSO))); + CComPtr pPSO; + HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, IID_PPV_ARGS(&pPSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create pipeline state"); + + m_pd3d12PSO = pPSO; } #ifdef D3D12_H_HAS_MESH_SHADER @@ -268,17 +473,18 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* for (const auto& Stage : ShaderStages) { - auto* pShaderD3D12 = Stage.pShader; + VERIFY_EXPR(Stage.Shaders.size() == 1); + auto* pShaderD3D12 = Stage.Shaders[0]; auto ShaderType = pShaderD3D12->GetDesc().ShaderType; VERIFY_EXPR(ShaderType == Stage.Type); D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr; switch (ShaderType) { - // clang-format off - case SHADER_TYPE_AMPLIFICATION: pd3d12ShaderBytecode = &d3d12PSODesc.AS; break; - case SHADER_TYPE_MESH: pd3d12ShaderBytecode = &d3d12PSODesc.MS; break; - case SHADER_TYPE_PIXEL: pd3d12ShaderBytecode = &d3d12PSODesc.PS; break; + // clang-format off + case SHADER_TYPE_AMPLIFICATION: pd3d12ShaderBytecode = &d3d12PSODesc.AS; break; + case SHADER_TYPE_MESH: pd3d12ShaderBytecode = &d3d12PSODesc.MS; break; + case SHADER_TYPE_PIXEL: pd3d12ShaderBytecode = &d3d12PSODesc.PS; break; // clang-format on default: UNEXPECTED("Unexpected shader type"); } @@ -321,9 +527,13 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* streamDesc.SizeInBytes = sizeof(d3d12PSODesc); streamDesc.pPipelineStateSubobjectStream = &d3d12PSODesc; - auto* device2 = pDeviceD3D12->GetD3D12Device2(); + auto* device2 = pDeviceD3D12->GetD3D12Device2(); + CComPtr pPSO; + HRESULT hr = device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&pPSO)); + if (FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create pipeline state"); - CHECK_D3D_RESULT_THROW(device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&m_pd3d12PSO)), "Failed to create pipeline state"); + m_pd3d12PSO = pPSO; } #endif // D3D12_H_HAS_MESH_SHADER else @@ -355,8 +565,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { - std::vector ShaderStages; - + TShaderStages ShaderStages; InitInternalObjects(CreateInfo, ShaderStages); auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); @@ -364,7 +573,8 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* D3D12_COMPUTE_PIPELINE_STATE_DESC d3d12PSODesc = {}; VERIFY_EXPR(ShaderStages[0].Type == SHADER_TYPE_COMPUTE); - auto* pByteCode = ShaderStages[0].pShader->GetShaderByteCode(); + VERIFY_EXPR(ShaderStages[0].Shaders.size() == 1); + auto* pByteCode = ShaderStages[0].Shaders[0]->GetShaderByteCode(); d3d12PSODesc.CS.pShaderBytecode = pByteCode->GetBufferPointer(); d3d12PSODesc.CS.BytecodeLength = pByteCode->GetBufferSize(); @@ -381,10 +591,101 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature(); - HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast(static_cast(&m_pd3d12PSO))); + CComPtr pPSO; + HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, IID_PPV_ARGS(&pPSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create pipeline state"); + m_pd3d12PSO = pPSO; + + if (*m_Desc.Name != 0) + { + m_pd3d12PSO->SetName(WidenString(m_Desc.Name).c_str()); + String RootSignatureDesc("Root signature for PSO '"); + RootSignatureDesc.append(m_Desc.Name); + RootSignatureDesc.push_back('\''); + m_RootSig.GetD3D12RootSignature()->SetName(WidenString(RootSignatureDesc).c_str()); + } + } + catch (...) + { + Destruct(); + throw; + } +} + +PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDeviceD3D12, + const RayTracingPipelineStateCreateInfo& CreateInfo) : + TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo.PSODesc}, + m_SRBMemAllocator{GetRawAllocator()} +{ + try + { + m_ResourceLayoutIndex.fill(-1); + + TShaderStages ShaderStages; + ExtractShaders(CreateInfo, ShaderStages); + + TNameToGroupIndexMap NameToGroupIndex; + std::vector Subobjects; + const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; + DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10}; + LinearAllocator MemPool{GetRawAllocator()}; + + const auto NumShaderStages = GetNumShaderStages(); + VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size()); + + MemPool.AddSpace(NumShaderStages); + MemPool.AddSpace(NumShaderStages * 2); + MemPool.AddSpace(NumShaderStages); + + ReserveSpaceForPipelineDesc(CreateInfo, ShaderIdentifierSize, MemPool); + + MemPool.Reserve(); + + m_pStaticResourceCaches = MemPool.ConstructArray(NumShaderStages, ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources); + + // The memory is now owned by PipelineStateD3D12Impl and will be freed by Destruct(). + auto* Ptr = MemPool.ReleaseOwnership(); + VERIFY_EXPR(Ptr == m_pStaticResourceCaches); + (void)Ptr; + + m_pShaderResourceLayouts = MemPool.ConstructArray(NumShaderStages * 2, std::ref(*this)); + + m_pStaticVarManagers = MemPool.Allocate(NumShaderStages); + for (Uint32 s = 0; s < NumShaderStages; ++s) + new (m_pStaticVarManagers + s) ShaderVariableManagerD3D12{*this, GetStaticShaderResCache(s)}; + + BuildRTPipelineDescription(CreateInfo, NameToGroupIndex, Subobjects, TempPool, MemPool); + InitializePipelineDesc(CreateInfo, ShaderIdentifierSize, std::move(NameToGroupIndex), MemPool); + + m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); + + // It is important to construct all objects before initializing them because if an exception is thrown, + // destructors will be called for all objects + + InitResourceLayouts(CreateInfo, ShaderStages); + + D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot; + GlobalRoot.pGlobalRootSignature = m_RootSig.GetD3D12RootSignature(); + Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot}); + + D3D12_STATE_OBJECT_DESC RTPipelineDesc; + RTPipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE; + RTPipelineDesc.NumSubobjects = static_cast(Subobjects.size()); + RTPipelineDesc.pSubobjects = Subobjects.data(); + + auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + CComPtr pSO; + HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&pSO)); + if (FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create ray tracing state object"); + + m_pd3d12PSO = pSO; + + GetShaderIdentifiers(pSO, CreateInfo, m_pRayTracingPipelineData->NameToGroupIndex, m_pRayTracingPipelineData->Shaders); + if (*m_Desc.Name != 0) { m_pd3d12PSO->SetName(WidenString(m_Desc.Name).c_str()); @@ -408,6 +709,8 @@ PipelineStateD3D12Impl::~PipelineStateD3D12Impl() void PipelineStateD3D12Impl::Destruct() { + TPipelineStateBase::Destruct(); + auto& ShaderResLayoutAllocator = GetRawAllocator(); for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { @@ -444,18 +747,19 @@ void PipelineStateD3D12Impl::Destruct() IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipelineStateBase) -void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, - std::vector& ShaderStages) +void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, + TShaderStages& ShaderStages) { auto pd3d12Device = GetDevice()->GetD3D12Device(); const auto& ResourceLayout = m_Desc.ResourceLayout; -#ifdef DILIGENT_DEVELOPMENT + // AZ TODO +#if 0 //def DILIGENT_DEVELOPMENT { const ShaderResources* pResources[MAX_SHADERS_IN_PIPELINE] = {}; for (size_t s = 0; s < ShaderStages.size(); ++s) { - const auto* pShader = ShaderStages[s].pShader; + const auto* pShader = ShaderStages[s].Shaders[0]; pResources[s] = &(*pShader->GetShaderResources()); } ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderStages(), @@ -466,9 +770,9 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto* pShaderD3D12 = ShaderStages[s].pShader; - auto ShaderType = pShaderD3D12->GetDesc().ShaderType; - auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); + auto Shaders = ShaderStages[s].Shaders; + auto ShaderType = ShaderStages[s].Type; + auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); m_ResourceLayoutIndex[ShaderInd] = static_cast(s); @@ -476,7 +780,7 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& pd3d12Device, m_Desc.PipelineType, ResourceLayout, - pShaderD3D12->GetShaderResources(), + Shaders, GetRawAllocator(), nullptr, 0, @@ -489,7 +793,7 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& pd3d12Device, m_Desc.PipelineType, ResourceLayout, - pShaderD3D12->GetShaderResources(), + Shaders, GetRawAllocator(), StaticVarType, _countof(StaticVarType), @@ -550,7 +854,8 @@ bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState* pPSO) const auto IsSameRootSignature = m_RootSig.IsSameAs(pPSOD3D12->m_RootSig); -#ifdef DILIGENT_DEBUG + // AZ TODO +#if 0 //def DILIGENT_DEBUG { bool IsCompatibleShaders = true; if (GetNumShaderStages() != pPSOD3D12->GetNumShaderStages()) @@ -601,10 +906,10 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou { if (Attrib.CommitResources) { - if (m_Desc.IsComputePipeline()) - CmdCtx.AsComputeContext().SetRootSignature(GetD3D12RootSignature()); - else + if (m_Desc.IsAnyGraphicsPipeline()) CmdCtx.AsGraphicsContext().SetRootSignature(GetD3D12RootSignature()); + else + CmdCtx.AsComputeContext().SetRootSignature(GetD3D12RootSignature()); } return nullptr; } @@ -630,18 +935,18 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou auto& ResourceCache = pResBindingD3D12Impl->GetResourceCache(); if (Attrib.CommitResources) { - if (m_Desc.IsComputePipeline()) - CmdCtx.AsComputeContext().SetRootSignature(GetD3D12RootSignature()); - else + if (m_Desc.IsAnyGraphicsPipeline()) CmdCtx.AsGraphicsContext().SetRootSignature(GetD3D12RootSignature()); + else + CmdCtx.AsComputeContext().SetRootSignature(GetD3D12RootSignature()); if (Attrib.TransitionResources) { - (m_RootSig.*m_RootSig.TransitionAndCommitDescriptorHandles)(m_pDevice, ResourceCache, CmdCtx, m_Desc.IsComputePipeline(), Attrib.ValidateStates); + (m_RootSig.*m_RootSig.TransitionAndCommitDescriptorHandles)(m_pDevice, ResourceCache, CmdCtx, !m_Desc.IsAnyGraphicsPipeline(), Attrib.ValidateStates); } else { - (m_RootSig.*m_RootSig.CommitDescriptorHandles)(m_pDevice, ResourceCache, CmdCtx, m_Desc.IsComputePipeline(), Attrib.ValidateStates); + (m_RootSig.*m_RootSig.CommitDescriptorHandles)(m_pDevice, ResourceCache, CmdCtx, !m_Desc.IsAnyGraphicsPipeline(), Attrib.ValidateStates); } } else @@ -653,7 +958,7 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou // Process only non-dynamic buffers at this point. Dynamic buffers will be handled by the Draw/Dispatch command. m_RootSig.CommitRootViews(ResourceCache, CmdCtx, - m_Desc.IsComputePipeline(), + !m_Desc.IsAnyGraphicsPipeline(), Attrib.CtxId, pDeviceCtx, Attrib.CommitResources, // CommitViews diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index 61ad5871..eee2e1fa 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -89,7 +89,6 @@ D3D_FEATURE_LEVEL RenderDeviceD3D12Impl::GetD3DFeatureLevel() const return FeatureLevelsData.MaxSupportedFeatureLevel; } -#ifdef D3D12_H_HAS_MESH_SHADER ID3D12Device2* RenderDeviceD3D12Impl::GetD3D12Device2() { if (!m_pd3d12Device2) @@ -98,7 +97,15 @@ ID3D12Device2* RenderDeviceD3D12Impl::GetD3D12Device2() } return m_pd3d12Device2; } -#endif + +ID3D12Device5* RenderDeviceD3D12Impl::GetD3D12Device5() +{ + if (!m_pd3d12Device5) + { + CHECK_D3D_RESULT_THROW(m_pd3d12Device->QueryInterface(IID_PPV_ARGS(&m_pd3d12Device5)), "Failed to get ID3D12Device5"); + } + return m_pd3d12Device5; +} RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCounters, IMemoryAllocator& RawMemAllocator, @@ -154,6 +161,8 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo m_pDxCompiler {CreateDXCompiler(DXCompilerTarget::Direct3D12, EngineCI.pDxCompilerPath)} // clang-format on { + static_assert(sizeof(DeviceObjectSizes) == sizeof(size_t) * 15, "Please add new objects to DeviceObjectSizes constructor"); + try { m_DeviceCaps.DevType = RENDER_DEVICE_TYPE_D3D12; @@ -203,9 +212,9 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo // Header may not have constants for D3D_SHADER_MODEL_6_1 and above. const D3D_SHADER_MODEL Models[] = // { - static_cast(0x65), // minimum required for mesh shader + static_cast(0x65), // minimum required for mesh shader and DXR 1.1 static_cast(0x64), - static_cast(0x63), + static_cast(0x63), // minimum required for DXR 1.0 static_cast(0x62), static_cast(0x61), D3D_SHADER_MODEL_6_0 // @@ -251,7 +260,16 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo m_DeviceCaps.Features.MeshShaders = MeshShadersSupported ? DEVICE_FEATURE_STATE_ENABLED : DEVICE_FEATURE_STATE_DISABLED; - // AZ TODO: ray tracing + { + D3D12_FEATURE_DATA_D3D12_OPTIONS5 d3d12Features = {}; + if (SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &d3d12Features, sizeof(d3d12Features)))) + { + if (d3d12Features.RaytracingTier >= D3D12_RAYTRACING_TIER_1_0) + { + m_DeviceCaps.Features.RayTracing = DEVICE_FEATURE_STATE_ENABLED; + } + } + } { D3D12_FEATURE_DATA_D3D12_OPTIONS d3d12Features = {}; @@ -294,6 +312,8 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo CHECK_REQUIRED_FEATURE(ShaderInt8, "8-bit shader operations are"); CHECK_REQUIRED_FEATURE(ResourceBuffer8BitAccess, "8-bit resoure buffer access is"); CHECK_REQUIRED_FEATURE(UniformBuffer8BitAccess, "8-bit uniform buffer access is"); + + CHECK_REQUIRED_FEATURE(RayTracing, "ray tracing is"); // clang-format on #undef CHECK_REQUIRED_FEATURE @@ -558,6 +578,11 @@ void RenderDeviceD3D12Impl::CreateComputePipelineState(const ComputePipelineStat CreatePipelineState(PSOCreateInfo, ppPipelineState); } +void RenderDeviceD3D12Impl::CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +{ + CreatePipelineState(PSOCreateInfo, ppPipelineState); +} + void RenderDeviceD3D12Impl::CreateBufferFromD3DResource(ID3D12Resource* pd3d12Buffer, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer) { CreateDeviceObject("buffer", BuffDesc, ppBuffer, diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 2afb9eb1..718f4b17 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -183,8 +183,17 @@ static constexpr D3D12_SHADER_VISIBILITY ShaderTypeInd2ShaderVisibilityMap[] D3D12_SHADER_VISIBILITY_ALL, // 5 #ifdef D3D12_H_HAS_MESH_SHADER D3D12_SHADER_VISIBILITY_AMPLIFICATION, // 6 - D3D12_SHADER_VISIBILITY_MESH // 7 + D3D12_SHADER_VISIBILITY_MESH, // 7 +#else + D3D12_SHADER_VISIBILITY(6), + D3D12_SHADER_VISIBILITY(7), #endif + D3D12_SHADER_VISIBILITY_ALL, // 8 + D3D12_SHADER_VISIBILITY_ALL, // 9 + D3D12_SHADER_VISIBILITY_ALL, // 10 + D3D12_SHADER_VISIBILITY_ALL, // 11 + D3D12_SHADER_VISIBILITY_ALL, // 12 + D3D12_SHADER_VISIBILITY_ALL, // 13 }; // clang-format on D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType) @@ -192,19 +201,26 @@ D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType) auto ShaderInd = GetShaderTypeIndex(ShaderType); auto ShaderVisibility = ShaderTypeInd2ShaderVisibilityMap[ShaderInd]; #ifdef DILIGENT_DEBUG + static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type"); switch (ShaderType) { // clang-format off - case SHADER_TYPE_VERTEX: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_VERTEX); break; - case SHADER_TYPE_PIXEL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_PIXEL); break; - case SHADER_TYPE_GEOMETRY: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_GEOMETRY); break; - case SHADER_TYPE_HULL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_HULL); break; - case SHADER_TYPE_DOMAIN: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_DOMAIN); break; - case SHADER_TYPE_COMPUTE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break; + case SHADER_TYPE_VERTEX: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_VERTEX); break; + case SHADER_TYPE_PIXEL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_PIXEL); break; + case SHADER_TYPE_GEOMETRY: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_GEOMETRY); break; + case SHADER_TYPE_HULL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_HULL); break; + case SHADER_TYPE_DOMAIN: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_DOMAIN); break; + case SHADER_TYPE_COMPUTE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break; # ifdef D3D12_H_HAS_MESH_SHADER - case SHADER_TYPE_AMPLIFICATION: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_AMPLIFICATION); break; - case SHADER_TYPE_MESH: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_MESH); break; + case SHADER_TYPE_AMPLIFICATION: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_AMPLIFICATION); break; + case SHADER_TYPE_MESH: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_MESH); break; # endif + case SHADER_TYPE_RAY_GEN: + case SHADER_TYPE_RAY_MISS: + case SHADER_TYPE_RAY_CLOSEST_HIT: + case SHADER_TYPE_RAY_ANY_HIT: + case SHADER_TYPE_RAY_INTERSECTION: + case SHADER_TYPE_CALLABLE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break; // clang-format on default: LOG_ERROR("Unknown shader type (", ShaderType, ")"); break; } @@ -212,46 +228,6 @@ D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType) return ShaderVisibility; } -// clang-format off -static SHADER_TYPE ShaderVisibility2ShaderTypeMap[] = -{ - SHADER_TYPE_COMPUTE, // D3D12_SHADER_VISIBILITY_ALL = 0 - SHADER_TYPE_VERTEX, // D3D12_SHADER_VISIBILITY_VERTEX = 1 - SHADER_TYPE_HULL, // D3D12_SHADER_VISIBILITY_HULL = 2 - SHADER_TYPE_DOMAIN, // D3D12_SHADER_VISIBILITY_DOMAIN = 3 - SHADER_TYPE_GEOMETRY, // D3D12_SHADER_VISIBILITY_GEOMETRY = 4 - SHADER_TYPE_PIXEL, // D3D12_SHADER_VISIBILITY_PIXEL = 5 - SHADER_TYPE_AMPLIFICATION, // D3D12_SHADER_VISIBILITY_AMPLIFICATION = 6 - SHADER_TYPE_MESH // D3D12_SHADER_VISIBILITY_MESH = 7 -}; -// clang-format on - -SHADER_TYPE ShaderTypeFromShaderVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility) -{ - VERIFY_EXPR(uint32_t(ShaderVisibility) < _countof(ShaderVisibility2ShaderTypeMap)); - auto ShaderType = ShaderVisibility2ShaderTypeMap[ShaderVisibility]; -#ifdef DILIGENT_DEBUG - switch (ShaderVisibility) - { - // clang-format off - case D3D12_SHADER_VISIBILITY_VERTEX: VERIFY_EXPR(ShaderType == SHADER_TYPE_VERTEX); break; - case D3D12_SHADER_VISIBILITY_PIXEL: VERIFY_EXPR(ShaderType == SHADER_TYPE_PIXEL); break; - case D3D12_SHADER_VISIBILITY_GEOMETRY: VERIFY_EXPR(ShaderType == SHADER_TYPE_GEOMETRY); break; - case D3D12_SHADER_VISIBILITY_HULL: VERIFY_EXPR(ShaderType == SHADER_TYPE_HULL); break; - case D3D12_SHADER_VISIBILITY_DOMAIN: VERIFY_EXPR(ShaderType == SHADER_TYPE_DOMAIN); break; - case D3D12_SHADER_VISIBILITY_ALL: VERIFY_EXPR(ShaderType == SHADER_TYPE_COMPUTE); break; -# ifdef D3D12_H_HAS_MESH_SHADER - case D3D12_SHADER_VISIBILITY_AMPLIFICATION: VERIFY_EXPR(ShaderType == SHADER_TYPE_AMPLIFICATION); break; - case D3D12_SHADER_VISIBILITY_MESH: VERIFY_EXPR(ShaderType == SHADER_TYPE_MESH); break; -# endif - // clang-format on - default: LOG_ERROR("Unknown shader visibility (", ShaderVisibility, ")"); break; - } -#endif - return ShaderType; -} - - // clang-format off static D3D12_DESCRIPTOR_HEAP_TYPE RangeType2HeapTypeMap[] { @@ -287,6 +263,10 @@ void RootSignature::InitImmutableSampler(SHADER_TYPE ShaderT const char* SamplerSuffix, const D3DShaderResourceAttribs& SamplerAttribs) { +#ifdef DILIGENT_DEBUG + m_DbgShaderStages |= ShaderType; +#endif + auto ShaderVisibility = GetShaderVisibility(ShaderType); auto SamplerFound = false; for (auto& ImtblSmplr : m_ImmutableSamplers) @@ -319,6 +299,10 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT Uint32& OffsetFromTableStart // Output parameter ) { +#ifdef DILIGENT_DEBUG + m_DbgShaderStages |= ShaderType; +#endif + const auto ShaderVisibility = GetShaderVisibility(ShaderType); if (RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV && ShaderResAttribs.BindCount == 1) { @@ -564,7 +548,9 @@ void RootSignature::Finalize(ID3D12Device* pd3d12Device) CComPtr signature; CComPtr error; HRESULT hr = D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); - hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pd3d12RootSignature), reinterpret_cast(static_cast(&m_pd3d12RootSignature))); + CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature"); + + hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pd3d12RootSignature), reinterpret_cast(static_cast(&m_pd3d12RootSignature))); CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature"); bool bHasDynamicDescriptors = m_TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0 || m_TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0; @@ -658,10 +644,6 @@ void RootSignature::InitResourceCache(RenderDeviceD3D12Impl* pDeviceD3D12Impl const auto& D3D12RootParam = static_cast(RootParam); auto& RootTableCache = ResourceCache.GetRootTable(RootParam.GetRootIndex()); - SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; -#ifdef DILIGENT_DEBUG - dbgShaderType = ShaderTypeFromShaderVisibility(D3D12RootParam.ShaderVisibility); -#endif VERIFY_EXPR(D3D12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE); auto TableSize = RootParam.GetDescriptorTableSize(); @@ -670,7 +652,7 @@ void RootSignature::InitResourceCache(RenderDeviceD3D12Impl* pDeviceD3D12Impl auto HeapType = HeapTypeFromRangeType(D3D12RootParam.DescriptorTable.pDescriptorRanges[0].RangeType); #ifdef DILIGENT_DEBUG - RootTableCache.SetDebugAttribs(TableSize, HeapType, dbgShaderType); + RootTableCache.SetDebugAttribs(TableSize, HeapType, m_DbgShaderStages); #endif // Space for dynamic variables is allocated at every draw call @@ -702,9 +684,8 @@ void RootSignature::InitResourceCache(RenderDeviceD3D12Impl* pDeviceD3D12Impl // Root views are not assigned valid table start offset VERIFY_EXPR(RootTableCache.m_TableStartOffset == ShaderResourceCacheD3D12::InvalidDescriptorOffset); - SHADER_TYPE dbgShaderType = ShaderTypeFromShaderVisibility(D3D12RootParam.ShaderVisibility); VERIFY_EXPR(D3D12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV); - RootTableCache.SetDebugAttribs(1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType); + RootTableCache.SetDebugAttribs(1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_DbgShaderStages); } #endif @@ -718,6 +699,7 @@ __forceinline void TransitionResource(CommandContext& Ctx, ShaderResourceCacheD3D12::Resource& Res, D3D12_DESCRIPTOR_RANGE_TYPE RangeType) { + static_assert(static_cast(CachedResourceType::NumTypes) == 7, "Please update this function to handle the new resource type"); switch (Res.Type) { case CachedResourceType::CBV: @@ -782,6 +764,11 @@ __forceinline void TransitionResource(CommandContext& Ctx, VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Unexpected descriptor range type"); break; + case CachedResourceType::AccelStruct: + { + } + break; + default: // Resource not bound VERIFY(Res.Type == CachedResourceType::Unknown, "Unexpected resource type"); @@ -794,6 +781,7 @@ __forceinline void TransitionResource(CommandContext& Ctx, void RootSignature::DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resource& Res, D3D12_DESCRIPTOR_RANGE_TYPE RangeType) { + static_assert(static_cast(CachedResourceType::NumTypes) == 7, "Please update this function to handle the new resource type"); switch (Res.Type) { case CachedResourceType::CBV: @@ -880,6 +868,11 @@ void RootSignature::DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resou VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Unexpected descriptor range type"); break; + case CachedResourceType::AccelStruct: + { + } + break; + default: // Resource not bound VERIFY(Res.Type == CachedResourceType::Unknown, "Unexpected resource type"); @@ -922,13 +915,11 @@ __forceinline void ProcessCachedTableResources(Uint32 RootI const auto& range = D3D12Param.DescriptorTable.pDescriptorRanges[r]; for (UINT d = 0; d < range.NumDescriptors; ++d) { - SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; #ifdef DILIGENT_DEBUG - dbgShaderType = ShaderTypeFromShaderVisibility(D3D12Param.ShaderVisibility); VERIFY(dbgHeapType == HeapTypeFromRangeType(range.RangeType), "Mistmatch between descriptor heap type and descriptor range type"); #endif auto OffsetFromTableStart = range.OffsetInDescriptorsFromTableStart + d; - auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, dbgShaderType); + auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, SHADER_TYPE_UNKNOWN); Operation(OffsetFromTableStart, range, Res); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp index 36a14167..a356d73a 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp @@ -94,7 +94,8 @@ ShaderD3D12Impl::ShaderD3D12Impl(IReferenceCounters* pRefCounters, pRenderDeviceD3D12, ShaderCI.Desc }, - ShaderD3DBase{ShaderCI, GetD3D12ShaderModel(pRenderDeviceD3D12, ShaderCI.HLSLVersion, ShaderCI.ShaderCompiler), pRenderDeviceD3D12->GetDxCompiler()} + ShaderD3DBase{ShaderCI, GetD3D12ShaderModel(pRenderDeviceD3D12, ShaderCI.HLSLVersion, ShaderCI.ShaderCompiler), pRenderDeviceD3D12->GetDxCompiler()}, + m_EntryPoint{ShaderCI.EntryPoint} // clang-format on { // Load shader resources diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index c0428e7e..157e42f7 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -57,12 +57,13 @@ D3D12_DESCRIPTOR_RANGE_TYPE GetDescriptorRangeType(CachedResourceType ResType) ResTypeToD3D12DescrRangeType() { // clang-format off - m_Map[(size_t)CachedResourceType::CBV] = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; - m_Map[(size_t)CachedResourceType::TexSRV] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; - m_Map[(size_t)CachedResourceType::BufSRV] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; - m_Map[(size_t)CachedResourceType::TexUAV] = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; - m_Map[(size_t)CachedResourceType::BufUAV] = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; - m_Map[(size_t)CachedResourceType::Sampler] = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + m_Map[(size_t)CachedResourceType::CBV] = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + m_Map[(size_t)CachedResourceType::TexSRV] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + m_Map[(size_t)CachedResourceType::BufSRV] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + m_Map[(size_t)CachedResourceType::TexUAV] = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + m_Map[(size_t)CachedResourceType::BufUAV] = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + m_Map[(size_t)CachedResourceType::Sampler] = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + m_Map[(size_t)CachedResourceType::AccelStruct] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; // clang-format on } @@ -113,240 +114,281 @@ void ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Shader-Resource-Layouts-and-Root-Signature-in-a-Pipeline-State-Object // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Initializing-Shader-Resource-Layouts-in-a-Pipeline-State -void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* pd3d12Device, - PIPELINE_TYPE PipelineType, - const PipelineResourceLayoutDesc& ResourceLayout, - std::shared_ptr pSrcResources, - IMemoryAllocator& LayoutDataAllocator, - const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheD3D12* pResourceCache, - RootSignature* pRootSig) +void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* pd3d12Device, + PIPELINE_TYPE PipelineType, + const PipelineResourceLayoutDesc& ResourceLayout, + const std::vector& Shaders, + IMemoryAllocator& LayoutDataAllocator, + const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheD3D12* pResourceCache, + RootSignature* pRootSig) { m_pd3d12Device = pd3d12Device; - m_pResources = std::move(pSrcResources); VERIFY_EXPR((pResourceCache != nullptr) ^ (pRootSig != nullptr)); + VERIFY_EXPR(Shaders.size() > 0); const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); std::array CbvSrvUavCount = {}; std::array SamplerCount = {}; + std::unordered_map ResourceNameToIndex; + // Count number of resources to allocate all needed memory - m_pResources->ProcessResources( - [&](const D3DShaderResourceAttribs& CB, Uint32) // - { - auto VarType = m_pResources->FindVariableType(CB, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - ++CbvSrvUavCount[VarType]; - }, - [&](const D3DShaderResourceAttribs& Sam, Uint32) // - { - auto VarType = m_pResources->FindVariableType(Sam, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - { - constexpr bool LogImtblSamplerArrayError = true; + m_IsUsingSeparateSamplers = !Shaders[0]->GetShaderResources()->IsUsingCombinedTextureSamplers(); + m_ShaderType = Shaders[0]->GetDesc().ShaderType; + size_t StringPoolSize = 0; - auto ImtblSamplerInd = m_pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); - // Skip immutable samplers - if (ImtblSamplerInd < 0) - ++SamplerCount[VarType]; - } - }, - [&](const D3DShaderResourceAttribs& TexSRV, Uint32) // + for (auto* pShader : Shaders) + { + auto pResources = pShader->GetShaderResources(); + VERIFY_EXPR(pResources->GetShaderType() == m_ShaderType); + const auto HandleResType = [&](const auto& Res, Uint32) // { - auto VarType = m_pResources->FindVariableType(TexSRV, ResourceLayout); + auto VarType = pResources->FindVariableType(Res, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) { - ++CbvSrvUavCount[VarType]; - if (TexSRV.IsCombinedWithSampler()) + bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, ~0u).second; + if (IsUniqueName) { - const auto& SamplerAttribs = m_pResources->GetCombinedSampler(TexSRV); - auto SamplerVarType = m_pResources->FindVariableType(SamplerAttribs, ResourceLayout); - DEV_CHECK_ERR(SamplerVarType == VarType, - "The type (", GetShaderVariableTypeLiteralName(VarType), ") of texture SRV variable '", TexSRV.Name, - "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SamplerVarType), - ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); - (void)SamplerVarType; + StringPoolSize += strlen(Res.Name) + 1; + ++CbvSrvUavCount[VarType]; } } - }, - [&](const D3DShaderResourceAttribs& TexUAV, Uint32) // - { - auto VarType = m_pResources->FindVariableType(TexUAV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - ++CbvSrvUavCount[VarType]; - }, - [&](const D3DShaderResourceAttribs& BufSRV, Uint32) // - { - auto VarType = m_pResources->FindVariableType(BufSRV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - ++CbvSrvUavCount[VarType]; - }, - [&](const D3DShaderResourceAttribs& BufUAV, Uint32) // - { - auto VarType = m_pResources->FindVariableType(BufUAV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - ++CbvSrvUavCount[VarType]; - } // - ); + }; + pResources->ProcessResources( + HandleResType, + [&](const D3DShaderResourceAttribs& Sam, Uint32) // + { + auto VarType = pResources->FindVariableType(Sam, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + constexpr bool LogImtblSamplerArrayError = true; + + auto ImtblSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); + // Skip immutable samplers + if (ImtblSamplerInd < 0) + { + bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Sam.Name}, ~0u).second; + if (IsUniqueName) + { + StringPoolSize += strlen(Sam.Name) + 1; + ++SamplerCount[VarType]; + } + } + } + }, + [&](const D3DShaderResourceAttribs& TexSRV, Uint32) // + { + auto VarType = pResources->FindVariableType(TexSRV, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{TexSRV.Name}, ~0u).second; + if (IsUniqueName) + { + StringPoolSize += strlen(TexSRV.Name) + 1; + ++CbvSrvUavCount[VarType]; + if (TexSRV.IsCombinedWithSampler()) + { + const auto& SamplerAttribs = pResources->GetCombinedSampler(TexSRV); + auto SamplerVarType = pResources->FindVariableType(SamplerAttribs, ResourceLayout); + DEV_CHECK_ERR(SamplerVarType == VarType, + "The type (", GetShaderVariableTypeLiteralName(VarType), ") of texture SRV variable '", TexSRV.Name, + "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SamplerVarType), + ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); + (void)SamplerVarType; + } + } + } + }, + HandleResType, + HandleResType, + HandleResType, + HandleResType); + } AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount); - std::array CurrCbvSrvUav = {}; - std::array CurrSampler = {}; + m_StringPool.Reserve(StringPoolSize, GetRawAllocator()); - Uint32 StaticResCacheTblSizes[4] = {0, 0, 0, 0}; + std::array CurrCbvSrvUav = {}; + std::array CurrSampler = {}; + std::array StaticResCacheTblSizes = {}; auto AddResource = [&](const D3DShaderResourceAttribs& Attribs, CachedResourceType ResType, SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 SamplerId = D3D12Resource::InvalidSamplerId) // { - Uint32 RootIndex = D3D12Resource::InvalidRootIndex; - Uint32 Offset = D3D12Resource::InvalidOffset; - - D3D12_DESCRIPTOR_RANGE_TYPE DescriptorRangeType = GetDescriptorRangeType(ResType); + auto ResIter = ResourceNameToIndex.find(HashMapStringKey{Attribs.Name}); + VERIFY_EXPR(ResIter != ResourceNameToIndex.end()); - if (pRootSig) - { - pRootSig->AllocateResourceSlot(m_pResources->GetShaderType(), PipelineType, Attribs, VarType, DescriptorRangeType, RootIndex, Offset); - VERIFY(RootIndex <= D3D12Resource::MaxRootIndex, "Root index excceeds allowed limit"); - } - else + if (ResIter->second == ~0u) { - // If root signature is not provided - use artifial root signature to store - // static shader resources: - // SRVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_SRV (0) - // UAVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_UAV (1) - // CBVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_CBV (2) - // Samplers at root index D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER (3) + Uint32 RootIndex = D3D12Resource::InvalidRootIndex; + Uint32 Offset = D3D12Resource::InvalidOffset; - // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Special-Resource-Layout-for-Managing-Static-Shader-Resources + D3D12_DESCRIPTOR_RANGE_TYPE DescriptorRangeType = GetDescriptorRangeType(ResType); - VERIFY_EXPR(pResourceCache != nullptr); + if (pRootSig) + { + pRootSig->AllocateResourceSlot(GetShaderType(), PipelineType, Attribs, VarType, DescriptorRangeType, RootIndex, Offset); + VERIFY(RootIndex <= D3D12Resource::MaxRootIndex, "Root index excceeds allowed limit"); + } + else + { + // If root signature is not provided - use artifial root signature to store + // static shader resources: + // SRVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_SRV (0) + // UAVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_UAV (1) + // CBVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_CBV (2) + // Samplers at root index D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER (3) - RootIndex = DescriptorRangeType; - Offset = Attribs.BindPoint; - // Resources in the static resource cache are indexed by the bind point - StaticResCacheTblSizes[RootIndex] = std::max(StaticResCacheTblSizes[RootIndex], Offset + Attribs.BindCount); - } - VERIFY(RootIndex != D3D12Resource::InvalidRootIndex, "Root index must be valid"); - VERIFY(Offset != D3D12Resource::InvalidOffset, "Offset must be valid"); - - // Immutable samplers are never copied, and SamplerId == InvalidSamplerId - auto& NewResource = (ResType == CachedResourceType::Sampler) ? - GetSampler(VarType, CurrSampler[VarType]++) : - GetSrvCbvUav(VarType, CurrCbvSrvUav[VarType]++); - ::new (&NewResource) D3D12Resource(*this, Attribs, VarType, ResType, RootIndex, Offset, SamplerId); - }; + // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Special-Resource-Layout-for-Managing-Static-Shader-Resources + VERIFY_EXPR(pResourceCache != nullptr); - m_pResources->ProcessResources( - [&](const D3DShaderResourceAttribs& CB, Uint32) // - { - auto VarType = m_pResources->FindVariableType(CB, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - AddResource(CB, CachedResourceType::CBV, VarType); - }, - [&](const D3DShaderResourceAttribs& Sam, Uint32) // - { - auto VarType = m_pResources->FindVariableType(Sam, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - { - // The error (if any) have already been logged when counting the resources - constexpr bool LogImtblSamplerArrayError = false; - - auto ImtblSamplerInd = m_pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); - if (ImtblSamplerInd >= 0) - { - if (pRootSig != nullptr) - pRootSig->InitImmutableSampler(m_pResources->GetShaderType(), Sam.Name, m_pResources->GetCombinedSamplerSuffix(), Sam); - } - else - { - AddResource(Sam, CachedResourceType::Sampler, VarType); - } + RootIndex = DescriptorRangeType; + Offset = Attribs.BindPoint; + // Resources in the static resource cache are indexed by the bind point + StaticResCacheTblSizes[RootIndex] = std::max(StaticResCacheTblSizes[RootIndex], Offset + Attribs.BindCount); } - }, - [&](const D3DShaderResourceAttribs& TexSRV, Uint32) // + VERIFY(RootIndex != D3D12Resource::InvalidRootIndex, "Root index must be valid"); + VERIFY(Offset != D3D12Resource::InvalidOffset, "Offset must be valid"); + + // Static samplers are never copied, and SamplerId == InvalidSamplerId + Uint32 ResOffset = (ResType == CachedResourceType::Sampler) ? + GetSamplerOffset(VarType, CurrSampler[VarType]++) : + GetSrvCbvUavOffset(VarType, CurrCbvSrvUav[VarType]++); + ResIter->second = ResOffset; + auto& NewResource = GetResource(ResOffset); + ::new (&NewResource) D3D12Resource{*this, VarType, ResType, RootIndex, Offset, SamplerId, m_StringPool.CopyString(Attribs.Name), Attribs.BindCount, Attribs.BindPoint, + Attribs.GetInputType(), Attribs.GetSRVDimension()}; + } + else { - auto VarType = m_pResources->FindVariableType(TexSRV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - { - static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES == 3, "Unexpected number of shader variable types"); - VERIFY(CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] == GetTotalSamplerCount(), "All samplers must be initialized before texture SRVs"); + // merge with existing + auto& ExistingRes = GetResource(ResIter->second); + VERIFY_EXPR(ExistingRes.VariableType == VarType); + VERIFY_EXPR(ExistingRes.GetInputType() == Attribs.GetInputType()); + VERIFY_EXPR(ExistingRes.BindCount == Attribs.BindCount); + } + }; - Uint32 SamplerId = D3D12Resource::InvalidSamplerId; - if (TexSRV.IsCombinedWithSampler()) + for (auto* pShader : Shaders) + { + auto pResources = pShader->GetShaderResources(); + pResources->ProcessResources( + [&](const D3DShaderResourceAttribs& CB, Uint32) // + { + auto VarType = pResources->FindVariableType(CB, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + AddResource(CB, CachedResourceType::CBV, VarType); + }, + [&](const D3DShaderResourceAttribs& Sam, Uint32) // + { + auto VarType = pResources->FindVariableType(Sam, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) { - const auto& SamplerAttribs = m_pResources->GetCombinedSampler(TexSRV); - auto SamplerVarType = m_pResources->FindVariableType(SamplerAttribs, ResourceLayout); - DEV_CHECK_ERR(SamplerVarType == VarType, - "The type (", GetShaderVariableTypeLiteralName(VarType), ") of texture SRV variable '", TexSRV.Name, - "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SamplerVarType), - ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); - // The error (if any) have already been logged when counting the resources - constexpr bool LogImtblSamplerArrayError = false; - - auto ImtblSamplerInd = m_pResources->FindImmutableSampler(SamplerAttribs, ResourceLayout, LogImtblSamplerArrayError); - if (ImtblSamplerInd >= 0) + constexpr bool LogStaticSamplerArrayError = false; + auto StaticSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogStaticSamplerArrayError); + if (StaticSamplerInd >= 0) { - // Immutable samplers are never copied, and SamplerId == InvalidSamplerId -#ifdef DILIGENT_DEBUG - auto SamplerCount = GetTotalSamplerCount(); - for (Uint32 s = 0; s < SamplerCount; ++s) - { - const auto& Sampler = GetSampler(s); - if (strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0) - LOG_ERROR("Immutable sampler '", Sampler.Attribs.Name, "' was found among resources. This seems to be a bug"); - } -#endif + if (pRootSig != nullptr) + pRootSig->InitImmutableSampler(pResources->GetShaderType(), Sam.Name, pResources->GetCombinedSamplerSuffix(), Sam); } else { - auto SamplerCount = GetTotalSamplerCount(); - bool SamplerFound = false; - for (SamplerId = 0; SamplerId < SamplerCount; ++SamplerId) + AddResource(Sam, CachedResourceType::Sampler, VarType); + } + } + }, + [&](const D3DShaderResourceAttribs& TexSRV, Uint32) // + { + auto VarType = pResources->FindVariableType(TexSRV, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES == 3, "Unexpected number of shader variable types"); + VERIFY(CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] == GetTotalSamplerCount(), "All samplers must be initialized before texture SRVs"); + + Uint32 SamplerId = D3D12Resource::InvalidSamplerId; + if (TexSRV.IsCombinedWithSampler()) + { + const auto& SamplerAttribs = pResources->GetCombinedSampler(TexSRV); + auto SamplerVarType = pResources->FindVariableType(SamplerAttribs, ResourceLayout); + DEV_CHECK_ERR(SamplerVarType == VarType, + "The type (", GetShaderVariableTypeLiteralName(VarType), ") of texture SRV variable '", TexSRV.Name, + "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SamplerVarType), + ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); + + // The error (if any) have already been logged when counting the resources + constexpr bool LogStaticSamplerArrayError = false; + auto StaticSamplerInd = pResources->FindImmutableSampler(SamplerAttribs, ResourceLayout, LogStaticSamplerArrayError); + if (StaticSamplerInd >= 0) { - const auto& Sampler = GetSampler(SamplerId); - SamplerFound = strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0; - if (SamplerFound) - break; + // Static samplers are never copied, and SamplerId == InvalidSamplerId +#ifdef DILIGENT_DEBUG + auto SamplerCount = GetTotalSamplerCount(); + for (Uint32 s = 0; s < SamplerCount; ++s) + { + const auto& Sampler = GetSampler(s); + if (strcmp(Sampler.Name, SamplerAttribs.Name) == 0) + LOG_ERROR("Static sampler '", Sampler.Name, "' was found among resources. This seems to be a bug"); + } +#endif } - - if (!SamplerFound) + else { - LOG_ERROR("Unable to find sampler '", SamplerAttribs.Name, "' assigned to texture SRV '", TexSRV.Name, "' in the list of already created resources. This seems to be a bug."); - SamplerId = D3D12Resource::InvalidSamplerId; + auto SamplerCount = GetTotalSamplerCount(); + bool SamplerFound = false; + for (SamplerId = 0; SamplerId < SamplerCount; ++SamplerId) + { + const auto& Sampler = GetSampler(SamplerId); + SamplerFound = strcmp(Sampler.Name, SamplerAttribs.Name) == 0; + if (SamplerFound) + break; + } + + if (!SamplerFound) + { + LOG_ERROR("Unable to find sampler '", SamplerAttribs.Name, "' assigned to texture SRV '", TexSRV.Name, "' in the list of already created resources. This seems to be a bug."); + SamplerId = D3D12Resource::InvalidSamplerId; + } + VERIFY(SamplerId <= D3D12Resource::MaxSamplerId, "Sampler index excceeds allowed limit"); } - VERIFY(SamplerId <= D3D12Resource::MaxSamplerId, "Sampler index excceeds allowed limit"); } + AddResource(TexSRV, CachedResourceType::TexSRV, VarType, SamplerId); } - AddResource(TexSRV, CachedResourceType::TexSRV, VarType, SamplerId); - } - }, - [&](const D3DShaderResourceAttribs& TexUAV, Uint32) // - { - auto VarType = m_pResources->FindVariableType(TexUAV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - AddResource(TexUAV, CachedResourceType::TexUAV, VarType); - }, - [&](const D3DShaderResourceAttribs& BufSRV, Uint32) // - { - auto VarType = m_pResources->FindVariableType(BufSRV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - AddResource(BufSRV, CachedResourceType::BufSRV, VarType); - }, - [&](const D3DShaderResourceAttribs& BufUAV, Uint32) // - { - auto VarType = m_pResources->FindVariableType(BufUAV, ResourceLayout); - if (IsAllowedType(VarType, AllowedTypeBits)) - AddResource(BufUAV, CachedResourceType::BufUAV, VarType); - } // - ); + }, + [&](const D3DShaderResourceAttribs& TexUAV, Uint32) // + { + auto VarType = pResources->FindVariableType(TexUAV, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + AddResource(TexUAV, CachedResourceType::TexUAV, VarType); + }, + [&](const D3DShaderResourceAttribs& BufSRV, Uint32) // + { + auto VarType = pResources->FindVariableType(BufSRV, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + AddResource(BufSRV, CachedResourceType::BufSRV, VarType); + }, + [&](const D3DShaderResourceAttribs& BufUAV, Uint32) // + { + auto VarType = pResources->FindVariableType(BufUAV, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + AddResource(BufUAV, CachedResourceType::BufUAV, VarType); + }, + [&](const D3DShaderResourceAttribs& AccelStruct, Uint32) // + { + auto VarType = pResources->FindVariableType(AccelStruct, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + AddResource(AccelStruct, CachedResourceType::AccelStruct, VarType); + } // + ); + } #ifdef DILIGENT_DEBUG for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) @@ -362,12 +404,12 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Initializing-the-Cache-for-Static-Shader-Resources // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Initializing-Shader-Objects VERIFY_EXPR(pRootSig == nullptr); - pResourceCache->Initialize(GetRawAllocator(), _countof(StaticResCacheTblSizes), StaticResCacheTblSizes); + pResourceCache->Initialize(GetRawAllocator(), static_cast(StaticResCacheTblSizes.size()), StaticResCacheTblSizes.data()); #ifdef DILIGENT_DEBUG - pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SRV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_SRV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); - pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_UAV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_UAV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); - pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_CBV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_CBV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); - pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER], D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SRV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_SRV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); + pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_UAV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_UAV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); + pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_CBV).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_CBV], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); + pResourceCache->GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).SetDebugAttribs(StaticResCacheTblSizes[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER], D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); #endif } } @@ -385,7 +427,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheCB(IDeviceObject* // resource mapping can be of wrong type RefCntAutoPtr pBuffD3D12(pBuffer, IID_BufferD3D12); #ifdef DILIGENT_DEVELOPMENT - VerifyConstantBufferBinding(Attribs, GetVariableType(), ArrayInd, pBuffer, pBuffD3D12.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); + VerifyConstantBufferBinding(*this, GetVariableType(), ArrayInd, pBuffer, pBuffD3D12.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); #endif if (pBuffD3D12) { @@ -421,6 +463,39 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheCB(IDeviceObject* } } +RESOURCE_DIMENSION ShaderResourceLayoutD3D12::D3D12Resource::GetResourceDimension() const +{ + switch (GetSRVDimension()) + { + // clang-format off + case D3D_SRV_DIMENSION_BUFFER: return RESOURCE_DIM_BUFFER; + case D3D_SRV_DIMENSION_TEXTURE1D: return RESOURCE_DIM_TEX_1D; + case D3D_SRV_DIMENSION_TEXTURE1DARRAY: return RESOURCE_DIM_TEX_1D_ARRAY; + case D3D_SRV_DIMENSION_TEXTURE2D: return RESOURCE_DIM_TEX_2D; + case D3D_SRV_DIMENSION_TEXTURE2DARRAY: return RESOURCE_DIM_TEX_2D_ARRAY; + case D3D_SRV_DIMENSION_TEXTURE2DMS: return RESOURCE_DIM_TEX_2D; + case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: return RESOURCE_DIM_TEX_2D_ARRAY; + case D3D_SRV_DIMENSION_TEXTURE3D: return RESOURCE_DIM_TEX_3D; + case D3D_SRV_DIMENSION_TEXTURECUBE: return RESOURCE_DIM_TEX_CUBE; + case D3D_SRV_DIMENSION_TEXTURECUBEARRAY: return RESOURCE_DIM_TEX_CUBE_ARRAY; + // clang-format on + default: + return RESOURCE_DIM_BUFFER; + } +} + +bool ShaderResourceLayoutD3D12::D3D12Resource::IsMultisample() const +{ + switch (GetSRVDimension()) + { + case D3D_SRV_DIMENSION_TEXTURE2DMS: + case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: + return true; + default: + return false; + } +} + template struct ResourceViewTraits @@ -431,7 +506,7 @@ struct ResourceViewTraits { static const INTERFACE_ID& IID; - static bool VerifyView(ITextureViewD3D12* pViewD3D12, const D3DShaderResourceAttribs& Attribs, const char* ShaderName) + static bool VerifyView(ITextureViewD3D12* pViewD3D12, const ShaderResourceLayoutD3D12::D3D12Resource& Attribs, const char* ShaderName) { return true; } @@ -443,7 +518,7 @@ struct ResourceViewTraits { static const INTERFACE_ID& IID; - static bool VerifyView(IBufferViewD3D12* pViewD3D12, const D3DShaderResourceAttribs& Attribs, const char* ShaderName) + static bool VerifyView(IBufferViewD3D12* pViewD3D12, const ShaderResourceLayoutD3D12::D3D12Resource& Attribs, const char* ShaderName) { return VerifyBufferViewModeD3D(pViewD3D12, Attribs, ShaderName); } @@ -464,8 +539,8 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheResourceView(IDeviceObject* // resource mapping can be of wrong type RefCntAutoPtr pViewD3D12{pView, ResourceViewTraits::IID}; #ifdef DILIGENT_DEVELOPMENT - VerifyResourceViewBinding(Attribs, GetVariableType(), ArrayIndex, pView, pViewD3D12.RawPtr(), {dbgExpectedViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); - ResourceViewTraits::VerifyView(pViewD3D12, Attribs, ParentResLayout.GetShaderName()); + VerifyResourceViewBinding(*this, GetVariableType(), ArrayIndex, pView, pViewD3D12.RawPtr(), {dbgExpectedViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); + ResourceViewTraits::VerifyView(pViewD3D12, *this, ParentResLayout.GetShaderName()); #endif if (pViewD3D12) { @@ -501,8 +576,8 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheSampler(IDeviceObject* Uint32 ArrayIndex, D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const { - VERIFY(Attribs.IsValidBindPoint(), "Invalid bind point"); - VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + VERIFY(IsValidBindPoint(), "Invalid bind point"); + VERIFY_EXPR(ArrayIndex < BindCount); RefCntAutoPtr pSamplerD3D12(pSampler, IID_SamplerD3D12); if (pSamplerD3D12) @@ -512,7 +587,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheSampler(IDeviceObject* if (DstSam.pObject != pSampler) { auto VarTypeStr = GetShaderVariableTypeLiteralName(GetVariableType()); - LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", Attribs.GetPrintName(ArrayIndex), + LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", GetPrintName(ArrayIndex), "' in shader '", ParentResLayout.GetShaderName(), "'. Attempting to bind another sampler is an error and will " "be ignored. Use another shader resource binding instance or label the variable as dynamic."); } @@ -541,18 +616,25 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheSampler(IDeviceObject* } else { - LOG_ERROR_MESSAGE("Failed to bind object '", pSampler->GetDesc().Name, "' to variable '", Attribs.GetPrintName(ArrayIndex), + LOG_ERROR_MESSAGE("Failed to bind object '", pSampler->GetDesc().Name, "' to variable '", GetPrintName(ArrayIndex), "' in shader '", ParentResLayout.GetShaderName(), "'. Incorect object type: sampler is expected."); } } +void ShaderResourceLayoutD3D12::D3D12Resource::CacheAccelStruct(IDeviceObject* pTLAS, + ShaderResourceCacheD3D12::Resource& DstRes, + Uint32 ArrayIndex, + D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const +{ +} + const ShaderResourceLayoutD3D12::D3D12Resource& ShaderResourceLayoutD3D12::GetAssignedSampler(const D3D12Resource& TexSrv) const { VERIFY(TexSrv.GetResType() == CachedResourceType::TexSRV, "Unexpected resource type: texture SRV is expected"); VERIFY(TexSrv.ValidSamplerAssigned(), "Texture SRV has no associated sampler"); const auto& SamInfo = GetSampler(TexSrv.SamplerId); VERIFY(SamInfo.GetVariableType() == TexSrv.GetVariableType(), "Inconsistent texture and sampler variable types"); - VERIFY(StreqSuff(SamInfo.Attribs.Name, TexSrv.Attribs.Name, m_pResources->GetCombinedSamplerSuffix()), "Sampler name '", SamInfo.Attribs.Name, "' does not match texture name '", TexSrv.Attribs.Name, '\''); + //VERIFY(StreqSuff(SamInfo.Name, TexSrv.Name, GetCombinedSamplerSuffix()), "Sampler name '", SamInfo.Name, "' does not match texture name '", TexSrv.Name, '\''); return SamInfo; } @@ -566,11 +648,11 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* Uint32 ArrayIndex, ShaderResourceCacheD3D12& ResourceCache) const { - VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + VERIFY_EXPR(ArrayIndex < BindCount); const bool IsSampler = GetResType() == CachedResourceType::Sampler; auto DescriptorHeapType = IsSampler ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - auto& DstRes = ResourceCache.GetRootTable(RootIndex).GetResource(OffsetFromTableStart + ArrayIndex, DescriptorHeapType, ParentResLayout.m_pResources->GetShaderType()); + auto& DstRes = ResourceCache.GetRootTable(RootIndex).GetResource(OffsetFromTableStart + ArrayIndex, DescriptorHeapType, ParentResLayout.GetShaderType()); auto ShdrVisibleHeapCPUDescriptorHandle = IsSampler ? ResourceCache.GetShaderVisibleTableCPUDescriptorHandle(RootIndex, OffsetFromTableStart + ArrayIndex) : @@ -584,7 +666,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* } else if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) { - if (GetResType() == CachedResourceType::CBV && Attribs.BindCount == 1) + if (GetResType() == CachedResourceType::CBV && BindCount == 1) { VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Non-array constant buffers are bound as root views and should not be assigned shader visible descriptor space"); } @@ -605,6 +687,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* if (pObj) { + static_assert(static_cast(CachedResourceType::NumTypes) == 7, "Please update this function to handle the new resource type"); switch (GetResType()) { case CachedResourceType::CBV: @@ -619,13 +702,13 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* if (ValidSamplerAssigned()) { auto& Sam = ParentResLayout.GetAssignedSampler(*this); - //VERIFY( !Sam.Attribs.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" ); - VERIFY_EXPR(Attribs.BindCount == Sam.Attribs.BindCount || Sam.Attribs.BindCount == 1); - auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0; + //VERIFY( !Sam.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" ); + VERIFY_EXPR(BindCount == Sam.BindCount || Sam.BindCount == 1); + auto SamplerArrInd = Sam.BindCount > 1 ? ArrayIndex : 0; auto ShdrVisibleSamplerHeapCPUDescriptorHandle = ResourceCache.GetShaderVisibleTableCPUDescriptorHandle(Sam.RootIndex, Sam.OffsetFromTableStart + SamplerArrInd); - auto& DstSam = ResourceCache.GetRootTable(Sam.RootIndex).GetResource(Sam.OffsetFromTableStart + SamplerArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, ParentResLayout.m_pResources->GetShaderType()); + auto& DstSam = ResourceCache.GetRootTable(Sam.RootIndex).GetResource(Sam.OffsetFromTableStart + SamplerArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, ParentResLayout.GetShaderType()); #ifdef DILIGENT_DEBUG { if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources) @@ -652,7 +735,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* } else { - LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", Sam.Attribs.Name, ". Sampler is not set in the texture view '", pTexView->GetDesc().Name, '\''); + LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", Sam.Name, ". Sampler is not set in the texture view '", pTexView->GetDesc().Name, '\''); } } }); @@ -675,23 +758,27 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* CacheSampler(pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle); break; + case CachedResourceType::AccelStruct: + CacheAccelStruct(pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle); + break; + default: UNEXPECTED("Unknown resource type ", static_cast(GetResType())); } } else { if (DstRes.pObject != nullptr && GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) - LOG_ERROR_MESSAGE("Shader variable '", Attribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another resource."); + LOG_ERROR_MESSAGE("Shader variable '", Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another resource."); DstRes = ShaderResourceCacheD3D12::Resource{}; if (ValidSamplerAssigned()) { auto& Sam = ParentResLayout.GetAssignedSampler(*this); D3D12_CPU_DESCRIPTOR_HANDLE NullHandle = {0}; - auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0; - auto& DstSam = ResourceCache.GetRootTable(Sam.RootIndex).GetResource(Sam.OffsetFromTableStart + SamplerArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, ParentResLayout.m_pResources->GetShaderType()); + auto SamplerArrInd = Sam.BindCount > 1 ? ArrayIndex : 0; + auto& DstSam = ResourceCache.GetRootTable(Sam.RootIndex).GetResource(Sam.OffsetFromTableStart + SamplerArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, ParentResLayout.GetShaderType()); if (DstSam.pObject != nullptr && Sam.GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) - LOG_ERROR_MESSAGE("Sampler variable '", Sam.Attribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another sampler."); + LOG_ERROR_MESSAGE("Sampler variable '", Sam.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another sampler."); DstSam = ShaderResourceCacheD3D12::Resource{}; } } @@ -699,7 +786,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* bool ShaderResourceLayoutD3D12::D3D12Resource::IsBound(Uint32 ArrayIndex, const ShaderResourceCacheD3D12& ResourceCache) const { - VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + VERIFY_EXPR(ArrayIndex < BindCount); if (RootIndex < ResourceCache.GetNumRootTables()) { @@ -709,7 +796,7 @@ bool ShaderResourceLayoutD3D12::D3D12Resource::IsBound(Uint32 ArrayIndex, const const auto& CachedRes = RootTable.GetResource(OffsetFromTableStart + ArrayIndex, GetResType() == CachedResourceType::Sampler ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, - ParentResLayout.m_pResources->GetShaderType()); + ParentResLayout.GetShaderType()); if (CachedRes.pObject != nullptr) { VERIFY(CachedRes.CPUDescriptorHandle.ptr != 0 || CachedRes.pObject.RawPtr()->GetDesc().Usage == USAGE_DYNAMIC, "No relevant descriptor handle"); @@ -721,6 +808,55 @@ bool ShaderResourceLayoutD3D12::D3D12Resource::IsBound(Uint32 ArrayIndex, const return false; } +HLSLShaderResourceDesc ShaderResourceLayoutD3D12::D3D12Resource::GetHLSLResourceDesc() const +{ + HLSLShaderResourceDesc ResourceDesc; + ResourceDesc.Name = Name; + ResourceDesc.ArraySize = BindCount; + ResourceDesc.ShaderRegister = BindPoint; + switch (GetInputType()) + { + case D3D_SIT_CBUFFER: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_CONSTANT_BUFFER; + break; + + case D3D_SIT_TBUFFER: + UNSUPPORTED("TBuffers are not supported"); + ResourceDesc.Type = SHADER_RESOURCE_TYPE_UNKNOWN; + break; + + case D3D_SIT_TEXTURE: + ResourceDesc.Type = (GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_SRV : SHADER_RESOURCE_TYPE_TEXTURE_SRV); + break; + + case D3D_SIT_SAMPLER: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_SAMPLER; + break; + + case D3D_SIT_UAV_RWTYPED: + ResourceDesc.Type = (GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_UAV : SHADER_RESOURCE_TYPE_TEXTURE_UAV); + break; + + case D3D_SIT_STRUCTURED: + case D3D_SIT_BYTEADDRESS: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV; + break; + + case D3D_SIT_UAV_RWSTRUCTURED: + case D3D_SIT_UAV_RWBYTEADDRESS: + case D3D_SIT_UAV_APPEND_STRUCTURED: + case D3D_SIT_UAV_CONSUME_STRUCTURED: + case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: + ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; + break; + + default: + UNEXPECTED("Unknown input type"); + } + + return ResourceDesc; +} + void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderResourceCacheD3D12& SrcCache, const ShaderResourceLayoutD3D12& DstLayout, ShaderResourceCacheD3D12& DstCache) const { @@ -739,18 +875,18 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR // Get resource attributes const auto& res = DstLayout.GetSrvCbvUav(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r); auto RangeType = GetDescriptorRangeType(res.GetResType()); - for (Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < res.BindCount; ++ArrInd) { - auto BindPoint = res.Attribs.BindPoint + ArrInd; + auto BindPoint = res.BindPoint + ArrInd; // Source resource in the static resource cache is in the root table at index RangeType, at offset BindPoint // D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0, // D3D12_DESCRIPTOR_RANGE_TYPE_UAV = 1 // D3D12_DESCRIPTOR_RANGE_TYPE_CBV = 2 - const auto& SrcRes = SrcCache.GetRootTable(RangeType).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); + const auto& SrcRes = SrcCache.GetRootTable(RangeType).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); if (!SrcRes.pObject) - LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); + LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); // Destination resource is at the root index and offset defined by the resource layout - auto& DstRes = DstCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); + auto& DstRes = DstCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); if (DstRes.pObject != SrcRes.pObject) { @@ -793,10 +929,10 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR { const auto& SamInfo = DstLayout.GetAssignedSampler(res); - //VERIFY(!SamInfo.Attribs.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache"); + //VERIFY(!SamInfo.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache"); - VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid"); - VERIFY_EXPR(SamInfo.Attribs.BindCount == res.Attribs.BindCount || SamInfo.Attribs.BindCount == 1); + VERIFY(SamInfo.IsValidBindPoint(), "Sampler bind point must be valid"); + VERIFY_EXPR(SamInfo.BindCount == res.BindCount || SamInfo.BindCount == 1); } } @@ -805,15 +941,15 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR for (Uint32 s = 0; s < SamplerCount; ++s) { const auto& SamInfo = DstLayout.GetSampler(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, s); - for (Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < SamInfo.BindCount; ++ArrInd) { - auto BindPoint = SamInfo.Attribs.BindPoint + ArrInd; + auto BindPoint = SamInfo.BindPoint + ArrInd; // Source sampler in the static resource cache is in the root table at index 3 // (D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = 3), at offset BindPoint - const auto& SrcSampler = SrcCache.GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + const auto& SrcSampler = SrcCache.GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (!SrcSampler.pObject) - LOG_ERROR_MESSAGE("No sampler assigned to static shader variable '", SamInfo.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); - auto& DstSampler = DstCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + LOG_ERROR_MESSAGE("No sampler assigned to static shader variable '", SamInfo.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); + auto& DstSampler = DstCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (DstSampler.pObject != SrcSampler.pObject) { @@ -852,9 +988,9 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 const auto& res = GetSrvCbvUav(VarType, r); VERIFY(res.GetVariableType() == VarType, "Unexpected variable type"); - for (Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < res.BindCount; ++ArrInd) { - const auto& CachedRes = ResourceCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); + const auto& CachedRes = ResourceCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); if (CachedRes.pObject) VERIFY(CachedRes.Type == res.GetResType(), "Inconsistent cached resource types"); else @@ -864,24 +1000,24 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 // Dynamic buffers do not have CPU descriptor handle as they do not keep D3D12 buffer, and space is allocated from the GPU ring buffer CachedRes.CPUDescriptorHandle.ptr == 0 && !(CachedRes.Type == CachedResourceType::CBV && CachedRes.pObject.RawPtr()->GetDesc().Usage == USAGE_DYNAMIC)) { - LOG_ERROR_MESSAGE("No resource is bound to ", GetShaderVariableTypeLiteralName(res.GetVariableType()), " variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); + LOG_ERROR_MESSAGE("No resource is bound to ", GetShaderVariableTypeLiteralName(res.GetVariableType()), " variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); BindingsOK = false; } - if (res.Attribs.BindCount > 1 && res.ValidSamplerAssigned()) + if (res.BindCount > 1 && res.ValidSamplerAssigned()) { // Verify that if single sampler is used for all texture array elements, all samplers set in the resource views are consistent const auto& SamInfo = GetAssignedSampler(res); - if (SamInfo.Attribs.BindCount == 1) + if (SamInfo.BindCount == 1) { - const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); // Conversion must always succeed as the type is verified when resource is bound to the variable if (const auto* pTexView = CachedRes.pObject.RawPtr()) { const auto* pSampler = pTexView->GetSampler(); if (pSampler != nullptr && CachedSampler.pObject != nullptr && CachedSampler.pObject != pSampler) { - LOG_ERROR_MESSAGE("All elements of texture array '", res.Attribs.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", ArrInd, " does not match bound sampler. This may cause incorrect behavior on GL platform."); + LOG_ERROR_MESSAGE("All elements of texture array '", res.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", ArrInd, " does not match bound sampler. This may cause incorrect behavior on GL platform."); } } } @@ -896,7 +1032,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 } else if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) { - if (res.GetResType() == CachedResourceType::CBV && res.Attribs.BindCount == 1) + if (res.GetResType() == CachedResourceType::CBV && res.BindCount == 1) { VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Non-array constant buffers are bound as root views and should not be assigned shader visible descriptor space"); } @@ -920,19 +1056,19 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 { VERIFY(res.GetResType() == CachedResourceType::TexSRV, "Sampler can only be assigned to a texture SRV"); const auto& SamInfo = GetAssignedSampler(res); - //VERIFY(!SamInfo.Attribs.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" ); - VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid"); + //VERIFY(!SamInfo.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" ); + VERIFY(SamInfo.IsValidBindPoint(), "Sampler bind point must be valid"); - for (Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < SamInfo.BindCount; ++ArrInd) { - const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (CachedSampler.pObject) VERIFY(CachedSampler.Type == CachedResourceType::Sampler, "Incorrect cached sampler type"); else VERIFY(CachedSampler.Type == CachedResourceType::Unknown, "Unexpected cached sampler type"); if (!CachedSampler.pObject || CachedSampler.CPUDescriptorHandle.ptr == 0) { - LOG_ERROR_MESSAGE("No sampler is assigned to texture variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); + LOG_ERROR_MESSAGE("No sampler is assigned to texture variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); BindingsOK = false; } @@ -965,16 +1101,16 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 const auto& sam = GetSampler(VarType, s); VERIFY(sam.GetVariableType() == VarType, "Unexpected sampler variable type"); - for (Uint32 ArrInd = 0; ArrInd < sam.Attribs.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < sam.BindCount; ++ArrInd) { - const auto& CachedSampler = ResourceCache.GetRootTable(sam.RootIndex).GetResource(sam.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + const auto& CachedSampler = ResourceCache.GetRootTable(sam.RootIndex).GetResource(sam.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (CachedSampler.pObject) VERIFY(CachedSampler.Type == CachedResourceType::Sampler, "Incorrect cached sampler type"); else VERIFY(CachedSampler.Type == CachedResourceType::Unknown, "Unexpected cached sampler type"); if (!CachedSampler.pObject || CachedSampler.CPUDescriptorHandle.ptr == 0) { - LOG_ERROR_MESSAGE("No sampler is bound to sampler variable '", sam.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); + LOG_ERROR_MESSAGE("No sampler is bound to sampler variable '", sam.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); BindingsOK = false; } } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp index 26f889e5..093a5480 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp @@ -106,12 +106,13 @@ ShaderResourcesD3D12::ShaderResourcesD3D12(ID3DBlob* pShaderBytecode, { public: // clang-format off - void OnNewCB (const D3DShaderResourceAttribs& CBAttribs) {} - void OnNewTexUAV (const D3DShaderResourceAttribs& TexUAV) {} - void OnNewBuffUAV(const D3DShaderResourceAttribs& BuffUAV) {} - void OnNewBuffSRV(const D3DShaderResourceAttribs& BuffSRV) {} - void OnNewSampler(const D3DShaderResourceAttribs& SamplerAttribs){} - void OnNewTexSRV (const D3DShaderResourceAttribs& TexAttribs) {} + void OnNewCB (const D3DShaderResourceAttribs& CBAttribs) {} + void OnNewTexUAV (const D3DShaderResourceAttribs& TexUAV) {} + void OnNewBuffUAV (const D3DShaderResourceAttribs& BuffUAV) {} + void OnNewBuffSRV (const D3DShaderResourceAttribs& BuffSRV) {} + void OnNewSampler (const D3DShaderResourceAttribs& SamplerAttribs){} + void OnNewTexSRV (const D3DShaderResourceAttribs& TexAttribs) {} + void OnNewAccelStruct(const D3DShaderResourceAttribs& ASAttribs) {} // clang-format on }; diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp index fd58eacf..1c3afa53 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp @@ -125,7 +125,7 @@ ShaderVariableD3D12Impl* ShaderVariableManagerD3D12::GetVariable(const Char* Nam for (Uint32 v = 0; v < m_NumVariables; ++v) { auto& Var = m_pVariables[v]; - if (strcmp(Var.m_Resource.Attribs.Name, Name) == 0) + if (strcmp(Var.m_Resource.Name, Name) == 0) { pVar = &Var; break; @@ -181,14 +181,14 @@ void ShaderVariableManagerD3D12::BindResources(IResourceMapping* pResourceMappin if ((Flags & (1 << Res.GetVariableType())) == 0) continue; - for (Uint32 ArrInd = 0; ArrInd < Res.Attribs.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < Res.BindCount; ++ArrInd) { if ((Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(ArrInd, m_ResourceCache)) continue; RefCntAutoPtr pObj; VERIFY_EXPR(pResourceMapping != nullptr); - pResourceMapping->GetResource(Res.Attribs.Name, &pObj, ArrInd); + pResourceMapping->GetResource(Res.Name, &pObj, ArrInd); if (pObj) { // Call non-virtual function @@ -197,7 +197,7 @@ void ShaderVariableManagerD3D12::BindResources(IResourceMapping* pResourceMappin else { if ((Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(ArrInd, m_ResourceCache)) - LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", Res.Attribs.GetPrintName(ArrInd), "': resource is not found in the resource mapping"); + LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", Res.GetPrintName(ArrInd), "': resource is not found in the resource mapping"); } } } -- cgit v1.2.3 From f8be662d357be9dcbb4b298d93b43d29ae93ce04 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 27 Oct 2020 19:08:28 -0700 Subject: A number of updates/fixes to PSO refactor merge --- .../include/D3D12TypeConversions.hpp | 4 + .../include/PipelineStateD3D12Impl.hpp | 7 +- .../include/RenderDeviceD3D12Impl.hpp | 5 + .../GraphicsEngineD3D12/include/RootSignature.hpp | 12 +- .../include/ShaderResourceBindingD3D12Impl.hpp | 1 + .../include/ShaderResourceCacheD3D12.hpp | 2 +- .../include/ShaderResourceLayoutD3D12.hpp | 173 ++++++------- .../include/ShaderResourcesD3D12.hpp | 33 +-- .../include/ShaderVariableD3D12.hpp | 4 +- .../src/D3D12TypeConversions.cpp | 53 ++++ .../src/PipelineStateD3D12Impl.cpp | 200 +++++++-------- .../src/RenderDeviceD3D12Impl.cpp | 9 +- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 81 +----- .../src/ShaderResourceLayoutD3D12.cpp | 274 ++++++++------------- .../src/ShaderVariableD3D12.cpp | 8 +- 15 files changed, 363 insertions(+), 503 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp index 89e52955..c6678ddd 100644 --- a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp +++ b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp @@ -75,4 +75,8 @@ D3D12_QUERY_TYPE QueryTypeToD3D12QueryType(QUERY_TYPE QueryType); D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE AttachmentLoadOpToD3D12BeginningAccessType(ATTACHMENT_LOAD_OP LoadOp); D3D12_RENDER_PASS_ENDING_ACCESS_TYPE AttachmentStoreOpToD3D12EndingAccessType(ATTACHMENT_STORE_OP StoreOp); +D3D12_SHADER_VISIBILITY ShaderTypeToD3D12ShaderVisibility(SHADER_TYPE ShaderType); +SHADER_TYPE D3D12ShaderVisibilityToShaderType(D3D12_SHADER_VISIBILITY ShaderVisibility); + + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index 4bdeb08c..6a27a029 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -133,13 +133,13 @@ private: void Append(ShaderD3D12Impl* pShader); size_t Count() const; - SHADER_TYPE Type; + SHADER_TYPE Type = SHADER_TYPE_UNKNOWN; std::vector Shaders; }; using TShaderStages = std::vector; - template - void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages); + template + void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, InitPSODescType InitPSODesc); void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages); void Destruct(); @@ -157,6 +157,7 @@ private: // Resource layout index in m_pShaderResourceLayouts array for every shader stage, // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex) std::array m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1}; + static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above"); }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 2bc13c31..ab72e22a 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -178,6 +178,11 @@ public: ShaderVersion GetMaxShaderModel() const; D3D_FEATURE_LEVEL GetD3DFeatureLevel() const; + static Uint32 GetShaderGroupHandleSize() + { + return D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; + } + private: template void CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState); diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index 6deac5f0..a6bf76b1 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -32,11 +32,11 @@ #include #include "ShaderResourceLayoutD3D12.hpp" #include "BufferD3D12Impl.hpp" +#include "D3D12TypeConversions.hpp" namespace Diligent { -D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType); D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType); class RootParameter @@ -513,10 +513,6 @@ private: class CommandContext& Ctx, bool IsCompute, bool ValidateStates) const; - -#ifdef DILIGENT_DEBUG - SHADER_TYPE m_DbgShaderStages = SHADER_TYPE_UNKNOWN; -#endif }; void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, @@ -537,7 +533,11 @@ void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; #ifdef DILIGENT_DEBUG - dbgShaderType = m_DbgShaderStages; + { + auto& Param = static_cast(RootView); + VERIFY_EXPR(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV); + dbgShaderType = D3D12ShaderVisibilityToShaderType(Param.ShaderVisibility); + } #endif auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType); diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp index ac16cf9f..f1eb5c85 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp @@ -86,6 +86,7 @@ private: // Resource layout index in m_ShaderResourceCache array for every shader stage, // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex) std::array m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1}; + static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above"); bool m_bStaticResourcesInitialized = false; const Uint8 m_NumShaders = 0; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp index cf69793a..73ebe3b8 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp @@ -167,7 +167,7 @@ public: const SHADER_TYPE dbgRefShaderType) const { VERIFY(m_dbgHeapType == dbgDescriptorHeapType, "Incosistent descriptor heap type"); - VERIFY((m_dbgShaderType & dbgRefShaderType) == dbgRefShaderType, "Incosistent shader type"); + VERIFY(dbgRefShaderType == SHADER_TYPE_UNKNOWN || m_dbgShaderType == SHADER_TYPE_UNKNOWN || m_dbgShaderType == dbgRefShaderType, "Incosistent shader type"); VERIFY(OffsetFromTableStart < m_NumResources, "Root table is not large enough to store descriptor at offset ", OffsetFromTableStart); return m_pResources[OffsetFromTableStart]; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index bd581101..1f2b3d2d 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -50,22 +50,9 @@ // m' == NumSamplers[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] // d' == NumSamplers[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] // -// Every D3D12Resource structure holds a reference to D3DShaderResourceAttribs structure from ShaderResourcesD3D12. -// ShaderResourceLayoutD3D12 holds shared pointer to ShaderResourcesD3D12 instance. Note that ShaderResourcesD3D12::SamplerId -// references a sampler in ShaderResourcesD3D12, while D3D12Resource::SamplerId references a sampler in ShaderResourceLayoutD3D12, -// and the two are not necessarily the same // // -// ________________SamplerId____________________ -// | | -// _____________________ ______________|_____________________________________________V________ -// | | unique_ptr | | | | | | | -// |ShaderResourcesD3D12 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | -// |_____________________| |________|___________|___________|___________|___________|____________| -// A A A A -// | \ / \ -// |shared_ptr Ref Ref Ref -// ________|__________________ ________\________________________/_________________________\________________________________________________ +// ___________________________ ____________________________________________________________________________________________________________ // | | unique_ptr | | | | | | | // | ShaderResourceLayoutD3D12 |--------------->| D3D12Resource[0] | D3D12Resource[1] | ... | D3D12Resource[smd] | D3D12Resource[smd+1] | ... | // |___________________________| |__________________|__________________|_______________|____________________|______________________|__________| @@ -79,9 +66,27 @@ // | | | | | | // | ShaderVariableManagerD3D12 |---------------->| ShaderVariableD3D12Impl[0] | ShaderVariableD3D12Impl[1] | ... | // |____________________________| |____________________________|____________________________|_________________| - // -// http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Figure2 +// +// +// +// +// One ShaderResourceLayoutD3D12 instance can be referenced by multiple objects +// +// +// ________________________ __ __________ ________________________________ +// | | | | | | | | +// | PipelineStateD3D12Impl |========>| ShaderResourceLayoutD3D12 |<-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl | +// |________________________| |____________________________| |____________________________| |________________________________| +// A +// \ +// \ __________ ________________________________ +// \ | | | | +// '-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl | +// |____________________________| |________________________________| +// +// +// // Resources in the resource cache are identified by the root index and offset in the descriptor table // // @@ -101,21 +106,26 @@ #include #include "ShaderBase.hpp" -#include "ShaderResourcesD3D12.hpp" #include "ShaderResourceCacheD3D12.hpp" #include "ShaderD3D12Impl.hpp" +#include "StringPool.hpp" +#include "D3DCommonTypeConversions.hpp" namespace Diligent { /// Diligent::ShaderResourceLayoutD3D12 class -// sizeof(ShaderResourceLayoutD3D12) == 64 (MS compiler, x64) +// sizeof(ShaderResourceLayoutD3D12) == 56 (MS compiler, x64) class ShaderResourceLayoutD3D12 final { public: explicit ShaderResourceLayoutD3D12(IObject& Owner) noexcept : m_Owner{Owner} - {} + { +#if defined(_MSC_VER) && defined(_WIN64) + static_assert(sizeof(*this) == 56, "Unexpected sizeof(ShaderResourceLayoutD3D12)"); +#endif + } // There are two modes a layout can be initialized: // - initialize static resource layout and initialize shader resource cache to hold static resources @@ -141,7 +151,7 @@ public: ~ShaderResourceLayoutD3D12(); - // sizeof(D3D12Resource) == 24 (x64) + // sizeof(D3D12Resource) == 32 (x64) struct D3D12Resource final { // clang-format off @@ -153,68 +163,57 @@ public: static constexpr const Uint32 ResourceTypeBits = 3; static constexpr const Uint32 VariableTypeBits = 2; - static constexpr const Uint32 RootIndexBits = 16 - ResourceTypeBits - VariableTypeBits; + static constexpr const Uint32 RootIndexBits = 32 - ResourceTypeBits - VariableTypeBits; - static constexpr const Uint32 InvalidRootIndex = (1 << RootIndexBits) - 1; - static constexpr const Uint32 MaxRootIndex = InvalidRootIndex - 1; + static constexpr const Uint32 InvalidRootIndex = (1U << RootIndexBits) - 1U; + static constexpr const Uint32 MaxRootIndex = InvalidRootIndex - 1U; - static constexpr const Uint32 InvalidSamplerId = 0xFFFF; - static constexpr const Uint32 MaxSamplerId = InvalidSamplerId-1; static constexpr const Uint32 InvalidOffset = static_cast(-1); - static_assert( SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES < (1 << VariableTypeBits), "2 bits is not enough to store SHADER_RESOURCE_VARIABLE_TYPE"); - static_assert( static_cast(CachedResourceType::NumTypes) < (1 << ResourceTypeBits), "3 bits is not enough to store CachedResourceType"); - + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES < (1 << VariableTypeBits), "Not enough bits to represent SHADER_RESOURCE_VARIABLE_TYPE"); + static_assert(static_cast(CachedResourceType::NumTypes) < (1 << ResourceTypeBits), "Not enough bits to represent CachedResourceType"); + /* 0 */ const ShaderResourceLayoutD3D12& ParentResLayout; -/*16 */ const Uint32 OffsetFromTableStart; -/*20.0*/ const Uint16 ResourceType : ResourceTypeBits; // | 0 1 2 | -/*20.3*/ const Uint16 VariableType : VariableTypeBits; // | 3 4 | -/*20.5*/ const Uint16 RootIndex : RootIndexBits; // | 5 6 7 ... 15 | -/*22 */ const Uint16 SamplerId; -/* */ const char* const Name; -/* */ const Uint16 BindCount; -/* */ const Uint16 BindPoint; -/* */ const Uint8 InputType; -/* */ const Uint8 SRVDimension; -/* */ // End of data +/* 8 */ const D3DShaderResourceAttribs Attribs; +/*24 */ const Uint32 OffsetFromTableStart; +/*28.0*/ const Uint32 ResourceType : ResourceTypeBits; // | 0 1 2 | +/*28.3*/ const Uint32 VariableType : VariableTypeBits; // | 3 4 | +/*28.5*/ const Uint32 RootIndex : RootIndexBits; // | 5 6 7 ... 15 | +/*32 */ // End of data // clang-format on D3D12Resource(const ShaderResourceLayoutD3D12& _ParentLayout, + StringPool& _StringPool, + const D3DShaderResourceAttribs& _Attribs, + Uint32 _SamplerId, SHADER_RESOURCE_VARIABLE_TYPE _VariableType, CachedResourceType _ResType, Uint32 _RootIndex, - Uint32 _OffsetFromTableStart, - Uint32 _SamplerId, - const char* _Name, - Uint32 _BindCount, - Uint32 _BindPoint, - D3D_SHADER_INPUT_TYPE _InputType, - D3D_SRV_DIMENSION _SRVDimension) noexcept : + Uint32 _OffsetFromTableStart) noexcept : // clang-format off - ParentResLayout {_ParentLayout }, - ResourceType {static_cast(_ResType) }, - VariableType {static_cast(_VariableType)}, - RootIndex {static_cast(_RootIndex) }, - SamplerId {static_cast(_SamplerId) }, - OffsetFromTableStart{ _OffsetFromTableStart }, - Name {_Name}, - BindCount {static_cast(_BindCount) }, - BindPoint {static_cast(_BindPoint) }, - InputType {static_cast(_InputType) }, - SRVDimension {static_cast(_SRVDimension) } + ParentResLayout{_ParentLayout}, + Attribs + { + _StringPool, + _Attribs, + _SamplerId + }, + ResourceType {static_cast(_ResType) }, + VariableType {static_cast(_VariableType)}, + RootIndex {static_cast(_RootIndex) }, + OffsetFromTableStart{ _OffsetFromTableStart } // clang-format on { +#if defined(_MSC_VER) && defined(_WIN64) + static_assert(sizeof(*this) == 32, "Unexpected sizeof(D3D12Resource)"); +#endif + VERIFY(IsValidOffset(), "Offset must be valid"); VERIFY(IsValidRootIndex(), "Root index must be valid"); VERIFY(_RootIndex <= MaxRootIndex, "Root index (", _RootIndex, ") exceeds max allowed value (", MaxRootIndex, ")"); + VERIFY(static_cast(_ResType) < (1 << ResourceTypeBits), "Resource type is out of representable range"); VERIFY(_VariableType < (1 << VariableTypeBits), "Variable type is out of representable range"); - VERIFY(_SamplerId == InvalidSamplerId || _SamplerId <= MaxSamplerId, "Sampler id (", _SamplerId, ") exceeds max allowed value (", MaxSamplerId, ")"); - VERIFY(_SamplerId == InvalidSamplerId || GetResType() == CachedResourceType::TexSRV, "A sampler can only be assigned to a Texture SRV"); - VERIFY(_BindCount <= std::numeric_limits::max(), "BindCount (", _BindCount, ") exceeds max representable value ", std::numeric_limits::max()); - VERIFY(_BindPoint <= std::numeric_limits::max(), "BindPoint (", _BindPoint, ") exceeds max representable value ", std::numeric_limits::max()); - VERIFY(_InputType <= std::numeric_limits::max(), "InputType (", _InputType, ") exceeds max representable value ", std::numeric_limits::max()); - VERIFY(_SRVDimension <= std::numeric_limits::max(), "SRVDimension (", _SRVDimension, ") exceeds max representable value ", std::numeric_limits::max()); } bool IsBound(Uint32 ArrayIndex, @@ -225,42 +224,12 @@ public: ShaderResourceCacheD3D12& ResourceCache) const; // clang-format off - bool ValidSamplerAssigned()const { return SamplerId != InvalidSamplerId; } - bool IsValidRootIndex() const { return RootIndex != InvalidRootIndex; } - bool IsValidOffset() const { return OffsetFromTableStart != InvalidOffset; } + bool IsValidRootIndex() const { return RootIndex != InvalidRootIndex; } + bool IsValidOffset() const { return OffsetFromTableStart != InvalidOffset; } // clang-format on CachedResourceType GetResType() const { return static_cast(ResourceType); } SHADER_RESOURCE_VARIABLE_TYPE GetVariableType() const { return static_cast(VariableType); } - HLSLShaderResourceDesc GetHLSLResourceDesc() const; - - bool IsValidBindPoint() const - { - return BindPoint != D3DShaderResourceAttribs::InvalidBindPoint; - } - - String GetPrintName(Uint32 ArrayInd) const - { - VERIFY_EXPR(ArrayInd < BindCount); - if (BindCount > 1) - return String(Name) + '[' + std::to_string(ArrayInd) + ']'; - else - return Name; - } - - D3D_SHADER_INPUT_TYPE GetInputType() const - { - return static_cast(InputType); - } - - D3D_SRV_DIMENSION GetSRVDimension() const - { - return static_cast(SRVDimension); - } - - RESOURCE_DIMENSION GetResourceDimension() const; - - bool IsMultisample() const; private: void CacheCB(IDeviceObject* pBuffer, @@ -393,21 +362,21 @@ private: return GetResource(m_SamplersOffsets[0] + s); } - void AllocateMemory(IMemoryAllocator& Allocator, - const std::array& CbvSrvUavCount, - const std::array& SamplerCount); + StringPool AllocateMemory(IMemoryAllocator& Allocator, + const std::array& CbvSrvUavCount, + const std::array& SamplerCount, + size_t StringPoolSize); // clang-format off /* 0 */ std::unique_ptr > m_ResourceBuffer; /* 16 */ std::array m_CbvSrvUavOffsets = {}; /* 24 */ std::array m_SamplersOffsets = {}; -/* 24 */ StringPool m_StringPool; /* 32 */ IObject& m_Owner; -/* 48 */ CComPtr m_pd3d12Device; -/* */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; +/* 40 */ CComPtr m_pd3d12Device; +/* 48 */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN; /* */ bool m_IsUsingSeparateSamplers = false; -/* 64 */ // End of data +/* 56 */ // End of data // clang-format on }; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp index fe867d89..1c4af270 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp @@ -30,7 +30,7 @@ /// \file /// Declaration of Diligent::ShaderResourcesD3D12 class -// ShaderResourcesD3D12 are created by ShaderD3D12Impl instances. They are then referenced by ShaderResourceLayoutD3D12 objects, which are in turn +// ShaderResourcesD3D12 are created by ShaderD3D12Impl instances. They are then used by ShaderResourceLayoutD3D12 objects, which are // created by instances of PipelineStatesD3D12Impl and ShaderD3D12Impl // // _________________ @@ -43,10 +43,10 @@ // | | unique_ptr | | | | | | | // | ShaderResourcesD3D12 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | // |______________________| |________|___________|___________|___________|___________|____________| -// A A A A -// | \ / \ -// |shared_ptr Ref Ref Ref -// ________|__________________ ________\________________________/_________________________\_________________________________________ +// A A A +// \ / \ +// Copy Copy Copy +// ___________________________ ________\________________________/_________________________\_________________________________________ // | | unique_ptr | | | | | | | // | ShaderResourceLayoutD3D12 |--------------->| SRV_CBV_UAV[0] | SRV_CBV_UAV[1] | ... | Sampler[0] | Sampler[1] | ... | // |___________________________| |___________________|_________________|_______________|__________________|_________________|__________| @@ -58,29 +58,6 @@ // | PipelineStateD3D12Impl | // |________________________| // -// -// -// One ShaderResourcesD3D12 instance can be referenced by multiple objects -// -// -// ________________________ __ __________ ________________________________ -// | | | | | | | | -// | PipelineStateD3D12Impl |========>| ShaderResourceLayoutD3D12 |<-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl | -// |________________________| |____________________________| |____________________________| |________________________________| -// | A -// |shared_ptr \ -// _________________ ___________V__________ \ __________ ________________________________ -// | | shared_ptr | | \ | | | | -// | ShaderD3D12Impl |---------------->| ShaderResourcesD3D12 | '-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl | -// |_________________| |______________________| |____________________________| |________________________________| -// | |___________________ A -// | | | -// V V |shared_ptr -// ___________ ____|___ -// | | | | -// | ShaderVariableManagerD3D12 |------>| ShaderResourceLayoutD3D12 | -// |____________________________| |___________________________| -// #include "ShaderResources.hpp" diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp index 1e60ecd8..c30d8296 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp @@ -186,7 +186,7 @@ public: virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final { - VerifyAndCorrectSetArrayArguments(m_Resource.Name, m_Resource.BindCount, FirstElement, NumElements); + VerifyAndCorrectSetArrayArguments(m_Resource.Attribs.Name, m_Resource.Attribs.BindCount, FirstElement, NumElements); for (Uint32 Elem = 0; Elem < NumElements; ++Elem) m_Resource.BindResource(ppObjects[Elem], FirstElement + Elem, m_ParentManager.m_ResourceCache); } @@ -198,7 +198,7 @@ public: virtual HLSLShaderResourceDesc DILIGENT_CALL_TYPE GetHLSLResourceDesc() const override final { - return m_Resource.GetHLSLResourceDesc(); + return m_Resource.Attribs.GetHLSLResourceDesc(); } virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 89c495b9..3ea4bad0 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -540,4 +540,57 @@ D3D12_RENDER_PASS_ENDING_ACCESS_TYPE AttachmentStoreOpToD3D12EndingAccessType(AT // clang-format on } +D3D12_SHADER_VISIBILITY ShaderTypeToD3D12ShaderVisibility(SHADER_TYPE ShaderType) +{ + static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type"); + switch (ShaderType) + { + // clang-format off + case SHADER_TYPE_VERTEX: return D3D12_SHADER_VISIBILITY_VERTEX; + case SHADER_TYPE_PIXEL: return D3D12_SHADER_VISIBILITY_PIXEL; + case SHADER_TYPE_GEOMETRY: return D3D12_SHADER_VISIBILITY_GEOMETRY; + case SHADER_TYPE_HULL: return D3D12_SHADER_VISIBILITY_HULL; + case SHADER_TYPE_DOMAIN: return D3D12_SHADER_VISIBILITY_DOMAIN; + case SHADER_TYPE_COMPUTE: return D3D12_SHADER_VISIBILITY_ALL; +# ifdef D3D12_H_HAS_MESH_SHADER + case SHADER_TYPE_AMPLIFICATION: return D3D12_SHADER_VISIBILITY_AMPLIFICATION; + case SHADER_TYPE_MESH: return D3D12_SHADER_VISIBILITY_MESH; +# endif + case SHADER_TYPE_RAY_GEN: + case SHADER_TYPE_RAY_MISS: + case SHADER_TYPE_RAY_CLOSEST_HIT: + case SHADER_TYPE_RAY_ANY_HIT: + case SHADER_TYPE_RAY_INTERSECTION: + case SHADER_TYPE_CALLABLE: return D3D12_SHADER_VISIBILITY_ALL; + // clang-format on + default: + LOG_ERROR("Unknown shader type (", ShaderType, ")"); + return D3D12_SHADER_VISIBILITY_ALL; + } +} + +SHADER_TYPE D3D12ShaderVisibilityToShaderType(D3D12_SHADER_VISIBILITY ShaderVisibility) +{ + static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type"); + switch (ShaderVisibility) + { + // clang-format off + case D3D12_SHADER_VISIBILITY_ALL: return SHADER_TYPE_UNKNOWN; + case D3D12_SHADER_VISIBILITY_VERTEX: return SHADER_TYPE_VERTEX; + case D3D12_SHADER_VISIBILITY_PIXEL: return SHADER_TYPE_PIXEL; + case D3D12_SHADER_VISIBILITY_GEOMETRY: return SHADER_TYPE_GEOMETRY; + case D3D12_SHADER_VISIBILITY_HULL: return SHADER_TYPE_HULL; + case D3D12_SHADER_VISIBILITY_DOMAIN: return SHADER_TYPE_DOMAIN; +# ifdef D3D12_H_HAS_MESH_SHADER + case D3D12_SHADER_VISIBILITY_AMPLIFICATION: return SHADER_TYPE_AMPLIFICATION; + case D3D12_SHADER_VISIBILITY_MESH: return SHADER_TYPE_MESH; +# endif + // clang-format on + default: + LOG_ERROR("Unknown shader visibility (", ShaderVisibility, ")"); + return SHADER_TYPE_UNKNOWN; + } +} + + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 6efa4acc..a446e960 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -108,8 +108,9 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI { #define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ray tracing PSO '", CreateInfo.PSODesc.Name, "' is invalid: ", ##__VA_ARGS__) - Uint32 ShaderIndex = 0; - Uint32 GroupIndex = 0; + Uint32 ShaderIndex = 0; + Uint32 GroupIndex = 0; + std::unordered_map UniqueShaders; const auto ShaderIndexToStr = [&TempPool](Uint32 Index) -> LPCWSTR { @@ -131,8 +132,8 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI auto Result = UniqueShaders.emplace(pShader, nullptr); if (Result.second) { - auto& LibDesc = *TempPool.Allocate(); - auto& ExportDesc = *TempPool.Allocate(); + auto& LibDesc = *TempPool.Construct(); + auto& ExportDesc = *TempPool.Construct(); auto* pShaderD3D12 = ValidatedCast(pShader); LibDesc.DXILLibrary.BytecodeLength = pShaderD3D12->GetShaderByteCode()->GetBufferSize(); @@ -161,56 +162,61 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i) { - AddDxilLib(CreateInfo.pGeneralShaders[i].pShader, CreateInfo.pGeneralShaders[i].Name); + const auto& GeneralShader = CreateInfo.pGeneralShaders[i]; + AddDxilLib(GeneralShader.pShader, GeneralShader.Name); - bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pGeneralShaders[i].Name)}, GroupIndex++).second; + bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(GeneralShader.Name)}, GroupIndex++).second; if (!IsUniqueName) LOG_PSO_ERROR_AND_THROW("pGeneralShaders[", i, "].Name must be unique"); } for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i) { - auto& HitGroupDesc = *TempPool.Allocate(); - HitGroupDesc.HitGroupExport = TempPool.CopyWString(CreateInfo.pTriangleHitShaders[i].Name); + const auto& TriHitShader = CreateInfo.pTriangleHitShaders[i]; + + auto& HitGroupDesc = *TempPool.Construct(); + HitGroupDesc.HitGroupExport = TempPool.CopyWString(TriHitShader.Name); HitGroupDesc.Type = D3D12_HIT_GROUP_TYPE_TRIANGLES; - HitGroupDesc.ClosestHitShaderImport = AddDxilLib(CreateInfo.pTriangleHitShaders[i].pClosestHitShader, nullptr); - HitGroupDesc.AnyHitShaderImport = AddDxilLib(CreateInfo.pTriangleHitShaders[i].pAnyHitShader, nullptr); + HitGroupDesc.ClosestHitShaderImport = AddDxilLib(TriHitShader.pClosestHitShader, nullptr); + HitGroupDesc.AnyHitShaderImport = AddDxilLib(TriHitShader.pAnyHitShader, nullptr); HitGroupDesc.IntersectionShaderImport = nullptr; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); - bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pTriangleHitShaders[i].Name)}, GroupIndex++).second; + bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(TriHitShader.Name)}, GroupIndex++).second; if (!IsUniqueName) LOG_PSO_ERROR_AND_THROW("pTriangleHitShaders[", i, "].Name must be unique"); } for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i) { - auto& HitGroupDesc = *TempPool.Allocate(); - HitGroupDesc.HitGroupExport = TempPool.CopyWString(CreateInfo.pProceduralHitShaders[i].Name); + const auto& ProcHitShader = CreateInfo.pProceduralHitShaders[i]; + + auto& HitGroupDesc = *TempPool.Construct(); + HitGroupDesc.HitGroupExport = TempPool.CopyWString(ProcHitShader.Name); HitGroupDesc.Type = D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE; - HitGroupDesc.ClosestHitShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pClosestHitShader, nullptr); - HitGroupDesc.AnyHitShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pAnyHitShader, nullptr); - HitGroupDesc.IntersectionShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pIntersectionShader, nullptr); + HitGroupDesc.ClosestHitShaderImport = AddDxilLib(ProcHitShader.pClosestHitShader, nullptr); + HitGroupDesc.AnyHitShaderImport = AddDxilLib(ProcHitShader.pAnyHitShader, nullptr); + HitGroupDesc.IntersectionShaderImport = AddDxilLib(ProcHitShader.pIntersectionShader, nullptr); Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); - bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pProceduralHitShaders[i].Name)}, GroupIndex++).second; + bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(ProcHitShader.Name)}, GroupIndex++).second; if (!IsUniqueName) LOG_PSO_ERROR_AND_THROW("pProceduralHitShaders[", i, "].Name must be unique"); } - VERIFY_EXPR(Uint32(CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount) == GroupIndex); + VERIFY_EXPR(Uint32{CreateInfo.GeneralShaderCount} + Uint32{CreateInfo.TriangleHitShaderCount} + Uint32{CreateInfo.ProceduralHitShaderCount} == GroupIndex); if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH) LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than equal to ", D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH); - auto& PipelineConfig = *TempPool.Allocate(); + auto& PipelineConfig = *TempPool.Construct(); // for compatibility with Vulkan set minimal recursion depth to 1 PipelineConfig.MaxTraceRecursionDepth = std::max(1, CreateInfo.RayTracingPipeline.MaxRecursionDepth); Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG, &PipelineConfig}); - auto& ShaderConfig = *TempPool.Allocate(); + auto& ShaderConfig = *TempPool.Construct(); ShaderConfig.MaxAttributeSizeInBytes = D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES; ShaderConfig.MaxPayloadSizeInBytes = 32; // AZ TODO Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &ShaderConfig}); @@ -225,56 +231,51 @@ void GetShaderIdentifiers(ID3D12StateObject* pSO, { const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; - WCHAR TempName[256] = {}; - auto ConvertWStr = [&TempName](const char* Src) { - Uint32 i = 0; - for (; i < _countof(TempName) && Src[i] != 0; ++i) - TempName[i] = static_cast(Src[i]); - TempName[i] = 0; - return TempName; - }; - CComPtr pStateObjectProperties; - auto hr = pSO->QueryInterface(IID_PPV_ARGS(&pStateObjectProperties)); + + auto hr = pSO->QueryInterface(IID_PPV_ARGS(&pStateObjectProperties)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to get state object properties"); for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i) { - auto iter = NameToGroupIndex.find(CreateInfo.pGeneralShaders[i].Name); + const auto& GeneralShader = CreateInfo.pGeneralShaders[i]; + + auto iter = NameToGroupIndex.find(GeneralShader.Name); if (iter == NameToGroupIndex.end()) - LOG_ERROR_AND_THROW("Failed to get shader group index by name"); + LOG_ERROR_AND_THROW("Failed to get shader group index for general shader group '", GeneralShader.Name, "'"); - WCHAR* ShaderName = ConvertWStr(CreateInfo.pGeneralShaders[i].Name); - const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName); + const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(GeneralShader.Name).c_str()); if (ShaderID == nullptr) - LOG_ERROR_AND_THROW("Failed to get shader identifier"); + LOG_ERROR_AND_THROW("Failed to get shader identifier for general shader group '", GeneralShader.Name, "'"); std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize); } for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i) { - auto iter = NameToGroupIndex.find(CreateInfo.pTriangleHitShaders[i].Name); + const auto& TriHitShader = CreateInfo.pTriangleHitShaders[i]; + + auto iter = NameToGroupIndex.find(TriHitShader.Name); if (iter == NameToGroupIndex.end()) - LOG_ERROR_AND_THROW("Failed to get shader group index by name"); + LOG_ERROR_AND_THROW("Failed to get shader group index for triangle hit group '", TriHitShader.Name, "'"); - WCHAR* ShaderName = ConvertWStr(CreateInfo.pTriangleHitShaders[i].Name); - const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName); + const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(TriHitShader.Name).c_str()); if (ShaderID == nullptr) - LOG_ERROR_AND_THROW("Failed to get shader identifier"); + LOG_ERROR_AND_THROW("Failed to get shader identifier for triangle hit group '", TriHitShader.Name, "'"); std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize); } for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i) { - auto iter = NameToGroupIndex.find(CreateInfo.pProceduralHitShaders[i].Name); + const auto& ProcHitShader = CreateInfo.pProceduralHitShaders[i]; + + auto iter = NameToGroupIndex.find(ProcHitShader.Name); if (iter == NameToGroupIndex.end()) - LOG_ERROR_AND_THROW("Failed to get shader group index by name"); + LOG_ERROR_AND_THROW("Failed to get shader group index for procedural hit shader group '", ProcHitShader.Name, "'"); - WCHAR* ShaderName = ConvertWStr(CreateInfo.pProceduralHitShaders[i].Name); - const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName); + const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(ProcHitShader.Name).c_str()); if (ShaderID == nullptr) - LOG_ERROR_AND_THROW("Failed to get shader identifier"); + LOG_ERROR_AND_THROW("Failed to get shader identifier for procedural hit shader group '", ProcHitShader.Name, "'"); std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize); } @@ -284,9 +285,9 @@ void GetShaderIdentifiers(ID3D12StateObject* pSO, PipelineStateD3D12Impl::ShaderStageInfo::ShaderStageInfo(SHADER_TYPE _Type, ShaderD3D12Impl* _pShader) : - Type{_Type} + Type{_Type}, + Shaders{{_pShader}} { - Shaders.push_back(_pShader); } void PipelineStateD3D12Impl::ShaderStageInfo::Append(ShaderD3D12Impl* pShader) @@ -300,9 +301,10 @@ size_t PipelineStateD3D12Impl::ShaderStageInfo::Count() const } -template +template void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, - TShaderStages& ShaderStages) + TShaderStages& ShaderStages, + InitPSODescType InitPSODesc) { m_ResourceLayoutIndex.fill(-1); @@ -334,7 +336,7 @@ void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& Create for (Uint32 s = 0; s < NumShaderStages; ++s) new (m_pStaticVarManagers + s) ShaderVariableManagerD3D12{*this, GetStaticShaderResCache(s)}; - InitializePipelineDesc(CreateInfo, MemPool); + InitPSODesc(CreateInfo, MemPool); m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); @@ -354,7 +356,12 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* try { TShaderStages ShaderStages; - InitInternalObjects(CreateInfo, ShaderStages); + InitInternalObjects(CreateInfo, ShaderStages, + [this](const GraphicsPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // + { + InitializePipelineDesc(CreateInfo, MemPool); + } // + ); auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); if (m_Desc.PipelineType == PIPELINE_TYPE_GRAPHICS) @@ -439,12 +446,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices. d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; - CComPtr pPSO; - HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, IID_PPV_ARGS(&pPSO)); + HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, IID_PPV_ARGS(&m_pd3d12PSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create pipeline state"); - - m_pd3d12PSO = pPSO; } #ifdef D3D12_H_HAS_MESH_SHADER @@ -527,13 +531,10 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* streamDesc.SizeInBytes = sizeof(d3d12PSODesc); streamDesc.pPipelineStateSubobjectStream = &d3d12PSODesc; - auto* device2 = pDeviceD3D12->GetD3D12Device2(); - CComPtr pPSO; - HRESULT hr = device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&pPSO)); + auto* device2 = pDeviceD3D12->GetD3D12Device2(); + HRESULT hr = device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&m_pd3d12PSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create pipeline state"); - - m_pd3d12PSO = pPSO; } #endif // D3D12_H_HAS_MESH_SHADER else @@ -566,7 +567,12 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* try { TShaderStages ShaderStages; - InitInternalObjects(CreateInfo, ShaderStages); + InitInternalObjects(CreateInfo, ShaderStages, + [this](const ComputePipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // + { + InitializePipelineDesc(CreateInfo, MemPool); + } // + ); auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); @@ -591,13 +597,10 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature(); - CComPtr pPSO; - HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, IID_PPV_ARGS(&pPSO)); + HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, IID_PPV_ARGS(&m_pd3d12PSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create pipeline state"); - m_pd3d12PSO = pPSO; - if (*m_Desc.Name != 0) { m_pd3d12PSO->SetName(WidenString(m_Desc.Name).c_str()); @@ -622,63 +625,30 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { - m_ResourceLayoutIndex.fill(-1); - - TShaderStages ShaderStages; - ExtractShaders(CreateInfo, ShaderStages); - - TNameToGroupIndexMap NameToGroupIndex; + TShaderStages ShaderStages; std::vector Subobjects; - const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10}; - LinearAllocator MemPool{GetRawAllocator()}; - - const auto NumShaderStages = GetNumShaderStages(); - VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size()); - - MemPool.AddSpace(NumShaderStages); - MemPool.AddSpace(NumShaderStages * 2); - MemPool.AddSpace(NumShaderStages); - - ReserveSpaceForPipelineDesc(CreateInfo, ShaderIdentifierSize, MemPool); - - MemPool.Reserve(); - - m_pStaticResourceCaches = MemPool.ConstructArray(NumShaderStages, ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources); - - // The memory is now owned by PipelineStateD3D12Impl and will be freed by Destruct(). - auto* Ptr = MemPool.ReleaseOwnership(); - VERIFY_EXPR(Ptr == m_pStaticResourceCaches); - (void)Ptr; - - m_pShaderResourceLayouts = MemPool.ConstructArray(NumShaderStages * 2, std::ref(*this)); - - m_pStaticVarManagers = MemPool.Allocate(NumShaderStages); - for (Uint32 s = 0; s < NumShaderStages; ++s) - new (m_pStaticVarManagers + s) ShaderVariableManagerD3D12{*this, GetStaticShaderResCache(s)}; - - BuildRTPipelineDescription(CreateInfo, NameToGroupIndex, Subobjects, TempPool, MemPool); - InitializePipelineDesc(CreateInfo, ShaderIdentifierSize, std::move(NameToGroupIndex), MemPool); - - m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); - - // It is important to construct all objects before initializing them because if an exception is thrown, - // destructors will be called for all objects - - InitResourceLayouts(CreateInfo, ShaderStages); + InitInternalObjects(CreateInfo, ShaderStages, + [&](const RayTracingPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // + { + TNameToGroupIndexMap NameToGroupIndex; + BuildRTPipelineDescription(CreateInfo, NameToGroupIndex, Subobjects, TempPool, MemPool); + InitializePipelineDesc(CreateInfo, std::move(NameToGroupIndex), MemPool); + } // + ); - D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot; - GlobalRoot.pGlobalRootSignature = m_RootSig.GetD3D12RootSignature(); + D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig.GetD3D12RootSignature()}; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot}); - D3D12_STATE_OBJECT_DESC RTPipelineDesc; - RTPipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE; - RTPipelineDesc.NumSubobjects = static_cast(Subobjects.size()); - RTPipelineDesc.pSubobjects = Subobjects.data(); + D3D12_STATE_OBJECT_DESC RTPipelineDesc = {}; + RTPipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE; + RTPipelineDesc.NumSubobjects = static_cast(Subobjects.size()); + RTPipelineDesc.pSubobjects = Subobjects.data(); - auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); CComPtr pSO; - HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&pSO)); + + auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&pSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create ray tracing state object"); diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index eee2e1fa..9feabb6a 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -136,7 +136,10 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo sizeof(FenceD3D12Impl), sizeof(QueryD3D12Impl), sizeof(RenderPassD3D12Impl), - sizeof(FramebufferD3D12Impl) + sizeof(FramebufferD3D12Impl), + 0, + 0, + 0 } }, m_pd3d12Device {pd3d12Device}, @@ -312,8 +315,8 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo CHECK_REQUIRED_FEATURE(ShaderInt8, "8-bit shader operations are"); CHECK_REQUIRED_FEATURE(ResourceBuffer8BitAccess, "8-bit resoure buffer access is"); CHECK_REQUIRED_FEATURE(UniformBuffer8BitAccess, "8-bit uniform buffer access is"); - - CHECK_REQUIRED_FEATURE(RayTracing, "ray tracing is"); + + CHECK_REQUIRED_FEATURE(RayTracing, "ray tracing is"); // clang-format on #undef CHECK_REQUIRED_FEATURE diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 718f4b17..35274af3 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -172,62 +172,6 @@ RootSignature::RootSignature() : m_SamplerRootTablesMap.fill(InvalidRootTableIndex); } -// clang-format off -static constexpr D3D12_SHADER_VISIBILITY ShaderTypeInd2ShaderVisibilityMap[] -{ - D3D12_SHADER_VISIBILITY_VERTEX, // 0 - D3D12_SHADER_VISIBILITY_PIXEL, // 1 - D3D12_SHADER_VISIBILITY_GEOMETRY, // 2 - D3D12_SHADER_VISIBILITY_HULL, // 3 - D3D12_SHADER_VISIBILITY_DOMAIN, // 4 - D3D12_SHADER_VISIBILITY_ALL, // 5 -#ifdef D3D12_H_HAS_MESH_SHADER - D3D12_SHADER_VISIBILITY_AMPLIFICATION, // 6 - D3D12_SHADER_VISIBILITY_MESH, // 7 -#else - D3D12_SHADER_VISIBILITY(6), - D3D12_SHADER_VISIBILITY(7), -#endif - D3D12_SHADER_VISIBILITY_ALL, // 8 - D3D12_SHADER_VISIBILITY_ALL, // 9 - D3D12_SHADER_VISIBILITY_ALL, // 10 - D3D12_SHADER_VISIBILITY_ALL, // 11 - D3D12_SHADER_VISIBILITY_ALL, // 12 - D3D12_SHADER_VISIBILITY_ALL, // 13 -}; -// clang-format on -D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType) -{ - auto ShaderInd = GetShaderTypeIndex(ShaderType); - auto ShaderVisibility = ShaderTypeInd2ShaderVisibilityMap[ShaderInd]; -#ifdef DILIGENT_DEBUG - static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type"); - switch (ShaderType) - { - // clang-format off - case SHADER_TYPE_VERTEX: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_VERTEX); break; - case SHADER_TYPE_PIXEL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_PIXEL); break; - case SHADER_TYPE_GEOMETRY: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_GEOMETRY); break; - case SHADER_TYPE_HULL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_HULL); break; - case SHADER_TYPE_DOMAIN: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_DOMAIN); break; - case SHADER_TYPE_COMPUTE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break; -# ifdef D3D12_H_HAS_MESH_SHADER - case SHADER_TYPE_AMPLIFICATION: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_AMPLIFICATION); break; - case SHADER_TYPE_MESH: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_MESH); break; -# endif - case SHADER_TYPE_RAY_GEN: - case SHADER_TYPE_RAY_MISS: - case SHADER_TYPE_RAY_CLOSEST_HIT: - case SHADER_TYPE_RAY_ANY_HIT: - case SHADER_TYPE_RAY_INTERSECTION: - case SHADER_TYPE_CALLABLE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break; - // clang-format on - default: LOG_ERROR("Unknown shader type (", ShaderType, ")"); break; - } -#endif - return ShaderVisibility; -} - // clang-format off static D3D12_DESCRIPTOR_HEAP_TYPE RangeType2HeapTypeMap[] { @@ -263,11 +207,7 @@ void RootSignature::InitImmutableSampler(SHADER_TYPE ShaderT const char* SamplerSuffix, const D3DShaderResourceAttribs& SamplerAttribs) { -#ifdef DILIGENT_DEBUG - m_DbgShaderStages |= ShaderType; -#endif - - auto ShaderVisibility = GetShaderVisibility(ShaderType); + auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType); auto SamplerFound = false; for (auto& ImtblSmplr : m_ImmutableSamplers) { @@ -299,11 +239,7 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT Uint32& OffsetFromTableStart // Output parameter ) { -#ifdef DILIGENT_DEBUG - m_DbgShaderStages |= ShaderType; -#endif - - const auto ShaderVisibility = GetShaderVisibility(ShaderType); + const auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType); if (RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV && ShaderResAttribs.BindCount == 1) { // Allocate single CBV directly in the root signature @@ -443,7 +379,7 @@ void RootSignature::AllocateImmutableSamplers(const PipelineResourceLayoutDesc& while (ShaderStages != 0) { auto Stage = ShaderStages & ~(ShaderStages - 1); - m_ImmutableSamplers.emplace_back(ImtblSamDesc, GetShaderVisibility(static_cast(Stage))); + m_ImmutableSamplers.emplace_back(ImtblSamDesc, ShaderTypeToD3D12ShaderVisibility(static_cast(Stage))); ShaderStages &= ~Stage; } } @@ -652,7 +588,7 @@ void RootSignature::InitResourceCache(RenderDeviceD3D12Impl* pDeviceD3D12Impl auto HeapType = HeapTypeFromRangeType(D3D12RootParam.DescriptorTable.pDescriptorRanges[0].RangeType); #ifdef DILIGENT_DEBUG - RootTableCache.SetDebugAttribs(TableSize, HeapType, m_DbgShaderStages); + RootTableCache.SetDebugAttribs(TableSize, HeapType, D3D12ShaderVisibilityToShaderType(D3D12RootParam.ShaderVisibility)); #endif // Space for dynamic variables is allocated at every draw call @@ -685,7 +621,7 @@ void RootSignature::InitResourceCache(RenderDeviceD3D12Impl* pDeviceD3D12Impl VERIFY_EXPR(RootTableCache.m_TableStartOffset == ShaderResourceCacheD3D12::InvalidDescriptorOffset); VERIFY_EXPR(D3D12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV); - RootTableCache.SetDebugAttribs(1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_DbgShaderStages); + RootTableCache.SetDebugAttribs(1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12ShaderVisibilityToShaderType(D3D12RootParam.ShaderVisibility)); } #endif @@ -915,11 +851,14 @@ __forceinline void ProcessCachedTableResources(Uint32 RootI const auto& range = D3D12Param.DescriptorTable.pDescriptorRanges[r]; for (UINT d = 0; d < range.NumDescriptors; ++d) { + SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; #ifdef DILIGENT_DEBUG - VERIFY(dbgHeapType == HeapTypeFromRangeType(range.RangeType), "Mistmatch between descriptor heap type and descriptor range type"); + dbgShaderType = D3D12ShaderVisibilityToShaderType(D3D12Param.ShaderVisibility); #endif + VERIFY(dbgHeapType == HeapTypeFromRangeType(range.RangeType), "Mistmatch between descriptor heap type and descriptor range type"); + auto OffsetFromTableStart = range.OffsetInDescriptorsFromTableStart + d; - auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, SHADER_TYPE_UNKNOWN); + auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, dbgShaderType); Operation(OffsetFromTableStart, range, Res); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 157e42f7..34b15c4c 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -39,6 +39,7 @@ #include "PipelineStateD3D12Impl.hpp" #include "ShaderResourceVariableBase.hpp" #include "ShaderVariableD3DBase.hpp" +#include "LinearAllocator.hpp" namespace Diligent { @@ -83,9 +84,10 @@ D3D12_DESCRIPTOR_RANGE_TYPE GetDescriptorRangeType(CachedResourceType ResType) } -void ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& Allocator, - const std::array& CbvSrvUavCount, - const std::array& SamplerCount) +StringPool ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& Allocator, + const std::array& CbvSrvUavCount, + const std::array& SamplerCount, + size_t StringPoolSize) { m_CbvSrvUavOffsets[0] = 0; for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) @@ -103,12 +105,21 @@ void ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& VERIFY_EXPR(GetSamplerCount(VarType) == SamplerCount[VarType]); } - size_t MemSize = GetTotalResourceCount() * sizeof(D3D12Resource); - if (MemSize == 0) - return; + LinearAllocator MemPool{Allocator}; + MemPool.AddSpace(GetTotalResourceCount()); + MemPool.AddSpace(StringPoolSize); - auto* pRawMem = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader resource layout resources", MemSize); - m_ResourceBuffer = std::unique_ptr>(pRawMem, Allocator); + MemPool.Reserve(); + + auto* pResources = MemPool.Allocate(GetTotalResourceCount()); + auto* pStringPoolData = MemPool.ConstructArray(StringPoolSize); + + m_ResourceBuffer = std::unique_ptr>(MemPool.Release(), Allocator); + VERIFY_EXPR(m_ResourceBuffer.get() == pResources); + + StringPool stringPool; + stringPool.AssignMemory(pStringPoolData, StringPoolSize); + return stringPool; } @@ -136,21 +147,23 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* std::unordered_map ResourceNameToIndex; - // Count number of resources to allocate all needed memory + // Count the number of resources to allocate all needed memory m_IsUsingSeparateSamplers = !Shaders[0]->GetShaderResources()->IsUsingCombinedTextureSamplers(); m_ShaderType = Shaders[0]->GetDesc().ShaderType; size_t StringPoolSize = 0; + static constexpr Uint32 InvalidResourceIndex = ~0u; + for (auto* pShader : Shaders) { auto pResources = pShader->GetShaderResources(); VERIFY_EXPR(pResources->GetShaderType() == m_ShaderType); - const auto HandleResType = [&](const auto& Res, Uint32) // + const auto HandleCbvSrvUav = [&](const auto& Res, Uint32) // { auto VarType = pResources->FindVariableType(Res, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) { - bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, ~0u).second; + bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, InvalidResourceIndex).second; if (IsUniqueName) { StringPoolSize += strlen(Res.Name) + 1; @@ -158,8 +171,9 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* } } }; + pResources->ProcessResources( - HandleResType, + HandleCbvSrvUav, [&](const D3DShaderResourceAttribs& Sam, Uint32) // { auto VarType = pResources->FindVariableType(Sam, ResourceLayout); @@ -171,7 +185,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* // Skip immutable samplers if (ImtblSamplerInd < 0) { - bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Sam.Name}, ~0u).second; + bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Sam.Name}, InvalidResourceIndex).second; if (IsUniqueName) { StringPoolSize += strlen(Sam.Name) + 1; @@ -185,7 +199,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* auto VarType = pResources->FindVariableType(TexSRV, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) { - bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{TexSRV.Name}, ~0u).second; + bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{TexSRV.Name}, InvalidResourceIndex).second; if (IsUniqueName) { StringPoolSize += strlen(TexSRV.Name) + 1; @@ -203,15 +217,13 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* } } }, - HandleResType, - HandleResType, - HandleResType, - HandleResType); + HandleCbvSrvUav, + HandleCbvSrvUav, + HandleCbvSrvUav, + HandleCbvSrvUav); } - AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount); - - m_StringPool.Reserve(StringPoolSize, GetRawAllocator()); + auto stringPool = AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount, StringPoolSize); std::array CurrCbvSrvUav = {}; std::array CurrSampler = {}; @@ -220,12 +232,12 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* auto AddResource = [&](const D3DShaderResourceAttribs& Attribs, CachedResourceType ResType, SHADER_RESOURCE_VARIABLE_TYPE VarType, - Uint32 SamplerId = D3D12Resource::InvalidSamplerId) // + Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId) // { auto ResIter = ResourceNameToIndex.find(HashMapStringKey{Attribs.Name}); VERIFY_EXPR(ResIter != ResourceNameToIndex.end()); - if (ResIter->second == ~0u) + if (ResIter->second == InvalidResourceIndex) { Uint32 RootIndex = D3D12Resource::InvalidRootIndex; Uint32 Offset = D3D12Resource::InvalidOffset; @@ -258,22 +270,31 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* VERIFY(RootIndex != D3D12Resource::InvalidRootIndex, "Root index must be valid"); VERIFY(Offset != D3D12Resource::InvalidOffset, "Offset must be valid"); - // Static samplers are never copied, and SamplerId == InvalidSamplerId + // Immutable samplers are never copied, and SamplerId == InvalidSamplerId Uint32 ResOffset = (ResType == CachedResourceType::Sampler) ? GetSamplerOffset(VarType, CurrSampler[VarType]++) : GetSrvCbvUavOffset(VarType, CurrCbvSrvUav[VarType]++); ResIter->second = ResOffset; auto& NewResource = GetResource(ResOffset); - ::new (&NewResource) D3D12Resource{*this, VarType, ResType, RootIndex, Offset, SamplerId, m_StringPool.CopyString(Attribs.Name), Attribs.BindCount, Attribs.BindPoint, - Attribs.GetInputType(), Attribs.GetSRVDimension()}; + ::new (&NewResource) D3D12Resource // + { + *this, + stringPool, + Attribs, + SamplerId, + VarType, + ResType, + RootIndex, + Offset // + }; } else { // merge with existing auto& ExistingRes = GetResource(ResIter->second); VERIFY_EXPR(ExistingRes.VariableType == VarType); - VERIFY_EXPR(ExistingRes.GetInputType() == Attribs.GetInputType()); - VERIFY_EXPR(ExistingRes.BindCount == Attribs.BindCount); + VERIFY_EXPR(ExistingRes.Attribs.GetInputType() == Attribs.GetInputType()); + VERIFY_EXPR(ExistingRes.Attribs.BindCount == Attribs.BindCount); } }; @@ -293,9 +314,9 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* if (IsAllowedType(VarType, AllowedTypeBits)) { // The error (if any) have already been logged when counting the resources - constexpr bool LogStaticSamplerArrayError = false; - auto StaticSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogStaticSamplerArrayError); - if (StaticSamplerInd >= 0) + constexpr bool LogImtblSamplerArrayError = false; + const auto ImtblSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); + if (ImtblSamplerInd >= 0) { if (pRootSig != nullptr) pRootSig->InitImmutableSampler(pResources->GetShaderType(), Sam.Name, pResources->GetCombinedSamplerSuffix(), Sam); @@ -314,7 +335,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES == 3, "Unexpected number of shader variable types"); VERIFY(CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] == GetTotalSamplerCount(), "All samplers must be initialized before texture SRVs"); - Uint32 SamplerId = D3D12Resource::InvalidSamplerId; + Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId; if (TexSRV.IsCombinedWithSampler()) { const auto& SamplerAttribs = pResources->GetCombinedSampler(TexSRV); @@ -325,18 +346,18 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); // The error (if any) have already been logged when counting the resources - constexpr bool LogStaticSamplerArrayError = false; - auto StaticSamplerInd = pResources->FindImmutableSampler(SamplerAttribs, ResourceLayout, LogStaticSamplerArrayError); - if (StaticSamplerInd >= 0) + constexpr bool LogImtblSamplerArrayError = false; + const auto ImtblSamplerInd = pResources->FindImmutableSampler(SamplerAttribs, ResourceLayout, LogImtblSamplerArrayError); + if (ImtblSamplerInd >= 0) { - // Static samplers are never copied, and SamplerId == InvalidSamplerId + // Immutable samplers are never copied, and SamplerId == InvalidSamplerId #ifdef DILIGENT_DEBUG auto SamplerCount = GetTotalSamplerCount(); for (Uint32 s = 0; s < SamplerCount; ++s) { const auto& Sampler = GetSampler(s); - if (strcmp(Sampler.Name, SamplerAttribs.Name) == 0) - LOG_ERROR("Static sampler '", Sampler.Name, "' was found among resources. This seems to be a bug"); + if (strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0) + LOG_ERROR("Immutable sampler '", Sampler.Attribs.Name, "' was found among resources. This seems to be a bug"); } #endif } @@ -347,7 +368,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* for (SamplerId = 0; SamplerId < SamplerCount; ++SamplerId) { const auto& Sampler = GetSampler(SamplerId); - SamplerFound = strcmp(Sampler.Name, SamplerAttribs.Name) == 0; + SamplerFound = strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0; if (SamplerFound) break; } @@ -355,9 +376,9 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* if (!SamplerFound) { LOG_ERROR("Unable to find sampler '", SamplerAttribs.Name, "' assigned to texture SRV '", TexSRV.Name, "' in the list of already created resources. This seems to be a bug."); - SamplerId = D3D12Resource::InvalidSamplerId; + SamplerId = D3DShaderResourceAttribs::InvalidSamplerId; } - VERIFY(SamplerId <= D3D12Resource::MaxSamplerId, "Sampler index excceeds allowed limit"); + VERIFY(SamplerId <= D3DShaderResourceAttribs::MaxSamplerId, "Sampler index excceeds allowed limit"); } } AddResource(TexSRV, CachedResourceType::TexSRV, VarType, SamplerId); @@ -391,6 +412,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* } #ifdef DILIGENT_DEBUG + VERIFY_EXPR(stringPool.GetRemainingSize() == 0); for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) { VERIFY(CurrCbvSrvUav[VarType] == CbvSrvUavCount[VarType], "Not all Srv/Cbv/Uavs are initialized, which result in a crash when dtor is called"); @@ -427,7 +449,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheCB(IDeviceObject* // resource mapping can be of wrong type RefCntAutoPtr pBuffD3D12(pBuffer, IID_BufferD3D12); #ifdef DILIGENT_DEVELOPMENT - VerifyConstantBufferBinding(*this, GetVariableType(), ArrayInd, pBuffer, pBuffD3D12.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); + VerifyConstantBufferBinding(Attribs, GetVariableType(), ArrayInd, pBuffer, pBuffD3D12.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); #endif if (pBuffD3D12) { @@ -463,40 +485,6 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheCB(IDeviceObject* } } -RESOURCE_DIMENSION ShaderResourceLayoutD3D12::D3D12Resource::GetResourceDimension() const -{ - switch (GetSRVDimension()) - { - // clang-format off - case D3D_SRV_DIMENSION_BUFFER: return RESOURCE_DIM_BUFFER; - case D3D_SRV_DIMENSION_TEXTURE1D: return RESOURCE_DIM_TEX_1D; - case D3D_SRV_DIMENSION_TEXTURE1DARRAY: return RESOURCE_DIM_TEX_1D_ARRAY; - case D3D_SRV_DIMENSION_TEXTURE2D: return RESOURCE_DIM_TEX_2D; - case D3D_SRV_DIMENSION_TEXTURE2DARRAY: return RESOURCE_DIM_TEX_2D_ARRAY; - case D3D_SRV_DIMENSION_TEXTURE2DMS: return RESOURCE_DIM_TEX_2D; - case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: return RESOURCE_DIM_TEX_2D_ARRAY; - case D3D_SRV_DIMENSION_TEXTURE3D: return RESOURCE_DIM_TEX_3D; - case D3D_SRV_DIMENSION_TEXTURECUBE: return RESOURCE_DIM_TEX_CUBE; - case D3D_SRV_DIMENSION_TEXTURECUBEARRAY: return RESOURCE_DIM_TEX_CUBE_ARRAY; - // clang-format on - default: - return RESOURCE_DIM_BUFFER; - } -} - -bool ShaderResourceLayoutD3D12::D3D12Resource::IsMultisample() const -{ - switch (GetSRVDimension()) - { - case D3D_SRV_DIMENSION_TEXTURE2DMS: - case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: - return true; - default: - return false; - } -} - - template struct ResourceViewTraits {}; @@ -506,7 +494,7 @@ struct ResourceViewTraits { static const INTERFACE_ID& IID; - static bool VerifyView(ITextureViewD3D12* pViewD3D12, const ShaderResourceLayoutD3D12::D3D12Resource& Attribs, const char* ShaderName) + static bool VerifyView(ITextureViewD3D12* pViewD3D12, const D3DShaderResourceAttribs& Attribs, const char* ShaderName) { return true; } @@ -518,7 +506,7 @@ struct ResourceViewTraits { static const INTERFACE_ID& IID; - static bool VerifyView(IBufferViewD3D12* pViewD3D12, const ShaderResourceLayoutD3D12::D3D12Resource& Attribs, const char* ShaderName) + static bool VerifyView(IBufferViewD3D12* pViewD3D12, const D3DShaderResourceAttribs& Attribs, const char* ShaderName) { return VerifyBufferViewModeD3D(pViewD3D12, Attribs, ShaderName); } @@ -539,8 +527,8 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheResourceView(IDeviceObject* // resource mapping can be of wrong type RefCntAutoPtr pViewD3D12{pView, ResourceViewTraits::IID}; #ifdef DILIGENT_DEVELOPMENT - VerifyResourceViewBinding(*this, GetVariableType(), ArrayIndex, pView, pViewD3D12.RawPtr(), {dbgExpectedViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); - ResourceViewTraits::VerifyView(pViewD3D12, *this, ParentResLayout.GetShaderName()); + VerifyResourceViewBinding(Attribs, GetVariableType(), ArrayIndex, pView, pViewD3D12.RawPtr(), {dbgExpectedViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); + ResourceViewTraits::VerifyView(pViewD3D12, Attribs, ParentResLayout.GetShaderName()); #endif if (pViewD3D12) { @@ -576,8 +564,8 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheSampler(IDeviceObject* Uint32 ArrayIndex, D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const { - VERIFY(IsValidBindPoint(), "Invalid bind point"); - VERIFY_EXPR(ArrayIndex < BindCount); + VERIFY(Attribs.IsValidBindPoint(), "Invalid bind point"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); RefCntAutoPtr pSamplerD3D12(pSampler, IID_SamplerD3D12); if (pSamplerD3D12) @@ -587,7 +575,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheSampler(IDeviceObject* if (DstSam.pObject != pSampler) { auto VarTypeStr = GetShaderVariableTypeLiteralName(GetVariableType()); - LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", GetPrintName(ArrayIndex), + LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", Attribs.GetPrintName(ArrayIndex), "' in shader '", ParentResLayout.GetShaderName(), "'. Attempting to bind another sampler is an error and will " "be ignored. Use another shader resource binding instance or label the variable as dynamic."); } @@ -616,7 +604,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheSampler(IDeviceObject* } else { - LOG_ERROR_MESSAGE("Failed to bind object '", pSampler->GetDesc().Name, "' to variable '", GetPrintName(ArrayIndex), + LOG_ERROR_MESSAGE("Failed to bind object '", pSampler->GetDesc().Name, "' to variable '", Attribs.GetPrintName(ArrayIndex), "' in shader '", ParentResLayout.GetShaderName(), "'. Incorect object type: sampler is expected."); } } @@ -631,8 +619,8 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheAccelStruct(IDeviceObject* const ShaderResourceLayoutD3D12::D3D12Resource& ShaderResourceLayoutD3D12::GetAssignedSampler(const D3D12Resource& TexSrv) const { VERIFY(TexSrv.GetResType() == CachedResourceType::TexSRV, "Unexpected resource type: texture SRV is expected"); - VERIFY(TexSrv.ValidSamplerAssigned(), "Texture SRV has no associated sampler"); - const auto& SamInfo = GetSampler(TexSrv.SamplerId); + VERIFY(TexSrv.Attribs.IsCombinedWithSampler(), "Texture SRV has no associated sampler"); + const auto& SamInfo = GetSampler(TexSrv.Attribs.GetCombinedSamplerId()); VERIFY(SamInfo.GetVariableType() == TexSrv.GetVariableType(), "Inconsistent texture and sampler variable types"); //VERIFY(StreqSuff(SamInfo.Name, TexSrv.Name, GetCombinedSamplerSuffix()), "Sampler name '", SamInfo.Name, "' does not match texture name '", TexSrv.Name, '\''); return SamInfo; @@ -648,7 +636,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* Uint32 ArrayIndex, ShaderResourceCacheD3D12& ResourceCache) const { - VERIFY_EXPR(ArrayIndex < BindCount); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); const bool IsSampler = GetResType() == CachedResourceType::Sampler; auto DescriptorHeapType = IsSampler ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; @@ -666,7 +654,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* } else if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) { - if (GetResType() == CachedResourceType::CBV && BindCount == 1) + if (GetResType() == CachedResourceType::CBV && Attribs.BindCount == 1) { VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Non-array constant buffers are bound as root views and should not be assigned shader visible descriptor space"); } @@ -699,12 +687,12 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle, TEXTURE_VIEW_SHADER_RESOURCE, [&](ITextureViewD3D12* pTexView) // { - if (ValidSamplerAssigned()) + if (Attribs.IsCombinedWithSampler()) { auto& Sam = ParentResLayout.GetAssignedSampler(*this); //VERIFY( !Sam.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" ); - VERIFY_EXPR(BindCount == Sam.BindCount || Sam.BindCount == 1); - auto SamplerArrInd = Sam.BindCount > 1 ? ArrayIndex : 0; + VERIFY_EXPR(Attribs.BindCount == Sam.Attribs.BindCount || Sam.Attribs.BindCount == 1); + auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0; auto ShdrVisibleSamplerHeapCPUDescriptorHandle = ResourceCache.GetShaderVisibleTableCPUDescriptorHandle(Sam.RootIndex, Sam.OffsetFromTableStart + SamplerArrInd); @@ -735,7 +723,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* } else { - LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", Sam.Name, ". Sampler is not set in the texture view '", pTexView->GetDesc().Name, '\''); + LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", Sam.Attribs.Name, ". Sampler is not set in the texture view '", pTexView->GetDesc().Name, '\''); } } }); @@ -768,17 +756,17 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* else { if (DstRes.pObject != nullptr && GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) - LOG_ERROR_MESSAGE("Shader variable '", Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another resource."); + LOG_ERROR_MESSAGE("Shader variable '", Attribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another resource."); DstRes = ShaderResourceCacheD3D12::Resource{}; - if (ValidSamplerAssigned()) + if (Attribs.IsCombinedWithSampler()) { auto& Sam = ParentResLayout.GetAssignedSampler(*this); D3D12_CPU_DESCRIPTOR_HANDLE NullHandle = {0}; - auto SamplerArrInd = Sam.BindCount > 1 ? ArrayIndex : 0; + auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0; auto& DstSam = ResourceCache.GetRootTable(Sam.RootIndex).GetResource(Sam.OffsetFromTableStart + SamplerArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, ParentResLayout.GetShaderType()); if (DstSam.pObject != nullptr && Sam.GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) - LOG_ERROR_MESSAGE("Sampler variable '", Sam.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another sampler."); + LOG_ERROR_MESSAGE("Sampler variable '", Sam.Attribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another sampler."); DstSam = ShaderResourceCacheD3D12::Resource{}; } } @@ -786,7 +774,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* bool ShaderResourceLayoutD3D12::D3D12Resource::IsBound(Uint32 ArrayIndex, const ShaderResourceCacheD3D12& ResourceCache) const { - VERIFY_EXPR(ArrayIndex < BindCount); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); if (RootIndex < ResourceCache.GetNumRootTables()) { @@ -808,56 +796,6 @@ bool ShaderResourceLayoutD3D12::D3D12Resource::IsBound(Uint32 ArrayIndex, const return false; } -HLSLShaderResourceDesc ShaderResourceLayoutD3D12::D3D12Resource::GetHLSLResourceDesc() const -{ - HLSLShaderResourceDesc ResourceDesc; - ResourceDesc.Name = Name; - ResourceDesc.ArraySize = BindCount; - ResourceDesc.ShaderRegister = BindPoint; - switch (GetInputType()) - { - case D3D_SIT_CBUFFER: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_CONSTANT_BUFFER; - break; - - case D3D_SIT_TBUFFER: - UNSUPPORTED("TBuffers are not supported"); - ResourceDesc.Type = SHADER_RESOURCE_TYPE_UNKNOWN; - break; - - case D3D_SIT_TEXTURE: - ResourceDesc.Type = (GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_SRV : SHADER_RESOURCE_TYPE_TEXTURE_SRV); - break; - - case D3D_SIT_SAMPLER: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_SAMPLER; - break; - - case D3D_SIT_UAV_RWTYPED: - ResourceDesc.Type = (GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_UAV : SHADER_RESOURCE_TYPE_TEXTURE_UAV); - break; - - case D3D_SIT_STRUCTURED: - case D3D_SIT_BYTEADDRESS: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV; - break; - - case D3D_SIT_UAV_RWSTRUCTURED: - case D3D_SIT_UAV_RWBYTEADDRESS: - case D3D_SIT_UAV_APPEND_STRUCTURED: - case D3D_SIT_UAV_CONSUME_STRUCTURED: - case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: - ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV; - break; - - default: - UNEXPECTED("Unknown input type"); - } - - return ResourceDesc; -} - - void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderResourceCacheD3D12& SrcCache, const ShaderResourceLayoutD3D12& DstLayout, ShaderResourceCacheD3D12& DstCache) const { // Static shader resources are stored as follows: @@ -875,16 +813,16 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR // Get resource attributes const auto& res = DstLayout.GetSrvCbvUav(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r); auto RangeType = GetDescriptorRangeType(res.GetResType()); - for (Uint32 ArrInd = 0; ArrInd < res.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd) { - auto BindPoint = res.BindPoint + ArrInd; + auto BindPoint = res.Attribs.BindPoint + ArrInd; // Source resource in the static resource cache is in the root table at index RangeType, at offset BindPoint // D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0, // D3D12_DESCRIPTOR_RANGE_TYPE_UAV = 1 // D3D12_DESCRIPTOR_RANGE_TYPE_CBV = 2 const auto& SrcRes = SrcCache.GetRootTable(RangeType).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); if (!SrcRes.pObject) - LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); + LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); // Destination resource is at the root index and offset defined by the resource layout auto& DstRes = DstCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); @@ -925,14 +863,14 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR } } - if (res.ValidSamplerAssigned()) + if (res.Attribs.IsCombinedWithSampler()) { const auto& SamInfo = DstLayout.GetAssignedSampler(res); //VERIFY(!SamInfo.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache"); - VERIFY(SamInfo.IsValidBindPoint(), "Sampler bind point must be valid"); - VERIFY_EXPR(SamInfo.BindCount == res.BindCount || SamInfo.BindCount == 1); + VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid"); + VERIFY_EXPR(SamInfo.Attribs.BindCount == res.Attribs.BindCount || SamInfo.Attribs.BindCount == 1); } } @@ -941,14 +879,14 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR for (Uint32 s = 0; s < SamplerCount; ++s) { const auto& SamInfo = DstLayout.GetSampler(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, s); - for (Uint32 ArrInd = 0; ArrInd < SamInfo.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd) { - auto BindPoint = SamInfo.BindPoint + ArrInd; + auto BindPoint = SamInfo.Attribs.BindPoint + ArrInd; // Source sampler in the static resource cache is in the root table at index 3 // (D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = 3), at offset BindPoint const auto& SrcSampler = SrcCache.GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (!SrcSampler.pObject) - LOG_ERROR_MESSAGE("No sampler assigned to static shader variable '", SamInfo.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); + LOG_ERROR_MESSAGE("No sampler assigned to static shader variable '", SamInfo.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); auto& DstSampler = DstCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (DstSampler.pObject != SrcSampler.pObject) @@ -988,7 +926,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 const auto& res = GetSrvCbvUav(VarType, r); VERIFY(res.GetVariableType() == VarType, "Unexpected variable type"); - for (Uint32 ArrInd = 0; ArrInd < res.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd) { const auto& CachedRes = ResourceCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType()); if (CachedRes.pObject) @@ -1000,15 +938,15 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 // Dynamic buffers do not have CPU descriptor handle as they do not keep D3D12 buffer, and space is allocated from the GPU ring buffer CachedRes.CPUDescriptorHandle.ptr == 0 && !(CachedRes.Type == CachedResourceType::CBV && CachedRes.pObject.RawPtr()->GetDesc().Usage == USAGE_DYNAMIC)) { - LOG_ERROR_MESSAGE("No resource is bound to ", GetShaderVariableTypeLiteralName(res.GetVariableType()), " variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); + LOG_ERROR_MESSAGE("No resource is bound to ", GetShaderVariableTypeLiteralName(res.GetVariableType()), " variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); BindingsOK = false; } - if (res.BindCount > 1 && res.ValidSamplerAssigned()) + if (res.Attribs.BindCount > 1 && res.Attribs.IsCombinedWithSampler()) { // Verify that if single sampler is used for all texture array elements, all samplers set in the resource views are consistent const auto& SamInfo = GetAssignedSampler(res); - if (SamInfo.BindCount == 1) + if (SamInfo.Attribs.BindCount == 1) { const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); // Conversion must always succeed as the type is verified when resource is bound to the variable @@ -1017,7 +955,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 const auto* pSampler = pTexView->GetSampler(); if (pSampler != nullptr && CachedSampler.pObject != nullptr && CachedSampler.pObject != pSampler) { - LOG_ERROR_MESSAGE("All elements of texture array '", res.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", ArrInd, " does not match bound sampler. This may cause incorrect behavior on GL platform."); + LOG_ERROR_MESSAGE("All elements of texture array '", res.Attribs.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", ArrInd, " does not match bound sampler. This may cause incorrect behavior on GL platform."); } } } @@ -1032,7 +970,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 } else if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources) { - if (res.GetResType() == CachedResourceType::CBV && res.BindCount == 1) + if (res.GetResType() == CachedResourceType::CBV && res.Attribs.BindCount == 1) { VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Non-array constant buffers are bound as root views and should not be assigned shader visible descriptor space"); } @@ -1052,14 +990,14 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 # endif } - if (res.ValidSamplerAssigned()) + if (res.Attribs.IsCombinedWithSampler()) { VERIFY(res.GetResType() == CachedResourceType::TexSRV, "Sampler can only be assigned to a texture SRV"); const auto& SamInfo = GetAssignedSampler(res); //VERIFY(!SamInfo.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" ); - VERIFY(SamInfo.IsValidBindPoint(), "Sampler bind point must be valid"); + VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid"); - for (Uint32 ArrInd = 0; ArrInd < SamInfo.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd) { const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (CachedSampler.pObject) @@ -1068,7 +1006,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 VERIFY(CachedSampler.Type == CachedResourceType::Unknown, "Unexpected cached sampler type"); if (!CachedSampler.pObject || CachedSampler.CPUDescriptorHandle.ptr == 0) { - LOG_ERROR_MESSAGE("No sampler is assigned to texture variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); + LOG_ERROR_MESSAGE("No sampler is assigned to texture variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); BindingsOK = false; } @@ -1101,7 +1039,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 const auto& sam = GetSampler(VarType, s); VERIFY(sam.GetVariableType() == VarType, "Unexpected sampler variable type"); - for (Uint32 ArrInd = 0; ArrInd < sam.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < sam.Attribs.BindCount; ++ArrInd) { const auto& CachedSampler = ResourceCache.GetRootTable(sam.RootIndex).GetResource(sam.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType()); if (CachedSampler.pObject) @@ -1110,7 +1048,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 VERIFY(CachedSampler.Type == CachedResourceType::Unknown, "Unexpected cached sampler type"); if (!CachedSampler.pObject || CachedSampler.CPUDescriptorHandle.ptr == 0) { - LOG_ERROR_MESSAGE("No sampler is bound to sampler variable '", sam.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); + LOG_ERROR_MESSAGE("No sampler is bound to sampler variable '", sam.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'"); BindingsOK = false; } } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp index 1c3afa53..fd58eacf 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp @@ -125,7 +125,7 @@ ShaderVariableD3D12Impl* ShaderVariableManagerD3D12::GetVariable(const Char* Nam for (Uint32 v = 0; v < m_NumVariables; ++v) { auto& Var = m_pVariables[v]; - if (strcmp(Var.m_Resource.Name, Name) == 0) + if (strcmp(Var.m_Resource.Attribs.Name, Name) == 0) { pVar = &Var; break; @@ -181,14 +181,14 @@ void ShaderVariableManagerD3D12::BindResources(IResourceMapping* pResourceMappin if ((Flags & (1 << Res.GetVariableType())) == 0) continue; - for (Uint32 ArrInd = 0; ArrInd < Res.BindCount; ++ArrInd) + for (Uint32 ArrInd = 0; ArrInd < Res.Attribs.BindCount; ++ArrInd) { if ((Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(ArrInd, m_ResourceCache)) continue; RefCntAutoPtr pObj; VERIFY_EXPR(pResourceMapping != nullptr); - pResourceMapping->GetResource(Res.Name, &pObj, ArrInd); + pResourceMapping->GetResource(Res.Attribs.Name, &pObj, ArrInd); if (pObj) { // Call non-virtual function @@ -197,7 +197,7 @@ void ShaderVariableManagerD3D12::BindResources(IResourceMapping* pResourceMappin else { if ((Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(ArrInd, m_ResourceCache)) - LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", Res.GetPrintName(ArrInd), "': resource is not found in the resource mapping"); + LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", Res.Attribs.GetPrintName(ArrInd), "': resource is not found in the resource mapping"); } } } -- cgit v1.2.3 From d829cacd06b2a78708e1e4772a833dad2ade5856 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 27 Oct 2020 19:52:33 -0700 Subject: Fixed two minor merge issues --- Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index d6b4290b..efae7b37 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -620,7 +620,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const RayTracingPipelineStateCreateInfo& CreateInfo) : - TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo.PSODesc}, + TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo}, m_SRBMemAllocator{GetRawAllocator()} { try -- cgit v1.2.3 From cbf6f3c8a7e1d4a370d4c9ca2840a143cfbea216 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 27 Oct 2020 20:58:28 -0700 Subject: ShaderResourceLayout{D3D12,Vk}: implemented GetShaderName --- .../include/ShaderResourceLayoutD3D12.hpp | 16 +++++++++++----- .../src/ShaderResourceLayoutD3D12.cpp | 12 ++++++++++-- 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index 1f2b3d2d..f7f2fa13 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -302,7 +302,7 @@ private: const Char* GetShaderName() const { - return ""; // AZ TODO + return GetStringPoolData(); } @@ -323,14 +323,14 @@ private: D3D12Resource& GetResource(Uint32 r) { VERIFY_EXPR(r < GetTotalResourceCount()); - auto* Resource = reinterpret_cast(m_ResourceBuffer.get()); - return Resource[r]; + auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); + return Resources[r]; } const D3D12Resource& GetResource(Uint32 r) const { VERIFY_EXPR(r < GetTotalResourceCount()); - auto* Resource = reinterpret_cast(m_ResourceBuffer.get()); - return Resource[r]; + const auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); + return Resources[r]; } Uint32 GetSrvCbvUavOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const @@ -362,6 +362,12 @@ private: return GetResource(m_SamplersOffsets[0] + s); } + const char* GetStringPoolData() const + { + const auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); + return reinterpret_cast(Resources + GetTotalResourceCount()); + } + StringPool AllocateMemory(IMemoryAllocator& Allocator, const std::array& CbvSrvUavCount, const std::array& SamplerCount, diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 34b15c4c..b4bb1f72 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -115,7 +115,8 @@ StringPool ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& auto* pStringPoolData = MemPool.ConstructArray(StringPoolSize); m_ResourceBuffer = std::unique_ptr>(MemPool.Release(), Allocator); - VERIFY_EXPR(m_ResourceBuffer.get() == pResources); + VERIFY_EXPR(pResources == nullptr || m_ResourceBuffer.get() == pResources); + VERIFY_EXPR(pStringPoolData == GetStringPoolData()); StringPool stringPool; stringPool.AssignMemory(pStringPoolData, StringPoolSize); @@ -145,12 +146,17 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* std::array CbvSrvUavCount = {}; std::array SamplerCount = {}; + // Maps resource name to its index in m_ResourceBuffer std::unordered_map ResourceNameToIndex; // Count the number of resources to allocate all needed memory m_IsUsingSeparateSamplers = !Shaders[0]->GetShaderResources()->IsUsingCombinedTextureSamplers(); m_ShaderType = Shaders[0]->GetDesc().ShaderType; - size_t StringPoolSize = 0; + + // Construct shader or shader group name + const auto ShaderName = GetShaderGroupName(Shaders); + + size_t StringPoolSize = ShaderName.length() + 1; static constexpr Uint32 InvalidResourceIndex = ~0u; @@ -225,6 +231,8 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* auto stringPool = AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount, StringPoolSize); + stringPool.CopyString(ShaderName); + std::array CurrCbvSrvUav = {}; std::array CurrSampler = {}; std::array StaticResCacheTblSizes = {}; -- cgit v1.2.3 From 135d5dc6743fc89d7a19c539fa06eca33506f51b Mon Sep 17 00:00:00 2001 From: azhirnov Date: Wed, 28 Oct 2020 19:33:03 +0300 Subject: added ray tracing implementation for dx12 and vulkan --- Graphics/GraphicsEngineD3D12/CMakeLists.txt | 9 + .../include/BottomLevelASD3D12Impl.hpp | 74 ++++++ .../include/BufferD3D12Impl.hpp | 6 + .../GraphicsEngineD3D12/include/CommandContext.hpp | 157 +++++------- .../include/D3D12ResourceBase.hpp | 2 +- .../include/D3D12TypeConversions.hpp | 4 + .../include/DeviceContextD3D12Impl.hpp | 21 +- .../include/FramebufferD3D12Impl.hpp | 2 +- .../include/RenderPassD3D12Impl.hpp | 2 +- .../include/ShaderBindingTableD3D12Impl.hpp | 79 ++++++ .../include/TopLevelASD3D12Impl.hpp | 83 +++++++ .../interface/BottomLevelASD3D12.h | 70 ++++++ .../interface/ShaderBindingTableD3D12.h | 71 ++++++ .../interface/TopLevelASD3D12.h | 77 ++++++ .../src/BottomLevelASD3D12Impl.cpp | 152 ++++++++++++ .../GraphicsEngineD3D12/src/BufferD3D12Impl.cpp | 4 +- .../GraphicsEngineD3D12/src/CommandContext.cpp | 99 ++++++-- .../src/D3D12TypeConversions.cpp | 70 +++++- .../src/DeviceContextD3D12Impl.cpp | 274 ++++++++++++++++++++- Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp | 2 +- .../src/PipelineStateD3D12Impl.cpp | 8 +- .../src/RenderDeviceD3D12Impl.cpp | 33 ++- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 15 ++ .../src/ShaderBindingTableD3D12Impl.cpp | 202 +++++++++++++++ .../src/ShaderResourceLayoutD3D12.cpp | 30 +++ .../src/TopLevelASD3D12Impl.cpp | 115 +++++++++ 26 files changed, 1512 insertions(+), 149 deletions(-) create mode 100644 Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp create mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp create mode 100644 Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp create mode 100644 Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h create mode 100644 Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h create mode 100644 Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h create mode 100644 Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp create mode 100644 Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp create mode 100644 Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/CMakeLists.txt b/Graphics/GraphicsEngineD3D12/CMakeLists.txt index 9941b62b..611bcbda 100644 --- a/Graphics/GraphicsEngineD3D12/CMakeLists.txt +++ b/Graphics/GraphicsEngineD3D12/CMakeLists.txt @@ -37,6 +37,9 @@ set(INCLUDE include/SwapChainD3D12Impl.hpp include/TextureD3D12Impl.hpp include/TextureViewD3D12Impl.hpp + include/BottomLevelASD3D12Impl.hpp + include/TopLevelASD3D12Impl.hpp + include/ShaderBindingTableD3D12Impl.hpp ) set(INTERFACE @@ -55,6 +58,9 @@ set(INTERFACE interface/SwapChainD3D12.h interface/TextureD3D12.h interface/TextureViewD3D12.h + interface/BottomLevelASD3D12.h + interface/TopLevelASD3D12.h + interface/ShaderBindingTableD3D12.h ) @@ -89,6 +95,9 @@ set(SRC src/SwapChainD3D12Impl.cpp src/TextureD3D12Impl.cpp src/TextureViewD3D12Impl.cpp + src/BottomLevelASD3D12Impl.cpp + src/TopLevelASD3D12Impl.cpp + src/ShaderBindingTableD3D12Impl.cpp ) if(PLATFORM_WIN32) diff --git a/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp new file mode 100644 index 00000000..b631bdcc --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp @@ -0,0 +1,74 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::BottomLevelASD3D12Impl class + +#include "BottomLevelASD3D12.h" +#include "RenderDeviceD3D12.h" +#include "BottomLevelASBase.hpp" +#include "D3D12ResourceBase.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +/// Bottom-level acceleration structure object implementation in Direct3D12 backend. +class BottomLevelASD3D12Impl final : public BottomLevelASBase, public D3D12ResourceBase +{ +public: + using TBottomLevelASBase = BottomLevelASBase; + + BottomLevelASD3D12Impl(IReferenceCounters* pRefCounters, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const BottomLevelASDesc& Desc, + bool bIsDeviceInternal = false); + ~BottomLevelASD3D12Impl(); + + virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IBottomLevelAS::GetScratchBufferSizes() in DirectX 12 backend. + virtual ScratchBufferSizes DILIGENT_CALL_TYPE GetScratchBufferSizes() const override { return m_ScratchSize; } + + /// Implementation of IBottomLevelASD3D12::GetD3D12BLAS(). + virtual ID3D12Resource* DILIGENT_CALL_TYPE GetD3D12BLAS() override final { return GetD3D12Resource(); } + + /// Implementation of IBottomLevelAS::GetNativeHandle() in Direct3D12 backend. + virtual void* DILIGENT_CALL_TYPE GetNativeHandle() override final { return GetD3D12BLAS(); } + + D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress() + { + return GetD3D12Resource()->GetGPUVirtualAddress(); + } + +private: + ScratchBufferSizes m_ScratchSize; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp index ab90dfe7..ad3027a8 100644 --- a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp @@ -103,6 +103,12 @@ public: } } + __forceinline D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress() + { + VERIFY_EXPR(m_Desc.Usage != USAGE_DYNAMIC); + return GetD3D12Resource()->GetGPUVirtualAddress(); + } + D3D12_CPU_DESCRIPTOR_HANDLE GetCBVHandle() { return m_CBVDescriptorAllocation.GetCpuHandle(); } private: diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp index 94f74933..511f1a03 100644 --- a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp +++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp @@ -34,6 +34,8 @@ #include "TextureViewD3D12.h" #include "TextureD3D12.h" #include "BufferD3D12.h" +#include "BottomLevelASD3D12.h" +#include "TopLevelASD3D12.h" #include "DescriptorHeap.hpp" namespace Diligent @@ -114,6 +116,8 @@ public: void TransitionResource(ITextureD3D12* pTexture, RESOURCE_STATE NewState); void TransitionResource(IBufferD3D12* pBuffer, RESOURCE_STATE NewState); + void TransitionResource(IBottomLevelASD3D12* pBLAS, RESOURCE_STATE NewState); + void TransitionResource(ITopLevelASD3D12* pTLAS, RESOURCE_STATE NewState); void TransitionResource(const StateTransitionDesc& Barrier); //void BeginResourceTransition(GpuResource& Resource, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false); @@ -238,8 +242,25 @@ protected: Uint32 m_MaxInterfaceVer = 0; }; +class ComputeContext : public CommandContext +{ +public: + void SetComputeRootSignature(ID3D12RootSignature* pRootSig) + { + if (pRootSig != m_pCurComputeRootSignature) + { + m_pCommandList->SetComputeRootSignature(m_pCurComputeRootSignature = pRootSig); + } + } -class GraphicsContext : public CommandContext + void Dispatch(size_t GroupCountX = 1, size_t GroupCountY = 1, size_t GroupCountZ = 1) + { + FlushResourceBarriers(); + m_pCommandList->Dispatch((UINT)GroupCountX, (UINT)GroupCountY, (UINT)GroupCountZ); + } +}; + +class GraphicsContext : public ComputeContext { public: void ClearRenderTarget(D3D12_CPU_DESCRIPTOR_HANDLE RTV, const float* Color) @@ -254,7 +275,7 @@ public: m_pCommandList->ClearDepthStencilView(DSV, ClearFlags, Depth, Stencil, 0, nullptr); } - void SetRootSignature(ID3D12RootSignature* pRootSig) + void SetGraphicsRootSignature(ID3D12RootSignature* pRootSig) { if (pRootSig != m_pCurGraphicsRootSignature) { @@ -291,47 +312,6 @@ public: } } - void SetConstants(UINT RootIndex, UINT NumConstants, const void* pConstants) - { - m_pCommandList->SetGraphicsRoot32BitConstants(RootIndex, NumConstants, pConstants, 0); - } - - void SetConstants(UINT RootIndex, DWParam X) - { - m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, X.Uint, 0); - } - - void SetConstants(UINT RootIndex, DWParam X, DWParam Y) - { - m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, X.Uint, 0); - m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, Y.Uint, 1); - } - - void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z) - { - m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, X.Uint, 0); - m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, Y.Uint, 1); - m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, Z.Uint, 2); - } - - void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z, DWParam W) - { - m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, X.Uint, 0); - m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, Y.Uint, 1); - m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, Z.Uint, 2); - m_pCommandList->SetGraphicsRoot32BitConstant(RootIndex, W.Uint, 3); - } - - void SetConstantBuffer(UINT RootIndex, D3D12_GPU_VIRTUAL_ADDRESS CBV) - { - m_pCommandList->SetGraphicsRootConstantBufferView(RootIndex, CBV); - } - - void SetDescriptorTable(UINT RootIndex, D3D12_GPU_DESCRIPTOR_HANDLE FirstHandle) - { - m_pCommandList->SetGraphicsRootDescriptorTable(RootIndex, FirstHandle); - } - void SetIndexBuffer(const D3D12_INDEX_BUFFER_VIEW& IBView) { m_pCommandList->IASetIndexBuffer(&IBView); @@ -384,83 +364,62 @@ public: { static_cast(m_pCommandList.p)->EndRenderPass(); } -}; -class GraphicsContext5 : public GraphicsContext4 -{ -}; - -class GraphicsContext6 : public GraphicsContext5 -{ -public: - void DrawMesh(UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ) + void SetRayTracingPipelineState(ID3D12StateObject* pPSO) { -#ifdef D3D12_H_HAS_MESH_SHADER - FlushResourceBarriers(); - static_cast(m_pCommandList.p)->DispatchMesh(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); -#else - UNSUPPORTED("DrawMesh is not supported in current D3D12 header"); -#endif - } -}; - -class ComputeContext : public CommandContext -{ -public: - void SetRootSignature(ID3D12RootSignature* pRootSig) - { - if (pRootSig != m_pCurComputeRootSignature) + if (pPSO != m_pCurPipelineState) { - m_pCommandList->SetComputeRootSignature(m_pCurComputeRootSignature = pRootSig); + static_cast(m_pCommandList.p)->SetPipelineState1(pPSO); + m_pCurPipelineState = pPSO; } } - void SetConstants(UINT RootIndex, UINT NumConstants, const void* pConstants) - { - m_pCommandList->SetComputeRoot32BitConstants(RootIndex, NumConstants, pConstants, 0); - } - - void SetConstants(UINT RootIndex, DWParam X) - { - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0); - } - - void SetConstants(UINT RootIndex, DWParam X, DWParam Y) + void BuildRaytracingAccelerationStructure(const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC& Desc, + UINT NumPostbuildInfoDescs, + const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC* pPostbuildInfoDescs) { - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0); - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Y.Uint, 1); + FlushResourceBarriers(); + static_cast(m_pCommandList.p)->BuildRaytracingAccelerationStructure(&Desc, NumPostbuildInfoDescs, pPostbuildInfoDescs); } - void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z) + void EmitRaytracingAccelerationStructurePostbuildInfo(const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC& Desc, + UINT NumSourceAccelerationStructures, + const D3D12_GPU_VIRTUAL_ADDRESS* pSourceAccelerationStructureData) { - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0); - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Y.Uint, 1); - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Z.Uint, 2); + FlushResourceBarriers(); + static_cast(m_pCommandList.p)->EmitRaytracingAccelerationStructurePostbuildInfo(&Desc, NumSourceAccelerationStructures, pSourceAccelerationStructureData); } - void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z, DWParam W) + void CopyRaytracingAccelerationStructure(D3D12_GPU_VIRTUAL_ADDRESS DestAccelerationStructureData, + D3D12_GPU_VIRTUAL_ADDRESS SourceAccelerationStructureData, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE Mode) { - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0); - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Y.Uint, 1); - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Z.Uint, 2); - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, W.Uint, 3); + FlushResourceBarriers(); + static_cast(m_pCommandList.p)->CopyRaytracingAccelerationStructure(DestAccelerationStructureData, SourceAccelerationStructureData, Mode); } - - void SetConstantBuffer(UINT RootIndex, D3D12_GPU_VIRTUAL_ADDRESS CBV) + void DispatchRays(const D3D12_DISPATCH_RAYS_DESC& Desc) { - m_pCommandList->SetComputeRootConstantBufferView(RootIndex, CBV); + FlushResourceBarriers(); + static_cast(m_pCommandList.p)->DispatchRays(&Desc); } +}; - void SetDescriptorTable(UINT RootIndex, D3D12_GPU_DESCRIPTOR_HANDLE FirstHandle) - { - m_pCommandList->SetComputeRootDescriptorTable(RootIndex, FirstHandle); - } +class GraphicsContext5 : public GraphicsContext4 +{ +}; - void Dispatch(size_t GroupCountX = 1, size_t GroupCountY = 1, size_t GroupCountZ = 1) +class GraphicsContext6 : public GraphicsContext5 +{ +public: + void DrawMesh(UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ) { +#ifdef D3D12_H_HAS_MESH_SHADER FlushResourceBarriers(); - m_pCommandList->Dispatch((UINT)GroupCountX, (UINT)GroupCountY, (UINT)GroupCountZ); + static_cast(m_pCommandList.p)->DispatchMesh(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); +#else + UNSUPPORTED("DrawMesh is not supported in current D3D12 header"); +#endif } }; diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp index 240ea165..e3a78c6c 100644 --- a/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp +++ b/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp @@ -43,7 +43,7 @@ public: ID3D12Resource* GetD3D12Resource() { return m_pd3d12Resource; } protected: - CComPtr m_pd3d12Resource; ///< D3D12 buffer object + CComPtr m_pd3d12Resource; ///< D3D12 resource object }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp index c6678ddd..389b76a1 100644 --- a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp +++ b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp @@ -78,5 +78,9 @@ D3D12_RENDER_PASS_ENDING_ACCESS_TYPE AttachmentStoreOpToD3D12EndingAccessType D3D12_SHADER_VISIBILITY ShaderTypeToD3D12ShaderVisibility(SHADER_TYPE ShaderType); SHADER_TYPE D3D12ShaderVisibilityToShaderType(D3D12_SHADER_VISIBILITY ShaderVisibility); +DXGI_FORMAT ValueTypeToIndexType(VALUE_TYPE Type); + +D3D12_RAYTRACING_GEOMETRY_FLAGS GeometryFlagsToD3D12RTGeometryFlags(RAYTRACING_GEOMETRY_FLAGS Flags); +D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_INSTANCE_FLAGS Flags); } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp index 39a354dd..3ac65274 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp @@ -42,6 +42,8 @@ #include "RenderPassD3D12Impl.hpp" #include "PipelineStateD3D12Impl.hpp" #include "D3D12DynamicHeap.hpp" +#include "BottomLevelASD3D12Impl.hpp" +#include "TopLevelASD3D12Impl.hpp" namespace Diligent { @@ -56,6 +58,8 @@ struct DeviceContextD3D12ImplTraits using QueryType = QueryD3D12Impl; using FramebufferType = FramebufferD3D12Impl; using RenderPassType = RenderPassD3D12Impl; + using BottomLevelASType = BottomLevelASD3D12Impl; + using TopLevelASType = TopLevelASD3D12Impl; }; /// Device context implementation in Direct3D12 backend. @@ -125,13 +129,13 @@ public: ITextureView* pDepthStencil, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - /// Implementation of IDeviceContext::BeginRenderPass() in Direct3D11 backend. + /// Implementation of IDeviceContext::BeginRenderPass() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE BeginRenderPass(const BeginRenderPassAttribs& Attribs) override final; - /// Implementation of IDeviceContext::NextSubpass() in Direct3D11 backend. + /// Implementation of IDeviceContext::NextSubpass() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE NextSubpass() override final; - /// Implementation of IDeviceContext::EndRenderPass() in Direct3D11 backend. + /// Implementation of IDeviceContext::EndRenderPass() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE EndRenderPass() override final; // clang-format off @@ -351,12 +355,23 @@ private: RESOURCE_STATE_TRANSITION_MODE TransitionMode, RESOURCE_STATE RequiredState, const char* OperationName); + __forceinline void TransitionOrVerifyBLASState(CommandContext& CmdCtx, + BottomLevelASD3D12Impl& BLAS, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + const char* OperationName); + __forceinline void TransitionOrVerifyTLASState(CommandContext& CmdCtx, + TopLevelASD3D12Impl& TLAS, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + const char* OperationName); __forceinline void PrepareForDraw(GraphicsContext& GraphCtx, DRAW_FLAGS Flags); __forceinline void PrepareForIndexedDraw(GraphicsContext& GraphCtx, DRAW_FLAGS Flags, VALUE_TYPE IndexType); __forceinline void PrepareForDispatchCompute(ComputeContext& GraphCtx); + __forceinline void PrepareForDispatchRays(GraphicsContext& GraphCtx); __forceinline void PrepareDrawIndirectBuffer(GraphicsContext& GraphCtx, IBuffer* pAttribsBuffer, diff --git a/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp index 59642660..31b65866 100644 --- a/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/FramebufferD3D12Impl.hpp @@ -39,7 +39,7 @@ namespace Diligent class FixedBlockMemoryAllocator; -/// Render pass implementation in Direct3D11 backend. +/// Render pass implementation in Direct3D12 backend. class FramebufferD3D12Impl final : public FramebufferBase { public: diff --git a/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp index 501e62df..00984731 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderPassD3D12Impl.hpp @@ -39,7 +39,7 @@ namespace Diligent class FixedBlockMemoryAllocator; -/// Render pass implementation in Direct3D11 backend. +/// Render pass implementation in Direct3D12 backend. class RenderPassD3D12Impl final : public RenderPassBase { public: diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp new file mode 100644 index 00000000..e866c6f2 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp @@ -0,0 +1,79 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderBindingTableD3D12Impl class + +#include "ShaderBindingTableD3D12.h" +#include "RenderDeviceD3D12.h" +#include "ShaderBindingTableBase.hpp" +#include "D3D12ResourceBase.hpp" +#include "RenderDeviceD3D12Impl.hpp" +#include "PipelineStateD3D12Impl.hpp" + +namespace Diligent +{ + +/// Shader binding table object implementation in Direct3D12 backend. +class ShaderBindingTableD3D12Impl final : public ShaderBindingTableBase, public D3D12ResourceBase +{ +public: + using TShaderBindingTableBase = ShaderBindingTableBase; + + ShaderBindingTableD3D12Impl(IReferenceCounters* pRefCounters, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const ShaderBindingTableDesc& Desc, + bool bIsDeviceInternal = false); + ~ShaderBindingTableD3D12Impl(); + + virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + virtual void DILIGENT_CALL_TYPE Verify() const override; + + virtual void DILIGENT_CALL_TYPE Reset(const ShaderBindingTableDesc& Desc) override; + + 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: + void ValidateDesc(const ShaderBindingTableDesc& Desc) const; + +private: + RefCntAutoPtr m_pBuffer; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp new file mode 100644 index 00000000..8eccf530 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp @@ -0,0 +1,83 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::TopLevelASD3D12Impl class + +#include "TopLevelASD3D12.h" +#include "RenderDeviceD3D12.h" +#include "TopLevelASBase.hpp" +#include "D3D12ResourceBase.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +/// Top-level acceleration structure object implementation in Direct3D12 backend. +class TopLevelASD3D12Impl final : public TopLevelASBase, public D3D12ResourceBase +{ +public: + using TTopLevelASBase = TopLevelASBase; + + TopLevelASD3D12Impl(IReferenceCounters* pRefCounters, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const TopLevelASDesc& Desc, + bool bIsDeviceInternal = false); + ~TopLevelASD3D12Impl(); + + virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of ITopLevelASD3D12::GetScratchBufferSizes() in DirectX 12 backend. + virtual ScratchBufferSizes DILIGENT_CALL_TYPE GetScratchBufferSizes() const override { return m_ScratchSize; } + + /// Implementation of ITopLevelASD3D12D3D12::GetD3D12TLAS(). + virtual ID3D12Resource* DILIGENT_CALL_TYPE GetD3D12TLAS() override final { return GetD3D12Resource(); } + + /// Implementation of ITopLevelASD3D12::GetNativeHandle() in Direct3D12 backend. + virtual void* DILIGENT_CALL_TYPE GetNativeHandle() override final { return GetD3D12TLAS(); } + + D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress() + { + return GetD3D12Resource()->GetGPUVirtualAddress(); + } + + /// Implementation of ITopLevelASD3D12::GetCPUDescriptorHandle() in Direct3D12 backend. + virtual D3D12_CPU_DESCRIPTOR_HANDLE DILIGENT_CALL_TYPE GetCPUDescriptorHandle() override final + { + return m_DescriptorHandle.GetCpuHandle(); + } + +private: + ScratchBufferSizes m_ScratchSize; + + // Allocation in a CPU-only descriptor heap + DescriptorHeapAllocation m_DescriptorHandle; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h b/Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h new file mode 100644 index 00000000..2b64da57 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h @@ -0,0 +1,70 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IBottomLevelASD3D12 interface + +#include "../../GraphicsEngine/interface/BottomLevelAS.h" +#include "../../GraphicsEngine/interface/DeviceContext.h" + +DILIGENT_BEGIN_NAMESPACE(Diligent) + +// {610228AF-F161-4B12-A00E-71E6E3BB97FE} +static const INTERFACE_ID IID_BottomLevelASD3D12 = + {0x610228af, 0xf161, 0x4b12, {0xa0, 0xe, 0x71, 0xe6, 0xe3, 0xbb, 0x97, 0xfe}}; + +#define DILIGENT_INTERFACE_NAME IBottomLevelASD3D12 +#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h" + +#define IBottomLevelASD3D12InclusiveMethods \ + IBottomLevelASInclusiveMethods; \ + IBottomLevelASD3D12Methods BottomLevelASD3D12 + +// clang-format off + +/// Exposes Direct3D12-specific functionality of a bottom-level acceleration structure object. +DILIGENT_BEGIN_INTERFACE(IBottomLevelASD3D12, IBottomLevelAS) +{ + /// Returns ID3D12Resource interface of the internal D3D12 acceleration structure object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + VIRTUAL ID3D12Resource* METHOD(GetD3D12BLAS)(THIS) PURE; +}; +DILIGENT_END_INTERFACE + +#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h" + +#if DILIGENT_C_INTERFACE + +# define IBottomLevelASD3D12_GetD3D12BLAS(This) CALL_IFACE_METHOD(IBottomLevelASD3D12, GetD3D12BLAS, This) + +#endif + +DILIGENT_END_NAMESPACE // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h new file mode 100644 index 00000000..f33bac1b --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h @@ -0,0 +1,71 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IShaderBindingTableD3D12 interface + +#include "../../GraphicsEngine/interface/ShaderBindingTable.h" +#include "DeviceContextD3D12.h" + +DILIGENT_BEGIN_NAMESPACE(Diligent) + +// {DCA2FAD9-2C41-4419-9D16-79731C0ED9D8} +static const INTERFACE_ID IID_ShaderBindingTableD3D12 = + {0xdca2fad9, 0x2c41, 0x4419, {0x9d, 0x16, 0x79, 0x73, 0x1c, 0xe, 0xd9, 0xd8}}; + +#define DILIGENT_INTERFACE_NAME IShaderBindingTableD3D12 +#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h" + +#define IShaderBindingTableD3D12InclusiveMethods \ + IShaderBindingTableInclusiveMethods; \ + IShaderBindingTableD3D12Methods ShaderBindingTable +// clang-format off + +/// 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 + +#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h" + +#if DILIGENT_C_INTERFACE + + +#endif + +DILIGENT_END_NAMESPACE // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h b/Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h new file mode 100644 index 00000000..5b2bd512 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h @@ -0,0 +1,77 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::ITopLevelASD3D12 interface + +#include "../../GraphicsEngine/interface/TopLevelAS.h" +#include "../../GraphicsEngine/interface/DeviceContext.h" + +DILIGENT_BEGIN_NAMESPACE(Diligent) + +// {46334F12-64CB-4F7C-BB71-31515B6F386D} +static const INTERFACE_ID IID_TopLevelASD3D12 = + {0x46334f12, 0x64cb, 0x4f7c, {0xbb, 0x71, 0x31, 0x51, 0x5b, 0x6f, 0x38, 0x6d}}; + +#define DILIGENT_INTERFACE_NAME ITopLevelASD3D12 +#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h" + +#define ITopLevelASD3D12InclusiveMethods \ + ITopLevelASInclusiveMethods; \ + ITopLevelASD3D12Methods TopLevelASD3D12 + +// clang-format off + +/// Exposes Direct3D12-specific functionality of a top-level acceleration structure object. +DILIGENT_BEGIN_INTERFACE(ITopLevelASD3D12, ITopLevelAS) +{ + /// Returns ID3D12Resource interface of the internal D3D12 acceleration structure object. + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + VIRTUAL ID3D12Resource* METHOD(GetD3D12TLAS)(THIS) PURE; + + /// Returns a CPU descriptor handle of the D3D12 acceleration structure + + /// The method does *NOT* call AddRef() on the returned interface, + /// so Release() must not be called. + VIRTUAL D3D12_CPU_DESCRIPTOR_HANDLE METHOD(GetCPUDescriptorHandle)(THIS) PURE; +}; +DILIGENT_END_INTERFACE + +#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h" + +#if DILIGENT_C_INTERFACE + +# define ITopLevelASD3D12_GetD3D12TLAS(This) CALL_IFACE_METHOD(ITopLevelASD3D12, GetD3D12TLAS, This) +# define ITopLevelASD3D12_GetCPUDescriptorHandle(This) CALL_IFACE_METHOD(ITopLevelASD3D12, GetCPUDescriptorHandle, This) + +#endif + +DILIGENT_END_NAMESPACE // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp new file mode 100644 index 00000000..31f0e6a3 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp @@ -0,0 +1,152 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "BottomLevelASD3D12Impl.hpp" +#include "RenderDeviceD3D12Impl.hpp" +#include "DeviceContextD3D12Impl.hpp" +#include "D3D12TypeConversions.hpp" +#include "GraphicsAccessories.hpp" +#include "DXGITypeConversions.hpp" +#include "EngineMemory.h" +#include "StringTools.hpp" + +namespace Diligent +{ + +BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRefCounters, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const BottomLevelASDesc& Desc, + bool bIsDeviceInternal) : + TBottomLevelASBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal} +{ + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO BottomLevelPrebuildInfo = {}; + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS BottomLevelInputs = {}; + std::vector Geometries; + + 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.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); + } + 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); + } + + 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(Geometries.size()); + + auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + + pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&BottomLevelInputs, &BottomLevelPrebuildInfo); + if (BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0) + LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info"); + + D3D12_HEAP_PROPERTIES HeapProps; + HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + HeapProps.CreationNodeMask = 1; + HeapProps.VisibleNodeMask = 1; + + D3D12_RESOURCE_DESC ASDesc = {}; + ASDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + ASDesc.Alignment = 0; + ASDesc.Width = BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes; + ASDesc.Height = 1; + ASDesc.DepthOrArraySize = 1; + ASDesc.MipLevels = 1; + ASDesc.Format = DXGI_FORMAT_UNKNOWN; + ASDesc.SampleDesc.Count = 1; + ASDesc.SampleDesc.Quality = 0; + ASDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + ASDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + + auto hr = pd3d12Device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE, + &ASDesc, D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE, nullptr, + __uuidof(m_pd3d12Resource), + reinterpret_cast(static_cast(&m_pd3d12Resource))); + if (FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create D3D12 Bottom-level acceleration structure"); + + if (*m_Desc.Name != 0) + m_pd3d12Resource->SetName(WidenString(m_Desc.Name).c_str()); + + m_ScratchSize.Build = static_cast(BottomLevelPrebuildInfo.ScratchDataSizeInBytes); + m_ScratchSize.Update = static_cast(BottomLevelPrebuildInfo.UpdateScratchDataSizeInBytes); +} + +BottomLevelASD3D12Impl::~BottomLevelASD3D12Impl() +{ + // D3D12 object can only be destroyed when it is no longer used by the GPU + auto* pDeviceD3D12Impl = ValidatedCast(GetDevice()); + pDeviceD3D12Impl->SafeReleaseDeviceObject(std::move(m_pd3d12Resource), m_Desc.CommandQueueMask); +} + +IMPLEMENT_QUERY_INTERFACE(BottomLevelASD3D12Impl, IID_BottomLevelASD3D12, TBottomLevelASBase) + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp index d7cd54b6..8e84b844 100644 --- a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp @@ -118,9 +118,9 @@ BufferD3D12Impl::BufferD3D12Impl(IReferenceCounters* pRefCounters, // understood by applications and row-major texture data is commonly marshaled through buffers. D3D12BuffDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; D3D12BuffDesc.Flags = D3D12_RESOURCE_FLAG_NONE; - if (m_Desc.BindFlags & BIND_UNORDERED_ACCESS) + if ((m_Desc.BindFlags & BIND_UNORDERED_ACCESS) || (m_Desc.BindFlags & BIND_RAY_TRACING)) D3D12BuffDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - if (!(m_Desc.BindFlags & BIND_SHADER_RESOURCE)) + if (!(m_Desc.BindFlags & BIND_SHADER_RESOURCE) && !(m_Desc.BindFlags & BIND_RAY_TRACING)) D3D12BuffDesc.Flags |= D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; auto* pd3d12Device = pRenderDeviceD3D12->GetD3D12Device(); diff --git a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp index 389bf3eb..6bc55ac3 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp @@ -30,6 +30,8 @@ #include "CommandContext.hpp" #include "TextureD3D12Impl.hpp" #include "BufferD3D12Impl.hpp" +#include "BottomLevelASD3D12Impl.hpp" +#include "TopLevelASD3D12Impl.hpp" #include "CommandListManager.hpp" #include "D3D12TypeConversions.hpp" @@ -39,9 +41,9 @@ namespace Diligent CommandContext::CommandContext(CommandListManager& CmdListManager) : // clang-format off - m_pCurGraphicsRootSignature {nullptr}, - m_pCurPipelineState {nullptr}, - m_pCurComputeRootSignature {nullptr}, + m_pCurGraphicsRootSignature {nullptr}, + m_pCurPipelineState {nullptr}, + m_pCurComputeRootSignature {nullptr}, m_PendingResourceBarriers (STD_ALLOCATOR_RAW_MEM(D3D12_RESOURCE_BARRIER, GetRawAllocator(), "Allocator for vector")) // clang-format on { @@ -78,7 +80,7 @@ void CommandContext::Reset(CommandListManager& CmdListManager) m_PrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; #if 0 - BindDescriptorHeaps(); + BindDescriptorHeaps(); #endif } @@ -115,6 +117,24 @@ void CommandContext::TransitionResource(IBufferD3D12* pBuffer, RESOURCE_STATE Ne TransitionResource(BufferBarrier); } +void CommandContext::TransitionResource(IBottomLevelASD3D12* pBLAS, RESOURCE_STATE NewState) +{ + VERIFY_EXPR(pBLAS != nullptr); + auto* pBLASfD3D12 = ValidatedCast(pBLAS); + VERIFY(pBLASfD3D12->IsInKnownState(), "BLAS state can't be unknown"); + StateTransitionDesc ASBarrier(pBLAS, RESOURCE_STATE_UNKNOWN, NewState, true); + TransitionResource(ASBarrier); +} + +void CommandContext::TransitionResource(ITopLevelASD3D12* pTLAS, RESOURCE_STATE NewState) +{ + VERIFY_EXPR(pTLAS != nullptr); + auto* pTLASfD3D12 = ValidatedCast(pTLAS); + VERIFY(pTLASfD3D12->IsInKnownState(), "TLAS state can't be unknown"); + StateTransitionDesc ASBarrier(pTLAS, RESOURCE_STATE_UNKNOWN, NewState, true); + TransitionResource(ASBarrier); +} + void CommandContext::InsertUAVBarrier(ID3D12Resource* pd3d12Resource) { m_PendingResourceBarriers.emplace_back(); @@ -147,25 +167,23 @@ static D3D12_RESOURCE_BARRIER_FLAGS TransitionTypeToD3D12ResourceBarrierFlag(STA void CommandContext::TransitionResource(const StateTransitionDesc& Barrier) { - DEV_CHECK_ERR((Barrier.pTexture != nullptr) ^ (Barrier.pBuffer != nullptr), "Exactly one of pTexture or pBuffer must not be null"); - DEV_CHECK_ERR(Barrier.NewState != RESOURCE_STATE_UNKNOWN, "New resource state can't be unknown"); - RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN; - ID3D12Resource* pd3d12Resource = nullptr; - TextureD3D12Impl* pTextureD3D12Impl = nullptr; - BufferD3D12Impl* pBufferD3D12Impl = nullptr; - if (Barrier.pTexture) + RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN; + ID3D12Resource* pd3d12Resource = nullptr; + RefCntAutoPtr pTextureD3D12Impl{Barrier.pResource, IID_TextureD3D12}; + RefCntAutoPtr pBufferD3D12Impl{Barrier.pResource, IID_BufferD3D12}; + RefCntAutoPtr pBLASD3D12Impl{Barrier.pResource, IID_BottomLevelASD3D12}; + RefCntAutoPtr pTLASD3D12Impl{Barrier.pResource, IID_TopLevelASD3D12}; + + if (pTextureD3D12Impl) { - pTextureD3D12Impl = ValidatedCast(Barrier.pTexture); - pd3d12Resource = pTextureD3D12Impl->GetD3D12Resource(); - OldState = pTextureD3D12Impl->GetState(); + pd3d12Resource = pTextureD3D12Impl->GetD3D12Resource(); + OldState = pTextureD3D12Impl->GetState(); } - else + else if (pBufferD3D12Impl) { - VERIFY_EXPR(Barrier.pBuffer != nullptr); - pBufferD3D12Impl = ValidatedCast(Barrier.pBuffer); - pd3d12Resource = pBufferD3D12Impl->GetD3D12Resource(); - OldState = pBufferD3D12Impl->GetState(); + pd3d12Resource = pBufferD3D12Impl->GetD3D12Resource(); + OldState = pBufferD3D12Impl->GetState(); #ifdef DILIGENT_DEVELOPMENT // Dynamic buffers wtih no SRV/UAV bind flags are suballocated in @@ -178,6 +196,20 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier) } #endif } + else if (pBLASD3D12Impl) + { + pd3d12Resource = pBLASD3D12Impl->GetD3D12Resource(); + OldState = pBLASD3D12Impl->GetState(); + } + else if (pTLASD3D12Impl) + { + pd3d12Resource = pTLASD3D12Impl->GetD3D12Resource(); + OldState = pTLASD3D12Impl->GetState(); + } + else + { + UNEXPECTED("unsupported resource type"); + } if (OldState == RESOURCE_STATE_UNKNOWN) { @@ -243,9 +275,8 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier) } } } - else + else if (pBufferD3D12Impl) { - VERIFY_EXPR(pBufferD3D12Impl); m_PendingResourceBarriers.emplace_back(BarrierDesc); } } @@ -259,10 +290,8 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier) pTextureD3D12Impl->SetState(NewState); } } - else + else if (pBufferD3D12Impl) { - VERIFY_EXPR(pBufferD3D12Impl); - VERIFY(!Barrier.UpdateResourceState || (Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE || Barrier.TransitionType == STATE_TRANSITION_TYPE_END), "Buffer state can't be updated in begin-split barrier"); if (Barrier.UpdateResourceState) @@ -275,9 +304,29 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier) "Dynamic buffers without SRV/UAV bind flag are expected to never " "transition from RESOURCE_STATE_GENERIC_READ state"); } + 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); + } + } + 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); + } + } } - if (OldState == RESOURCE_STATE_UNORDERED_ACCESS && Barrier.NewState == RESOURCE_STATE_UNORDERED_ACCESS) + if ((OldState == RESOURCE_STATE_UNORDERED_ACCESS && Barrier.NewState == RESOURCE_STATE_UNORDERED_ACCESS) || + (OldState == RESOURCE_STATE_BUILD_AS_WRITE && Barrier.NewState == RESOURCE_STATE_BUILD_AS_WRITE) || + (OldState == RESOURCE_STATE_RAY_TRACING && Barrier.NewState == RESOURCE_STATE_RAY_TRACING)) { DEV_CHECK_ERR(Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE, "UAV barriers must not be split"); InsertUAVBarrier(pd3d12Resource); diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 3ea4bad0..ddab5096 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -351,8 +351,9 @@ static D3D12_RESOURCE_STATES ResourceStateFlagToD3D12ResourceState(RESOURCE_STAT case RESOURCE_STATE_RESOLVE_SOURCE: return D3D12_RESOURCE_STATE_RESOLVE_SOURCE; case RESOURCE_STATE_INPUT_ATTACHMENT: return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; case RESOURCE_STATE_PRESENT: return D3D12_RESOURCE_STATE_PRESENT; - case RESOURCE_STATE_BUILD_AS: return D3D12_RESOURCE_STATES(0); - case RESOURCE_STATE_RAY_TRACING: return D3D12_RESOURCE_STATES(0); // AZ TODO + case RESOURCE_STATE_BUILD_AS_READ: return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + case RESOURCE_STATE_BUILD_AS_WRITE: return D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + case RESOURCE_STATE_RAY_TRACING: return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; // clang-format on default: UNEXPECTED("Unexpected resource state flag"); @@ -379,7 +380,7 @@ public: } private: - static constexpr Uint32 MaxFlagBitPos = 18; + static constexpr Uint32 MaxFlagBitPos = 19; std::array FlagBitPosToResStateMap; }; @@ -422,7 +423,6 @@ static RESOURCE_STATE D3D12ResourceStateToResourceStateFlags(D3D12_RESOURCE_STAT case D3D12_RESOURCE_STATE_COPY_SOURCE: return RESOURCE_STATE_COPY_SOURCE; case D3D12_RESOURCE_STATE_RESOLVE_DEST: return RESOURCE_STATE_RESOLVE_DEST; case D3D12_RESOURCE_STATE_RESOLVE_SOURCE: return RESOURCE_STATE_RESOLVE_SOURCE; - // AZ TODO // clang-format on default: UNEXPECTED("Unexpected D3D12 resource state"); @@ -592,5 +592,67 @@ SHADER_TYPE D3D12ShaderVisibilityToShaderType(D3D12_SHADER_VISIBILITY ShaderVisi } } +DXGI_FORMAT ValueTypeToIndexType(VALUE_TYPE IndexType) +{ + switch (IndexType) + { + // clang-format off + case VT_UNDEFINED: return DXGI_FORMAT_UNKNOWN; // only for ray tracing + case VT_UINT16: return DXGI_FORMAT_R16_UINT; + case VT_UINT32: return DXGI_FORMAT_R32_UINT; + // clang-format on + default: + UNEXPECTED("Unexpected index type"); + return DXGI_FORMAT_R32_UINT; + } +} + +D3D12_RAYTRACING_GEOMETRY_FLAGS GeometryFlagsToD3D12RTGeometryFlags(RAYTRACING_GEOMETRY_FLAGS Flags) +{ + static_assert(RAYTRACING_GEOMETRY_FLAGS_LAST == RAYTRACING_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION, + "Please update the switch below to handle the new ray tracing geometry flag"); + + Uint32 Result = 0; + for (Uint32 Bit = 1; Bit <= Flags; Bit <<= 1) + { + if ((Flags & Bit) != Bit) + continue; + + switch (static_cast(Bit)) + { + // clang-format off + case RAYTRACING_GEOMETRY_OPAQUE: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE; break; + case RAYTRACING_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION; break; + // clang-format on + default: UNEXPECTED("unknown geometry flag"); + } + } + return static_cast(Result); +} + +D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_INSTANCE_FLAGS Flags) +{ + static_assert(RAYTRACING_INSTANCE_FLAGS_LAST == RAYTRACING_INSTANCE_FORCE_NO_OPAQUE, + "Please update the switch below to handle the new ray tracing instance flag"); + + Uint32 Result = 0; + for (Uint32 Bit = 1; Bit <= Flags; Bit <<= 1) + { + if ((Flags & Bit) != Bit) + continue; + + switch (static_cast(Bit)) + { + // clang-format off + case RAYTRACING_INSTANCE_TRIANGLE_FACING_CULL_DISABLE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_CULL_DISABLE ; break; + case RAYTRACING_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE ; break; + case RAYTRACING_INSTANCE_FORCE_OPAQUE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OPAQUE ; break; + case RAYTRACING_INSTANCE_FORCE_NO_OPAQUE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_NON_OPAQUE ; break; + // clang-format on + default: UNEXPECTED("unknown instance flag"); + } + } + return static_cast(Result); +} } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 6ca74c27..95025c4c 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -39,6 +39,7 @@ #include "D3D12DynamicHeap.hpp" #include "CommandListD3D12Impl.hpp" #include "DXGITypeConversions.hpp" +#include "ShaderBindingTableD3D12Impl.hpp" namespace Diligent { @@ -262,6 +263,8 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) } case PIPELINE_TYPE_RAY_TRACING: { + auto* pd3d12SO = pPipelineStateD3D12->GetD3D12StateObject(); + CmdCtx.AsGraphicsContext4().SetRayTracingPipelineState(pd3d12SO); break; } default: @@ -449,7 +452,7 @@ void DeviceContextD3D12Impl::PrepareForDraw(GraphicsContext& GraphCtx, DRAW_FLAG } #endif - GraphCtx.SetRootSignature(m_pPipelineState->GetD3D12RootSignature()); + GraphCtx.SetGraphicsRootSignature(m_pPipelineState->GetD3D12RootSignature()); if (m_State.pCommittedResourceCache != nullptr) { @@ -605,7 +608,7 @@ void DeviceContextD3D12Impl::DrawMeshIndirect(const DrawMeshIndirectAttribs& Att void DeviceContextD3D12Impl::PrepareForDispatchCompute(ComputeContext& ComputeCtx) { - ComputeCtx.SetRootSignature(m_pPipelineState->GetD3D12RootSignature()); + ComputeCtx.SetComputeRootSignature(m_pPipelineState->GetD3D12RootSignature()); if (m_State.pCommittedResourceCache != nullptr) { if (m_State.pCommittedResourceCache->GetNumDynamicCBsBound() > 0) @@ -634,6 +637,37 @@ void DeviceContextD3D12Impl::PrepareForDispatchCompute(ComputeContext& ComputeCt #endif } +void DeviceContextD3D12Impl::PrepareForDispatchRays(GraphicsContext& GraphCtx) +{ + GraphCtx.SetComputeRootSignature(m_pPipelineState->GetD3D12RootSignature()); + if (m_State.pCommittedResourceCache != nullptr) + { + if (m_State.pCommittedResourceCache->GetNumDynamicCBsBound() > 0) + { + // Only process dynamic buffers. Non-dynamic buffers are committed by CommitShaderResources + m_pPipelineState->GetRootSignature() + .CommitRootViews(*m_State.pCommittedResourceCache, + GraphCtx, + true, // IsCompute + m_ContextId, + this, + true, // CommitViews + true, // ProcessDynamicBuffers + false, // ProcessNonDynamicBuffers + false, // TransitionStates + false // ValidateStates + ); + } + } +#ifdef DILIGENT_DEVELOPMENT + else + { + if (m_pPipelineState->ContainsShaderResources()) + LOG_ERROR_MESSAGE("Pipeline state '", m_pPipelineState->GetDesc().Name, "' contains shader resources, but IDeviceContext::CommitShaderResources() was not called with non-null SRB"); + } +#endif +} + void DeviceContextD3D12Impl::DispatchCompute(const DispatchComputeAttribs& Attribs) { if (!DvpVerifyDispatchArguments(Attribs)) @@ -2139,6 +2173,46 @@ void DeviceContextD3D12Impl::TransitionOrVerifyTextureState(CommandContext& #endif } +void DeviceContextD3D12Impl::TransitionOrVerifyBLASState(CommandContext& CmdCtx, + BottomLevelASD3D12Impl& BLAS, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + const char* OperationName) +{ + if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) + { + if (BLAS.IsInKnownState() && !BLAS.CheckState(RequiredState)) + CmdCtx.TransitionResource(&BLAS, RequiredState); + } +#ifdef DILIGENT_DEVELOPMENT + else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) + { + DvpVerifyBLASState(BLAS, RequiredState, OperationName); + } +#endif +} + +void DeviceContextD3D12Impl::TransitionOrVerifyTLASState(CommandContext& CmdCtx, + TopLevelASD3D12Impl& TLAS, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + const char* OperationName) +{ + // AZ TODO: transit BLAS state too? + + if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) + { + if (TLAS.IsInKnownState() && !TLAS.CheckState(RequiredState)) + CmdCtx.TransitionResource(&TLAS, RequiredState); + } +#ifdef DILIGENT_DEVELOPMENT + else if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY) + { + DvpVerifyTLASState(TLAS, RequiredState, OperationName); + } +#endif +} + void DeviceContextD3D12Impl::TransitionTextureState(ITexture* pTexture, D3D12_RESOURCE_STATES State) { VERIFY_EXPR(pTexture != nullptr); @@ -2202,22 +2276,218 @@ void DeviceContextD3D12Impl::ResolveTextureSubresource(ITexture* void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) { + if (!TDeviceContextBase::BuildBLAS(Attribs, 0)) + return; + + auto* pBLASD12 = ValidatedCast(Attribs.pBLAS); + auto* pScratchD12 = ValidatedCast(Attribs.pScratchBuffer); + auto& BLASDesc = pBLASD12->GetDesc(); + + auto& CmdCtx = GetCmdContext(); + const char* OpName = "Build BottomLevelAS (DeviceContextD3D12Impl::BuildBLAS)"; + 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; + std::vector Geometries; + + if (Attribs.pTriangleData != nullptr) + { + Geometries.resize(Attribs.TriangleDataCount); + + for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i) + { + auto& src = Attribs.pTriangleData[i]; + Uint32 j = pBLASD12->GetGeometryIndex(src.GeometryName); + auto& dst = Geometries.data()[j]; + auto& tri = dst.Triangles; + + if (j >= Geometries.size()) + { + UNEXPECTED("Failed to find geometry by name"); + continue; + } + + dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; + dst.Flags = GeometryFlagsToD3D12RTGeometryFlags(src.Flags); + + auto* pVB = ValidatedCast(src.pVertexBuffer); + tri.VertexFormat = TypeToDXGI_Format(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); + tri.VertexCount = src.VertexCount; + tri.VertexBuffer.StartAddress = pVB->GetGPUAddress() + src.VertexOffset; + tri.VertexBuffer.StrideInBytes = src.VertexStride; + + if (src.pIndexBuffer) + { + auto* pIB = ValidatedCast(src.pIndexBuffer); + tri.IndexBuffer = pIB->GetGPUAddress() + src.IndexOffset; + tri.IndexCount = src.IndexCount; + tri.IndexFormat = ValueTypeToIndexType(src.IndexType); + + TransitionOrVerifyBufferState(CmdCtx, *pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + } + else + { + tri.IndexFormat = DXGI_FORMAT_UNKNOWN; + tri.IndexBuffer = 0; + } + + if (src.pTransformBuffer) + { + VERIFY_EXPR(BLASDesc.pTriangles[j].AllowsTransforms); + + auto* pTB = ValidatedCast(src.pTransformBuffer); + tri.Transform3x4 = pTB->GetGPUAddress() + src.TransformBufferOffset; + + TransitionOrVerifyBufferState(CmdCtx, *pTB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + } + else + { + VERIFY_EXPR(!BLASDesc.pTriangles[j].AllowsTransforms); + tri.Transform3x4 = 0; + } + } + } + else if (Attribs.pBoxData != nullptr) + { + Geometries.resize(Attribs.BoxDataCount); + + for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i) + { + auto& src = Attribs.pBoxData[i]; + Uint32 j = pBLASD12->GetGeometryIndex(src.GeometryName); + auto& dst = Geometries.data()[j]; + auto& box = dst.AABBs; + + if (j >= Geometries.size()) + { + UNEXPECTED("Failed to find geometry by name"); + continue; + } + + dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS; + dst.Flags = GeometryFlagsToD3D12RTGeometryFlags(src.Flags); + + auto* pBB = ValidatedCast(src.pBoxBuffer); + box.AABBCount = src.BoxCount; + box.AABBs.StartAddress = pBB->GetGPUAddress() + src.BoxOffset; + box.AABBs.StrideInBytes = src.BoxStride; + + TransitionOrVerifyBufferState(CmdCtx, *pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + } + } + + Inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + Inputs.NumDescs = static_cast(Geometries.size()); + Inputs.pGeometryDescs = Geometries.data(); + + Desc.DestAccelerationStructureData = pBLASD12->GetGPUAddress(); + Desc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress(); + Desc.SourceAccelerationStructureData = 0; + + CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(Desc, 0, nullptr); + ++m_State.NumCommands; } void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) { + if (!TDeviceContextBase::BuildTLAS(Attribs, 0)) + return; + + static_assert(TLAS_INSTANCE_DATA_SIZE == sizeof(D3D12_RAYTRACING_INSTANCE_DESC), "Value in TLAS_INSTANCE_DATA_SIZE doesn't match the actual instance description size"); + + auto* pTLASD12 = ValidatedCast(Attribs.pTLAS); + auto* pScratchD12 = ValidatedCast(Attribs.pScratchBuffer); + auto* pInstancesD12 = ValidatedCast(Attribs.pInstanceBuffer); + //auto& TLASDesc = pTLASD12->GetDesc(); + + auto& CmdCtx = GetCmdContext(); + const char* OpName = "Build TopLevelAS (DeviceContextD3D12Impl::BuildTLAS)"; + TransitionOrVerifyTLASState(CmdCtx, *pTLASD12, Attribs.TLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); + TransitionOrVerifyBufferState(CmdCtx, *pScratchD12, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); + + pTLASD12->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount, Attribs.HitShadersPerInstance); + + // 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; + + for (Uint32 i = 0; i < Attribs.InstanceCount; ++i) + { + auto& src = Attribs.pInstances[i]; + auto& dst = static_cast(pMappedInstances)[i]; + auto* pBLASD12 = ValidatedCast(src.pBLAS); + + static_assert(sizeof(dst.Transform) == sizeof(src.Transform), "size mismatch"); + std::memcpy(&dst.Transform, src.Transform, sizeof(dst.Transform)); + + dst.InstanceID = src.CustomId; + dst.InstanceContributionToHitGroupIndex = pTLASD12->GetInstanceDesc(src.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize + dst.InstanceMask = src.Mask; + dst.Flags = InstanceFlagsToD3D12RTInstanceFlags(src.Flags); + dst.AccelerationStructure = pBLASD12->GetGPUAddress(); + + TransitionOrVerifyBLASState(CmdCtx, *pBLASD12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + } + UpdateBufferRegion(pInstancesD12, TmpSpace, Attribs.InstanceBufferOffset, Size, Attribs.InstanceBufferTransitionMode); + } + TransitionOrVerifyBufferState(CmdCtx, *pInstancesD12, Attribs.InstanceBufferTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC Desc = {}; + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS& Inputs = Desc.Inputs; + + Inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + Inputs.NumDescs = Attribs.InstanceCount; + Inputs.InstanceDescs = pInstancesD12->GetGPUAddress(); + + Desc.DestAccelerationStructureData = pTLASD12->GetGPUAddress(); + Desc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress(); + Desc.SourceAccelerationStructureData = 0; + + CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(Desc, 0, nullptr); + ++m_State.NumCommands; } void DeviceContextD3D12Impl::CopyBLAS(const CopyBLASAttribs& Attribs) { + if (!TDeviceContextBase::CopyBLAS(Attribs, 0)) + return; + + // AZ TODO } void DeviceContextD3D12Impl::CopyTLAS(const CopyTLASAttribs& Attribs) { + if (!TDeviceContextBase::CopyTLAS(Attribs, 0)) + return; + + // AZ TODO } void DeviceContextD3D12Impl::TraceRays(const TraceRaysAttribs& Attribs) { + if (!TDeviceContextBase::TraceRays(Attribs, 0)) + return; + + D3D12_DISPATCH_RAYS_DESC Desc = {}; + + Desc.Width = Attribs.DimensionX; + Desc.Height = Attribs.DimensionY; + Desc.Depth = Attribs.DimensionZ; + + auto* pSBTD12 = ValidatedCast(Attribs.pSBT); + pSBTD12->GetD3D12AddressRangeAndStride(this, Attribs.TransitionMode, Desc.RayGenerationShaderRecord, Desc.MissShaderTable, Desc.HitGroupTable, Desc.CallableShaderTable); + + auto& CmdCtx = GetCmdContext().AsGraphicsContext4(); + PrepareForDispatchRays(CmdCtx); + + CmdCtx.DispatchRays(Desc); + ++m_State.NumCommands; } } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp b/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp index be5c68eb..0da4470b 100644 --- a/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp +++ b/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp @@ -113,7 +113,7 @@ GenerateMipsHelper::GenerateMipsHelper(ID3D12Device* pd3d12Device) void GenerateMipsHelper::GenerateMips(ID3D12Device* pd3d12Device, TextureViewD3D12Impl* pTexView, CommandContext& Ctx) const { auto& ComputeCtx = Ctx.AsComputeContext(); - ComputeCtx.SetRootSignature(m_pGenerateMipsRS); + ComputeCtx.SetComputeRootSignature(m_pGenerateMipsRS); auto* pTexD3D12 = pTexView->GetTexture(); const auto& TexDesc = pTexD3D12->GetDesc(); const auto& ViewDesc = pTexView->GetDesc(); diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index efae7b37..9cc7faa5 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -877,9 +877,9 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou if (Attrib.CommitResources) { if (m_Desc.IsAnyGraphicsPipeline()) - CmdCtx.AsGraphicsContext().SetRootSignature(GetD3D12RootSignature()); + CmdCtx.AsGraphicsContext().SetGraphicsRootSignature(GetD3D12RootSignature()); else - CmdCtx.AsComputeContext().SetRootSignature(GetD3D12RootSignature()); + CmdCtx.AsComputeContext().SetComputeRootSignature(GetD3D12RootSignature()); } return nullptr; } @@ -906,9 +906,9 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou if (Attrib.CommitResources) { if (m_Desc.IsAnyGraphicsPipeline()) - CmdCtx.AsGraphicsContext().SetRootSignature(GetD3D12RootSignature()); + CmdCtx.AsGraphicsContext().SetGraphicsRootSignature(GetD3D12RootSignature()); else - CmdCtx.AsComputeContext().SetRootSignature(GetD3D12RootSignature()); + CmdCtx.AsComputeContext().SetComputeRootSignature(GetD3D12RootSignature()); if (Attrib.TransitionResources) { diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index 9feabb6a..f8f545e7 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -40,6 +40,9 @@ #include "QueryD3D12Impl.hpp" #include "RenderPassD3D12Impl.hpp" #include "FramebufferD3D12Impl.hpp" +#include "BottomLevelASD3D12Impl.hpp" +#include "TopLevelASD3D12Impl.hpp" +#include "ShaderBindingTableD3D12Impl.hpp" #include "EngineMemory.h" namespace Diligent @@ -137,9 +140,9 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo sizeof(QueryD3D12Impl), sizeof(RenderPassD3D12Impl), sizeof(FramebufferD3D12Impl), - 0, - 0, - 0 + sizeof(BottomLevelASD3D12Impl), + sizeof(TopLevelASD3D12Impl), + sizeof(ShaderBindingTableD3D12Impl) } }, m_pd3d12Device {pd3d12Device}, @@ -725,19 +728,37 @@ void RenderDeviceD3D12Impl::CreateFramebuffer(const FramebufferDesc& Desc, IFram void RenderDeviceD3D12Impl::CreateBLAS(const BottomLevelASDesc& Desc, IBottomLevelAS** ppBLAS) { - // AZ TODO + CreateDeviceObject("BottomLevelAS", Desc, ppBLAS, + [&]() // + { + BottomLevelASD3D12Impl* pBottomLevelASVk(NEW_RC_OBJ(m_BLASAllocator, "BottomLevelASD3D12Impl instance", BottomLevelASD3D12Impl)(this, Desc)); + pBottomLevelASVk->QueryInterface(IID_BottomLevelAS, reinterpret_cast(ppBLAS)); + OnCreateDeviceObject(pBottomLevelASVk); + }); } void RenderDeviceD3D12Impl::CreateTLAS(const TopLevelASDesc& Desc, ITopLevelAS** ppTLAS) { - // AZ TODO + CreateDeviceObject("TopLevelAS", Desc, ppTLAS, + [&]() // + { + TopLevelASD3D12Impl* pTopLevelASVk(NEW_RC_OBJ(m_TLASAllocator, "TopLevelASD3D12Impl instance", TopLevelASD3D12Impl)(this, Desc)); + pTopLevelASVk->QueryInterface(IID_TopLevelAS, reinterpret_cast(ppTLAS)); + OnCreateDeviceObject(pTopLevelASVk); + }); } void RenderDeviceD3D12Impl::CreateSBT(const ShaderBindingTableDesc& Desc, IShaderBindingTable** ppSBT) { - // AZ TODO + CreateDeviceObject("ShaderBindingTable", Desc, ppSBT, + [&]() // + { + ShaderBindingTableD3D12Impl* pSBTVk(NEW_RC_OBJ(m_SBTAllocator, "ShaderBindingTableD3D12Impl instance", ShaderBindingTableD3D12Impl)(this, Desc)); + pSBTVk->QueryInterface(IID_ShaderBindingTable, reinterpret_cast(ppSBT)); + OnCreateDeviceObject(pSBTVk); + }); } DescriptorHeapAllocation RenderDeviceD3D12Impl::AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count /*= 1*/) diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 35274af3..d0db2201 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -33,6 +33,7 @@ #include "CommandContext.hpp" #include "RenderDeviceD3D12Impl.hpp" #include "TextureD3D12Impl.hpp" +#include "TopLevelASD3D12Impl.hpp" #include "D3D12TypeConversions.hpp" #include "HashUtils.hpp" @@ -702,6 +703,10 @@ __forceinline void TransitionResource(CommandContext& Ctx, case CachedResourceType::AccelStruct: { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); + auto* pTLASD3D12 = Res.pObject.RawPtr(); + if (pTLASD3D12->IsInKnownState() && !pTLASD3D12->CheckState(RESOURCE_STATE_RAY_TRACING)) + Ctx.TransitionResource(pTLASD3D12, RESOURCE_STATE_RAY_TRACING); } break; @@ -806,6 +811,16 @@ void RootSignature::DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resou case CachedResourceType::AccelStruct: { + VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); + const auto* pTLASD3D12 = Res.pObject.RawPtr(); + if (pTLASD3D12->IsInKnownState() && !pTLASD3D12->CheckState(RESOURCE_STATE_RAY_TRACING)) + { + LOG_ERROR_MESSAGE("TLAS '", pTLASD3D12->GetDesc().Name, "' must be in RESOURCE_STATE_RAY_TRACING state. Actual state: ", + GetResourceStateString(pTLASD3D12->GetState()), + ". Call IDeviceContext::TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION " + "when calling IDeviceContext::CommitShaderResources() or explicitly transition the TLAS state " + "with IDeviceContext::TransitionResourceStates()."); + } } break; diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp new file mode 100644 index 00000000..3727913f --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp @@ -0,0 +1,202 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "ShaderBindingTableD3D12Impl.hpp" +#include "RenderDeviceD3D12Impl.hpp" +#include "DeviceContextD3D12Impl.hpp" +#include "D3D12TypeConversions.hpp" +#include "GraphicsAccessories.hpp" +#include "DXGITypeConversions.hpp" +#include "EngineMemory.h" +#include "StringTools.hpp" + +namespace Diligent +{ + +ShaderBindingTableD3D12Impl::ShaderBindingTableD3D12Impl(IReferenceCounters* pRefCounters, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const ShaderBindingTableDesc& Desc, + bool bIsDeviceInternal) : + TShaderBindingTableBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal} +{ + ValidateDesc(Desc); + + m_ShaderRecordStride = m_Desc.ShaderRecordSize + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; +} + +ShaderBindingTableD3D12Impl::~ShaderBindingTableD3D12Impl() +{ +} + +IMPLEMENT_QUERY_INTERFACE(ShaderBindingTableD3D12Impl, IID_ShaderBindingTableD3D12, TShaderBindingTableBase) + +void ShaderBindingTableD3D12Impl::ValidateDesc(const ShaderBindingTableDesc& Desc) const +{ + if (Desc.ShaderRecordSize + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES > D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE) + { + LOG_ERROR_AND_THROW("Description of Shader binding table '", (Desc.Name ? Desc.Name : ""), + "' is invalid: ShaderRecordSize is too big, max size is: ", D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE - D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES); + } +} + +void ShaderBindingTableD3D12Impl::Verify() const +{ + // AZ TODO +} + +void ShaderBindingTableD3D12Impl::Reset(const ShaderBindingTableDesc& Desc) +{ + m_RayGenShaderRecord.clear(); + m_MissShadersRecord.clear(); + m_CallableShadersRecord.clear(); + m_HitGroupsRecord.clear(); + m_Changed = true; + + try + { + ValidateShaderBindingTableDesc(Desc); + ValidateDesc(Desc); + } + catch (const std::runtime_error&) + { + // AZ TODO + return; + } + + m_Desc = Desc; + m_ShaderRecordStride = m_Desc.ShaderRecordSize + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; +} + +void ShaderBindingTableD3D12Impl::ResetHitGroups(Uint32 HitShadersPerInstance) +{ + // AZ TODO +} + +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(offset), static_cast(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()->GetGPUAddress(0, ValidatedCast(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(m_RayGenShaderRecord.size()), m_RayGenShaderRecord.data(), TransitionMode); + + if (m_MissShadersRecord.size()) + pContext->UpdateBuffer(m_pBuffer, MissShaderOffset, static_cast(m_MissShadersRecord.size()), m_MissShadersRecord.data(), TransitionMode); + + if (m_HitGroupsRecord.size()) + pContext->UpdateBuffer(m_pBuffer, HitGroupOffset, static_cast(m_HitGroupsRecord.size()), m_HitGroupsRecord.data(), TransitionMode); + + if (m_CallableShadersRecord.size()) + pContext->UpdateBuffer(m_pBuffer, CallableShadersOffset, static_cast(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/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index b4bb1f72..6dbdb97f 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -40,6 +40,7 @@ #include "ShaderResourceVariableBase.hpp" #include "ShaderVariableD3DBase.hpp" #include "LinearAllocator.hpp" +#include "TopLevelASD3D12.h" namespace Diligent { @@ -622,6 +623,35 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheAccelStruct(IDeviceObject* Uint32 ArrayIndex, D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const { + VERIFY(Attribs.IsValidBindPoint(), "Invalid bind point"); + VERIFY_EXPR(ArrayIndex < Attribs.BindCount); + + RefCntAutoPtr pTLASD3D12(pTLAS, IID_TopLevelASD3D12); + if (pTLASD3D12) + { + if (GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC && DstRes.pObject != nullptr) + { + // Do not update resource if one is already bound unless it is dynamic. This may be + // dangerous as CopyDescriptorsSimple() may interfere with GPU reading the same descriptor. + return; + } + + DstRes.Type = GetResType(); + DstRes.CPUDescriptorHandle = pTLASD3D12->GetCPUDescriptorHandle(); + VERIFY(DstRes.CPUDescriptorHandle.ptr != 0, "No relevant D3D12 resource"); + + if (ShdrVisibleHeapCPUDescriptorHandle.ptr != 0) + { + // Dynamic resources are assigned descriptor in the GPU-visible heap at every draw call, and + // the descriptor is copied by the RootSignature when resources are committed + VERIFY(DstRes.pObject == nullptr, "Static and mutable resource descriptors must be copied only once"); + + ID3D12Device* pd3d12Device = ParentResLayout.m_pd3d12Device; + pd3d12Device->CopyDescriptorsSimple(1, ShdrVisibleHeapCPUDescriptorHandle, DstRes.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + + DstRes.pObject = std::move(pTLASD3D12); + } } const ShaderResourceLayoutD3D12::D3D12Resource& ShaderResourceLayoutD3D12::GetAssignedSampler(const D3D12Resource& TexSrv) const diff --git a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp new file mode 100644 index 00000000..5f411640 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" +#include "TopLevelASD3D12Impl.hpp" +#include "RenderDeviceD3D12Impl.hpp" +#include "DeviceContextD3D12Impl.hpp" +#include "D3D12TypeConversions.hpp" +#include "GraphicsAccessories.hpp" +#include "DXGITypeConversions.hpp" +#include "EngineMemory.h" +#include "StringTools.hpp" + +namespace Diligent +{ + +TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounters, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const TopLevelASDesc& Desc, + bool bIsDeviceInternal) : + TTopLevelASBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal} +{ + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO TopLevelPrebuildInfo = {}; + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS TopLevelInputs = {}; + + TopLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + TopLevelInputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE; + TopLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + TopLevelInputs.NumDescs = Desc.MaxInstanceCount; + + VERIFY_EXPR(Desc.MaxInstanceCount <= D3D12_RAYTRACING_MAX_INSTANCES_PER_TOP_LEVEL_ACCELERATION_STRUCTURE); + + auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + + pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&TopLevelInputs, &TopLevelPrebuildInfo); + if (TopLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0) + LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info"); + + D3D12_HEAP_PROPERTIES HeapProps; + HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + HeapProps.CreationNodeMask = 1; + HeapProps.VisibleNodeMask = 1; + + D3D12_RESOURCE_DESC ASDesc = {}; + ASDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + ASDesc.Alignment = 0; + ASDesc.Width = TopLevelPrebuildInfo.ResultDataMaxSizeInBytes; + ASDesc.Height = 1; + ASDesc.DepthOrArraySize = 1; + ASDesc.MipLevels = 1; + ASDesc.Format = DXGI_FORMAT_UNKNOWN; + ASDesc.SampleDesc.Count = 1; + ASDesc.SampleDesc.Quality = 0; + ASDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + ASDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + + auto hr = pd3d12Device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE, + &ASDesc, D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE, nullptr, + __uuidof(m_pd3d12Resource), + reinterpret_cast(static_cast(&m_pd3d12Resource))); + if (FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create D3D12 Top-level acceleration structure"); + + if (*m_Desc.Name != 0) + m_pd3d12Resource->SetName(WidenString(m_Desc.Name).c_str()); + + m_ScratchSize.Build = static_cast(TopLevelPrebuildInfo.ScratchDataSizeInBytes); + m_ScratchSize.Update = static_cast(TopLevelPrebuildInfo.UpdateScratchDataSizeInBytes); + + m_DescriptorHandle = pDeviceD3D12->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + D3D12_SHADER_RESOURCE_VIEW_DESC SRVDesc; + SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE; + SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + SRVDesc.Format = DXGI_FORMAT_UNKNOWN; + SRVDesc.RaytracingAccelerationStructure.Location = GetGPUAddress(); + pd3d12Device->CreateShaderResourceView(nullptr, &SRVDesc, m_DescriptorHandle.GetCpuHandle()); +} + +TopLevelASD3D12Impl::~TopLevelASD3D12Impl() +{ + // D3D12 object can only be destroyed when it is no longer used by the GPU + auto* pDeviceD3D12Impl = ValidatedCast(GetDevice()); + pDeviceD3D12Impl->SafeReleaseDeviceObject(std::move(m_pd3d12Resource), m_Desc.CommandQueueMask); +} + +IMPLEMENT_QUERY_INTERFACE(TopLevelASD3D12Impl, IID_TopLevelASD3D12, TTopLevelASBase) + +} // namespace Diligent -- cgit v1.2.3 From 85129a6868aca02adc80a0a5360fa47579dac526 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 29 Oct 2020 22:45:25 -0700 Subject: Added include tests for BLAS, TLAS and SBT headers, fixed few issues --- Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h | 2 +- Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h | 2 +- Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h b/Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h index 2b64da57..bcfe3d73 100644 --- a/Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/BottomLevelASD3D12.h @@ -63,7 +63,7 @@ DILIGENT_END_INTERFACE #if DILIGENT_C_INTERFACE -# define IBottomLevelASD3D12_GetD3D12BLAS(This) CALL_IFACE_METHOD(IBottomLevelASD3D12, GetD3D12BLAS, This) +# define IBottomLevelASD3D12_GetD3D12BLAS(This) CALL_IFACE_METHOD(BottomLevelASD3D12, GetD3D12BLAS, This) #endif diff --git a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h index f33bac1b..4b0835cd 100644 --- a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h @@ -44,7 +44,7 @@ static const INTERFACE_ID IID_ShaderBindingTableD3D12 = #define IShaderBindingTableD3D12InclusiveMethods \ IShaderBindingTableInclusiveMethods; \ - IShaderBindingTableD3D12Methods ShaderBindingTable + IShaderBindingTableD3D12Methods ShaderBindingTableD3D12 // clang-format off /// Exposes Direct3D12-specific functionality of a shader binding table object. diff --git a/Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h b/Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h index 5b2bd512..6434eaba 100644 --- a/Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/TopLevelASD3D12.h @@ -69,8 +69,8 @@ DILIGENT_END_INTERFACE #if DILIGENT_C_INTERFACE -# define ITopLevelASD3D12_GetD3D12TLAS(This) CALL_IFACE_METHOD(ITopLevelASD3D12, GetD3D12TLAS, This) -# define ITopLevelASD3D12_GetCPUDescriptorHandle(This) CALL_IFACE_METHOD(ITopLevelASD3D12, GetCPUDescriptorHandle, This) +# define ITopLevelASD3D12_GetD3D12TLAS(This) CALL_IFACE_METHOD(TopLevelASD3D12, GetD3D12TLAS, This) +# define ITopLevelASD3D12_GetCPUDescriptorHandle(This) CALL_IFACE_METHOD(TopLevelASD3D12, GetCPUDescriptorHandle, This) #endif -- cgit v1.2.3 From 076e2f20ce80ef9ea6ccb351c2bfdc3b99ac8015 Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 30 Oct 2020 14:18:45 -0700 Subject: A number of minor updates --- .../GraphicsEngineD3D12/src/CommandContext.cpp | 11 +- .../src/D3D12TypeConversions.cpp | 36 +++--- .../src/DeviceContextD3D12Impl.cpp | 134 +++++++++++---------- .../src/ShaderBindingTableD3D12Impl.cpp | 2 +- .../src/ShaderResourceLayoutD3D12.cpp | 6 +- .../src/TopLevelASD3D12Impl.cpp | 58 ++++----- 6 files changed, 124 insertions(+), 123 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp index 6bc55ac3..4285e11a 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp @@ -171,9 +171,9 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier) RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN; ID3D12Resource* pd3d12Resource = nullptr; RefCntAutoPtr pTextureD3D12Impl{Barrier.pResource, IID_TextureD3D12}; - RefCntAutoPtr pBufferD3D12Impl{Barrier.pResource, IID_BufferD3D12}; - RefCntAutoPtr pBLASD3D12Impl{Barrier.pResource, IID_BottomLevelASD3D12}; - RefCntAutoPtr pTLASD3D12Impl{Barrier.pResource, IID_TopLevelASD3D12}; + RefCntAutoPtr pBufferD3D12Impl{pTextureD3D12Impl ? nullptr : Barrier.pResource, IID_BufferD3D12}; + RefCntAutoPtr pBLASD3D12Impl{pBufferD3D12Impl ? nullptr : Barrier.pResource, IID_BottomLevelASD3D12}; + RefCntAutoPtr pTLASD3D12Impl{pBLASD3D12Impl ? nullptr : Barrier.pResource, IID_TopLevelASD3D12}; if (pTextureD3D12Impl) { @@ -324,9 +324,8 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier) } } - if ((OldState == RESOURCE_STATE_UNORDERED_ACCESS && Barrier.NewState == RESOURCE_STATE_UNORDERED_ACCESS) || - (OldState == RESOURCE_STATE_BUILD_AS_WRITE && Barrier.NewState == RESOURCE_STATE_BUILD_AS_WRITE) || - (OldState == RESOURCE_STATE_RAY_TRACING && Barrier.NewState == RESOURCE_STATE_RAY_TRACING)) + 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)) { DEV_CHECK_ERR(Barrier.TransitionType == STATE_TRANSITION_TYPE_IMMEDIATE, "UAV barriers must not be split"); InsertUAVBarrier(pd3d12Resource); diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index ddab5096..a6d6963e 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -612,22 +612,21 @@ D3D12_RAYTRACING_GEOMETRY_FLAGS GeometryFlagsToD3D12RTGeometryFlags(RAYTRACING_G static_assert(RAYTRACING_GEOMETRY_FLAGS_LAST == RAYTRACING_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION, "Please update the switch below to handle the new ray tracing geometry flag"); - Uint32 Result = 0; - for (Uint32 Bit = 1; Bit <= Flags; Bit <<= 1) + D3D12_RAYTRACING_GEOMETRY_FLAGS Result = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; + while (Flags != RAYTRACING_GEOMETRY_NONE) { - if ((Flags & Bit) != Bit) - continue; - - switch (static_cast(Bit)) + auto FlagBit = static_cast(1 << PlatformMisc::GetLSB(Uint32{Flags})); + switch (FlagBit) { // clang-format off - case RAYTRACING_GEOMETRY_OPAQUE: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE; break; + case RAYTRACING_GEOMETRY_OPAQUE: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE; break; case RAYTRACING_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION; break; // clang-format on default: UNEXPECTED("unknown geometry flag"); } + Flags &= ~FlagBit; } - return static_cast(Result); + return Result; } D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_INSTANCE_FLAGS Flags) @@ -635,24 +634,23 @@ D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_I static_assert(RAYTRACING_INSTANCE_FLAGS_LAST == RAYTRACING_INSTANCE_FORCE_NO_OPAQUE, "Please update the switch below to handle the new ray tracing instance flag"); - Uint32 Result = 0; - for (Uint32 Bit = 1; Bit <= Flags; Bit <<= 1) + D3D12_RAYTRACING_INSTANCE_FLAGS Result = D3D12_RAYTRACING_INSTANCE_FLAG_NONE; + while (Flags != RAYTRACING_INSTANCE_NONE) { - if ((Flags & Bit) != Bit) - continue; - - switch (static_cast(Bit)) + auto FlagBit = static_cast(1 << PlatformMisc::GetLSB(Uint32{Flags})); + switch (FlagBit) { // clang-format off - case RAYTRACING_INSTANCE_TRIANGLE_FACING_CULL_DISABLE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_CULL_DISABLE ; break; - case RAYTRACING_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE ; break; - case RAYTRACING_INSTANCE_FORCE_OPAQUE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OPAQUE ; break; - case RAYTRACING_INSTANCE_FORCE_NO_OPAQUE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_NON_OPAQUE ; break; + case RAYTRACING_INSTANCE_TRIANGLE_FACING_CULL_DISABLE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_CULL_DISABLE; break; + case RAYTRACING_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE; break; + case RAYTRACING_INSTANCE_FORCE_OPAQUE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OPAQUE; break; + case RAYTRACING_INSTANCE_FORCE_NO_OPAQUE: Result |= D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_NON_OPAQUE; break; // clang-format on default: UNEXPECTED("unknown instance flag"); } + Flags &= ~FlagBit; } - return static_cast(Result); + return Result; } } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 95025c4c..3cd896ac 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2279,9 +2279,9 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) if (!TDeviceContextBase::BuildBLAS(Attribs, 0)) return; - auto* pBLASD12 = ValidatedCast(Attribs.pBLAS); - auto* pScratchD12 = ValidatedCast(Attribs.pScratchBuffer); - auto& BLASDesc = pBLASD12->GetDesc(); + auto* const pBLASD12 = ValidatedCast(Attribs.pBLAS); + auto* const pScratchD12 = ValidatedCast(Attribs.pScratchBuffer); + const auto& BLASDesc = pBLASD12->GetDesc(); auto& CmdCtx = GetCmdContext(); const char* OpName = "Build BottomLevelAS (DeviceContextD3D12Impl::BuildBLAS)"; @@ -2298,54 +2298,54 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i) { - auto& src = Attribs.pTriangleData[i]; - Uint32 j = pBLASD12->GetGeometryIndex(src.GeometryName); - auto& dst = Geometries.data()[j]; - auto& tri = dst.Triangles; + const auto& SrcTris = Attribs.pTriangleData[i]; + Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcTris.GeometryName); + auto& d3d12Geo = Geometries[GeoIdx]; + auto& d3d12Tris = d3d12Geo.Triangles; - if (j >= Geometries.size()) + if (GeoIdx >= Geometries.size()) { UNEXPECTED("Failed to find geometry by name"); continue; } - dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; - dst.Flags = GeometryFlagsToD3D12RTGeometryFlags(src.Flags); + d3d12Geo.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; + d3d12Geo.Flags = GeometryFlagsToD3D12RTGeometryFlags(SrcTris.Flags); - auto* pVB = ValidatedCast(src.pVertexBuffer); - tri.VertexFormat = TypeToDXGI_Format(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); - tri.VertexCount = src.VertexCount; - tri.VertexBuffer.StartAddress = pVB->GetGPUAddress() + src.VertexOffset; - tri.VertexBuffer.StrideInBytes = src.VertexStride; + auto* const pVB = ValidatedCast(SrcTris.pVertexBuffer); + d3d12Tris.VertexFormat = TypeToDXGI_Format(SrcTris.VertexValueType, SrcTris.VertexComponentCount, SrcTris.VertexValueType < VT_FLOAT16); + d3d12Tris.VertexCount = SrcTris.VertexCount; + d3d12Tris.VertexBuffer.StartAddress = pVB->GetGPUAddress() + SrcTris.VertexOffset; + d3d12Tris.VertexBuffer.StrideInBytes = SrcTris.VertexStride; - if (src.pIndexBuffer) + if (SrcTris.pIndexBuffer) { - auto* pIB = ValidatedCast(src.pIndexBuffer); - tri.IndexBuffer = pIB->GetGPUAddress() + src.IndexOffset; - tri.IndexCount = src.IndexCount; - tri.IndexFormat = ValueTypeToIndexType(src.IndexType); + auto* const pIB = ValidatedCast(SrcTris.pIndexBuffer); + d3d12Tris.IndexBuffer = pIB->GetGPUAddress() + SrcTris.IndexOffset; + d3d12Tris.IndexCount = SrcTris.IndexCount; + d3d12Tris.IndexFormat = ValueTypeToIndexType(SrcTris.IndexType); TransitionOrVerifyBufferState(CmdCtx, *pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } else { - tri.IndexFormat = DXGI_FORMAT_UNKNOWN; - tri.IndexBuffer = 0; + d3d12Tris.IndexFormat = DXGI_FORMAT_UNKNOWN; + d3d12Tris.IndexBuffer = 0; } - if (src.pTransformBuffer) + if (SrcTris.pTransformBuffer) { - VERIFY_EXPR(BLASDesc.pTriangles[j].AllowsTransforms); + VERIFY_EXPR(BLASDesc.pTriangles[GeoIdx].AllowsTransforms); - auto* pTB = ValidatedCast(src.pTransformBuffer); - tri.Transform3x4 = pTB->GetGPUAddress() + src.TransformBufferOffset; + auto* const pTB = ValidatedCast(SrcTris.pTransformBuffer); + d3d12Tris.Transform3x4 = pTB->GetGPUAddress() + SrcTris.TransformBufferOffset; TransitionOrVerifyBufferState(CmdCtx, *pTB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } else { - VERIFY_EXPR(!BLASDesc.pTriangles[j].AllowsTransforms); - tri.Transform3x4 = 0; + VERIFY_EXPR(!BLASDesc.pTriangles[GeoIdx].AllowsTransforms); + d3d12Tris.Transform3x4 = 0; } } } @@ -2355,24 +2355,24 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i) { - auto& src = Attribs.pBoxData[i]; - Uint32 j = pBLASD12->GetGeometryIndex(src.GeometryName); - auto& dst = Geometries.data()[j]; - auto& box = dst.AABBs; + const auto& SrcBoxes = Attribs.pBoxData[i]; + Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcBoxes.GeometryName); + auto& d3d12Geo = Geometries[GeoIdx]; + auto& d3d12AABs = d3d12Geo.AABBs; - if (j >= Geometries.size()) + if (GeoIdx >= Geometries.size()) { UNEXPECTED("Failed to find geometry by name"); continue; } - dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS; - dst.Flags = GeometryFlagsToD3D12RTGeometryFlags(src.Flags); + d3d12Geo.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS; + d3d12Geo.Flags = GeometryFlagsToD3D12RTGeometryFlags(SrcBoxes.Flags); - auto* pBB = ValidatedCast(src.pBoxBuffer); - box.AABBCount = src.BoxCount; - box.AABBs.StartAddress = pBB->GetGPUAddress() + src.BoxOffset; - box.AABBs.StrideInBytes = src.BoxStride; + auto* pBB = ValidatedCast(SrcBoxes.pBoxBuffer); + d3d12AABs.AABBCount = SrcBoxes.BoxCount; + d3d12AABs.AABBs.StartAddress = pBB->GetGPUAddress() + SrcBoxes.BoxOffset; + d3d12AABs.AABBs.StrideInBytes = SrcBoxes.BoxStride; TransitionOrVerifyBufferState(CmdCtx, *pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } @@ -2418,18 +2418,18 @@ void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) for (Uint32 i = 0; i < Attribs.InstanceCount; ++i) { - auto& src = Attribs.pInstances[i]; - auto& dst = static_cast(pMappedInstances)[i]; - auto* pBLASD12 = ValidatedCast(src.pBLAS); + const auto& Inst = Attribs.pInstances[i]; + auto& d3d12Inst = static_cast(pMappedInstances)[i]; + auto* const pBLASD12 = ValidatedCast(Inst.pBLAS); - static_assert(sizeof(dst.Transform) == sizeof(src.Transform), "size mismatch"); - std::memcpy(&dst.Transform, src.Transform, sizeof(dst.Transform)); + static_assert(sizeof(d3d12Inst.Transform) == sizeof(Inst.Transform), "size mismatch"); + std::memcpy(&d3d12Inst.Transform, Inst.Transform, sizeof(d3d12Inst.Transform)); - dst.InstanceID = src.CustomId; - dst.InstanceContributionToHitGroupIndex = pTLASD12->GetInstanceDesc(src.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize - dst.InstanceMask = src.Mask; - dst.Flags = InstanceFlagsToD3D12RTInstanceFlags(src.Flags); - dst.AccelerationStructure = pBLASD12->GetGPUAddress(); + d3d12Inst.InstanceID = Inst.CustomId; + d3d12Inst.InstanceContributionToHitGroupIndex = pTLASD12->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize + d3d12Inst.InstanceMask = Inst.Mask; + d3d12Inst.Flags = InstanceFlagsToD3D12RTInstanceFlags(Inst.Flags); + d3d12Inst.AccelerationStructure = pBLASD12->GetGPUAddress(); TransitionOrVerifyBLASState(CmdCtx, *pBLASD12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } @@ -2437,19 +2437,19 @@ void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) } TransitionOrVerifyBufferState(CmdCtx, *pInstancesD12, Attribs.InstanceBufferTransitionMode, RESOURCE_STATE_BUILD_AS_READ, 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; - Inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; - Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; - Inputs.NumDescs = Attribs.InstanceCount; - Inputs.InstanceDescs = pInstancesD12->GetGPUAddress(); + d3d12BuildASInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + d3d12BuildASInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + d3d12BuildASInputs.NumDescs = Attribs.InstanceCount; + d3d12BuildASInputs.InstanceDescs = pInstancesD12->GetGPUAddress(); - Desc.DestAccelerationStructureData = pTLASD12->GetGPUAddress(); - Desc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress(); - Desc.SourceAccelerationStructureData = 0; + d3d12BuildASDesc.DestAccelerationStructureData = pTLASD12->GetGPUAddress(); + d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress(); + d3d12BuildASDesc.SourceAccelerationStructureData = 0; - CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(Desc, 0, nullptr); + CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr); ++m_State.NumCommands; } @@ -2474,19 +2474,23 @@ void DeviceContextD3D12Impl::TraceRays(const TraceRaysAttribs& Attribs) if (!TDeviceContextBase::TraceRays(Attribs, 0)) return; - D3D12_DISPATCH_RAYS_DESC Desc = {}; + D3D12_DISPATCH_RAYS_DESC d3d12DispatchDesc = {}; - Desc.Width = Attribs.DimensionX; - Desc.Height = Attribs.DimensionY; - Desc.Depth = Attribs.DimensionZ; + d3d12DispatchDesc.Width = Attribs.DimensionX; + d3d12DispatchDesc.Height = Attribs.DimensionY; + d3d12DispatchDesc.Depth = Attribs.DimensionZ; auto* pSBTD12 = ValidatedCast(Attribs.pSBT); - pSBTD12->GetD3D12AddressRangeAndStride(this, Attribs.TransitionMode, Desc.RayGenerationShaderRecord, Desc.MissShaderTable, Desc.HitGroupTable, Desc.CallableShaderTable); + pSBTD12->GetD3D12AddressRangeAndStride(this, Attribs.TransitionMode, + d3d12DispatchDesc.RayGenerationShaderRecord, + d3d12DispatchDesc.MissShaderTable, + d3d12DispatchDesc.HitGroupTable, + d3d12DispatchDesc.CallableShaderTable); auto& CmdCtx = GetCmdContext().AsGraphicsContext4(); PrepareForDispatchRays(CmdCtx); - CmdCtx.DispatchRays(Desc); + CmdCtx.DispatchRays(d3d12DispatchDesc); ++m_State.NumCommands; } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp index 3727913f..d352caf0 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp @@ -110,7 +110,7 @@ void ShaderBindingTableD3D12Impl::GetD3D12AddressRangeAndStride(IDeviceContextD3 D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& CallableShaderBindingTable) { const auto AlignToLarger = [](size_t offset) -> Uint32 { - return Align(static_cast(offset), static_cast(D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT)); + return Align(static_cast(offset), Uint32{D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT}); }; const Uint32 RayGenOffset = 0; diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 6dbdb97f..bfc8693a 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -456,7 +456,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheCB(IDeviceObject* // We cannot use ValidatedCast<> here as the resource retrieved from the // resource mapping can be of wrong type - RefCntAutoPtr pBuffD3D12(pBuffer, IID_BufferD3D12); + RefCntAutoPtr pBuffD3D12{pBuffer, IID_BufferD3D12}; #ifdef DILIGENT_DEVELOPMENT VerifyConstantBufferBinding(Attribs, GetVariableType(), ArrayInd, pBuffer, pBuffD3D12.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); #endif @@ -576,7 +576,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheSampler(IDeviceObject* VERIFY(Attribs.IsValidBindPoint(), "Invalid bind point"); VERIFY_EXPR(ArrayIndex < Attribs.BindCount); - RefCntAutoPtr pSamplerD3D12(pSampler, IID_SamplerD3D12); + RefCntAutoPtr pSamplerD3D12{pSampler, IID_SamplerD3D12}; if (pSamplerD3D12) { if (GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC && DstSam.pObject != nullptr) @@ -626,7 +626,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheAccelStruct(IDeviceObject* VERIFY(Attribs.IsValidBindPoint(), "Invalid bind point"); VERIFY_EXPR(ArrayIndex < Attribs.BindCount); - RefCntAutoPtr pTLASD3D12(pTLAS, IID_TopLevelASD3D12); + RefCntAutoPtr pTLASD3D12{pTLAS, IID_TopLevelASD3D12}; if (pTLASD3D12) { if (GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC && DstRes.pObject != nullptr) diff --git a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp index 5f411640..3bbf3308 100644 --- a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp @@ -44,20 +44,20 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte bool bIsDeviceInternal) : TTopLevelASBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal} { - D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO TopLevelPrebuildInfo = {}; - D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS TopLevelInputs = {}; + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO d3d12TopLevelPrebuildInfo = {}; + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS d3d12TopLevelInputs = {}; - TopLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; - TopLevelInputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE; - TopLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; - TopLevelInputs.NumDescs = Desc.MaxInstanceCount; + 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; VERIFY_EXPR(Desc.MaxInstanceCount <= D3D12_RAYTRACING_MAX_INSTANCES_PER_TOP_LEVEL_ACCELERATION_STRUCTURE); auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5(); - pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&TopLevelInputs, &TopLevelPrebuildInfo); - if (TopLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0) + pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&d3d12TopLevelInputs, &d3d12TopLevelPrebuildInfo); + if (d3d12TopLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0) LOG_ERROR_AND_THROW("Failed to get ray tracing acceleration structure prebuild info"); D3D12_HEAP_PROPERTIES HeapProps; @@ -67,21 +67,21 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte HeapProps.CreationNodeMask = 1; HeapProps.VisibleNodeMask = 1; - D3D12_RESOURCE_DESC ASDesc = {}; - ASDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - ASDesc.Alignment = 0; - ASDesc.Width = TopLevelPrebuildInfo.ResultDataMaxSizeInBytes; - ASDesc.Height = 1; - ASDesc.DepthOrArraySize = 1; - ASDesc.MipLevels = 1; - ASDesc.Format = DXGI_FORMAT_UNKNOWN; - ASDesc.SampleDesc.Count = 1; - ASDesc.SampleDesc.Quality = 0; - ASDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - ASDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + D3D12_RESOURCE_DESC d3d12ASDesc = {}; + d3d12ASDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + d3d12ASDesc.Alignment = 0; + d3d12ASDesc.Width = d3d12TopLevelPrebuildInfo.ResultDataMaxSizeInBytes; + d3d12ASDesc.Height = 1; + d3d12ASDesc.DepthOrArraySize = 1; + d3d12ASDesc.MipLevels = 1; + d3d12ASDesc.Format = DXGI_FORMAT_UNKNOWN; + d3d12ASDesc.SampleDesc.Count = 1; + d3d12ASDesc.SampleDesc.Quality = 0; + d3d12ASDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + d3d12ASDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; auto hr = pd3d12Device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE, - &ASDesc, D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE, nullptr, + &d3d12ASDesc, D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE, nullptr, __uuidof(m_pd3d12Resource), reinterpret_cast(static_cast(&m_pd3d12Resource))); if (FAILED(hr)) @@ -90,17 +90,17 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte if (*m_Desc.Name != 0) m_pd3d12Resource->SetName(WidenString(m_Desc.Name).c_str()); - m_ScratchSize.Build = static_cast(TopLevelPrebuildInfo.ScratchDataSizeInBytes); - m_ScratchSize.Update = static_cast(TopLevelPrebuildInfo.UpdateScratchDataSizeInBytes); + m_ScratchSize.Build = static_cast(d3d12TopLevelPrebuildInfo.ScratchDataSizeInBytes); + m_ScratchSize.Update = static_cast(d3d12TopLevelPrebuildInfo.UpdateScratchDataSizeInBytes); m_DescriptorHandle = pDeviceD3D12->AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - D3D12_SHADER_RESOURCE_VIEW_DESC SRVDesc; - SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE; - SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - SRVDesc.Format = DXGI_FORMAT_UNKNOWN; - SRVDesc.RaytracingAccelerationStructure.Location = GetGPUAddress(); - pd3d12Device->CreateShaderResourceView(nullptr, &SRVDesc, m_DescriptorHandle.GetCpuHandle()); + D3D12_SHADER_RESOURCE_VIEW_DESC d3d12SRVDesc; + d3d12SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE; + d3d12SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + d3d12SRVDesc.Format = DXGI_FORMAT_UNKNOWN; + d3d12SRVDesc.RaytracingAccelerationStructure.Location = GetGPUAddress(); + pd3d12Device->CreateShaderResourceView(nullptr, &d3d12SRVDesc, m_DescriptorHandle.GetCpuHandle()); } TopLevelASD3D12Impl::~TopLevelASD3D12Impl() -- cgit v1.2.3 From 9a8133811d75501ae3d6e4a5c58f821fb38f8e5d Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 30 Oct 2020 14:54:48 -0700 Subject: Fixed clang compiler warning --- Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 9cc7faa5..405f6d4b 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -286,7 +286,7 @@ void GetShaderIdentifiers(ID3D12StateObject* pSO, PipelineStateD3D12Impl::ShaderStageInfo::ShaderStageInfo(SHADER_TYPE _Type, ShaderD3D12Impl* _pShader) : Type{_Type}, - Shaders{{_pShader}} + Shaders{_pShader} { } -- cgit v1.2.3 From efa43e2bd2475a4dec6771bf9759f6a99f7d77ed Mon Sep 17 00:00:00 2001 From: azhirnov Date: Tue, 3 Nov 2020 13:52:24 +0300 Subject: fixed resource state transitions, some improvements for ray tracing --- .../include/PipelineStateD3D12Impl.hpp | 7 +++- .../include/RenderDeviceD3D12Impl.hpp | 6 +-- .../include/ShaderBindingTableD3D12Impl.hpp | 7 ---- .../include/TopLevelASD3D12Impl.hpp | 5 ++- .../interface/ShaderBindingTableD3D12.h | 1 + .../src/DeviceContextD3D12Impl.cpp | 44 ++++++++++++++++++--- .../src/PipelineStateD3D12Impl.cpp | 45 ++++++++++++++++++---- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 2 +- .../src/ShaderBindingTableD3D12Impl.cpp | 40 ------------------- 9 files changed, 88 insertions(+), 69 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index 6a27a029..f336c6ff 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -144,8 +144,11 @@ private: void Destruct(); - CComPtr m_pd3d12PSO; - RootSignature m_RootSig; + void CreateLocalRootSignature(const RayTracingPipelineDesc& Desc); + + CComPtr m_pd3d12PSO; + RootSignature m_RootSig; + CComPtr m_LocalRootSignature; // Must be defined before default SRB SRBMemoryAllocator m_SRBMemAllocator; diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index ab72e22a..636175d5 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -178,10 +178,8 @@ public: ShaderVersion GetMaxShaderModel() const; D3D_FEATURE_LEVEL GetD3DFeatureLevel() const; - static Uint32 GetShaderGroupHandleSize() - { - return D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; - } + static Uint32 GetShaderGroupHandleSize() { return D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; } + static Uint32 GetMaxShaderRecordStride() { return D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE; } private: template diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp index e866c6f2..daf84d14 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp @@ -54,10 +54,6 @@ public: virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - virtual void DILIGENT_CALL_TYPE Verify() const override; - - virtual void DILIGENT_CALL_TYPE Reset(const ShaderBindingTableDesc& Desc) override; - virtual void DILIGENT_CALL_TYPE ResetHitGroups(Uint32 HitShadersPerInstance) override; virtual void DILIGENT_CALL_TYPE BindAll(const BindAllAttribs& Attribs) override; @@ -69,9 +65,6 @@ public: D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& HitShaderBindingTable, D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE& CallableShaderBindingTable) override; -private: - void ValidateDesc(const ShaderBindingTableDesc& Desc) const; - private: RefCntAutoPtr m_pBuffer; }; diff --git a/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp index 8eccf530..c61ab368 100644 --- a/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp @@ -33,6 +33,7 @@ #include "TopLevelASD3D12.h" #include "RenderDeviceD3D12.h" #include "TopLevelASBase.hpp" +#include "BottomLevelASD3D12Impl.hpp" #include "D3D12ResourceBase.hpp" #include "RenderDeviceD3D12Impl.hpp" @@ -40,10 +41,10 @@ namespace Diligent { /// Top-level acceleration structure object implementation in Direct3D12 backend. -class TopLevelASD3D12Impl final : public TopLevelASBase, public D3D12ResourceBase +class TopLevelASD3D12Impl final : public TopLevelASBase, public D3D12ResourceBase { public: - using TTopLevelASBase = TopLevelASBase; + using TTopLevelASBase = TopLevelASBase; TopLevelASD3D12Impl(IReferenceCounters* pRefCounters, class RenderDeviceD3D12Impl* pDeviceD3D12, diff --git a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h index 4b0835cd..aa50251a 100644 --- a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h @@ -65,6 +65,7 @@ DILIGENT_END_INTERFACE #if DILIGENT_C_INTERFACE +# define IShaderBindingTableD3D12_GetD3D12AddressRangeAndStride(This, ...) CALL_IFACE_METHOD(ShaderBindingTableD3D12, GetD3D12AddressRangeAndStride, This, __VA_ARGS__) #endif diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 3cd896ac..0adcaa59 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2198,8 +2198,6 @@ void DeviceContextD3D12Impl::TransitionOrVerifyTLASState(CommandContext& RESOURCE_STATE RequiredState, const char* OperationName) { - // AZ TODO: transit BLAS state too? - if (TransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION) { if (TLAS.IsInKnownState() && !TLAS.CheckState(RequiredState)) @@ -2210,6 +2208,11 @@ void DeviceContextD3D12Impl::TransitionOrVerifyTLASState(CommandContext& { DvpVerifyTLASState(TLAS, RequiredState, OperationName); } + + if (RequiredState & RESOURCE_STATE_RAY_TRACING) + { + TLAS.CheckBLASVersion(); + } #endif } @@ -2318,6 +2321,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) d3d12Tris.VertexBuffer.StartAddress = pVB->GetGPUAddress() + SrcTris.VertexOffset; d3d12Tris.VertexBuffer.StrideInBytes = SrcTris.VertexStride; + TransitionOrVerifyBufferState(CmdCtx, *pVB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + if (SrcTris.pIndexBuffer) { auto* const pIB = ValidatedCast(SrcTris.pIndexBuffer); @@ -2389,6 +2394,10 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(Desc, 0, nullptr); ++m_State.NumCommands; + +#ifdef DILIGENT_DEVELOPMENT + pBLASD12->UpdateVersion(); +#endif } void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) @@ -2401,7 +2410,6 @@ void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) auto* pTLASD12 = ValidatedCast(Attribs.pTLAS); auto* pScratchD12 = ValidatedCast(Attribs.pScratchBuffer); auto* pInstancesD12 = ValidatedCast(Attribs.pInstanceBuffer); - //auto& TLASDesc = pTLASD12->GetDesc(); auto& CmdCtx = GetCmdContext(); const char* OpName = "Build TopLevelAS (DeviceContextD3D12Impl::BuildTLAS)"; @@ -2423,7 +2431,7 @@ void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) auto* const pBLASD12 = ValidatedCast(Inst.pBLAS); static_assert(sizeof(d3d12Inst.Transform) == sizeof(Inst.Transform), "size mismatch"); - std::memcpy(&d3d12Inst.Transform, Inst.Transform, sizeof(d3d12Inst.Transform)); + std::memcpy(&d3d12Inst.Transform, Inst.Transform.data, sizeof(d3d12Inst.Transform)); d3d12Inst.InstanceID = Inst.CustomId; d3d12Inst.InstanceContributionToHitGroupIndex = pTLASD12->GetInstanceDesc(Inst.InstanceName).ContributionToHitGroupIndex; // AZ TODO: optimize @@ -2458,7 +2466,20 @@ void DeviceContextD3D12Impl::CopyBLAS(const CopyBLASAttribs& Attribs) if (!TDeviceContextBase::CopyBLAS(Attribs, 0)) return; - // AZ TODO + auto* pSrcD3D12 = ValidatedCast(Attribs.pSrc); + auto* pDstD3D12 = ValidatedCast(Attribs.pDst); + auto& CmdCtx = GetCmdContext(); + + 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); + + CmdCtx.AsGraphicsContext4().CopyRaytracingAccelerationStructure(pSrcD3D12->GetGPUAddress(), pDstD3D12->GetGPUAddress(), D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE); + ++m_State.NumCommands; + +#ifdef DILIGENT_DEVELOPMENT + pDstD3D12->UpdateVersion(); +#endif } void DeviceContextD3D12Impl::CopyTLAS(const CopyTLASAttribs& Attribs) @@ -2466,7 +2487,18 @@ void DeviceContextD3D12Impl::CopyTLAS(const CopyTLASAttribs& Attribs) if (!TDeviceContextBase::CopyTLAS(Attribs, 0)) return; - // AZ TODO + auto* pSrcD3D12 = ValidatedCast(Attribs.pSrc); + auto* pDstD3D12 = ValidatedCast(Attribs.pDst); + auto& CmdCtx = GetCmdContext(); + + 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); + + CmdCtx.AsGraphicsContext4().CopyRaytracingAccelerationStructure(pSrcD3D12->GetGPUAddress(), pDstD3D12->GetGPUAddress(), D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE); + ++m_State.NumCommands; } void DeviceContextD3D12Impl::TraceRays(const TraceRaysAttribs& Attribs) diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 405f6d4b..b1fe19fe 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -224,7 +224,7 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI } template -void GetShaderIdentifiers(ID3D12StateObject* pSO, +void GetShaderIdentifiers(ID3D12DeviceChild* pSO, const RayTracingPipelineStateCreateInfo& CreateInfo, const TNameToGroupIndexMap& NameToGroupIndex, Uint8* ShaderData) @@ -625,6 +625,8 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { + CreateLocalRootSignature(CreateInfo.RayTracingPipeline); + TShaderStages ShaderStages; std::vector Subobjects; DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10}; @@ -640,21 +642,21 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig.GetD3D12RootSignature()}; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot}); + D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {m_LocalRootSignature}; + if (m_LocalRootSignature) + Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE, &LocalRoot}); + D3D12_STATE_OBJECT_DESC RTPipelineDesc = {}; RTPipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE; RTPipelineDesc.NumSubobjects = static_cast(Subobjects.size()); RTPipelineDesc.pSubobjects = Subobjects.data(); - CComPtr pSO; - auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); - HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&pSO)); + HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&m_pd3d12PSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create ray tracing state object"); - m_pd3d12PSO = pSO; - - GetShaderIdentifiers(pSO, CreateInfo, m_pRayTracingPipelineData->NameToGroupIndex, m_pRayTracingPipelineData->Shaders); + GetShaderIdentifiers(m_pd3d12PSO, CreateInfo, m_pRayTracingPipelineData->NameToGroupIndex, m_pRayTracingPipelineData->Shaders); if (*m_Desc.Name != 0) { @@ -672,6 +674,35 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* } } +void PipelineStateD3D12Impl::CreateLocalRootSignature(const RayTracingPipelineDesc& Desc) +{ + // AZ TODO + /*if (Desc.ShaderRecordSize == 0) + return; + + D3D12_ROOT_SIGNATURE_DESC d3d12RootSignatureDesc = {}; + D3D12_ROOT_PARAMETER d3d12Params = {}; + + d3d12Params.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + d3d12Params.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + d3d12Params.Constants.Num32BitValues = Desc.ShaderRecordSize / 4; + d3d12Params.Constants.RegisterSpace = Desc.LocalRootRegisterSpace; + d3d12Params.Constants.ShaderRegister = 0; + + d3d12RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE; + d3d12RootSignatureDesc.NumParameters = 1; + d3d12RootSignatureDesc.pParameters = &d3d12Params; + + CComPtr signature; + auto hr = D3D12SerializeRootSignature(&d3d12RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr); + CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature"); + + auto pd3d12Device = GetDevice()->GetD3D12Device(); + + hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_LocalRootSignature)); + CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature");*/ +} + PipelineStateD3D12Impl::~PipelineStateD3D12Impl() { Destruct(); diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index d0db2201..e6af12c8 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -705,7 +705,7 @@ __forceinline void TransitionResource(CommandContext& Ctx, { VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); auto* pTLASD3D12 = Res.pObject.RawPtr(); - if (pTLASD3D12->IsInKnownState() && !pTLASD3D12->CheckState(RESOURCE_STATE_RAY_TRACING)) + if (pTLASD3D12->IsInKnownState()) Ctx.TransitionResource(pTLASD3D12, RESOURCE_STATE_RAY_TRACING); } break; diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp index d352caf0..d71d98b7 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp @@ -44,9 +44,6 @@ ShaderBindingTableD3D12Impl::ShaderBindingTableD3D12Impl(IReferenceCounters* bool bIsDeviceInternal) : TShaderBindingTableBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal} { - ValidateDesc(Desc); - - m_ShaderRecordStride = m_Desc.ShaderRecordSize + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; } ShaderBindingTableD3D12Impl::~ShaderBindingTableD3D12Impl() @@ -55,43 +52,6 @@ ShaderBindingTableD3D12Impl::~ShaderBindingTableD3D12Impl() IMPLEMENT_QUERY_INTERFACE(ShaderBindingTableD3D12Impl, IID_ShaderBindingTableD3D12, TShaderBindingTableBase) -void ShaderBindingTableD3D12Impl::ValidateDesc(const ShaderBindingTableDesc& Desc) const -{ - if (Desc.ShaderRecordSize + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES > D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE) - { - LOG_ERROR_AND_THROW("Description of Shader binding table '", (Desc.Name ? Desc.Name : ""), - "' is invalid: ShaderRecordSize is too big, max size is: ", D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE - D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES); - } -} - -void ShaderBindingTableD3D12Impl::Verify() const -{ - // AZ TODO -} - -void ShaderBindingTableD3D12Impl::Reset(const ShaderBindingTableDesc& Desc) -{ - m_RayGenShaderRecord.clear(); - m_MissShadersRecord.clear(); - m_CallableShadersRecord.clear(); - m_HitGroupsRecord.clear(); - m_Changed = true; - - try - { - ValidateShaderBindingTableDesc(Desc); - ValidateDesc(Desc); - } - catch (const std::runtime_error&) - { - // AZ TODO - return; - } - - m_Desc = Desc; - m_ShaderRecordStride = m_Desc.ShaderRecordSize + D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; -} - void ShaderBindingTableD3D12Impl::ResetHitGroups(Uint32 HitShadersPerInstance) { // AZ TODO -- cgit v1.2.3 From 5e81b867be771dc7f2add0d7b403af4aeaa744db Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 5 Nov 2020 03:43:05 +0300 Subject: Added AS copy with compacting. Added UB & SB size checks for Vulkan. Some improvements for ray tracing & tests. --- .../GraphicsEngineD3D12/include/CommandContext.hpp | 5 +- .../include/D3D12TypeConversions.hpp | 3 + .../include/DeviceContextD3D12Impl.hpp | 6 + .../include/RenderDeviceD3D12Impl.hpp | 3 + .../include/ShaderBindingTableD3D12Impl.hpp | 10 - .../interface/ShaderBindingTableD3D12.h | 10 - .../src/BottomLevelASD3D12Impl.cpp | 126 +++++++------ .../GraphicsEngineD3D12/src/CommandContext.cpp | 26 ++- .../src/CommandQueueD3D12Impl.cpp | 2 + .../src/D3D12TypeConversions.cpp | 46 ++++- .../src/DeviceContextD3D12Impl.cpp | 204 +++++++++++++++------ .../GraphicsEngineD3D12/src/FenceD3D12Impl.cpp | 6 +- .../src/ShaderBindingTableD3D12Impl.cpp | 97 ---------- .../src/TopLevelASD3D12Impl.cpp | 44 +++-- 14 files changed, 336 insertions(+), 252 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') 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(m_pCommandList.p)->EmitRaytracingAccelerationStructurePostbuildInfo(&Desc, NumSourceAccelerationStructures, pSourceAccelerationStructureData); + static_cast(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 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 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 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 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(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(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(d3d12BottomLevelPrebuildInfo.ScratchDataSizeInBytes); + m_ScratchSize.Update = static_cast(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(BottomLevelPrebuildInfo.ScratchDataSizeInBytes); - m_ScratchSize.Update = static_cast(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(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(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(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(~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 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(SrcTris.pVertexBuffer); - d3d12Tris.VertexFormat = TypeToDXGI_Format(SrcTris.VertexValueType, SrcTris.VertexComponentCount, SrcTris.VertexValueType < VT_FLOAT16); + auto* const pVB = ValidatedCast(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(SrcTris.pIndexBuffer); + auto* const pIB = ValidatedCast(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(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(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(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(pMappedInstances)[i]; + auto& d3d12Inst = static_cast(TmpSpace.CPUAddress)[i]; auto* const pBLASD12 = ValidatedCast(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(Attribs.pSrc); auto* pDstD3D12 = ValidatedCast(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(Attribs.pSrc); auto* pDstD3D12 = ValidatedCast(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(Attribs.pBLAS); + auto* pDestBuffD3D12 = ValidatedCast(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(Attribs.pTLAS); + auto* pDestBuffD3D12 = ValidatedCast(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(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(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(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(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()->GetGPUAddress(0, ValidatedCast(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(m_RayGenShaderRecord.size()), m_RayGenShaderRecord.data(), TransitionMode); - - if (m_MissShadersRecord.size()) - pContext->UpdateBuffer(m_pBuffer, MissShaderOffset, static_cast(m_MissShadersRecord.size()), m_MissShadersRecord.data(), TransitionMode); - - if (m_HitGroupsRecord.size()) - pContext->UpdateBuffer(m_pBuffer, HitGroupOffset, static_cast(m_HitGroupsRecord.size()), m_HitGroupsRecord.data(), TransitionMode); - - if (m_CallableShadersRecord.size()) - pContext->UpdateBuffer(m_pBuffer, CallableShadersOffset, static_cast(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(d3d12TopLevelPrebuildInfo.ScratchDataSizeInBytes); + m_ScratchSize.Update = static_cast(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(d3d12TopLevelPrebuildInfo.ScratchDataSizeInBytes); - m_ScratchSize.Update = static_cast(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() -- cgit v1.2.3 From 8e0218168e2f63812f658298b3571c53879a5780 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 5 Nov 2020 19:58:57 +0300 Subject: Added support for local root signature & shader record. Bug fix for ray tracing. --- .../include/DeviceContextD3D12Impl.hpp | 4 +- .../include/PipelineStateD3D12Impl.hpp | 11 ++-- .../GraphicsEngineD3D12/include/RootSignature.hpp | 19 ++++++ .../include/ShaderResourceLayoutD3D12.hpp | 3 +- .../src/DeviceContextD3D12Impl.cpp | 19 ++++-- .../src/PipelineStateD3D12Impl.cpp | 73 ++++++++-------------- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 53 ++++++++++++++++ .../src/ShaderResourceLayoutD3D12.cpp | 9 ++- 8 files changed, 127 insertions(+), 64 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp index a112b90e..1ef31842 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp @@ -262,10 +262,10 @@ public: virtual void DILIGENT_CALL_TYPE TransitionBufferState(IBuffer* pBuffer, D3D12_RESOURCE_STATES State) override final; /// Implementation of IDeviceContext::BuildBLAS() in Direct3D12 backend. - virtual void DILIGENT_CALL_TYPE BuildBLAS(const BLASBuildAttribs& Attribs) override final; + virtual void DILIGENT_CALL_TYPE BuildBLAS(const BuildBLASAttribs& Attribs) override final; /// Implementation of IDeviceContext::BuildTLAS() in Direct3D12 backend. - virtual void DILIGENT_CALL_TYPE BuildTLAS(const TLASBuildAttribs& Attribs) override final; + virtual void DILIGENT_CALL_TYPE BuildTLAS(const BuildTLASAttribs& Attribs) override final; /// Implementation of IDeviceContext::CopyBLAS() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE CopyBLAS(const CopyBLASAttribs& Attribs) override final; diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index f336c6ff..15eff0d9 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -139,16 +139,13 @@ private: using TShaderStages = std::vector; template - void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, InitPSODescType InitPSODesc); - void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages); + void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot, InitPSODescType InitPSODesc); + void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot); void Destruct(); - void CreateLocalRootSignature(const RayTracingPipelineDesc& Desc); - - CComPtr m_pd3d12PSO; - RootSignature m_RootSig; - CComPtr m_LocalRootSignature; + CComPtr m_pd3d12PSO; + RootSignature m_RootSig; // Must be defined before default SRB SRBMemoryAllocator m_SRBMemAllocator; diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index a6bf76b1..331c62e5 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -587,4 +587,23 @@ void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, } } + +class LocalRootSignature +{ +public: + LocalRootSignature(const char* pCBName, Uint32 ShaderRecordSize); + + bool SetOrMerge(const D3DShaderResourceAttribs& CB); + + ID3D12RootSignature* Create(ID3D12Device* pDevice); + +private: + static constexpr Uint32 InvalidBindPoint = ~0u; + + const char* m_pName = nullptr; + Uint32 m_BindPoint = InvalidBindPoint; + const Uint32 m_ShaderRecordSize = 0; + CComPtr m_LocalRootSignature; +}; + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index f7f2fa13..fe161157 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -140,7 +140,8 @@ public: const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes, Uint32 NumAllowedTypes, ShaderResourceCacheD3D12* pResourceCache, - class RootSignature* pRootSig); + class RootSignature* pRootSig, + class LocalRootSignature* pLocalRootSig); // clang-format off ShaderResourceLayoutD3D12 (const ShaderResourceLayoutD3D12&) = delete; diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 41de3a47..99e4156d 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2272,7 +2272,7 @@ void DeviceContextD3D12Impl::ResolveTextureSubresource(ITexture* CmdCtx.ResolveSubresource(pDstTexD3D12->GetD3D12Resource(), DstSubresIndex, pSrcTexD3D12->GetD3D12Resource(), SrcSubresIndex, DXGIFmt); } -void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) +void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) { if (!TDeviceContextBase::BuildBLAS(Attribs, 0)) return; @@ -2344,6 +2344,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) auto* const pTB = ValidatedCast(SrcTris.pTransformBuffer); d3d12Tris.Transform3x4 = pTB->GetGPUAddress() + SrcTris.TransformBufferOffset; + VERIFY_EXPR(d3d12Tris.Transform3x4 % D3D12_RAYTRACING_TRANSFORM3X4_BYTE_ALIGNMENT == 0); + TransitionOrVerifyBufferState(CmdCtx, *pTB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } else @@ -2378,6 +2380,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) d3d12AABs.AABBs.StartAddress = pBB->GetGPUAddress() + SrcBoxes.BoxOffset; d3d12AABs.AABBs.StrideInBytes = SrcBoxes.BoxStride; + VERIFY_EXPR(d3d12AABs.AABBs.StartAddress % D3D12_RAYTRACING_AABB_BYTE_ALIGNMENT == 0); + TransitionOrVerifyBufferState(CmdCtx, *pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } } @@ -2389,9 +2393,11 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) d3d12BuildASInputs.pGeometryDescs = Geometries.data(); d3d12BuildASDesc.DestAccelerationStructureData = pBLASD12->GetGPUAddress(); - d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress(); + d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress() + Attribs.ScratchBufferOffset; d3d12BuildASDesc.SourceAccelerationStructureData = 0; + VERIFY_EXPR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0); + CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr); ++m_State.NumCommands; @@ -2400,7 +2406,7 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs) #endif } -void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) +void DeviceContextD3D12Impl::BuildTLAS(const BuildTLASAttribs& Attribs) { if (!TDeviceContextBase::BuildTLAS(Attribs, 0)) return; @@ -2451,12 +2457,15 @@ void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs) d3d12BuildASInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(pTLASD12->GetDesc().Flags); d3d12BuildASInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; d3d12BuildASInputs.NumDescs = Attribs.InstanceCount; - d3d12BuildASInputs.InstanceDescs = pInstancesD12->GetGPUAddress(); + d3d12BuildASInputs.InstanceDescs = pInstancesD12->GetGPUAddress() + Attribs.InstanceBufferOffset; d3d12BuildASDesc.DestAccelerationStructureData = pTLASD12->GetGPUAddress(); - d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress(); + d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress() + Attribs.ScratchBufferOffset; d3d12BuildASDesc.SourceAccelerationStructureData = 0; + VERIFY_EXPR(d3d12BuildASInputs.InstanceDescs % D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT == 0); + VERIFY_EXPR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0); + CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr); ++m_State.NumCommands; } diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index b1fe19fe..1a12f25b 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -208,17 +208,18 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI VERIFY_EXPR(Uint32{CreateInfo.GeneralShaderCount} + Uint32{CreateInfo.TriangleHitShaderCount} + Uint32{CreateInfo.ProceduralHitShaderCount} == GroupIndex); - if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH) - LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than equal to ", D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH); + const Uint32 RecursionDepthLimit = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH - 1; + if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > RecursionDepthLimit) + LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than or equal to ", RecursionDepthLimit); auto& PipelineConfig = *TempPool.Construct(); - // for compatibility with Vulkan set minimal recursion depth to 1 - PipelineConfig.MaxTraceRecursionDepth = std::max(1, CreateInfo.RayTracingPipeline.MaxRecursionDepth); + // For compatibility with Vulkan set minimal recursion depth to one, zero means no tracing of rays at all. + PipelineConfig.MaxTraceRecursionDepth = CreateInfo.RayTracingPipeline.MaxRecursionDepth + 1; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG, &PipelineConfig}); auto& ShaderConfig = *TempPool.Construct(); - ShaderConfig.MaxAttributeSizeInBytes = D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES; - ShaderConfig.MaxPayloadSizeInBytes = 32; // AZ TODO + ShaderConfig.MaxAttributeSizeInBytes = CreateInfo.MaxAttributeSize == 0 ? D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES : CreateInfo.MaxAttributeSize; + ShaderConfig.MaxPayloadSizeInBytes = CreateInfo.MaxPayloadSize == 0 ? 32 : CreateInfo.MaxPayloadSize; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &ShaderConfig}); #undef LOG_PSO_ERROR_AND_THROW } @@ -304,6 +305,7 @@ size_t PipelineStateD3D12Impl::ShaderStageInfo::Count() const template void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, + LocalRootSignature* pLocalRoot, InitPSODescType InitPSODesc) { m_ResourceLayoutIndex.fill(-1); @@ -343,7 +345,7 @@ void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& Create // It is important to construct all objects before initializing them because if an exception is thrown, // destructors will be called for all objects - InitResourceLayouts(CreateInfo, ShaderStages); + InitResourceLayouts(CreateInfo, ShaderStages, pLocalRoot); } @@ -356,7 +358,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* try { TShaderStages ShaderStages; - InitInternalObjects(CreateInfo, ShaderStages, + InitInternalObjects(CreateInfo, ShaderStages, nullptr, [this](const GraphicsPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // { InitializePipelineDesc(CreateInfo, MemPool); @@ -567,7 +569,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* try { TShaderStages ShaderStages; - InitInternalObjects(CreateInfo, ShaderStages, + InitInternalObjects(CreateInfo, ShaderStages, nullptr, [this](const ComputePipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // { InitializePipelineDesc(CreateInfo, MemPool); @@ -625,12 +627,12 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { - CreateLocalRootSignature(CreateInfo.RayTracingPipeline); - + LocalRootSignature LocalRootSig{CreateInfo.pShaderRecordName, CreateInfo.RayTracingPipeline.ShaderRecordSize}; TShaderStages ShaderStages; std::vector Subobjects; DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10}; - InitInternalObjects(CreateInfo, ShaderStages, + + InitInternalObjects(CreateInfo, ShaderStages, &LocalRootSig, [&](const RayTracingPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // { TNameToGroupIndexMap NameToGroupIndex; @@ -639,11 +641,13 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* } // ); + auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig.GetD3D12RootSignature()}; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot}); - D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {m_LocalRootSignature}; - if (m_LocalRootSignature) + D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {LocalRootSig.Create(pd3d12Device)}; + if (LocalRoot.pLocalRootSignature) Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE, &LocalRoot}); D3D12_STATE_OBJECT_DESC RTPipelineDesc = {}; @@ -651,8 +655,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* RTPipelineDesc.NumSubobjects = static_cast(Subobjects.size()); RTPipelineDesc.pSubobjects = Subobjects.data(); - auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); - HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&m_pd3d12PSO)); + HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&m_pd3d12PSO)); if (FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create ray tracing state object"); @@ -674,35 +677,6 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* } } -void PipelineStateD3D12Impl::CreateLocalRootSignature(const RayTracingPipelineDesc& Desc) -{ - // AZ TODO - /*if (Desc.ShaderRecordSize == 0) - return; - - D3D12_ROOT_SIGNATURE_DESC d3d12RootSignatureDesc = {}; - D3D12_ROOT_PARAMETER d3d12Params = {}; - - d3d12Params.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; - d3d12Params.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; - d3d12Params.Constants.Num32BitValues = Desc.ShaderRecordSize / 4; - d3d12Params.Constants.RegisterSpace = Desc.LocalRootRegisterSpace; - d3d12Params.Constants.ShaderRegister = 0; - - d3d12RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE; - d3d12RootSignatureDesc.NumParameters = 1; - d3d12RootSignatureDesc.pParameters = &d3d12Params; - - CComPtr signature; - auto hr = D3D12SerializeRootSignature(&d3d12RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr); - CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature"); - - auto pd3d12Device = GetDevice()->GetD3D12Device(); - - hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_LocalRootSignature)); - CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature");*/ -} - PipelineStateD3D12Impl::~PipelineStateD3D12Impl() { Destruct(); @@ -749,7 +723,8 @@ IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipel void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, - TShaderStages& ShaderStages) + TShaderStages& ShaderStages, + LocalRootSignature* pLocalRoot) { auto pd3d12Device = GetDevice()->GetD3D12Device(); const auto& ResourceLayout = m_Desc.ResourceLayout; @@ -786,7 +761,8 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& nullptr, 0, nullptr, - &m_RootSig // + &m_RootSig, + pLocalRoot // ); const SHADER_RESOURCE_VARIABLE_TYPE StaticVarType[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; @@ -799,7 +775,8 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& StaticVarType, _countof(StaticVarType), m_pStaticResourceCaches + s, - nullptr // + nullptr, + pLocalRoot // ); m_pStaticVarManagers[s].Initialize( diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index e6af12c8..921a6e4c 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -1109,4 +1109,57 @@ void RootSignature::TransitionResources(ShaderResourceCacheD3D12& ResourceCache, ); } + +LocalRootSignature::LocalRootSignature(const char* pCBName, Uint32 ShaderRecordSize) : + m_pName{pCBName}, + m_ShaderRecordSize{ShaderRecordSize} +{ + VERIFY_EXPR((m_pName != nullptr) == (m_ShaderRecordSize > 0)); +} + +bool LocalRootSignature::SetOrMerge(const D3DShaderResourceAttribs& CB) +{ + if (m_ShaderRecordSize > 0 && + CB.GetInputType() == D3D_SIT_CBUFFER && + strcmp(m_pName, CB.Name) == 0) + { + if (m_BindPoint == InvalidBindPoint) + m_BindPoint = CB.BindPoint; + + VERIFY_EXPR(CB.BindCount == 1); + VERIFY_EXPR(m_BindPoint == CB.BindPoint); + + return true; + } + return false; +} + +ID3D12RootSignature* LocalRootSignature::Create(ID3D12Device* pDevice) +{ + if (m_ShaderRecordSize == 0 || m_BindPoint == InvalidBindPoint) + return nullptr; + + D3D12_ROOT_SIGNATURE_DESC d3d12RootSignatureDesc = {}; + D3D12_ROOT_PARAMETER d3d12Params = {}; + + d3d12Params.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + d3d12Params.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + d3d12Params.Constants.Num32BitValues = m_ShaderRecordSize / 4; + d3d12Params.Constants.RegisterSpace = 0; + d3d12Params.Constants.ShaderRegister = m_BindPoint; + + d3d12RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE; + d3d12RootSignatureDesc.NumParameters = 1; + d3d12RootSignatureDesc.pParameters = &d3d12Params; + + CComPtr signature; + auto hr = D3D12SerializeRootSignature(&d3d12RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr); + CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature"); + + hr = pDevice->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_LocalRootSignature)); + CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature"); + + return m_LocalRootSignature; +} + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index bfc8693a..6218fbd3 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -135,7 +135,8 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes, Uint32 NumAllowedTypes, ShaderResourceCacheD3D12* pResourceCache, - RootSignature* pRootSig) + RootSignature* pRootSig, + LocalRootSignature* pLocalRootSig) { m_pd3d12Device = pd3d12Device; @@ -170,6 +171,9 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* auto VarType = pResources->FindVariableType(Res, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) { + if (pLocalRootSig && pLocalRootSig->SetOrMerge(Res)) + return; + bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, InvalidResourceIndex).second; if (IsUniqueName) { @@ -313,6 +317,9 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* pResources->ProcessResources( [&](const D3DShaderResourceAttribs& CB, Uint32) // { + if (pLocalRootSig && pLocalRootSig->SetOrMerge(CB)) + return; + auto VarType = pResources->FindVariableType(CB, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) AddResource(CB, CachedResourceType::CBV, VarType); -- cgit v1.2.3 From 569fb5a399cdb1cb39fb10d8db1fd78ab56f6c9e Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 5 Nov 2020 17:31:31 -0800 Subject: A number of minor updates/fixes --- .../include/RenderDeviceD3D12Impl.hpp | 20 +++++++++++++------- .../GraphicsEngineD3D12/include/RootSignature.hpp | 2 +- .../interface/ShaderBindingTableD3D12.h | 4 ++++ .../GraphicsEngineD3D12/src/CommandContext.cpp | 4 ++-- .../src/D3D12TypeConversions.cpp | 8 ++++---- .../src/DeviceContextD3D12Impl.cpp | 11 +++++++---- .../src/RenderDeviceD3D12Impl.cpp | 22 +++++++++++----------- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 6 +++--- .../GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp | 2 +- .../src/TopLevelASD3D12Impl.cpp | 2 +- 10 files changed, 47 insertions(+), 34 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 619368fd..ad48b876 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -175,14 +175,20 @@ public: ID3D12Device2* GetD3D12Device2(); ID3D12Device5* GetD3D12Device5(); - ShaderVersion GetMaxShaderModel() const; - D3D_FEATURE_LEVEL GetD3DFeatureLevel() const; + struct Properties + { + const Uint32 ShaderGroupHandleSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; + const Uint32 MaxShaderRecordStride = D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE; + const Uint32 ShaderGroupBaseAlignment = D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT; + const Uint32 MaxDrawMeshTasksCount = 64000; - 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; } + ShaderVersion MaxShaderVersion; + }; - static Uint32 GetMaxDrawMeshTasksCount() { return 64000; } + const Properties& GetProperties() const + { + return m_Properties; + } private: template @@ -217,7 +223,7 @@ private: QueryManagerD3D12 m_QueryMgr; - D3D_SHADER_MODEL m_MaxShaderModel = D3D_SHADER_MODEL_5_1; + Properties m_Properties; std::unique_ptr m_pDxCompiler; }; diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index 331c62e5..d74a7b0c 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -603,7 +603,7 @@ private: const char* m_pName = nullptr; Uint32 m_BindPoint = InvalidBindPoint; const Uint32 m_ShaderRecordSize = 0; - CComPtr m_LocalRootSignature; + CComPtr m_pd3d12RootSignature; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h index 18ebd984..827df3b7 100644 --- a/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/ShaderBindingTableD3D12.h @@ -47,12 +47,16 @@ static const INTERFACE_ID IID_ShaderBindingTableD3D12 = IShaderBindingTableD3D12Methods ShaderBindingTableD3D12 // clang-format off +#if DILIGENT_CPP_INTERFACE // Empty structs are not allwed in C + /// Exposes Direct3D12-specific functionality of a shader binding table object. DILIGENT_BEGIN_INTERFACE(IShaderBindingTableD3D12, IShaderBindingTable) { }; DILIGENT_END_INTERFACE +#endif + #include "../../../Primitives/interface/UndefInterfaceHelperMacros.h" #if DILIGENT_C_INTERFACE diff --git a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp index 1e301bb2..fdb93efb 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp @@ -224,8 +224,8 @@ 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. + // RESOURCE_STATE_UNORDERED_ACCESS and RESOURCE_STATE_BUILD_AS_WRITE are converted to D3D12_RESOURCE_STATE_UNORDERED_ACCESS. + // UAV barrier must be inserted between D3D12_RESOURCE_STATE_UNORDERED_ACCESS resource usages. 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); diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 1f1f621c..12ece1da 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -609,18 +609,18 @@ DXGI_FORMAT ValueTypeToIndexType(VALUE_TYPE IndexType) D3D12_RAYTRACING_GEOMETRY_FLAGS GeometryFlagsToD3D12RTGeometryFlags(RAYTRACING_GEOMETRY_FLAGS Flags) { - static_assert(RAYTRACING_GEOMETRY_FLAGS_LAST == RAYTRACING_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION, + static_assert(RAYTRACING_GEOMETRY_FLAGS_LAST == RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANY_HIT_INVOCATION, "Please update the switch below to handle the new ray tracing geometry flag"); D3D12_RAYTRACING_GEOMETRY_FLAGS Result = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; - while (Flags != RAYTRACING_GEOMETRY_NONE) + while (Flags != RAYTRACING_GEOMETRY_FLAG_NONE) { auto FlagBit = static_cast(1 << PlatformMisc::GetLSB(Uint32{Flags})); switch (FlagBit) { // clang-format off - case RAYTRACING_GEOMETRY_OPAQUE: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE; break; - case RAYTRACING_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION; break; + case RAYTRACING_GEOMETRY_FLAG_OPAQUE: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE; break; + case RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANY_HIT_INVOCATION: Result |= D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION; break; // clang-format on default: UNEXPECTED("unknown geometry flag"); } diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 99e4156d..125c4d81 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2380,7 +2380,7 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) d3d12AABs.AABBs.StartAddress = pBB->GetGPUAddress() + SrcBoxes.BoxOffset; d3d12AABs.AABBs.StrideInBytes = SrcBoxes.BoxStride; - VERIFY_EXPR(d3d12AABs.AABBs.StartAddress % D3D12_RAYTRACING_AABB_BYTE_ALIGNMENT == 0); + DEV_CHECK_ERR(d3d12AABs.AABBs.StartAddress % D3D12_RAYTRACING_AABB_BYTE_ALIGNMENT == 0, "AABB start address is not properly aligned"); TransitionOrVerifyBufferState(CmdCtx, *pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } @@ -2396,7 +2396,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress() + Attribs.ScratchBufferOffset; d3d12BuildASDesc.SourceAccelerationStructureData = 0; - VERIFY_EXPR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0); + DEV_CHECK_ERR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0, + "Scratch data address is not properly aligned"); CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr); ++m_State.NumCommands; @@ -2463,8 +2464,10 @@ void DeviceContextD3D12Impl::BuildTLAS(const BuildTLASAttribs& Attribs) d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress() + Attribs.ScratchBufferOffset; d3d12BuildASDesc.SourceAccelerationStructureData = 0; - VERIFY_EXPR(d3d12BuildASInputs.InstanceDescs % D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT == 0); - VERIFY_EXPR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0); + DEV_CHECK_ERR(d3d12BuildASInputs.InstanceDescs % D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT == 0, + "Instance data address is not properly aligned"); + DEV_CHECK_ERR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0, + "Scratch data address is not properly algined"); CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr); ++m_State.NumCommands; diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index f8f545e7..9ea84f06 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -68,12 +68,8 @@ static CComPtr DXGIAdapterFromD3D12Device(ID3D12Device* pd3d12Dev return nullptr; } -ShaderVersion RenderDeviceD3D12Impl::GetMaxShaderModel() const -{ - return ShaderVersion{static_cast((m_MaxShaderModel >> 4) & 0xF), static_cast(m_MaxShaderModel & 0xF)}; -} -D3D_FEATURE_LEVEL RenderDeviceD3D12Impl::GetD3DFeatureLevel() const +static D3D_FEATURE_LEVEL GetD3DFeatureLevel(ID3D12Device* pd3d12Device) { D3D_FEATURE_LEVEL FeatureLevels[] = { @@ -88,7 +84,7 @@ D3D_FEATURE_LEVEL RenderDeviceD3D12Impl::GetD3DFeatureLevel() const FeatureLevelsData.pFeatureLevelsRequested = FeatureLevels; FeatureLevelsData.NumFeatureLevels = _countof(FeatureLevels); - m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &FeatureLevelsData, sizeof(FeatureLevelsData)); + pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &FeatureLevelsData, sizeof(FeatureLevelsData)); return FeatureLevelsData.MaxSupportedFeatureLevel; } @@ -172,7 +168,7 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo try { m_DeviceCaps.DevType = RENDER_DEVICE_TYPE_D3D12; - auto FeatureLevel = GetD3DFeatureLevel(); + auto FeatureLevel = GetD3DFeatureLevel(m_pd3d12Device); switch (FeatureLevel) { case D3D_FEATURE_LEVEL_12_0: @@ -210,10 +206,11 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo m_DeviceCaps.Features.VertexPipelineUAVWritesAndAtomics = DEVICE_FEATURE_STATE_ENABLED; // Detect maximum shader model. + D3D_SHADER_MODEL MaxShaderModel = D3D_SHADER_MODEL_5_1; { // Direct3D12 supports shader model 5.1 on all feature levels. // https://docs.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels#feature-level-support - m_MaxShaderModel = D3D_SHADER_MODEL_5_1; + MaxShaderModel = D3D_SHADER_MODEL_5_1; // Header may not have constants for D3D_SHADER_MODEL_6_1 and above. const D3D_SHADER_MODEL Models[] = // @@ -231,13 +228,16 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo D3D12_FEATURE_DATA_SHADER_MODEL ShaderModel = {Model}; if (SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &ShaderModel, sizeof(ShaderModel)))) { - m_MaxShaderModel = ShaderModel.HighestShaderModel; + MaxShaderModel = ShaderModel.HighestShaderModel; break; } } - LOG_INFO_MESSAGE("Max device shader model: ", (m_MaxShaderModel >> 4) & 0xF, '_', m_MaxShaderModel & 0xF); + LOG_INFO_MESSAGE("Max device shader model: ", (MaxShaderModel >> 4) & 0xF, '_', MaxShaderModel & 0xF); } + m_Properties.MaxShaderVersion.Major = static_cast((MaxShaderModel >> 4) & 0xF); + m_Properties.MaxShaderVersion.Minor = static_cast(MaxShaderModel & 0xF); + // Check if mesh shader is supported. bool MeshShadersSupported = false; #ifdef D3D12_H_HAS_MESH_SHADER @@ -248,7 +248,7 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &FeatureData, sizeof(FeatureData))) && FeatureData.MeshShaderTier != D3D12_MESH_SHADER_TIER_NOT_SUPPORTED; - MeshShadersSupported = (m_MaxShaderModel >= D3D_SHADER_MODEL_6_5 && MeshShadersSupported); + MeshShadersSupported = (MaxShaderModel >= D3D_SHADER_MODEL_6_5 && MeshShadersSupported); } #else if (EngineCI.Features.MeshShaders == DEVICE_FEATURE_STATE_ENABLED) diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 921a6e4c..8a8bfd4d 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -1156,10 +1156,10 @@ ID3D12RootSignature* LocalRootSignature::Create(ID3D12Device* pDevice) auto hr = D3D12SerializeRootSignature(&d3d12RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr); CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature"); - hr = pDevice->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_LocalRootSignature)); - CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature"); + hr = pDevice->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_pd3d12RootSignature)); + CHECK_D3D_RESULT_THROW(hr, "Failed to create D3D12 root signature"); - return m_LocalRootSignature; + return m_pd3d12RootSignature; } } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp index a356d73a..52c39f23 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp @@ -59,7 +59,7 @@ static ShaderVersion GetD3D12ShaderModel(RenderDeviceD3D12Impl* pDevice, const S CompilerSM = ShaderVersion{5, 1}; } - ShaderVersion DeviceSM = pDevice->GetMaxShaderModel(); + ShaderVersion DeviceSM = pDevice->GetProperties().MaxShaderVersion; ShaderVersion MaxSupportedSM = DeviceSM.Major == CompilerSM.Major ? (DeviceSM.Minor < CompilerSM.Minor ? DeviceSM : CompilerSM) : diff --git a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp index 2d087d08..ad26155a 100644 --- a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp @@ -112,7 +112,7 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte d3d12SRVDesc.RaytracingAccelerationStructure.Location = GetGPUAddress(); pd3d12Device->CreateShaderResourceView(nullptr, &d3d12SRVDesc, m_DescriptorHandle.GetCpuHandle()); - VERIFY_EXPR(GetGPUAddress() % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0); + DEV_CHECK_ERR(GetGPUAddress() % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0, "GPU virtual address is expect to be at least 256-byte aligned"); SetState(RESOURCE_STATE_BUILD_AS_READ); } -- cgit v1.2.3 From db5cfe224b9ff00234b29ff097262bc7377b90c4 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 5 Nov 2020 21:43:17 -0800 Subject: Refactored BufferBase --- Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp index 8e84b844..106c2336 100644 --- a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp @@ -348,7 +348,7 @@ void BufferD3D12Impl::CreateViewInternal(const BufferViewDesc& OrigViewDesc, IBu void BufferD3D12Impl::CreateUAV(BufferViewDesc& UAVDesc, D3D12_CPU_DESCRIPTOR_HANDLE UAVDescriptor) { - CorrectBufferViewDesc(UAVDesc); + ValidateAndCorrectBufferViewDesc(m_Desc, UAVDesc); D3D12_UNORDERED_ACCESS_VIEW_DESC D3D12_UAVDesc; BufferViewDesc_to_D3D12_UAV_DESC(m_Desc, UAVDesc, D3D12_UAVDesc); @@ -359,7 +359,7 @@ void BufferD3D12Impl::CreateUAV(BufferViewDesc& UAVDesc, D3D12_CPU_DESCRIPTOR_HA void BufferD3D12Impl::CreateSRV(struct BufferViewDesc& SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVDescriptor) { - CorrectBufferViewDesc(SRVDesc); + ValidateAndCorrectBufferViewDesc(m_Desc, SRVDesc); D3D12_SHADER_RESOURCE_VIEW_DESC D3D12_SRVDesc; BufferViewDesc_to_D3D12_SRV_DESC(m_Desc, SRVDesc, D3D12_SRVDesc); -- cgit v1.2.3 From 4de58520987882e1daa162e31cabca3f334c20a8 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 5 Nov 2020 22:46:17 -0800 Subject: Refactored TextureBase --- Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp index 22829770..1c15b351 100644 --- a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp @@ -424,7 +424,7 @@ void TextureD3D12Impl::CreateViewInternal(const struct TextureViewDesc& ViewDesc VERIFY(&TexViewAllocator == &m_dbgTexViewObjAllocator, "Texture view allocator does not match allocator provided during texture initialization"); auto UpdatedViewDesc = ViewDesc; - CorrectTextureViewDesc(UpdatedViewDesc); + ValidatedAndCorrectTextureViewDesc(m_Desc, UpdatedViewDesc); DescriptorHeapAllocation ViewDescriptor; switch (ViewDesc.ViewType) -- cgit v1.2.3 From 44bf7cf539949a6f26862201729fce5000b493f0 Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 6 Nov 2020 20:25:14 -0800 Subject: Few minor updates to TLAS and BLAS implementations --- .../include/BottomLevelASD3D12Impl.hpp | 8 +------- .../include/TopLevelASD3D12Impl.hpp | 7 +------ .../src/BottomLevelASD3D12Impl.cpp | 20 ++++++++------------ .../GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp | 4 ---- 4 files changed, 10 insertions(+), 29 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp index b631bdcc..c16d8473 100644 --- a/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp @@ -51,10 +51,7 @@ public: bool bIsDeviceInternal = false); ~BottomLevelASD3D12Impl(); - virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IBottomLevelAS::GetScratchBufferSizes() in DirectX 12 backend. - virtual ScratchBufferSizes DILIGENT_CALL_TYPE GetScratchBufferSizes() const override { return m_ScratchSize; } + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_BottomLevelASD3D12, TBottomLevelASBase); /// Implementation of IBottomLevelASD3D12::GetD3D12BLAS(). virtual ID3D12Resource* DILIGENT_CALL_TYPE GetD3D12BLAS() override final { return GetD3D12Resource(); } @@ -66,9 +63,6 @@ public: { return GetD3D12Resource()->GetGPUVirtualAddress(); } - -private: - ScratchBufferSizes m_ScratchSize; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp index c61ab368..3fa15e5e 100644 --- a/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp @@ -52,10 +52,7 @@ public: bool bIsDeviceInternal = false); ~TopLevelASD3D12Impl(); - virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of ITopLevelASD3D12::GetScratchBufferSizes() in DirectX 12 backend. - virtual ScratchBufferSizes DILIGENT_CALL_TYPE GetScratchBufferSizes() const override { return m_ScratchSize; } + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_TopLevelASD3D12, TTopLevelASBase); /// Implementation of ITopLevelASD3D12D3D12::GetD3D12TLAS(). virtual ID3D12Resource* DILIGENT_CALL_TYPE GetD3D12TLAS() override final { return GetD3D12Resource(); } @@ -75,8 +72,6 @@ public: } private: - ScratchBufferSizes m_ScratchSize; - // Allocation in a CPU-only descriptor heap DescriptorHeapAllocation m_DescriptorHandle; }; diff --git a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp index 1fc9f876..02e45b0e 100644 --- a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp @@ -28,11 +28,9 @@ #include "pch.h" #include "BottomLevelASD3D12Impl.hpp" #include "RenderDeviceD3D12Impl.hpp" -#include "DeviceContextD3D12Impl.hpp" #include "D3D12TypeConversions.hpp" #include "GraphicsAccessories.hpp" #include "DXGITypeConversions.hpp" -#include "EngineMemory.h" #include "StringTools.hpp" namespace Diligent @@ -55,16 +53,16 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef { D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO d3d12BottomLevelPrebuildInfo = {}; D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS d3d12BottomLevelInputs = {}; - std::vector Geometries; + std::vector d3d12Geometries; if (m_Desc.pTriangles != nullptr) { - Geometries.resize(m_Desc.TriangleCount); + d3d12Geometries.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]; + auto& dst = d3d12Geometries[i]; dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; dst.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; @@ -83,12 +81,12 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef } else if (m_Desc.pBoxes != nullptr) { - Geometries.resize(m_Desc.BoxCount); + d3d12Geometries.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]; + auto& dst = d3d12Geometries[i]; dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS; dst.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; @@ -105,13 +103,13 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef UNEXPECTED("Either pTriangles or pBoxes must not be null"); } - VERIFY_EXPR(Geometries.size() <= D3D12_RAYTRACING_MAX_GEOMETRIES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE); + VERIFY_EXPR(d3d12Geometries.size() <= D3D12_RAYTRACING_MAX_GEOMETRIES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE); 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(Geometries.size()); + d3d12BottomLevelInputs.pGeometryDescs = d3d12Geometries.data(); + d3d12BottomLevelInputs.NumDescs = static_cast(d3d12Geometries.size()); pd3d12Device->GetRaytracingAccelerationStructurePrebuildInfo(&d3d12BottomLevelInputs, &d3d12BottomLevelPrebuildInfo); if (d3d12BottomLevelPrebuildInfo.ResultDataMaxSizeInBytes == 0) @@ -165,6 +163,4 @@ BottomLevelASD3D12Impl::~BottomLevelASD3D12Impl() pDeviceD3D12Impl->SafeReleaseDeviceObject(std::move(m_pd3d12Resource), m_Desc.CommandQueueMask); } -IMPLEMENT_QUERY_INTERFACE(BottomLevelASD3D12Impl, IID_BottomLevelASD3D12, TBottomLevelASBase) - } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp index ad26155a..51dadde1 100644 --- a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp @@ -28,11 +28,9 @@ #include "pch.h" #include "TopLevelASD3D12Impl.hpp" #include "RenderDeviceD3D12Impl.hpp" -#include "DeviceContextD3D12Impl.hpp" #include "D3D12TypeConversions.hpp" #include "GraphicsAccessories.hpp" #include "DXGITypeConversions.hpp" -#include "EngineMemory.h" #include "StringTools.hpp" namespace Diligent @@ -124,6 +122,4 @@ TopLevelASD3D12Impl::~TopLevelASD3D12Impl() pDeviceD3D12Impl->SafeReleaseDeviceObject(std::move(m_pd3d12Resource), m_Desc.CommandQueueMask); } -IMPLEMENT_QUERY_INTERFACE(TopLevelASD3D12Impl, IID_TopLevelASD3D12, TTopLevelASBase) - } // namespace Diligent -- cgit v1.2.3 From 01aad5aee954e7c1e9494dcc98af8eba3901e3d8 Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 6 Nov 2020 22:53:33 -0800 Subject: Updated handling of BLASTriangleDesc::VertexValueType and VertexComponentCount --- .../src/BottomLevelASD3D12Impl.cpp | 25 ++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp index 02e45b0e..5bb182dc 100644 --- a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp @@ -68,12 +68,25 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef 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; + + // Vertex format must be one of the following (https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_raytracing_geometry_triangles_desc): + // * DXGI_FORMAT_R32G32_FLOAT - third component is assumed 0 + // * DXGI_FORMAT_R32G32B32_FLOAT + // * DXGI_FORMAT_R16G16_FLOAT - third component is assumed 0 + // * DXGI_FORMAT_R16G16B16A16_FLOAT - A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes. + // * DXGI_FORMAT_R16G16_SNORM - third component is assumed 0 + // * DXGI_FORMAT_R16G16B16A16_SNORM - A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes. + dst.Triangles.VertexFormat = TypeToDXGI_Format(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); + VERIFY(dst.Triangles.VertexFormat == DXGI_FORMAT_R32G32_FLOAT || dst.Triangles.VertexFormat == DXGI_FORMAT_R32G32B32_FLOAT || + dst.Triangles.VertexFormat == DXGI_FORMAT_R16G16_FLOAT || dst.Triangles.VertexFormat == DXGI_FORMAT_R16G16B16A16_FLOAT || + dst.Triangles.VertexFormat == DXGI_FORMAT_R16G16_SNORM || dst.Triangles.VertexFormat == DXGI_FORMAT_R16G16B16A16_SNORM, + "Unsupported vertex format"); + + 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; } -- cgit v1.2.3 From bc359543f2023a325957cdff9153eee11c2af501 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 7 Nov 2020 00:34:35 -0800 Subject: BLASTriangleDesc: fixed VertexValueType and VertexComponentCount handling --- .../src/BottomLevelASD3D12Impl.cpp | 38 +++++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp index 5bb182dc..1aecb097 100644 --- a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp @@ -76,11 +76,39 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef // * DXGI_FORMAT_R16G16B16A16_FLOAT - A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes. // * DXGI_FORMAT_R16G16_SNORM - third component is assumed 0 // * DXGI_FORMAT_R16G16B16A16_SNORM - A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes. - dst.Triangles.VertexFormat = TypeToDXGI_Format(src.VertexValueType, src.VertexComponentCount, src.VertexValueType < VT_FLOAT16); - VERIFY(dst.Triangles.VertexFormat == DXGI_FORMAT_R32G32_FLOAT || dst.Triangles.VertexFormat == DXGI_FORMAT_R32G32B32_FLOAT || - dst.Triangles.VertexFormat == DXGI_FORMAT_R16G16_FLOAT || dst.Triangles.VertexFormat == DXGI_FORMAT_R16G16B16A16_FLOAT || - dst.Triangles.VertexFormat == DXGI_FORMAT_R16G16_SNORM || dst.Triangles.VertexFormat == DXGI_FORMAT_R16G16B16A16_SNORM, - "Unsupported vertex format"); + // Note that DXGI_FORMAT_R16G16B16A16_FLOAT and DXGI_FORMAT_R16G16B16A16_SNORM are workarounds for missing 16-bit 3-component DXGI formats + switch (src.VertexValueType) + { + case VT_FLOAT16: + switch (src.VertexComponentCount) + { + case 2: dst.Triangles.VertexFormat = DXGI_FORMAT_R16G16_FLOAT; break; + case 3: dst.Triangles.VertexFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; break; + default: UNEXPECTED("Only 2 and 3 component vertex formats are expected"); + } + break; + + case VT_FLOAT32: + switch (src.VertexComponentCount) + { + case 2: dst.Triangles.VertexFormat = DXGI_FORMAT_R32G32_FLOAT; break; + case 3: dst.Triangles.VertexFormat = DXGI_FORMAT_R32G32B32_FLOAT; break; + default: UNEXPECTED("Only 2 and 3 component vertex formats are expected"); + } + break; + + case VT_INT16: + switch (src.VertexComponentCount) + { + case 2: dst.Triangles.VertexFormat = DXGI_FORMAT_R16G16_SNORM; break; + case 3: dst.Triangles.VertexFormat = DXGI_FORMAT_R16G16B16A16_SNORM; break; + default: UNEXPECTED("Only 2 and 3 component vertex formats are expected"); + } + break; + + default: + UNEXPECTED(GetValueTypeString(src.VertexValueType), " is not a valid vertex component type"); + } dst.Triangles.VertexCount = src.MaxVertexCount; dst.Triangles.IndexCount = src.IndexType == VT_UNDEFINED ? 0 : src.MaxPrimitiveCount * 3; -- cgit v1.2.3 From fee27bd45c5451d1a3b7ef35f1c83f45f7e60f7c Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 7 Nov 2020 09:35:22 -0800 Subject: Corrected ray rtacing vertex format handling in D3D12 --- .../include/D3D12TypeConversions.hpp | 2 + .../src/BottomLevelASD3D12Impl.cpp | 44 +----------------- .../src/D3D12TypeConversions.cpp | 54 ++++++++++++++++++++++ .../src/DeviceContextD3D12Impl.cpp | 3 +- 4 files changed, 60 insertions(+), 43 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp index 8b1818f2..774fefcd 100644 --- a/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp +++ b/Graphics/GraphicsEngineD3D12/include/D3D12TypeConversions.hpp @@ -86,4 +86,6 @@ D3D12_RAYTRACING_INSTANCE_FLAGS InstanceFlagsToD3D12RTInstanceFlags(RAYTRACING_I D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS BuildASFlagsToD3D12ASBuildFlags(RAYTRACING_BUILD_AS_FLAGS Flags); D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE CopyASModeToD3D12ASCopyMode(COPY_AS_MODE Mode); +DXGI_FORMAT TypeToRayTracingVertexFormat(VALUE_TYPE ValueType, Uint32 ComponentCount); + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp index 1aecb097..fa82ee9a 100644 --- a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp @@ -68,48 +68,8 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef dst.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; dst.Triangles.VertexBuffer.StartAddress = 0; dst.Triangles.VertexBuffer.StrideInBytes = 0; - - // Vertex format must be one of the following (https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_raytracing_geometry_triangles_desc): - // * DXGI_FORMAT_R32G32_FLOAT - third component is assumed 0 - // * DXGI_FORMAT_R32G32B32_FLOAT - // * DXGI_FORMAT_R16G16_FLOAT - third component is assumed 0 - // * DXGI_FORMAT_R16G16B16A16_FLOAT - A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes. - // * DXGI_FORMAT_R16G16_SNORM - third component is assumed 0 - // * DXGI_FORMAT_R16G16B16A16_SNORM - A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes. - // Note that DXGI_FORMAT_R16G16B16A16_FLOAT and DXGI_FORMAT_R16G16B16A16_SNORM are workarounds for missing 16-bit 3-component DXGI formats - switch (src.VertexValueType) - { - case VT_FLOAT16: - switch (src.VertexComponentCount) - { - case 2: dst.Triangles.VertexFormat = DXGI_FORMAT_R16G16_FLOAT; break; - case 3: dst.Triangles.VertexFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; break; - default: UNEXPECTED("Only 2 and 3 component vertex formats are expected"); - } - break; - - case VT_FLOAT32: - switch (src.VertexComponentCount) - { - case 2: dst.Triangles.VertexFormat = DXGI_FORMAT_R32G32_FLOAT; break; - case 3: dst.Triangles.VertexFormat = DXGI_FORMAT_R32G32B32_FLOAT; break; - default: UNEXPECTED("Only 2 and 3 component vertex formats are expected"); - } - break; - - case VT_INT16: - switch (src.VertexComponentCount) - { - case 2: dst.Triangles.VertexFormat = DXGI_FORMAT_R16G16_SNORM; break; - case 3: dst.Triangles.VertexFormat = DXGI_FORMAT_R16G16B16A16_SNORM; break; - default: UNEXPECTED("Only 2 and 3 component vertex formats are expected"); - } - break; - - default: - UNEXPECTED(GetValueTypeString(src.VertexValueType), " is not a valid vertex component type"); - } - + dst.Triangles.VertexFormat = TypeToRayTracingVertexFormat(src.VertexValueType, src.VertexComponentCount); + VERIFY(dst.Triangles.VertexFormat != DXGI_FORMAT_UNKNOWN, "Unsupported combination of vertex value type and component count"); dst.Triangles.VertexCount = src.MaxVertexCount; dst.Triangles.IndexCount = src.IndexType == VT_UNDEFINED ? 0 : src.MaxPrimitiveCount * 3; dst.Triangles.IndexFormat = ValueTypeToIndexType(src.IndexType); diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 12ece1da..e9ae5af6 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -695,4 +695,58 @@ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE CopyASModeToD3D12ASCopyMode(CO } } +DXGI_FORMAT TypeToRayTracingVertexFormat(VALUE_TYPE ValueType, Uint32 ComponentCount) +{ + // Vertex format must be one of the following (https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_raytracing_geometry_triangles_desc): + // * DXGI_FORMAT_R32G32_FLOAT - third component is assumed 0 + // * DXGI_FORMAT_R32G32B32_FLOAT + // * DXGI_FORMAT_R16G16_FLOAT - third component is assumed 0 + // * DXGI_FORMAT_R16G16B16A16_FLOAT - A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes. + // * DXGI_FORMAT_R16G16_SNORM - third component is assumed 0 + // * DXGI_FORMAT_R16G16B16A16_SNORM - A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes. + // Note that DXGI_FORMAT_R16G16B16A16_FLOAT and DXGI_FORMAT_R16G16B16A16_SNORM are merely workarounds for missing 16-bit 3-component DXGI formats + switch (ValueType) + { + case VT_FLOAT16: + switch (ComponentCount) + { + case 2: return DXGI_FORMAT_R16G16_FLOAT; + case 3: return DXGI_FORMAT_R16G16B16A16_FLOAT; + + default: + UNEXPECTED("Only 2 and 3 component vertex formats are expected"); + return DXGI_FORMAT_UNKNOWN; + } + break; + + case VT_FLOAT32: + switch (ComponentCount) + { + case 2: return DXGI_FORMAT_R32G32_FLOAT; + case 3: return DXGI_FORMAT_R32G32B32_FLOAT; + + default: + UNEXPECTED("Only 2 and 3 component vertex formats are expected"); + return DXGI_FORMAT_UNKNOWN; + } + break; + + case VT_INT16: + switch (ComponentCount) + { + case 2: return DXGI_FORMAT_R16G16_SNORM; + case 3: return DXGI_FORMAT_R16G16B16A16_SNORM; + + default: + UNEXPECTED("Only 2 and 3 component vertex formats are expected"); + return DXGI_FORMAT_UNKNOWN; + } + break; + + default: + UNEXPECTED(GetValueTypeString(ValueType), " is not a valid vertex component type"); + return DXGI_FORMAT_UNKNOWN; + } +} + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 125c4d81..c78976ea 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2315,7 +2315,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) auto* const pVB = ValidatedCast(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.VertexFormat = TypeToRayTracingVertexFormat(TriDesc.VertexValueType, TriDesc.VertexComponentCount); + VERIFY(d3d12Tris.VertexFormat != DXGI_FORMAT_UNKNOWN, "Unsupported combination of vertex value type and component count"); d3d12Tris.VertexCount = SrcTris.VertexCount; d3d12Tris.VertexBuffer.StartAddress = pVB->GetGPUAddress() + SrcTris.VertexOffset; d3d12Tris.VertexBuffer.StrideInBytes = SrcTris.VertexStride; -- cgit v1.2.3 From 0f35896a60c4de02ccfc91ace18bcef4450fa4d9 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Sat, 7 Nov 2020 22:34:49 +0300 Subject: Added ability to update AS. --- .../include/BottomLevelASD3D12Impl.hpp | 6 +- .../include/RenderDeviceD3D12Impl.hpp | 14 ++- .../include/ShaderBindingTableD3D12Impl.hpp | 9 +- .../include/ShaderResourceLayoutD3D12.hpp | 2 + .../include/TopLevelASD3D12Impl.hpp | 6 +- .../interface/PipelineStateD3D12.h | 1 + .../interface/RenderDeviceD3D12.h | 34 ++++++ .../src/BottomLevelASD3D12Impl.cpp | 26 +++-- .../src/DeviceContextD3D12Impl.cpp | 114 +++++++++++++-------- .../src/PipelineStateD3D12Impl.cpp | 20 ++-- .../src/RenderDeviceD3D12Impl.cpp | 45 ++++++-- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 4 +- .../src/ShaderBindingTableD3D12Impl.cpp | 10 -- .../src/ShaderResourceLayoutD3D12.cpp | 17 +++ .../src/TopLevelASD3D12Impl.cpp | 16 ++- 15 files changed, 233 insertions(+), 91 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp index c16d8473..12118e18 100644 --- a/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/BottomLevelASD3D12Impl.hpp @@ -45,10 +45,14 @@ class BottomLevelASD3D12Impl final : public BottomLevelASBase; + BottomLevelASD3D12Impl(IReferenceCounters* pRefCounters, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const BottomLevelASDesc& Desc); BottomLevelASD3D12Impl(IReferenceCounters* pRefCounters, class RenderDeviceD3D12Impl* pDeviceD3D12, const BottomLevelASDesc& Desc, - bool bIsDeviceInternal = false); + RESOURCE_STATE InitialState, + ID3D12Resource* pd3d12BLAS); ~BottomLevelASD3D12Impl(); IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_BottomLevelASD3D12, TBottomLevelASBase); diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index ad48b876..5c4ad160 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -133,6 +133,18 @@ public: RESOURCE_STATE InitialState, IBuffer** ppBuffer) override final; + /// Implementation of IRenderDeviceD3D12::CreateBLASFromD3DResource(). + virtual void DILIGENT_CALL_TYPE CreateBLASFromD3DResource(ID3D12Resource* pd3d12BLAS, + const BottomLevelASDesc& Desc, + RESOURCE_STATE InitialState, + IBottomLevelAS** ppBLAS) override final; + + /// Implementation of IRenderDeviceD3D12::CreateTLASFromD3DResource(). + virtual void DILIGENT_CALL_TYPE CreateTLASFromD3DResource(ID3D12Resource* pd3d12TLAS, + const TopLevelASDesc& Desc, + RESOURCE_STATE InitialState, + ITopLevelAS** ppTLAS) override final; + DescriptorHeapAllocation AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1); DescriptorHeapAllocation AllocateGPUDescriptors(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1); @@ -180,7 +192,7 @@ public: const Uint32 ShaderGroupHandleSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; const Uint32 MaxShaderRecordStride = D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE; const Uint32 ShaderGroupBaseAlignment = D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT; - const Uint32 MaxDrawMeshTasksCount = 64000; + const Uint32 MaxDrawMeshTasksCount = 64000; // from specs: https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#dispatchmesh-api ShaderVersion MaxShaderVersion; }; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp index 537f240a..ca1442c5 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderBindingTableD3D12Impl.hpp @@ -33,6 +33,7 @@ #include "ShaderBindingTableD3D12.h" #include "RenderDeviceD3D12.h" #include "ShaderBindingTableBase.hpp" +#include "TopLevelASD3D12Impl.hpp" #include "D3D12ResourceBase.hpp" #include "RenderDeviceD3D12Impl.hpp" #include "PipelineStateD3D12Impl.hpp" @@ -41,10 +42,10 @@ namespace Diligent { /// Shader binding table object implementation in Direct3D12 backend. -class ShaderBindingTableD3D12Impl final : public ShaderBindingTableBase, public D3D12ResourceBase +class ShaderBindingTableD3D12Impl final : public ShaderBindingTableBase, public D3D12ResourceBase { public: - using TShaderBindingTableBase = ShaderBindingTableBase; + using TShaderBindingTableBase = ShaderBindingTableBase; ShaderBindingTableD3D12Impl(IReferenceCounters* pRefCounters, class RenderDeviceD3D12Impl* pDeviceD3D12, @@ -53,10 +54,6 @@ public: ~ShaderBindingTableD3D12Impl(); virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - virtual void DILIGENT_CALL_TYPE ResetHitGroups(Uint32 HitShadersPerInstance) override; - - virtual void DILIGENT_CALL_TYPE BindAll(const BindAllAttribs& Attribs) override; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index fe161157..58a8141d 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -297,6 +297,8 @@ public: SHADER_TYPE GetShaderType() const { return m_ShaderType; } + bool IsCompatibleWith(const ShaderResourceLayoutD3D12& ResLayout) const; + private: const D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv) const; D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv); diff --git a/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp index 3fa15e5e..522fd426 100644 --- a/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/TopLevelASD3D12Impl.hpp @@ -46,10 +46,14 @@ class TopLevelASD3D12Impl final : public TopLevelASBase; + TopLevelASD3D12Impl(IReferenceCounters* pRefCounters, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const TopLevelASDesc& Desc); TopLevelASD3D12Impl(IReferenceCounters* pRefCounters, class RenderDeviceD3D12Impl* pDeviceD3D12, const TopLevelASDesc& Desc, - bool bIsDeviceInternal = false); + RESOURCE_STATE InitialState, + ID3D12Resource* pd3d12TLAS); ~TopLevelASD3D12Impl(); IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_TopLevelASD3D12, TTopLevelASBase); diff --git a/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h b/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h index cd315d3e..bec8d338 100644 --- a/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/PipelineStateD3D12.h @@ -75,6 +75,7 @@ DILIGENT_END_INTERFACE // clang-format off # define IPipelineStateD3D12_GetD3D12PipelineState(This) CALL_IFACE_METHOD(PipelineStateD3D12, GetD3D12PipelineState, This) +# define IPipelineStateD3D12_GetD3D12StateObject(This) CALL_IFACE_METHOD(PipelineStateD3D12, GetD3D12StateObject, This) # define IPipelineStateD3D12_GetD3D12RootSignature(This) CALL_IFACE_METHOD(PipelineStateD3D12, GetD3D12RootSignature, This) // clang-format on diff --git a/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h index 136f7307..8d8d1fba 100644 --- a/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h @@ -99,6 +99,38 @@ DILIGENT_BEGIN_INTERFACE(IRenderDeviceD3D12, IRenderDevice) const BufferDesc REF BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer) PURE; + + /// Creates a bottom-level AS object from native d3d12 resoruce + + /// \param [in] pd3d12BLAS - Pointer to the native d3d12 acceleration structure resource + /// \param [in] Desc - Bottom-level AS description. + /// \param [in] InitialState - Initial BLAS state. Can be RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_BUILD_AS_READ, RESOURCE_STATE_BUILD_AS_WRITE. + /// See Diligent::RESOURCE_STATE. + /// \param [out] ppBLAS - Address of the memory location where the pointer to the + /// bottom-level AS interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one reference. + VIRTUAL void METHOD(CreateBLASFromD3DResource)(THIS_ + ID3D12Resource* pd3d12BLAS, + const BottomLevelASDesc REF Desc, + RESOURCE_STATE InitialState, + IBottomLevelAS** ppBLAS) PURE; + + /// Creates a top-level AS object from native d3d12 resoruce + + /// \param [in] pd3d12TLAS - Pointer to the native d3d12 acceleration structure resource + /// \param [in] Desc - Top-level AS description. + /// \param [in] InitialState - Initial TLAS state. Can be RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_BUILD_AS_READ, RESOURCE_STATE_BUILD_AS_WRITE, RESOURCE_STATE_RAY_TRACING. + /// See Diligent::RESOURCE_STATE. + /// \param [out] ppTLAS - Address of the memory location where the pointer to the + /// top-level AS interface will be stored. + /// The function calls AddRef(), so that the new object will contain + /// one reference. + VIRTUAL void METHOD(CreateTLASFromD3DResource)(THIS_ + ID3D12Resource* pd3d12TLAS, + const TopLevelASDesc REF Desc, + RESOURCE_STATE InitialState, + ITopLevelAS** ppTLAS) PURE; }; DILIGENT_END_INTERFACE @@ -114,6 +146,8 @@ DILIGENT_END_INTERFACE # define IRenderDeviceD3D12_IsFenceSignaled(This, ...) CALL_IFACE_METHOD(RenderDeviceD3D12, IsFenceSignaled, This, __VA_ARGS__) # define IRenderDeviceD3D12_CreateTextureFromD3DResource(This, ...) CALL_IFACE_METHOD(RenderDeviceD3D12, CreateTextureFromD3DResource, This, __VA_ARGS__) # define IRenderDeviceD3D12_CreateBufferFromD3DResource(This, ...) CALL_IFACE_METHOD(RenderDeviceD3D12, CreateBufferFromD3DResource, This, __VA_ARGS__) +# define IRenderDeviceD3D12_CreateBLASFromD3DResource(This, ...) CALL_IFACE_METHOD(RenderDeviceD3D12, CreateBLASFromD3DResource, This, __VA_ARGS__) +# define IRenderDeviceD3D12_CreateTLASFromD3DResource(This, ...) CALL_IFACE_METHOD(RenderDeviceD3D12, CreateTLASFromD3DResource, This, __VA_ARGS__) // clang-format on diff --git a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp index fa82ee9a..d2e119b3 100644 --- a/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BottomLevelASD3D12Impl.cpp @@ -38,9 +38,8 @@ namespace Diligent BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRefCounters, class RenderDeviceD3D12Impl* pDeviceD3D12, - const BottomLevelASDesc& Desc, - bool bIsDeviceInternal) : - TBottomLevelASBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal} + const BottomLevelASDesc& Desc) : + TBottomLevelASBase{pRefCounters, pDeviceD3D12, Desc} { auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5(); UINT64 ResultDataMaxSizeInBytes = 0; @@ -66,15 +65,15 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef dst.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; dst.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE; + 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; dst.Triangles.VertexBuffer.StartAddress = 0; dst.Triangles.VertexBuffer.StrideInBytes = 0; + dst.Triangles.VertexCount = src.MaxVertexCount; dst.Triangles.VertexFormat = TypeToRayTracingVertexFormat(src.VertexValueType, src.VertexComponentCount); VERIFY(dst.Triangles.VertexFormat != DXGI_FORMAT_UNKNOWN, "Unsupported combination of vertex value type and component count"); - 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; } @@ -157,6 +156,17 @@ BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRef SetState(RESOURCE_STATE_BUILD_AS_READ); } +BottomLevelASD3D12Impl::BottomLevelASD3D12Impl(IReferenceCounters* pRefCounters, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const BottomLevelASDesc& Desc, + RESOURCE_STATE InitialState, + ID3D12Resource* pd3d12BLAS) : + TBottomLevelASBase{pRefCounters, pDeviceD3D12, Desc} +{ + m_pd3d12Resource = pd3d12BLAS; + SetState(InitialState); +} + BottomLevelASD3D12Impl::~BottomLevelASD3D12Impl() { // D3D12 object can only be destroyed when it is no longer used by the GPU diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index c78976ea..3d1c836f 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2277,14 +2277,14 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) if (!TDeviceContextBase::BuildBLAS(Attribs, 0)) return; - auto* const pBLASD12 = ValidatedCast(Attribs.pBLAS); - auto* const pScratchD12 = ValidatedCast(Attribs.pScratchBuffer); - const auto& BLASDesc = pBLASD12->GetDesc(); + auto* const pBLASD3D12 = ValidatedCast(Attribs.pBLAS); + auto* const pScratchD3D12 = ValidatedCast(Attribs.pScratchBuffer); + const auto& BLASDesc = pBLASD3D12->GetDesc(); auto& CmdCtx = GetCmdContext(); const char* OpName = "Build BottomLevelAS (DeviceContextD3D12Impl::BuildBLAS)"; - TransitionOrVerifyBLASState(CmdCtx, *pBLASD12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); - TransitionOrVerifyBufferState(CmdCtx, *pScratchD12, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); + TransitionOrVerifyBLASState(CmdCtx, *pBLASD3D12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); + TransitionOrVerifyBufferState(CmdCtx, *pScratchD3D12, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC d3d12BuildASDesc = {}; D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS& d3d12BuildASInputs = d3d12BuildASDesc.Inputs; @@ -2293,19 +2293,21 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) if (Attribs.pTriangleData != nullptr) { Geometries.resize(Attribs.TriangleDataCount); + pBLASD3D12->SetActualGeometryCount(Attribs.TriangleDataCount); for (Uint32 i = 0; i < Attribs.TriangleDataCount; ++i) { const auto& SrcTris = Attribs.pTriangleData[i]; - Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcTris.GeometryName); + Uint32 Idx = i; + Uint32 GeoIdx = pBLASD3D12->UpdateGeometryIndex(SrcTris.GeometryName, Idx, Attribs.Update); - if (GeoIdx >= Geometries.size()) + if (GeoIdx == INVALID_INDEX || Idx == INVALID_INDEX) { UNEXPECTED("Failed to find geometry by name"); continue; } - auto& d3d12Geo = Geometries[GeoIdx]; + auto& d3d12Geo = Geometries[Idx]; auto& d3d12Tris = d3d12Geo.Triangles; const auto& TriDesc = BLASDesc.pTriangles[GeoIdx]; @@ -2315,11 +2317,11 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) auto* const pVB = ValidatedCast(SrcTris.pVertexBuffer); // vertex format in SrcTris may be undefined, so use vertex format from description - d3d12Tris.VertexFormat = TypeToRayTracingVertexFormat(TriDesc.VertexValueType, TriDesc.VertexComponentCount); - VERIFY(d3d12Tris.VertexFormat != DXGI_FORMAT_UNKNOWN, "Unsupported combination of vertex value type and component count"); - d3d12Tris.VertexCount = SrcTris.VertexCount; d3d12Tris.VertexBuffer.StartAddress = pVB->GetGPUAddress() + SrcTris.VertexOffset; d3d12Tris.VertexBuffer.StrideInBytes = SrcTris.VertexStride; + d3d12Tris.VertexCount = SrcTris.VertexCount; + d3d12Tris.VertexFormat = TypeToRayTracingVertexFormat(TriDesc.VertexValueType, TriDesc.VertexComponentCount); + VERIFY(d3d12Tris.VertexFormat != DXGI_FORMAT_UNKNOWN, "Unsupported combination of vertex value type and component count"); TransitionOrVerifyBufferState(CmdCtx, *pVB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); @@ -2358,19 +2360,21 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) else if (Attribs.pBoxData != nullptr) { Geometries.resize(Attribs.BoxDataCount); + pBLASD3D12->SetActualGeometryCount(Attribs.BoxDataCount); for (Uint32 i = 0; i < Attribs.BoxDataCount; ++i) { const auto& SrcBoxes = Attribs.pBoxData[i]; - Uint32 GeoIdx = pBLASD12->GetGeometryIndex(SrcBoxes.GeometryName); + Uint32 Idx = i; + Uint32 GeoIdx = pBLASD3D12->UpdateGeometryIndex(SrcBoxes.GeometryName, Idx, Attribs.Update); - if (GeoIdx >= Geometries.size()) + if (GeoIdx == INVALID_INDEX || Idx == INVALID_INDEX) { UNEXPECTED("Failed to find geometry by name"); continue; } - auto& d3d12Geo = Geometries[GeoIdx]; + auto& d3d12Geo = Geometries[Idx]; auto& d3d12AABs = d3d12Geo.AABBs; d3d12Geo.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS; @@ -2393,10 +2397,16 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) d3d12BuildASInputs.NumDescs = static_cast(Geometries.size()); d3d12BuildASInputs.pGeometryDescs = Geometries.data(); - d3d12BuildASDesc.DestAccelerationStructureData = pBLASD12->GetGPUAddress(); - d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress() + Attribs.ScratchBufferOffset; + d3d12BuildASDesc.DestAccelerationStructureData = pBLASD3D12->GetGPUAddress(); + d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD3D12->GetGPUAddress() + Attribs.ScratchBufferOffset; d3d12BuildASDesc.SourceAccelerationStructureData = 0; + if (Attribs.Update) + { + d3d12BuildASInputs.Flags |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE; + d3d12BuildASDesc.SourceAccelerationStructureData = d3d12BuildASDesc.DestAccelerationStructureData; + } + DEV_CHECK_ERR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0, "Scratch data address is not properly aligned"); @@ -2404,7 +2414,7 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) ++m_State.NumCommands; #ifdef DILIGENT_DEVELOPMENT - pBLASD12->UpdateVersion(); + pBLASD3D12->UpdateVersion(); #endif } @@ -2415,16 +2425,25 @@ void DeviceContextD3D12Impl::BuildTLAS(const BuildTLASAttribs& Attribs) static_assert(TLAS_INSTANCE_DATA_SIZE == sizeof(D3D12_RAYTRACING_INSTANCE_DESC), "Value in TLAS_INSTANCE_DATA_SIZE doesn't match the actual instance description size"); - auto* pTLASD12 = ValidatedCast(Attribs.pTLAS); - auto* pScratchD12 = ValidatedCast(Attribs.pScratchBuffer); - auto* pInstancesD12 = ValidatedCast(Attribs.pInstanceBuffer); + auto* pTLASD3D12 = ValidatedCast(Attribs.pTLAS); + auto* pScratchD3D12 = ValidatedCast(Attribs.pScratchBuffer); + auto* pInstancesD3D12 = ValidatedCast(Attribs.pInstanceBuffer); auto& CmdCtx = GetCmdContext(); const char* OpName = "Build TopLevelAS (DeviceContextD3D12Impl::BuildTLAS)"; - TransitionOrVerifyTLASState(CmdCtx, *pTLASD12, Attribs.TLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); - TransitionOrVerifyBufferState(CmdCtx, *pScratchD12, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); + TransitionOrVerifyTLASState(CmdCtx, *pTLASD3D12, Attribs.TLASTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); + TransitionOrVerifyBufferState(CmdCtx, *pScratchD3D12, Attribs.ScratchBufferTransitionMode, RESOURCE_STATE_BUILD_AS_WRITE, OpName); - pTLASD12->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount, Attribs.HitShadersPerInstance); + if (Attribs.Update) + { + if (!pTLASD3D12->UpdateInstances(Attribs.pInstances, Attribs.InstanceCount, Attribs.BaseContributionToHitGroupIndex, Attribs.HitShadersPerInstance, Attribs.BindingMode)) + return; + } + else + { + if (!pTLASD3D12->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount, Attribs.BaseContributionToHitGroupIndex, Attribs.HitShadersPerInstance, Attribs.BindingMode)) + return; + } // copy instance data into instance buffer { @@ -2433,38 +2452,52 @@ void DeviceContextD3D12Impl::BuildTLAS(const BuildTLASAttribs& Attribs) for (Uint32 i = 0; i < Attribs.InstanceCount; ++i) { - const auto& Inst = Attribs.pInstances[i]; - auto& d3d12Inst = static_cast(TmpSpace.CPUAddress)[i]; - auto* const pBLASD12 = ValidatedCast(Inst.pBLAS); + const auto& Inst = Attribs.pInstances[i]; + const auto InstDesc = pTLASD3D12->GetInstanceDesc(Inst.InstanceName); + + if (InstDesc.InstanceIndex >= Attribs.InstanceCount) + { + UNEXPECTED("Failed to find instance by name"); + return; + } + + auto& d3d12Inst = static_cast(TmpSpace.CPUAddress)[InstDesc.InstanceIndex]; + auto* pBLASD3D12 = ValidatedCast(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; + d3d12Inst.InstanceContributionToHitGroupIndex = InstDesc.ContributionToHitGroupIndex; d3d12Inst.InstanceMask = Inst.Mask; d3d12Inst.Flags = InstanceFlagsToD3D12RTInstanceFlags(Inst.Flags); - d3d12Inst.AccelerationStructure = pBLASD12->GetGPUAddress(); + d3d12Inst.AccelerationStructure = pBLASD3D12->GetGPUAddress(); - TransitionOrVerifyBLASState(CmdCtx, *pBLASD12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + TransitionOrVerifyBLASState(CmdCtx, *pBLASD3D12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } - UpdateBufferRegion(pInstancesD12, TmpSpace, Attribs.InstanceBufferOffset, Size, Attribs.InstanceBufferTransitionMode); + UpdateBufferRegion(pInstancesD3D12, TmpSpace, Attribs.InstanceBufferOffset, Size, Attribs.InstanceBufferTransitionMode); } - TransitionOrVerifyBufferState(CmdCtx, *pInstancesD12, Attribs.InstanceBufferTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + TransitionOrVerifyBufferState(CmdCtx, *pInstancesD3D12, Attribs.InstanceBufferTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC d3d12BuildASDesc = {}; 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.Flags = BuildASFlagsToD3D12ASBuildFlags(pTLASD3D12->GetDesc().Flags); d3d12BuildASInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; d3d12BuildASInputs.NumDescs = Attribs.InstanceCount; - d3d12BuildASInputs.InstanceDescs = pInstancesD12->GetGPUAddress() + Attribs.InstanceBufferOffset; + d3d12BuildASInputs.InstanceDescs = pInstancesD3D12->GetGPUAddress() + Attribs.InstanceBufferOffset; - d3d12BuildASDesc.DestAccelerationStructureData = pTLASD12->GetGPUAddress(); - d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress() + Attribs.ScratchBufferOffset; + d3d12BuildASDesc.DestAccelerationStructureData = pTLASD3D12->GetGPUAddress(); + d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD3D12->GetGPUAddress() + Attribs.ScratchBufferOffset; d3d12BuildASDesc.SourceAccelerationStructureData = 0; + if (Attribs.Update) + { + d3d12BuildASInputs.Flags |= D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE; + d3d12BuildASDesc.SourceAccelerationStructureData = d3d12BuildASDesc.DestAccelerationStructureData; + } + DEV_CHECK_ERR(d3d12BuildASInputs.InstanceDescs % D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT == 0, "Instance data address is not properly aligned"); DEV_CHECK_ERR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0, @@ -2486,7 +2519,8 @@ void DeviceContextD3D12Impl::CopyBLAS(const CopyBLASAttribs& Attribs) // Dst BLAS description has specified CompactedSize, but doesn't have specified pTriangles and pBoxes. // We should copy geometries because it required for SBT to map geometry name to hit group. - pDstD3D12->CopyDescription(*pSrcD3D12); + pDstD3D12->CopyGeometryDescription(*pSrcD3D12); + pDstD3D12->SetActualGeometryCount(pSrcD3D12->GetActualGeometryCount()); const char* OpName = "Copy BottomLevelAS (DeviceContextD3D12Impl::CopyBLAS)"; TransitionOrVerifyBLASState(CmdCtx, *pSrcD3D12, Attribs.SrcTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); @@ -2579,16 +2613,16 @@ void DeviceContextD3D12Impl::TraceRays(const TraceRaysAttribs& Attribs) VERIFY_EXPR((Attribs.DimensionX * Attribs.DimensionY * Attribs.DimensionZ) <= D3D12_RAYTRACING_MAX_RAY_GENERATION_SHADER_THREADS); - auto& CmdCtx = GetCmdContext().AsGraphicsContext4(); - auto* pSBTD12 = ValidatedCast(Attribs.pSBT); - IBuffer* pBuffer = nullptr; + auto& CmdCtx = GetCmdContext().AsGraphicsContext4(); + auto* pSBTD3D12 = ValidatedCast(Attribs.pSBT); + IBuffer* pBuffer = nullptr; ShaderBindingTableD3D12Impl::BindingTable RayGenShaderRecord = {}; ShaderBindingTableD3D12Impl::BindingTable MissShaderTable = {}; ShaderBindingTableD3D12Impl::BindingTable HitGroupTable = {}; ShaderBindingTableD3D12Impl::BindingTable CallableShaderTable = {}; - pSBTD12->GetData(pBuffer, RayGenShaderRecord, MissShaderTable, HitGroupTable, CallableShaderTable); + pSBTD3D12->GetData(pBuffer, RayGenShaderRecord, MissShaderTable, HitGroupTable, CallableShaderTable); auto* pBufferD3D12 = ValidatedCast(pBuffer); diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 1a12f25b..be30c978 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -729,16 +729,17 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& auto pd3d12Device = GetDevice()->GetD3D12Device(); const auto& ResourceLayout = m_Desc.ResourceLayout; - // AZ TODO -#if 0 //def DILIGENT_DEVELOPMENT +#ifdef DILIGENT_DEVELOPMENT { - const ShaderResources* pResources[MAX_SHADERS_IN_PIPELINE] = {}; + std::vector Resources; for (size_t s = 0; s < ShaderStages.size(); ++s) { - const auto* pShader = ShaderStages[s].Shaders[0]; - pResources[s] = &(*pShader->GetShaderResources()); + for (auto* pShader : ShaderStages[s].Shaders) + { + Resources.push_back(&(*pShader->GetShaderResources())); + } } - ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderStages(), + ShaderResources::DvpVerifyResourceLayout(ResourceLayout, Resources.data(), static_cast(Resources.size()), (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_IMMUTABLE_SAMPLERS) == 0); } @@ -832,8 +833,7 @@ bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState* pPSO) const auto IsSameRootSignature = m_RootSig.IsSameAs(pPSOD3D12->m_RootSig); - // AZ TODO -#if 0 //def DILIGENT_DEBUG +#ifdef DILIGENT_DEBUG { bool IsCompatibleShaders = true; if (GetNumShaderStages() != pPSOD3D12->GetNumShaderStages()) @@ -849,8 +849,8 @@ bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState* pPSO) const break; } - const auto& Res0 = GetShaderResLayout(s).GetResources(); - const auto& Res1 = pPSOD3D12->GetShaderResLayout(s).GetResources(); + const auto& Res0 = GetShaderResLayout(s); + const auto& Res1 = pPSOD3D12->GetShaderResLayout(s); if (!Res0.IsCompatibleWith(Res1)) { IsCompatibleShaders = false; diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index 9ea84f06..76bf71c4 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -724,6 +724,19 @@ void RenderDeviceD3D12Impl::CreateFramebuffer(const FramebufferDesc& Desc, IFram }); } +void RenderDeviceD3D12Impl::CreateBLASFromD3DResource(ID3D12Resource* pd3d12BLAS, + const BottomLevelASDesc& Desc, + RESOURCE_STATE InitialState, + IBottomLevelAS** ppBLAS) +{ + CreateDeviceObject("buffer", Desc, ppBLAS, + [&]() // + { + BottomLevelASD3D12Impl* pBottomLevelASD3D12{NEW_RC_OBJ(m_BLASAllocator, "BottomLevelASD3D12Impl instance", BottomLevelASD3D12Impl)(this, Desc, InitialState, pd3d12BLAS)}; + pBottomLevelASD3D12->QueryInterface(IID_BottomLevelAS, reinterpret_cast(ppBLAS)); + OnCreateDeviceObject(pBottomLevelASD3D12); + }); +} void RenderDeviceD3D12Impl::CreateBLAS(const BottomLevelASDesc& Desc, IBottomLevelAS** ppBLAS) @@ -731,9 +744,23 @@ void RenderDeviceD3D12Impl::CreateBLAS(const BottomLevelASDesc& Desc, CreateDeviceObject("BottomLevelAS", Desc, ppBLAS, [&]() // { - BottomLevelASD3D12Impl* pBottomLevelASVk(NEW_RC_OBJ(m_BLASAllocator, "BottomLevelASD3D12Impl instance", BottomLevelASD3D12Impl)(this, Desc)); - pBottomLevelASVk->QueryInterface(IID_BottomLevelAS, reinterpret_cast(ppBLAS)); - OnCreateDeviceObject(pBottomLevelASVk); + BottomLevelASD3D12Impl* pBottomLevelASD3D12(NEW_RC_OBJ(m_BLASAllocator, "BottomLevelASD3D12Impl instance", BottomLevelASD3D12Impl)(this, Desc)); + pBottomLevelASD3D12->QueryInterface(IID_BottomLevelAS, reinterpret_cast(ppBLAS)); + OnCreateDeviceObject(pBottomLevelASD3D12); + }); +} + +void RenderDeviceD3D12Impl::CreateTLASFromD3DResource(ID3D12Resource* pd3d12TLAS, + const TopLevelASDesc& Desc, + RESOURCE_STATE InitialState, + ITopLevelAS** ppTLAS) +{ + CreateDeviceObject("TopLevelAS", Desc, ppTLAS, + [&]() // + { + TopLevelASD3D12Impl* pTopLevelASD3D12{NEW_RC_OBJ(m_TLASAllocator, "TopLevelASD3D12Impl instance", TopLevelASD3D12Impl)(this, Desc, InitialState, pd3d12TLAS)}; + pTopLevelASD3D12->QueryInterface(IID_TopLevelAS, reinterpret_cast(ppTLAS)); + OnCreateDeviceObject(pTopLevelASD3D12); }); } @@ -743,9 +770,9 @@ void RenderDeviceD3D12Impl::CreateTLAS(const TopLevelASDesc& Desc, CreateDeviceObject("TopLevelAS", Desc, ppTLAS, [&]() // { - TopLevelASD3D12Impl* pTopLevelASVk(NEW_RC_OBJ(m_TLASAllocator, "TopLevelASD3D12Impl instance", TopLevelASD3D12Impl)(this, Desc)); - pTopLevelASVk->QueryInterface(IID_TopLevelAS, reinterpret_cast(ppTLAS)); - OnCreateDeviceObject(pTopLevelASVk); + TopLevelASD3D12Impl* pTopLevelASD3D12(NEW_RC_OBJ(m_TLASAllocator, "TopLevelASD3D12Impl instance", TopLevelASD3D12Impl)(this, Desc)); + pTopLevelASD3D12->QueryInterface(IID_TopLevelAS, reinterpret_cast(ppTLAS)); + OnCreateDeviceObject(pTopLevelASD3D12); }); } @@ -755,9 +782,9 @@ void RenderDeviceD3D12Impl::CreateSBT(const ShaderBindingTableDesc& Desc, CreateDeviceObject("ShaderBindingTable", Desc, ppSBT, [&]() // { - ShaderBindingTableD3D12Impl* pSBTVk(NEW_RC_OBJ(m_SBTAllocator, "ShaderBindingTableD3D12Impl instance", ShaderBindingTableD3D12Impl)(this, Desc)); - pSBTVk->QueryInterface(IID_ShaderBindingTable, reinterpret_cast(ppSBT)); - OnCreateDeviceObject(pSBTVk); + ShaderBindingTableD3D12Impl* pSBTD3D12(NEW_RC_OBJ(m_SBTAllocator, "ShaderBindingTableD3D12Impl instance", ShaderBindingTableD3D12Impl)(this, Desc)); + pSBTD3D12->QueryInterface(IID_ShaderBindingTable, reinterpret_cast(ppSBT)); + OnCreateDeviceObject(pSBTD3D12); }); } diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 8a8bfd4d..2ac15372 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -1154,10 +1154,10 @@ ID3D12RootSignature* LocalRootSignature::Create(ID3D12Device* pDevice) CComPtr signature; auto hr = D3D12SerializeRootSignature(&d3d12RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr); - CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature"); + CHECK_D3D_RESULT_THROW(hr, "Failed to serialize local root signature"); hr = pDevice->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_pd3d12RootSignature)); - CHECK_D3D_RESULT_THROW(hr, "Failed to create D3D12 root signature"); + CHECK_D3D_RESULT_THROW(hr, "Failed to create D3D12 local root signature"); return m_pd3d12RootSignature; } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp index ac67ba57..0e15bd4f 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderBindingTableD3D12Impl.cpp @@ -52,14 +52,4 @@ ShaderBindingTableD3D12Impl::~ShaderBindingTableD3D12Impl() IMPLEMENT_QUERY_INTERFACE(ShaderBindingTableD3D12Impl, IID_ShaderBindingTableD3D12, TShaderBindingTableBase) -void ShaderBindingTableD3D12Impl::ResetHitGroups(Uint32 HitShadersPerInstance) -{ - // AZ TODO -} - -void ShaderBindingTableD3D12Impl::BindAll(const BindAllAttribs& Attribs) -{ - // AZ TODO -} - } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 6218fbd3..5923797c 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -1104,4 +1104,21 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 } #endif +bool ShaderResourceLayoutD3D12::IsCompatibleWith(const ShaderResourceLayoutD3D12& ResLayout) const +{ + if (GetTotalResourceCount() != ResLayout.GetTotalResourceCount()) + return false; + + for (Uint32 i = 0; i < GetTotalResourceCount(); ++i) + { + const auto& lRes = GetResource(i); + const auto& rRes = ResLayout.GetResource(i); + + if (!lRes.Attribs.IsCompatibleWith(rRes.Attribs)) + return false; + } + + return true; +} + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp index 51dadde1..dff2dcfb 100644 --- a/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/TopLevelASD3D12Impl.cpp @@ -38,9 +38,8 @@ namespace Diligent TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounters, class RenderDeviceD3D12Impl* pDeviceD3D12, - const TopLevelASDesc& Desc, - bool bIsDeviceInternal) : - TTopLevelASBase{pRefCounters, pDeviceD3D12, Desc, bIsDeviceInternal} + const TopLevelASDesc& Desc) : + TTopLevelASBase{pRefCounters, pDeviceD3D12, Desc} { auto* pd3d12Device = pDeviceD3D12->GetD3D12Device5(); UINT64 ResultDataMaxSizeInBytes = 0; @@ -115,6 +114,17 @@ TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounte SetState(RESOURCE_STATE_BUILD_AS_READ); } +TopLevelASD3D12Impl::TopLevelASD3D12Impl(IReferenceCounters* pRefCounters, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const TopLevelASDesc& Desc, + RESOURCE_STATE InitialState, + ID3D12Resource* pd3d12TLAS) : + TTopLevelASBase{pRefCounters, pDeviceD3D12, Desc} +{ + m_pd3d12Resource = pd3d12TLAS; + SetState(InitialState); +} + TopLevelASD3D12Impl::~TopLevelASD3D12Impl() { // D3D12 object can only be destroyed when it is no longer used by the GPU -- cgit v1.2.3 From 5888241b0f6127c82b64caebb9cb61b933ba4535 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 9 Nov 2020 21:24:46 -0800 Subject: A bunch of minor updates --- .../GraphicsEngineD3D12/interface/RenderDeviceD3D12.h | 18 +++++++++--------- .../GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h index 8d8d1fba..6616126c 100644 --- a/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h @@ -111,11 +111,11 @@ DILIGENT_BEGIN_INTERFACE(IRenderDeviceD3D12, IRenderDevice) /// The function calls AddRef(), so that the new object will contain /// one reference. VIRTUAL void METHOD(CreateBLASFromD3DResource)(THIS_ - ID3D12Resource* pd3d12BLAS, - const BottomLevelASDesc REF Desc, - RESOURCE_STATE InitialState, - IBottomLevelAS** ppBLAS) PURE; - + ID3D12Resource* pd3d12BLAS, + const BottomLevelASDesc REF Desc, + RESOURCE_STATE InitialState, + IBottomLevelAS** ppBLAS) PURE; + /// Creates a top-level AS object from native d3d12 resoruce /// \param [in] pd3d12TLAS - Pointer to the native d3d12 acceleration structure resource @@ -127,10 +127,10 @@ DILIGENT_BEGIN_INTERFACE(IRenderDeviceD3D12, IRenderDevice) /// The function calls AddRef(), so that the new object will contain /// one reference. VIRTUAL void METHOD(CreateTLASFromD3DResource)(THIS_ - ID3D12Resource* pd3d12TLAS, - const TopLevelASDesc REF Desc, - RESOURCE_STATE InitialState, - ITopLevelAS** ppTLAS) PURE; + ID3D12Resource* pd3d12TLAS, + const TopLevelASDesc REF Desc, + RESOURCE_STATE InitialState, + ITopLevelAS** ppTLAS) PURE; }; DILIGENT_END_INTERFACE diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index be30c978..84453dfa 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -208,9 +208,9 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI VERIFY_EXPR(Uint32{CreateInfo.GeneralShaderCount} + Uint32{CreateInfo.TriangleHitShaderCount} + Uint32{CreateInfo.ProceduralHitShaderCount} == GroupIndex); - const Uint32 RecursionDepthLimit = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH - 1; + constexpr Uint32 RecursionDepthLimit = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH - 1; if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > RecursionDepthLimit) - LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than or equal to ", RecursionDepthLimit); + LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth (", CreateInfo.RayTracingPipeline.MaxRecursionDepth, ") must be <= ", RecursionDepthLimit); auto& PipelineConfig = *TempPool.Construct(); // For compatibility with Vulkan set minimal recursion depth to one, zero means no tracing of rays at all. -- cgit v1.2.3 From 0f5eaa1eb5bf6cd85146a29bd988903e22084832 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 12 Nov 2020 18:19:35 +0300 Subject: fixed and improved shader binding --- Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 3d1c836f..8496181a 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2436,12 +2436,12 @@ void DeviceContextD3D12Impl::BuildTLAS(const BuildTLASAttribs& Attribs) if (Attribs.Update) { - if (!pTLASD3D12->UpdateInstances(Attribs.pInstances, Attribs.InstanceCount, Attribs.BaseContributionToHitGroupIndex, Attribs.HitShadersPerInstance, Attribs.BindingMode)) + if (!pTLASD3D12->UpdateInstances(Attribs.pInstances, Attribs.InstanceCount, Attribs.BaseContributionToHitGroupIndex, Attribs.HitGroupStride, Attribs.BindingMode)) return; } else { - if (!pTLASD3D12->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount, Attribs.BaseContributionToHitGroupIndex, Attribs.HitShadersPerInstance, Attribs.BindingMode)) + if (!pTLASD3D12->SetInstanceData(Attribs.pInstances, Attribs.InstanceCount, Attribs.BaseContributionToHitGroupIndex, Attribs.HitGroupStride, Attribs.BindingMode)) return; } @@ -2471,9 +2471,13 @@ void DeviceContextD3D12Impl::BuildTLAS(const BuildTLASAttribs& Attribs) d3d12Inst.InstanceContributionToHitGroupIndex = InstDesc.ContributionToHitGroupIndex; d3d12Inst.InstanceMask = Inst.Mask; d3d12Inst.Flags = InstanceFlagsToD3D12RTInstanceFlags(Inst.Flags); - d3d12Inst.AccelerationStructure = pBLASD3D12->GetGPUAddress(); + d3d12Inst.AccelerationStructure = 0; - TransitionOrVerifyBLASState(CmdCtx, *pBLASD3D12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + if (pBLASD3D12) + { + d3d12Inst.AccelerationStructure = pBLASD3D12->GetGPUAddress(); + TransitionOrVerifyBLASState(CmdCtx, *pBLASD3D12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); + } } UpdateBufferRegion(pInstancesD3D12, TmpSpace, Attribs.InstanceBufferOffset, Size, Attribs.InstanceBufferTransitionMode); } -- cgit v1.2.3 From f8d57c40eb9a7f8f54494aa348cc01c15e56ee41 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 12 Nov 2020 18:23:20 +0300 Subject: remap resource binding for DirectX 12 --- .../GraphicsEngineD3D12/include/RootSignature.hpp | 39 ++++++---- .../include/ShaderResourceLayoutD3D12.hpp | 4 +- .../src/PipelineStateD3D12Impl.cpp | 91 ++++++++++++++++++++++ Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 33 ++++++-- .../src/ShaderResourceLayoutD3D12.cpp | 17 +++- 5 files changed, 158 insertions(+), 26 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index d74a7b0c..fe78a852 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -321,6 +321,7 @@ public: const D3DShaderResourceAttribs& ShaderResAttribs, SHADER_RESOURCE_VARIABLE_TYPE VariableType, D3D12_DESCRIPTOR_RANGE_TYPE RangeType, + Uint32& BindPoint, Uint32& RootIndex, Uint32& OffsetFromTableStart); @@ -373,6 +374,27 @@ public: return m_RootParams.GetHash(); } + // Note: sizeof(m_ImmutableSamplers) == 56 (MS compiler, release x64) + struct ImmutableSamplerAttribs + { + ImmutableSamplerDesc SamplerDesc; + UINT ShaderRegister = static_cast(-1); + UINT ArraySize = 0; + UINT RegisterSpace = 0; + D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast(-1); + String Name; + SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN; + + ImmutableSamplerAttribs() noexcept {} + ImmutableSamplerAttribs(const ImmutableSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility, SHADER_TYPE Stage) noexcept : + SamplerDesc(SamDesc), + ShaderVisibility(Visibility), + ShaderType{Stage} + {} + }; + const ImmutableSamplerAttribs* GetImmutableSamplers() const { return m_ImmutableSamplers.data(); } + size_t GetImmutableSamplerCount() const { return m_ImmutableSamplers.size(); } + private: #ifdef DILIGENT_DEBUG void dbgVerifyRootParameters() const; @@ -478,23 +500,10 @@ private: // This array contains the same data for Sampler root table std::array m_SamplerRootTablesMap = {}; - RootParamsManager m_RootParams; + std::array m_NumResources = {}; - struct ImmutableSamplerAttribs - { - ImmutableSamplerDesc SamplerDesc; - UINT ShaderRegister = static_cast(-1); - UINT ArraySize = 0; - UINT RegisterSpace = 0; - D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast(-1); + RootParamsManager m_RootParams; - ImmutableSamplerAttribs() noexcept {} - ImmutableSamplerAttribs(const ImmutableSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility) noexcept : - SamplerDesc(SamDesc), - ShaderVisibility(Visibility) - {} - }; - // Note: sizeof(m_ImmutableSamplers) == 56 (MS compiler, release x64) std::vector> m_ImmutableSamplers; IMemoryAllocator& m_MemAllocator; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index 58a8141d..6f71f8f8 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -190,6 +190,7 @@ public: Uint32 _SamplerId, SHADER_RESOURCE_VARIABLE_TYPE _VariableType, CachedResourceType _ResType, + Uint32 _BindPoint, Uint32 _RootIndex, Uint32 _OffsetFromTableStart) noexcept : // clang-format off @@ -198,7 +199,8 @@ public: { _StringPool, _Attribs, - _SamplerId + _SamplerId, + _BindPoint }, ResourceType {static_cast(_ResType) }, VariableType {static_cast(_VariableType)}, diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 84453dfa..714643c3 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -38,6 +38,8 @@ #include "StringTools.hpp" #include "ShaderVariableD3D12.hpp" #include "DynamicLinearAllocator.hpp" +#include "DXCompiler.hpp" +#include "dxc/dxcapi.h" namespace Diligent { @@ -282,6 +284,90 @@ void GetShaderIdentifiers(ID3D12DeviceChild* pSO, } } +void RemapResourceBinding(IDXCompiler* compiler, + const RootSignature& RootSig, + const std::array& ResourceLayoutIndex, + const ShaderResourceLayoutD3D12* pResourceLayouts, + const ShaderResourceLayoutD3D12* pStaticLayouts, + Uint32 NumStages, + std::vector& Subobjects, + std::vector>& ShaderBlobs) noexcept(false) +{ + IDXCompiler::TBindingMapPerStage BindingMapPerStage; + String EntryPoint; + + const auto ExtractResources = [&](const ShaderResourceLayoutD3D12* pLayouts) // + { + for (Uint32 ShaderIdx = 0; ShaderIdx < ResourceLayoutIndex.size(); ++ShaderIdx) + { + const Int8 LayoutIdx = ResourceLayoutIndex[ShaderIdx]; + if (LayoutIdx < 0) + continue; + + auto& BindingMap = BindingMapPerStage[ShaderIdx]; + const auto& ResLayout = pLayouts[LayoutIdx]; + for (Uint32 v = 0; v < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; ++v) + { + auto VarType = static_cast(v); + Uint32 ResCount = ResLayout.GetCbvSrvUavCount(VarType); + Uint32 SampCount = ResLayout.GetSamplerCount(VarType); + + for (Uint32 i = 0; i < ResCount; ++i) + { + const auto& Attribs = ResLayout.GetSrvCbvUav(VarType, i).Attribs; + auto Iter = BindingMap.emplace(HashMapStringKey{Attribs.Name}, Attribs.BindPoint).first; + VERIFY_EXPR(Iter->second == Attribs.BindPoint); + } + for (Uint32 i = 0; i < SampCount; ++i) + { + const auto& Attribs = ResLayout.GetSampler(VarType, i).Attribs; + auto Iter = BindingMap.emplace(HashMapStringKey{Attribs.Name}, Attribs.BindPoint).first; + VERIFY_EXPR(Iter->second == Attribs.BindPoint); + } + } + } + }; + ExtractResources(pResourceLayouts); + ExtractResources(pStaticLayouts); + + for (size_t i = 0; i < RootSig.GetImmutableSamplerCount(); ++i) + { + const auto& ImtblSmplr = RootSig.GetImmutableSamplers()[i]; + const Uint32 ShaderIdx = GetShaderTypePipelineIndex(ImtblSmplr.ShaderType, PIPELINE_TYPE_RAY_TRACING); + const Int8 LayoutIdx = ResourceLayoutIndex[ShaderIdx]; + if (LayoutIdx < 0) + continue; + + auto& BindingMap = BindingMapPerStage[ShaderIdx]; + BindingMap.emplace(HashMapStringKey{ImtblSmplr.Name.c_str()}, ImtblSmplr.ShaderRegister); + } + + for (auto& SubObj : Subobjects) + { + if (SubObj.Type == D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY) + { + auto& DxilLib = *reinterpret_cast(const_cast(SubObj.pDesc)); + VERIFY_EXPR(DxilLib.NumExports == 1); + + const auto& Export = *DxilLib.pExports; + EntryPoint.resize(wcslen(Export.ExportToRename)); + for (size_t i = 0; i < EntryPoint.size(); ++i) + EntryPoint[i] = static_cast(Export.ExportToRename[i]); + + CComPtr pBlob; + compiler->RemapResourceBinding(BindingMapPerStage, EntryPoint.c_str(), DxilLib.DXILLibrary.pShaderBytecode, DxilLib.DXILLibrary.BytecodeLength, &pBlob); + + if (!pBlob) + LOG_ERROR_AND_THROW("Failed to remap resource bindings"); + + DxilLib.DXILLibrary.pShaderBytecode = pBlob->GetBufferPointer(); + DxilLib.DXILLibrary.BytecodeLength = pBlob->GetBufferSize(); + + ShaderBlobs.push_back(pBlob); + } + } +} + } // namespace @@ -650,6 +736,11 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* if (LocalRoot.pLocalRootSignature) Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE, &LocalRoot}); + std::vector> ShaderBlobs; + RemapResourceBinding(pDeviceD3D12->GetDxCompiler(), m_RootSig, m_ResourceLayoutIndex, + &m_pShaderResourceLayouts[0], &m_pShaderResourceLayouts[GetNumShaderStages()], GetNumShaderStages(), + Subobjects, ShaderBlobs); + D3D12_STATE_OBJECT_DESC RTPipelineDesc = {}; RTPipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE; RTPipelineDesc.NumSubobjects = static_cast(Subobjects.size()); diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 2ac15372..cbe9d7bd 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -39,6 +39,7 @@ namespace Diligent { +static constexpr auto RayTracingMask = SHADER_TYPE_RAY_GEN | SHADER_TYPE_RAY_MISS | SHADER_TYPE_RAY_CLOSEST_HIT | SHADER_TYPE_RAY_ANY_HIT | SHADER_TYPE_RAY_INTERSECTION | SHADER_TYPE_CALLABLE; RootSignature::RootParamsManager::RootParamsManager(IMemoryAllocator& MemAllocator) : m_MemAllocator{MemAllocator}, @@ -218,6 +219,13 @@ void RootSignature::InitImmutableSampler(SHADER_TYPE ShaderT ImtblSmplr.ShaderRegister = SamplerAttribs.BindPoint; ImtblSmplr.ArraySize = SamplerAttribs.BindCount; ImtblSmplr.RegisterSpace = 0; + ImtblSmplr.Name = SamplerName; + + if (ShaderType & RayTracingMask) + { + ImtblSmplr.ShaderRegister = m_NumResources[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER]; + m_NumResources[D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER] += SamplerAttribs.BindCount; + } SamplerFound = true; break; @@ -236,11 +244,22 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT const D3DShaderResourceAttribs& ShaderResAttribs, SHADER_RESOURCE_VARIABLE_TYPE VariableType, D3D12_DESCRIPTOR_RANGE_TYPE RangeType, + Uint32& BindPoint, // in/out parameter Uint32& RootIndex, // Output parameter Uint32& OffsetFromTableStart // Output parameter ) { const auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType); + + // update resource binding for ray tracing + if (ShaderType & RayTracingMask) + { + BindPoint = m_NumResources[RangeType]; + m_NumResources[RangeType] += ShaderResAttribs.BindCount; + } + else + BindPoint = ShaderResAttribs.BindPoint; + if (RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV && ShaderResAttribs.BindCount == 1) { // Allocate single CBV directly in the root signature @@ -250,7 +269,7 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT OffsetFromTableStart = 0; // Add new root view to existing root parameters - m_RootParams.AddRootView(D3D12_ROOT_PARAMETER_TYPE_CBV, RootIndex, ShaderResAttribs.BindPoint, ShaderVisibility, VariableType); + m_RootParams.AddRootView(D3D12_ROOT_PARAMETER_TYPE_CBV, RootIndex, BindPoint, ShaderVisibility, VariableType); } else { @@ -293,7 +312,7 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT Uint32 NewDescriptorRangeIndex = d3d12RootParam.DescriptorTable.NumDescriptorRanges - 1; CurrParam.SetDescriptorRange(NewDescriptorRangeIndex, RangeType, // Range type (CBV, SRV, UAV or SAMPLER) - ShaderResAttribs.BindPoint, // Shader register + BindPoint, // Shader register ShaderResAttribs.BindCount, // Number of registers used (1 for non-array resources) 0, // Register space. Always 0 for now OffsetFromTableStart // Offset in descriptors from the table start @@ -376,11 +395,11 @@ void RootSignature::AllocateImmutableSamplers(const PipelineResourceLayoutDesc& for (Uint32 sam = 0; sam < ResourceLayout.NumImmutableSamplers; ++sam) { const auto& ImtblSamDesc = ResourceLayout.ImmutableSamplers[sam]; - Uint32 ShaderStages = ImtblSamDesc.ShaderStages; + SHADER_TYPE ShaderStages = ImtblSamDesc.ShaderStages; while (ShaderStages != 0) { - auto Stage = ShaderStages & ~(ShaderStages - 1); - m_ImmutableSamplers.emplace_back(ImtblSamDesc, ShaderTypeToD3D12ShaderVisibility(static_cast(Stage))); + auto Stage = ShaderStages & ~static_cast(ShaderStages - 1); + m_ImmutableSamplers.emplace_back(ImtblSamDesc, ShaderTypeToD3D12ShaderVisibility(Stage), Stage); ShaderStages &= ~Stage; } } @@ -475,8 +494,8 @@ void RootSignature::Finalize(ID3D12Device* pd3d12Device) rootSignatureDesc.pStaticSamplers = D3D12StaticSamplers.data(); // Release immutable samplers array, we no longer need it - std::vector> EmptySamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerAttribs, GetRawAllocator(), "Allocator for vector")); - m_ImmutableSamplers.swap(EmptySamplers); + //std::vector> EmptySamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerAttribs, GetRawAllocator(), "Allocator for vector")); + //m_ImmutableSamplers.swap(EmptySamplers); VERIFY_EXPR(D3D12StaticSamplers.size() == TotalD3D12StaticSamplers); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 5923797c..30665698 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -91,7 +91,9 @@ StringPool ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& size_t StringPoolSize) { m_CbvSrvUavOffsets[0] = 0; - for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; + VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; + VarType = static_cast(VarType + 1)) { VERIFY(m_CbvSrvUavOffsets[VarType] + CbvSrvUavCount[VarType] <= std::numeric_limits::max(), "Offset is not representable in 16 bits"); m_CbvSrvUavOffsets[VarType + 1] = static_cast(m_CbvSrvUavOffsets[VarType] + CbvSrvUavCount[VarType]); @@ -99,7 +101,9 @@ StringPool ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& } m_SamplersOffsets[0] = m_CbvSrvUavOffsets[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; - for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; + VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; + VarType = static_cast(VarType + 1)) { VERIFY(m_SamplersOffsets[VarType] + SamplerCount[VarType] <= std::numeric_limits::max(), "Offset is not representable in 16 bits"); m_SamplersOffsets[VarType + 1] = static_cast(m_SamplersOffsets[VarType] + SamplerCount[VarType]); @@ -254,13 +258,15 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* { Uint32 RootIndex = D3D12Resource::InvalidRootIndex; Uint32 Offset = D3D12Resource::InvalidOffset; + Uint32 BindPoint = D3DShaderResourceAttribs::InvalidBindPoint; D3D12_DESCRIPTOR_RANGE_TYPE DescriptorRangeType = GetDescriptorRangeType(ResType); if (pRootSig) { - pRootSig->AllocateResourceSlot(GetShaderType(), PipelineType, Attribs, VarType, DescriptorRangeType, RootIndex, Offset); + pRootSig->AllocateResourceSlot(GetShaderType(), PipelineType, Attribs, VarType, DescriptorRangeType, BindPoint, RootIndex, Offset); VERIFY(RootIndex <= D3D12Resource::MaxRootIndex, "Root index excceeds allowed limit"); + VERIFY(BindPoint <= D3DShaderResourceAttribs::MaxBindPoint, "Bind point excceeds allowed limit"); } else { @@ -277,6 +283,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* RootIndex = DescriptorRangeType; Offset = Attribs.BindPoint; + BindPoint = Attribs.BindPoint; // Resources in the static resource cache are indexed by the bind point StaticResCacheTblSizes[RootIndex] = std::max(StaticResCacheTblSizes[RootIndex], Offset + Attribs.BindCount); } @@ -297,6 +304,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* SamplerId, VarType, ResType, + BindPoint, RootIndex, Offset // }; @@ -307,7 +315,10 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* auto& ExistingRes = GetResource(ResIter->second); VERIFY_EXPR(ExistingRes.VariableType == VarType); VERIFY_EXPR(ExistingRes.Attribs.GetInputType() == Attribs.GetInputType()); + VERIFY_EXPR(ExistingRes.Attribs.GetSRVDimension() == Attribs.GetSRVDimension()); VERIFY_EXPR(ExistingRes.Attribs.BindCount == Attribs.BindCount); + VERIFY_EXPR(ExistingRes.Attribs.BindPoint == Attribs.BindPoint || + Attribs.BindPoint == D3DShaderResourceAttribs::InvalidBindPoint); } }; -- cgit v1.2.3 From 53572161c4ee39ff7d66b84e4a9f4979da2f8f0b Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 12 Nov 2020 18:23:43 +0300 Subject: added address alignment checks --- Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 8496181a..d5db05e9 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2323,6 +2323,9 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) d3d12Tris.VertexFormat = TypeToRayTracingVertexFormat(TriDesc.VertexValueType, TriDesc.VertexComponentCount); VERIFY(d3d12Tris.VertexFormat != DXGI_FORMAT_UNKNOWN, "Unsupported combination of vertex value type and component count"); + VERIFY(d3d12Tris.VertexBuffer.StartAddress % GetValueSize(TriDesc.VertexValueType) == 0, "Vertex start address is not properly aligned"); + VERIFY(d3d12Tris.VertexBuffer.StrideInBytes % GetValueSize(TriDesc.VertexValueType) == 0, "Vertex stride is not properly aligned"); + TransitionOrVerifyBufferState(CmdCtx, *pVB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); if (SrcTris.pIndexBuffer) @@ -2334,6 +2337,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) d3d12Tris.IndexBuffer = pIB->GetGPUAddress() + SrcTris.IndexOffset; d3d12Tris.IndexCount = SrcTris.PrimitiveCount * 3; + VERIFY(d3d12Tris.IndexBuffer % GetValueSize(TriDesc.IndexType) == 0, "Index start address is not properly aligned"); + TransitionOrVerifyBufferState(CmdCtx, *pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } else @@ -2347,7 +2352,7 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) auto* const pTB = ValidatedCast(SrcTris.pTransformBuffer); d3d12Tris.Transform3x4 = pTB->GetGPUAddress() + SrcTris.TransformBufferOffset; - VERIFY_EXPR(d3d12Tris.Transform3x4 % D3D12_RAYTRACING_TRANSFORM3X4_BYTE_ALIGNMENT == 0); + VERIFY(d3d12Tris.Transform3x4 % D3D12_RAYTRACING_TRANSFORM3X4_BYTE_ALIGNMENT == 0, "Transform start address is not properly aligned"); TransitionOrVerifyBufferState(CmdCtx, *pTB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } @@ -2386,6 +2391,7 @@ void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs) d3d12AABs.AABBs.StrideInBytes = SrcBoxes.BoxStride; DEV_CHECK_ERR(d3d12AABs.AABBs.StartAddress % D3D12_RAYTRACING_AABB_BYTE_ALIGNMENT == 0, "AABB start address is not properly aligned"); + DEV_CHECK_ERR(d3d12AABs.AABBs.StrideInBytes % D3D12_RAYTRACING_AABB_BYTE_ALIGNMENT == 0, "AABB stride is not properly aligned"); TransitionOrVerifyBufferState(CmdCtx, *pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } -- cgit v1.2.3 From 275afc41cf421a1a78d8d9c7e46883248689b379 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Fri, 13 Nov 2020 04:11:49 +0300 Subject: bug fix for ray tracing, fixed KHR via NV emulation. --- Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index d5db05e9..9e38a75e 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2477,13 +2477,9 @@ void DeviceContextD3D12Impl::BuildTLAS(const BuildTLASAttribs& Attribs) d3d12Inst.InstanceContributionToHitGroupIndex = InstDesc.ContributionToHitGroupIndex; d3d12Inst.InstanceMask = Inst.Mask; d3d12Inst.Flags = InstanceFlagsToD3D12RTInstanceFlags(Inst.Flags); - d3d12Inst.AccelerationStructure = 0; + d3d12Inst.AccelerationStructure = pBLASD3D12->GetGPUAddress(); - if (pBLASD3D12) - { - d3d12Inst.AccelerationStructure = pBLASD3D12->GetGPUAddress(); - TransitionOrVerifyBLASState(CmdCtx, *pBLASD3D12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); - } + TransitionOrVerifyBLASState(CmdCtx, *pBLASD3D12, Attribs.BLASTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName); } UpdateBufferRegion(pInstancesD3D12, TmpSpace, Attribs.InstanceBufferOffset, Size, Attribs.InstanceBufferTransitionMode); } -- cgit v1.2.3 From 43c3821993cb3d6ec3025fa7156da8544d2a1dac Mon Sep 17 00:00:00 2001 From: azhirnov Date: Mon, 16 Nov 2020 20:30:23 +0300 Subject: D3D12 resource binding refactoring, rename LinearAllocator to FixedLinearAllocator. --- .../src/PipelineStateD3D12Impl.cpp | 128 ++++++++------------- .../src/ShaderResourceBindingD3D12Impl.cpp | 4 +- .../src/ShaderResourceLayoutD3D12.cpp | 4 +- 3 files changed, 53 insertions(+), 83 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 714643c3..74621eca 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -100,18 +100,18 @@ private: std::array m_Map; }; +using TBindingMapPerStage = std::array; -template void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateInfo, - TNameToGroupIndexMap& NameToGroupIndex, std::vector& Subobjects, + std::vector>& ShaderBlobs, DynamicLinearAllocator& TempPool, - LinearAllocator& MemPool) + IDXCompiler* compiler, + const TBindingMapPerStage& BindingMapPerStage) noexcept(false) { #define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ray tracing PSO '", CreateInfo.PSODesc.Name, "' is invalid: ", ##__VA_ARGS__) Uint32 ShaderIndex = 0; - Uint32 GroupIndex = 0; std::unordered_map UniqueShaders; @@ -134,12 +134,18 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI auto Result = UniqueShaders.emplace(pShader, nullptr); if (Result.second) { - auto& LibDesc = *TempPool.Construct(); - auto& ExportDesc = *TempPool.Construct(); - auto* pShaderD3D12 = ValidatedCast(pShader); - - LibDesc.DXILLibrary.BytecodeLength = pShaderD3D12->GetShaderByteCode()->GetBufferSize(); - LibDesc.DXILLibrary.pShaderBytecode = pShaderD3D12->GetShaderByteCode()->GetBufferPointer(); + auto& LibDesc = *TempPool.Construct(); + auto& ExportDesc = *TempPool.Construct(); + auto* pShaderD3D12 = ValidatedCast(pShader); + Uint32 ShaderIdx = GetShaderTypePipelineIndex(pShaderD3D12->GetDesc().ShaderType, PIPELINE_TYPE_RAY_TRACING); + auto& BindingMap = BindingMapPerStage[ShaderIdx]; + + CComPtr pBlob; + if (!compiler->RemapResourceBinding(BindingMap, reinterpret_cast(pShaderD3D12->GetShaderByteCode()), &pBlob)) + LOG_ERROR_AND_THROW("Failed to remap resource bindings"); + + LibDesc.DXILLibrary.BytecodeLength = pBlob->GetBufferSize(); + LibDesc.DXILLibrary.pShaderBytecode = pBlob->GetBufferPointer(); LibDesc.NumExports = 1; LibDesc.pExports = &ExportDesc; @@ -152,6 +158,7 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI ExportDesc.Name = ShaderIndexToStr(++ShaderIndex); Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY, &LibDesc}); + ShaderBlobs.push_back(pBlob); Result.first->second = ExportDesc.Name; return ExportDesc.Name; @@ -162,14 +169,12 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI return nullptr; }; + ShaderBlobs.reserve(CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount); + for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i) { const auto& GeneralShader = CreateInfo.pGeneralShaders[i]; AddDxilLib(GeneralShader.pShader, GeneralShader.Name); - - bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(GeneralShader.Name)}, GroupIndex++).second; - if (!IsUniqueName) - LOG_PSO_ERROR_AND_THROW("pGeneralShaders[", i, "].Name must be unique"); } for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i) @@ -184,10 +189,6 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI HitGroupDesc.IntersectionShaderImport = nullptr; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); - - bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(TriHitShader.Name)}, GroupIndex++).second; - if (!IsUniqueName) - LOG_PSO_ERROR_AND_THROW("pTriangleHitShaders[", i, "].Name must be unique"); } for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i) @@ -202,14 +203,8 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI HitGroupDesc.IntersectionShaderImport = AddDxilLib(ProcHitShader.pIntersectionShader, nullptr); Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); - - bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(ProcHitShader.Name)}, GroupIndex++).second; - if (!IsUniqueName) - LOG_PSO_ERROR_AND_THROW("pProceduralHitShaders[", i, "].Name must be unique"); } - VERIFY_EXPR(Uint32{CreateInfo.GeneralShaderCount} + Uint32{CreateInfo.TriangleHitShaderCount} + Uint32{CreateInfo.ProceduralHitShaderCount} == GroupIndex); - constexpr Uint32 RecursionDepthLimit = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH - 1; if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > RecursionDepthLimit) LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth (", CreateInfo.RayTracingPipeline.MaxRecursionDepth, ") must be <= ", RecursionDepthLimit); @@ -284,18 +279,12 @@ void GetShaderIdentifiers(ID3D12DeviceChild* pSO, } } -void RemapResourceBinding(IDXCompiler* compiler, - const RootSignature& RootSig, - const std::array& ResourceLayoutIndex, - const ShaderResourceLayoutD3D12* pResourceLayouts, - const ShaderResourceLayoutD3D12* pStaticLayouts, - Uint32 NumStages, - std::vector& Subobjects, - std::vector>& ShaderBlobs) noexcept(false) +void ExtractResourceBindingMap(const RootSignature& RootSig, + const std::array& ResourceLayoutIndex, + const ShaderResourceLayoutD3D12* pResourceLayouts, + const ShaderResourceLayoutD3D12* pStaticLayouts, + TBindingMapPerStage& BindingMapPerStage) noexcept(false) { - IDXCompiler::TBindingMapPerStage BindingMapPerStage; - String EntryPoint; - const auto ExtractResources = [&](const ShaderResourceLayoutD3D12* pLayouts) // { for (Uint32 ShaderIdx = 0; ShaderIdx < ResourceLayoutIndex.size(); ++ShaderIdx) @@ -315,13 +304,17 @@ void RemapResourceBinding(IDXCompiler* compi for (Uint32 i = 0; i < ResCount; ++i) { const auto& Attribs = ResLayout.GetSrvCbvUav(VarType, i).Attribs; - auto Iter = BindingMap.emplace(HashMapStringKey{Attribs.Name}, Attribs.BindPoint).first; + VERIFY_EXPR(Attribs.Name != nullptr && strlen(Attribs.Name) > 0); + + auto Iter = BindingMap.emplace(HashMapStringKey{Attribs.Name}, Attribs.BindPoint).first; VERIFY_EXPR(Iter->second == Attribs.BindPoint); } for (Uint32 i = 0; i < SampCount; ++i) { const auto& Attribs = ResLayout.GetSampler(VarType, i).Attribs; - auto Iter = BindingMap.emplace(HashMapStringKey{Attribs.Name}, Attribs.BindPoint).first; + VERIFY_EXPR(Attribs.Name != nullptr && strlen(Attribs.Name) > 0); + + auto Iter = BindingMap.emplace(HashMapStringKey{Attribs.Name}, Attribs.BindPoint).first; VERIFY_EXPR(Iter->second == Attribs.BindPoint); } } @@ -338,34 +331,13 @@ void RemapResourceBinding(IDXCompiler* compi if (LayoutIdx < 0) continue; + VERIFY_EXPR(ImtblSmplr.Name.length() > 0); + if (ImtblSmplr.Name.empty()) + continue; + auto& BindingMap = BindingMapPerStage[ShaderIdx]; BindingMap.emplace(HashMapStringKey{ImtblSmplr.Name.c_str()}, ImtblSmplr.ShaderRegister); } - - for (auto& SubObj : Subobjects) - { - if (SubObj.Type == D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY) - { - auto& DxilLib = *reinterpret_cast(const_cast(SubObj.pDesc)); - VERIFY_EXPR(DxilLib.NumExports == 1); - - const auto& Export = *DxilLib.pExports; - EntryPoint.resize(wcslen(Export.ExportToRename)); - for (size_t i = 0; i < EntryPoint.size(); ++i) - EntryPoint[i] = static_cast(Export.ExportToRename[i]); - - CComPtr pBlob; - compiler->RemapResourceBinding(BindingMapPerStage, EntryPoint.c_str(), DxilLib.DXILLibrary.pShaderBytecode, DxilLib.DXILLibrary.BytecodeLength, &pBlob); - - if (!pBlob) - LOG_ERROR_AND_THROW("Failed to remap resource bindings"); - - DxilLib.DXILLibrary.pShaderBytecode = pBlob->GetBufferPointer(); - DxilLib.DXILLibrary.BytecodeLength = pBlob->GetBufferSize(); - - ShaderBlobs.push_back(pBlob); - } - } } } // namespace @@ -398,7 +370,7 @@ void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& Create ExtractShaders(CreateInfo, ShaderStages); - LinearAllocator MemPool{GetRawAllocator()}; + FixedLinearAllocator MemPool{GetRawAllocator()}; const auto NumShaderStages = GetNumShaderStages(); VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size()); @@ -445,7 +417,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { TShaderStages ShaderStages; InitInternalObjects(CreateInfo, ShaderStages, nullptr, - [this](const GraphicsPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // + [this](const GraphicsPipelineStateCreateInfo& CreateInfo, FixedLinearAllocator& MemPool) // { InitializePipelineDesc(CreateInfo, MemPool); } // @@ -656,7 +628,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { TShaderStages ShaderStages; InitInternalObjects(CreateInfo, ShaderStages, nullptr, - [this](const ComputePipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // + [this](const ComputePipelineStateCreateInfo& CreateInfo, FixedLinearAllocator& MemPool) // { InitializePipelineDesc(CreateInfo, MemPool); } // @@ -713,22 +685,26 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { - LocalRootSignature LocalRootSig{CreateInfo.pShaderRecordName, CreateInfo.RayTracingPipeline.ShaderRecordSize}; - TShaderStages ShaderStages; - std::vector Subobjects; - DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10}; + LocalRootSignature LocalRootSig{CreateInfo.pShaderRecordName, CreateInfo.RayTracingPipeline.ShaderRecordSize}; + TShaderStages ShaderStages; + DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10}; InitInternalObjects(CreateInfo, ShaderStages, &LocalRootSig, - [&](const RayTracingPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) // + [&](const RayTracingPipelineStateCreateInfo& CreateInfo, FixedLinearAllocator& MemPool) // { - TNameToGroupIndexMap NameToGroupIndex; - BuildRTPipelineDescription(CreateInfo, NameToGroupIndex, Subobjects, TempPool, MemPool); - InitializePipelineDesc(CreateInfo, std::move(NameToGroupIndex), MemPool); + InitializePipelineDesc(CreateInfo, MemPool); } // ); auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); + TBindingMapPerStage BindingMapPerStage; + ExtractResourceBindingMap(m_RootSig, m_ResourceLayoutIndex, &m_pShaderResourceLayouts[0], &m_pShaderResourceLayouts[GetNumShaderStages()], BindingMapPerStage); + + std::vector Subobjects; + std::vector> ShaderBlobs; + BuildRTPipelineDescription(CreateInfo, Subobjects, ShaderBlobs, TempPool, pDeviceD3D12->GetDxCompiler(), BindingMapPerStage); + D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig.GetD3D12RootSignature()}; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot}); @@ -736,11 +712,6 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* if (LocalRoot.pLocalRootSignature) Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE, &LocalRoot}); - std::vector> ShaderBlobs; - RemapResourceBinding(pDeviceD3D12->GetDxCompiler(), m_RootSig, m_ResourceLayoutIndex, - &m_pShaderResourceLayouts[0], &m_pShaderResourceLayouts[GetNumShaderStages()], GetNumShaderStages(), - Subobjects, ShaderBlobs); - D3D12_STATE_OBJECT_DESC RTPipelineDesc = {}; RTPipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE; RTPipelineDesc.NumSubobjects = static_cast(Subobjects.size()); @@ -812,7 +783,6 @@ void PipelineStateD3D12Impl::Destruct() IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipelineStateBase) - void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot) diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp index 1511bd01..c7c3ede6 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp @@ -30,7 +30,7 @@ #include "PipelineStateD3D12Impl.hpp" #include "ShaderD3D12Impl.hpp" #include "RenderDeviceD3D12Impl.hpp" -#include "LinearAllocator.hpp" +#include "FixedLinearAllocator.hpp" namespace Diligent { @@ -53,7 +53,7 @@ ShaderResourceBindingD3D12Impl::ShaderResourceBindingD3D12Impl(IReferenceCounter { m_ResourceLayoutIndex.fill(-1); - LinearAllocator MemPool{GetRawAllocator()}; + FixedLinearAllocator MemPool{GetRawAllocator()}; MemPool.AddSpace(m_NumShaders); MemPool.Reserve(); m_pShaderVarMgrs = MemPool.ConstructArray(m_NumShaders, std::ref(*this), std::ref(m_ShaderResourceCache)); diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 30665698..f5b4e806 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -39,7 +39,7 @@ #include "PipelineStateD3D12Impl.hpp" #include "ShaderResourceVariableBase.hpp" #include "ShaderVariableD3DBase.hpp" -#include "LinearAllocator.hpp" +#include "FixedLinearAllocator.hpp" #include "TopLevelASD3D12.h" namespace Diligent @@ -110,7 +110,7 @@ StringPool ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& VERIFY_EXPR(GetSamplerCount(VarType) == SamplerCount[VarType]); } - LinearAllocator MemPool{Allocator}; + FixedLinearAllocator MemPool{Allocator}; MemPool.AddSpace(GetTotalResourceCount()); MemPool.AddSpace(StringPoolSize); -- cgit v1.2.3 From f833f01c4fb6174aed9f90edb1266631a444cecc Mon Sep 17 00:00:00 2001 From: azhirnov Date: Mon, 16 Nov 2020 23:37:39 +0300 Subject: Some fixes for PSO --- Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 74621eca..3c63b7d7 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -205,7 +205,9 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); } + constexpr Uint32 MaxPayloadSize = sizeof(float) * 8; constexpr Uint32 RecursionDepthLimit = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH - 1; + if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > RecursionDepthLimit) LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth (", CreateInfo.RayTracingPipeline.MaxRecursionDepth, ") must be <= ", RecursionDepthLimit); @@ -216,7 +218,7 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI auto& ShaderConfig = *TempPool.Construct(); ShaderConfig.MaxAttributeSizeInBytes = CreateInfo.MaxAttributeSize == 0 ? D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES : CreateInfo.MaxAttributeSize; - ShaderConfig.MaxPayloadSizeInBytes = CreateInfo.MaxPayloadSize == 0 ? 32 : CreateInfo.MaxPayloadSize; + ShaderConfig.MaxPayloadSizeInBytes = CreateInfo.MaxPayloadSize == 0 ? MaxPayloadSize : CreateInfo.MaxPayloadSize; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &ShaderConfig}); #undef LOG_PSO_ERROR_AND_THROW } -- cgit v1.2.3 From a8d6acd496404dc5b01df997ad9d07504d6ccf1b Mon Sep 17 00:00:00 2001 From: azhirnov Date: Wed, 18 Nov 2020 05:01:18 +0300 Subject: Removed SWAP_CHAIN_USAGE_UNORDERED_ACCESS, fixed shader group checks --- Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 3c63b7d7..f98781eb 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -205,7 +205,7 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); } - constexpr Uint32 MaxPayloadSize = sizeof(float) * 8; + constexpr Uint32 DefaultPayloadSize = sizeof(float) * 8; constexpr Uint32 RecursionDepthLimit = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH - 1; if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > RecursionDepthLimit) @@ -218,7 +218,7 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI auto& ShaderConfig = *TempPool.Construct(); ShaderConfig.MaxAttributeSizeInBytes = CreateInfo.MaxAttributeSize == 0 ? D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES : CreateInfo.MaxAttributeSize; - ShaderConfig.MaxPayloadSizeInBytes = CreateInfo.MaxPayloadSize == 0 ? MaxPayloadSize : CreateInfo.MaxPayloadSize; + ShaderConfig.MaxPayloadSizeInBytes = CreateInfo.MaxPayloadSize == 0 ? DefaultPayloadSize : CreateInfo.MaxPayloadSize; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &ShaderConfig}); #undef LOG_PSO_ERROR_AND_THROW } -- cgit v1.2.3 From c3058653add8f8a9d147de652a94c178a6973ac6 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Wed, 25 Nov 2020 19:14:57 +0300 Subject: Added RootSignatureBuilder, some fixed for vulkan ray tracing --- .../include/PipelineStateD3D12Impl.hpp | 4 +- .../GraphicsEngineD3D12/include/RootSignature.hpp | 116 ++++---- .../include/ShaderResourceLayoutD3D12.hpp | 2 +- .../src/PipelineStateD3D12Impl.cpp | 31 +- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 312 +++++++++++---------- .../src/ShaderResourceLayoutD3D12.cpp | 2 +- 6 files changed, 258 insertions(+), 209 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index 15eff0d9..021a38b0 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -139,8 +139,8 @@ private: using TShaderStages = std::vector; template - void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot, InitPSODescType InitPSODesc); - void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot); + void InitInternalObjects(const PSOCreateInfoType& CreateInfo, RootSignatureBuilder& RootSigBuilder, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot, InitPSODescType InitPSODesc); + void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, RootSignatureBuilder& RootSigBuilder, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot); void Destruct(); diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index fe78a852..44b83433 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -298,33 +298,15 @@ private: /// Implementation of the Diligent::RootSignature class class RootSignature { + friend class RootSignatureBuilder; + public: RootSignature(); - void AllocateImmutableSamplers(const PipelineResourceLayoutDesc& ResourceLayout); - - void Finalize(ID3D12Device* pd3d12Device); - ID3D12RootSignature* GetD3D12RootSignature() const { return m_pd3d12RootSignature; } - size_t GetResourceCacheRequiredMemSize() const; - void InitResourceCache(class RenderDeviceD3D12Impl* pDeviceD3D12Impl, class ShaderResourceCacheD3D12& ResourceCache, IMemoryAllocator& CacheMemAllocator) const; - void InitImmutableSampler(SHADER_TYPE ShaderType, - const char* SamplerName, - const char* SamplerSuffix, - const D3DShaderResourceAttribs& ShaderResAttribs); - - void AllocateResourceSlot(SHADER_TYPE ShaderType, - PIPELINE_TYPE PipelineType, - const D3DShaderResourceAttribs& ShaderResAttribs, - SHADER_RESOURCE_VARIABLE_TYPE VariableType, - D3D12_DESCRIPTOR_RANGE_TYPE RangeType, - Uint32& BindPoint, - Uint32& RootIndex, - Uint32& OffsetFromTableStart); - // This method should be thread-safe as it does not modify any object state void (RootSignature::*CommitDescriptorHandles)(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, ShaderResourceCacheD3D12& ResourceCache, @@ -374,32 +356,7 @@ public: return m_RootParams.GetHash(); } - // Note: sizeof(m_ImmutableSamplers) == 56 (MS compiler, release x64) - struct ImmutableSamplerAttribs - { - ImmutableSamplerDesc SamplerDesc; - UINT ShaderRegister = static_cast(-1); - UINT ArraySize = 0; - UINT RegisterSpace = 0; - D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast(-1); - String Name; - SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN; - - ImmutableSamplerAttribs() noexcept {} - ImmutableSamplerAttribs(const ImmutableSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility, SHADER_TYPE Stage) noexcept : - SamplerDesc(SamDesc), - ShaderVisibility(Visibility), - ShaderType{Stage} - {} - }; - const ImmutableSamplerAttribs* GetImmutableSamplers() const { return m_ImmutableSamplers.data(); } - size_t GetImmutableSamplerCount() const { return m_ImmutableSamplers.size(); } - private: -#ifdef DILIGENT_DEBUG - void dbgVerifyRootParameters() const; -#endif - #ifdef DILIGENT_DEVELOPMENT static void DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resource& Res, D3D12_DESCRIPTOR_RANGE_TYPE RangeType); @@ -500,12 +457,8 @@ private: // This array contains the same data for Sampler root table std::array m_SamplerRootTablesMap = {}; - std::array m_NumResources = {}; - RootParamsManager m_RootParams; - std::vector> m_ImmutableSamplers; - IMemoryAllocator& m_MemAllocator; // Commits descriptor handles for static and mutable variables @@ -524,6 +477,71 @@ private: bool ValidateStates) const; }; + +class RootSignatureBuilder +{ +public: + explicit RootSignatureBuilder(RootSignature& RootSig); + + void AllocateImmutableSamplers(const PipelineResourceLayoutDesc& ResourceLayout); + + void InitImmutableSampler(SHADER_TYPE ShaderType, + const char* SamplerName, + const char* SamplerSuffix, + const D3DShaderResourceAttribs& ShaderResAttribs); + + void AllocateResourceSlot(SHADER_TYPE ShaderType, + PIPELINE_TYPE PipelineType, + const D3DShaderResourceAttribs& ShaderResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType, + Uint32& BindPoint, + Uint32& RootIndex, + Uint32& OffsetFromTableStart); + + void Finalize(ID3D12Device* pd3d12Device); + + size_t GetResourceCacheRequiredMemSize() const; + + size_t GetHash() const + { + return m_RootSig.GetHash(); + } + + // Note: sizeof(m_ImmutableSamplers) == 56 (MS compiler, release x64) + struct ImmutableSamplerAttribs + { + ImmutableSamplerDesc SamplerDesc; + UINT ShaderRegister = static_cast(-1); + UINT ArraySize = 0; + UINT RegisterSpace = 0; + D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast(-1); + String Name; + SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN; + + ImmutableSamplerAttribs() noexcept {} + ImmutableSamplerAttribs(const ImmutableSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility, SHADER_TYPE Stage) noexcept : + SamplerDesc(SamDesc), + ShaderVisibility(Visibility), + ShaderType{Stage} + {} + }; + const ImmutableSamplerAttribs* GetImmutableSamplers() const { return m_ImmutableSamplers.data(); } + size_t GetImmutableSamplerCount() const { return m_ImmutableSamplers.size(); } + +private: +#ifdef DILIGENT_DEBUG + void dbgVerifyRootParameters() const; +#endif + + RootSignature& m_RootSig; + + std::array m_NumResources = {}; + + std::vector> m_ImmutableSamplers; +}; + + void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, CommandContext& CmdCtx, bool IsCompute, diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index 6f71f8f8..de0ecc29 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -140,7 +140,7 @@ public: const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes, Uint32 NumAllowedTypes, ShaderResourceCacheD3D12* pResourceCache, - class RootSignature* pRootSig, + class RootSignatureBuilder* pRootSig, class LocalRootSignature* pLocalRootSig); // clang-format off diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index f98781eb..6e71fcd6 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -281,7 +281,7 @@ void GetShaderIdentifiers(ID3D12DeviceChild* pSO, } } -void ExtractResourceBindingMap(const RootSignature& RootSig, +void ExtractResourceBindingMap(const RootSignatureBuilder& RootSig, const std::array& ResourceLayoutIndex, const ShaderResourceLayoutD3D12* pResourceLayouts, const ShaderResourceLayoutD3D12* pStaticLayouts, @@ -364,6 +364,7 @@ size_t PipelineStateD3D12Impl::ShaderStageInfo::Count() const template void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, + RootSignatureBuilder& RootSigBuilder, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot, InitPSODescType InitPSODesc) @@ -400,12 +401,12 @@ void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& Create InitPSODesc(CreateInfo, MemPool); - m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); + RootSigBuilder.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); // It is important to construct all objects before initializing them because if an exception is thrown, // destructors will be called for all objects - InitResourceLayouts(CreateInfo, ShaderStages, pLocalRoot); + InitResourceLayouts(CreateInfo, RootSigBuilder, ShaderStages, pLocalRoot); } @@ -417,8 +418,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { - TShaderStages ShaderStages; - InitInternalObjects(CreateInfo, ShaderStages, nullptr, + RootSignatureBuilder RootSigBuilder{m_RootSig}; + TShaderStages ShaderStages; + InitInternalObjects(CreateInfo, RootSigBuilder, ShaderStages, nullptr, [this](const GraphicsPipelineStateCreateInfo& CreateInfo, FixedLinearAllocator& MemPool) // { InitializePipelineDesc(CreateInfo, MemPool); @@ -628,8 +630,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { - TShaderStages ShaderStages; - InitInternalObjects(CreateInfo, ShaderStages, nullptr, + RootSignatureBuilder RootSigBuilder{m_RootSig}; + TShaderStages ShaderStages; + InitInternalObjects(CreateInfo, RootSigBuilder, ShaderStages, nullptr, [this](const ComputePipelineStateCreateInfo& CreateInfo, FixedLinearAllocator& MemPool) // { InitializePipelineDesc(CreateInfo, MemPool); @@ -690,8 +693,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* LocalRootSignature LocalRootSig{CreateInfo.pShaderRecordName, CreateInfo.RayTracingPipeline.ShaderRecordSize}; TShaderStages ShaderStages; DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10}; + RootSignatureBuilder RootSigBuilder{m_RootSig}; - InitInternalObjects(CreateInfo, ShaderStages, &LocalRootSig, + InitInternalObjects(CreateInfo, RootSigBuilder, ShaderStages, &LocalRootSig, [&](const RayTracingPipelineStateCreateInfo& CreateInfo, FixedLinearAllocator& MemPool) // { InitializePipelineDesc(CreateInfo, MemPool); @@ -701,7 +705,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); TBindingMapPerStage BindingMapPerStage; - ExtractResourceBindingMap(m_RootSig, m_ResourceLayoutIndex, &m_pShaderResourceLayouts[0], &m_pShaderResourceLayouts[GetNumShaderStages()], BindingMapPerStage); + ExtractResourceBindingMap(RootSigBuilder, m_ResourceLayoutIndex, &m_pShaderResourceLayouts[0], &m_pShaderResourceLayouts[GetNumShaderStages()], BindingMapPerStage); std::vector Subobjects; std::vector> ShaderBlobs; @@ -786,6 +790,7 @@ void PipelineStateD3D12Impl::Destruct() IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipelineStateBase) void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, + RootSignatureBuilder& RootSigBuilder, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot) { @@ -825,7 +830,7 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& nullptr, 0, nullptr, - &m_RootSig, + &RootSigBuilder, pLocalRoot // ); @@ -850,7 +855,7 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& 0 // ); } - m_RootSig.Finalize(pd3d12Device); + RootSigBuilder.Finalize(pd3d12Device); if (m_Desc.SRBAllocationGranularity > 1) { @@ -867,11 +872,11 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& ShaderVarMgrDataSizes[s] = ShaderVariableManagerD3D12::GetRequiredMemorySize(m_pShaderResourceLayouts[s], AllowedVarTypes.data(), static_cast(AllowedVarTypes.size()), NumVariablesUnused); } - auto CacheMemorySize = m_RootSig.GetResourceCacheRequiredMemSize(); + auto CacheMemorySize = RootSigBuilder.GetResourceCacheRequiredMemSize(); m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderStages(), ShaderVarMgrDataSizes.data(), 1, &CacheMemorySize); } - m_ShaderResourceLayoutHash = m_RootSig.GetHash(); + m_ShaderResourceLayoutHash = RootSigBuilder.GetHash(); } void PipelineStateD3D12Impl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index cbe9d7bd..ab997d1d 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -165,49 +165,18 @@ size_t RootSignature::RootParamsManager::GetHash() const return hash; } -RootSignature::RootSignature() : - m_RootParams{GetRawAllocator()}, - m_MemAllocator{GetRawAllocator()}, - m_ImmutableSamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerAttribs, GetRawAllocator(), "Allocator for vector")) -{ - m_SrvCbvUavRootTablesMap.fill(InvalidRootTableIndex); - m_SamplerRootTablesMap.fill(InvalidRootTableIndex); -} -// clang-format off -static D3D12_DESCRIPTOR_HEAP_TYPE RangeType2HeapTypeMap[] -{ - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0 - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_UAV = ( D3D12_DESCRIPTOR_RANGE_TYPE_SRV + 1 ) - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_CBV = ( D3D12_DESCRIPTOR_RANGE_TYPE_UAV + 1 ) - D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER //D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = ( D3D12_DESCRIPTOR_RANGE_TYPE_CBV + 1 ) -}; -// clang-format on -D3D12_DESCRIPTOR_HEAP_TYPE HeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType) +RootSignatureBuilder::RootSignatureBuilder(RootSignature& RootSig) : + m_RootSig{RootSig}, + m_ImmutableSamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerAttribs, GetRawAllocator(), "Allocator for vector")) { - VERIFY_EXPR(RangeType >= D3D12_DESCRIPTOR_RANGE_TYPE_SRV && RangeType <= D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER); - auto HeapType = RangeType2HeapTypeMap[RangeType]; - -#ifdef DILIGENT_DEBUG - switch (RangeType) - { - // clang-format off - case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; - case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; - case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; - case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); break; - // clang-format on - default: UNEXPECTED("Unexpected descriptor range type"); break; - } -#endif - return HeapType; } -void RootSignature::InitImmutableSampler(SHADER_TYPE ShaderType, - const char* SamplerName, - const char* SamplerSuffix, - const D3DShaderResourceAttribs& SamplerAttribs) +void RootSignatureBuilder::InitImmutableSampler(SHADER_TYPE ShaderType, + const char* SamplerName, + const char* SamplerSuffix, + const D3DShaderResourceAttribs& SamplerAttribs) { auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType); auto SamplerFound = false; @@ -238,18 +207,20 @@ void RootSignature::InitImmutableSampler(SHADER_TYPE ShaderT } } + // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Shader-Resource-Layouts-and-Root-Signature-in-a-Pipeline-State-Object -void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderType, - PIPELINE_TYPE PipelineType, - const D3DShaderResourceAttribs& ShaderResAttribs, - SHADER_RESOURCE_VARIABLE_TYPE VariableType, - D3D12_DESCRIPTOR_RANGE_TYPE RangeType, - Uint32& BindPoint, // in/out parameter - Uint32& RootIndex, // Output parameter - Uint32& OffsetFromTableStart // Output parameter +void RootSignatureBuilder::AllocateResourceSlot(SHADER_TYPE ShaderType, + PIPELINE_TYPE PipelineType, + const D3DShaderResourceAttribs& ShaderResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType, + Uint32& BindPoint, // in/out parameter + Uint32& RootIndex, // Output parameter + Uint32& OffsetFromTableStart // Output parameter ) { const auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType); + auto& RootParams = m_RootSig.m_RootParams; // update resource binding for ray tracing if (ShaderType & RayTracingMask) @@ -265,11 +236,11 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT // Allocate single CBV directly in the root signature // Get the next available root index past all allocated tables and root views - RootIndex = m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); + RootIndex = RootParams.GetNumRootTables() + RootParams.GetNumRootViews(); OffsetFromTableStart = 0; // Add new root view to existing root parameters - m_RootParams.AddRootView(D3D12_ROOT_PARAMETER_TYPE_CBV, RootIndex, BindPoint, ShaderVisibility, VariableType); + RootParams.AddRootView(D3D12_ROOT_PARAMETER_TYPE_CBV, RootIndex, BindPoint, ShaderVisibility, VariableType); } else { @@ -278,26 +249,26 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT const auto RootTableType = (VariableType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) ? SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC : SHADER_RESOURCE_VARIABLE_TYPE_STATIC; const auto TableIndKey = ShaderInd * SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES + RootTableType; // Get the table array index (this is not the root index!) - auto& RootTableArrayInd = ((RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER) ? m_SamplerRootTablesMap : m_SrvCbvUavRootTablesMap)[TableIndKey]; - if (RootTableArrayInd == InvalidRootTableIndex) + auto& RootTableArrayInd = ((RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER) ? m_RootSig.m_SamplerRootTablesMap : m_RootSig.m_SrvCbvUavRootTablesMap)[TableIndKey]; + if (RootTableArrayInd == RootSignature::InvalidRootTableIndex) { // Root table has not been assigned to this combination yet // Get the next available root index past all allocated tables and root views - RootIndex = m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); - VERIFY_EXPR(m_RootParams.GetNumRootTables() < 255); - RootTableArrayInd = static_cast(m_RootParams.GetNumRootTables()); + RootIndex = RootParams.GetNumRootTables() + RootParams.GetNumRootViews(); + VERIFY_EXPR(RootParams.GetNumRootTables() < 255); + RootTableArrayInd = static_cast(RootParams.GetNumRootTables()); // Add root table with one single-descriptor range - m_RootParams.AddRootTable(RootIndex, ShaderVisibility, RootTableType, 1); + RootParams.AddRootTable(RootIndex, ShaderVisibility, RootTableType, 1); } else { // Add a new single-descriptor range to the existing table at index RootTableArrayInd - m_RootParams.AddDescriptorRanges(RootTableArrayInd, 1); + RootParams.AddDescriptorRanges(RootTableArrayInd, 1); } // Reference to either existing or just added table - auto& CurrParam = m_RootParams.GetRootTable(RootTableArrayInd); + auto& CurrParam = RootParams.GetRootTable(RootTableArrayInd); RootIndex = CurrParam.GetRootIndex(); const auto& d3d12RootParam = static_cast(CurrParam); @@ -321,73 +292,7 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT } -#ifdef DILIGENT_DEBUG -void RootSignature::dbgVerifyRootParameters() const -{ - Uint32 dbgTotalSrvCbvUavSlots = 0; - Uint32 dbgTotalSamplerSlots = 0; - for (Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) - { - auto& RootTable = m_RootParams.GetRootTable(rt); - auto& Param = static_cast(RootTable); - VERIFY(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table"); - auto& Table = Param.DescriptorTable; - VERIFY(Table.NumDescriptorRanges > 0, "Descriptor table is expected to be non-empty"); - VERIFY(Table.pDescriptorRanges[0].OffsetInDescriptorsFromTableStart == 0, "Descriptor table is expected to start at 0 offset"); - bool IsResourceTable = Table.pDescriptorRanges[0].RangeType != D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; - for (Uint32 r = 0; r < Table.NumDescriptorRanges; ++r) - { - const auto& range = Table.pDescriptorRanges[r]; - if (IsResourceTable) - { - // clang-format off - VERIFY(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV || - range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV || - range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, - "Resource type is expected to be SRV, CBV or UAV"); - // clang-format on - dbgTotalSrvCbvUavSlots += range.NumDescriptors; - } - else - { - VERIFY(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Resource type is expected to be sampler"); - dbgTotalSamplerSlots += range.NumDescriptors; - } - - if (r > 0) - { - VERIFY(Table.pDescriptorRanges[r].OffsetInDescriptorsFromTableStart == Table.pDescriptorRanges[r - 1].OffsetInDescriptorsFromTableStart + Table.pDescriptorRanges[r - 1].NumDescriptors, "Ranges in a descriptor table are expected to be consequtive"); - } - } - } - - Uint32 dbgTotalRootViews = 0; - for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) - { - auto& RootView = m_RootParams.GetRootView(rv); - auto& Param = static_cast(RootView); - VERIFY(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV, "Root parameter is expected to be a CBV"); - ++dbgTotalRootViews; - } - - // clang-format off - VERIFY(dbgTotalSrvCbvUavSlots == - m_TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + - m_TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + - m_TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of SRV CBV UAV resource slots"); - VERIFY(dbgTotalSamplerSlots == - m_TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + - m_TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + - m_TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of sampler slots"); - VERIFY(dbgTotalRootViews == - m_TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + - m_TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + - m_TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of root views"); - // clang-format on -} -#endif - -void RootSignature::AllocateImmutableSamplers(const PipelineResourceLayoutDesc& ResourceLayout) +void RootSignatureBuilder::AllocateImmutableSamplers(const PipelineResourceLayoutDesc& ResourceLayout) { if (ResourceLayout.NumImmutableSamplers > 0) { @@ -406,11 +311,18 @@ void RootSignature::AllocateImmutableSamplers(const PipelineResourceLayoutDesc& } } -void RootSignature::Finalize(ID3D12Device* pd3d12Device) + +void RootSignatureBuilder::Finalize(ID3D12Device* pd3d12Device) { - for (Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) + auto& RootParams = m_RootSig.m_RootParams; + auto& TotalSamplerSlots = m_RootSig.m_TotalSamplerSlots; + auto& TotalSrvCbvUavSlots = m_RootSig.m_TotalSrvCbvUavSlots; + auto& TotalRootViews = m_RootSig.m_TotalRootViews; + auto& d3d12RootSignature = m_RootSig.m_pd3d12RootSignature; + + for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt) { - const auto& RootTbl = m_RootParams.GetRootTable(rt); + const auto& RootTbl = RootParams.GetRootTable(rt); const auto& d3d12RootParam = static_cast(RootTbl); VERIFY_EXPR(d3d12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE); @@ -418,13 +330,13 @@ void RootSignature::Finalize(ID3D12Device* pd3d12Device) VERIFY(d3d12RootParam.DescriptorTable.NumDescriptorRanges > 0 && TableSize > 0, "Unexpected empty descriptor table"); auto IsSamplerTable = d3d12RootParam.DescriptorTable.pDescriptorRanges[0].RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; auto VarType = RootTbl.GetShaderVariableType(); - (IsSamplerTable ? m_TotalSamplerSlots : m_TotalSrvCbvUavSlots)[VarType] += TableSize; + (IsSamplerTable ? TotalSamplerSlots : TotalSrvCbvUavSlots)[VarType] += TableSize; } - for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + for (Uint32 rv = 0; rv < RootParams.GetNumRootViews(); ++rv) { - const auto& RootView = m_RootParams.GetRootView(rv); - ++m_TotalRootViews[RootView.GetShaderVariableType()]; + const auto& RootView = RootParams.GetRootView(rv); + ++TotalRootViews[RootView.GetShaderVariableType()]; } #ifdef DILIGENT_DEBUG @@ -434,19 +346,19 @@ void RootSignature::Finalize(ID3D12Device* pd3d12Device) D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; - auto TotalParams = m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); + auto TotalParams = RootParams.GetNumRootTables() + RootParams.GetNumRootViews(); std::vector> D3D12Parameters(TotalParams, D3D12_ROOT_PARAMETER{}, STD_ALLOCATOR_RAW_MEM(D3D12_ROOT_PARAMETER, GetRawAllocator(), "Allocator for vector")); - for (Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) + for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt) { - const auto& RootTable = m_RootParams.GetRootTable(rt); + const auto& RootTable = RootParams.GetRootTable(rt); const D3D12_ROOT_PARAMETER& SrcParam = RootTable; VERIFY(SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE && SrcParam.DescriptorTable.NumDescriptorRanges > 0, "Non-empty descriptor table is expected"); D3D12Parameters[RootTable.GetRootIndex()] = SrcParam; } - for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + for (Uint32 rv = 0; rv < RootParams.GetNumRootViews(); ++rv) { - const auto& RootView = m_RootParams.GetRootView(rv); + const auto& RootView = RootParams.GetRootView(rv); const D3D12_ROOT_PARAMETER& SrcParam = RootView; VERIFY(SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV, "Root CBV is expected"); D3D12Parameters[RootView.GetRootIndex()] = SrcParam; @@ -504,30 +416,144 @@ void RootSignature::Finalize(ID3D12Device* pd3d12Device) CComPtr signature; CComPtr error; HRESULT hr = D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); + if (error) + { + LOG_ERROR_MESSAGE("Error: ", (const char*)error->GetBufferPointer()); + } CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature"); - hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pd3d12RootSignature), reinterpret_cast(static_cast(&m_pd3d12RootSignature))); + hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(d3d12RootSignature), reinterpret_cast(static_cast(&d3d12RootSignature))); CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature"); - bool bHasDynamicDescriptors = m_TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0 || m_TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0; + bool bHasDynamicDescriptors = TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0 || TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0; if (bHasDynamicDescriptors) { - CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD; - TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD; + m_RootSig.CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD; + m_RootSig.TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD; } else { - CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM; - TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM; + m_RootSig.CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM; + m_RootSig.TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM; } } -size_t RootSignature::GetResourceCacheRequiredMemSize() const + +#ifdef DILIGENT_DEBUG +void RootSignatureBuilder::dbgVerifyRootParameters() const { - auto CacheTableSizes = GetCacheTableSizes(); + auto& RootParams = m_RootSig.m_RootParams; + auto& TotalSamplerSlots = m_RootSig.m_TotalSamplerSlots; + auto& TotalSrvCbvUavSlots = m_RootSig.m_TotalSrvCbvUavSlots; + auto& TotalRootViews = m_RootSig.m_TotalRootViews; + + Uint32 dbgTotalSrvCbvUavSlots = 0; + Uint32 dbgTotalSamplerSlots = 0; + for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt) + { + auto& RootTable = RootParams.GetRootTable(rt); + auto& Param = static_cast(RootTable); + VERIFY(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table"); + auto& Table = Param.DescriptorTable; + VERIFY(Table.NumDescriptorRanges > 0, "Descriptor table is expected to be non-empty"); + VERIFY(Table.pDescriptorRanges[0].OffsetInDescriptorsFromTableStart == 0, "Descriptor table is expected to start at 0 offset"); + bool IsResourceTable = Table.pDescriptorRanges[0].RangeType != D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + for (Uint32 r = 0; r < Table.NumDescriptorRanges; ++r) + { + const auto& range = Table.pDescriptorRanges[r]; + if (IsResourceTable) + { + // clang-format off + VERIFY(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV || + range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV || + range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, + "Resource type is expected to be SRV, CBV or UAV"); + // clang-format on + dbgTotalSrvCbvUavSlots += range.NumDescriptors; + } + else + { + VERIFY(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Resource type is expected to be sampler"); + dbgTotalSamplerSlots += range.NumDescriptors; + } + + if (r > 0) + { + VERIFY(Table.pDescriptorRanges[r].OffsetInDescriptorsFromTableStart == Table.pDescriptorRanges[r - 1].OffsetInDescriptorsFromTableStart + Table.pDescriptorRanges[r - 1].NumDescriptors, "Ranges in a descriptor table are expected to be consequtive"); + } + } + } + + Uint32 dbgTotalRootViews = 0; + for (Uint32 rv = 0; rv < RootParams.GetNumRootViews(); ++rv) + { + auto& RootView = RootParams.GetRootView(rv); + auto& Param = static_cast(RootView); + VERIFY(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV, "Root parameter is expected to be a CBV"); + ++dbgTotalRootViews; + } + + // clang-format off + VERIFY(dbgTotalSrvCbvUavSlots == + TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + + TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + + TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of SRV CBV UAV resource slots"); + VERIFY(dbgTotalSamplerSlots == + TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + + TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + + TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of sampler slots"); + VERIFY(dbgTotalRootViews == + TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + + TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + + TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of root views"); + // clang-format on +} +#endif + +size_t RootSignatureBuilder::GetResourceCacheRequiredMemSize() const +{ + auto CacheTableSizes = m_RootSig.GetCacheTableSizes(); return ShaderResourceCacheD3D12::GetRequiredMemorySize(static_cast(CacheTableSizes.size()), CacheTableSizes.data()); } + +RootSignature::RootSignature() : + m_RootParams{GetRawAllocator()}, + m_MemAllocator{GetRawAllocator()} +{ + m_SrvCbvUavRootTablesMap.fill(InvalidRootTableIndex); + m_SamplerRootTablesMap.fill(InvalidRootTableIndex); +} + +// clang-format off +static D3D12_DESCRIPTOR_HEAP_TYPE RangeType2HeapTypeMap[] +{ + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0 + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_UAV = ( D3D12_DESCRIPTOR_RANGE_TYPE_SRV + 1 ) + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_CBV = ( D3D12_DESCRIPTOR_RANGE_TYPE_UAV + 1 ) + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER //D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = ( D3D12_DESCRIPTOR_RANGE_TYPE_CBV + 1 ) +}; +// clang-format on +D3D12_DESCRIPTOR_HEAP_TYPE HeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType) +{ + VERIFY_EXPR(RangeType >= D3D12_DESCRIPTOR_RANGE_TYPE_SRV && RangeType <= D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER); + auto HeapType = RangeType2HeapTypeMap[RangeType]; + +#ifdef DILIGENT_DEBUG + switch (RangeType) + { + // clang-format off + case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; + case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); break; + // clang-format on + default: UNEXPECTED("Unexpected descriptor range type"); break; + } +#endif + return HeapType; +} + std::vector> RootSignature::GetCacheTableSizes() const { // Get root table size for every root index diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index f5b4e806..771e2c23 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -139,7 +139,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes, Uint32 NumAllowedTypes, ShaderResourceCacheD3D12* pResourceCache, - RootSignature* pRootSig, + RootSignatureBuilder* pRootSig, LocalRootSignature* pLocalRootSig) { m_pd3d12Device = pd3d12Device; -- cgit v1.2.3 From 1f9e0a4cd484687c13999d4a6686e104e0a93470 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Tue, 8 Dec 2020 17:56:12 +0300 Subject: some improvements for ray tracing --- Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp | 10 ++++++---- Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp | 2 -- Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp | 6 +----- Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp | 6 ++++++ 4 files changed, 13 insertions(+), 11 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 5c4ad160..bf44fbb6 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -189,10 +189,12 @@ public: struct Properties { - const Uint32 ShaderGroupHandleSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; - const Uint32 MaxShaderRecordStride = D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE; - const Uint32 ShaderGroupBaseAlignment = D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT; - const Uint32 MaxDrawMeshTasksCount = 64000; // from specs: https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#dispatchmesh-api + const Uint32 ShaderGroupHandleSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES; + const Uint32 MaxShaderRecordStride = D3D12_RAYTRACING_MAX_SHADER_RECORD_STRIDE; + const Uint32 ShaderGroupBaseAlignment = D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT; + const Uint32 MaxDrawMeshTasksCount = 64000; // from specs: https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#dispatchmesh-api + const Uint32 MaxRayTracingRecursionDepth = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH; + const Uint32 MaxRayGenThreads = D3D12_RAYTRACING_MAX_RAY_GENERATION_SHADER_THREADS; ShaderVersion MaxShaderVersion; }; diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 9e38a75e..a4517b4d 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -2617,8 +2617,6 @@ 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* pSBTD3D12 = ValidatedCast(Attribs.pSBT); IBuffer* pBuffer = nullptr; diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 6e71fcd6..bb2cb5c4 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -205,11 +205,7 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc}); } - constexpr Uint32 DefaultPayloadSize = sizeof(float) * 8; - constexpr Uint32 RecursionDepthLimit = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH - 1; - - if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > RecursionDepthLimit) - LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth (", CreateInfo.RayTracingPipeline.MaxRecursionDepth, ") must be <= ", RecursionDepthLimit); + constexpr Uint32 DefaultPayloadSize = sizeof(float) * 8; auto& PipelineConfig = *TempPool.Construct(); // For compatibility with Vulkan set minimal recursion depth to one, zero means no tracing of rays at all. diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index 76bf71c4..56588dee 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -165,6 +165,12 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo { static_assert(sizeof(DeviceObjectSizes) == sizeof(size_t) * 15, "Please add new objects to DeviceObjectSizes constructor"); + // set device properties + { + static_assert(sizeof(DeviceProperties) == sizeof(Uint32) * 1, "Please set new properties below"); + m_DeviceProperties.MaxRayTracingRecursionDepth = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH; + } + try { m_DeviceCaps.DevType = RENDER_DEVICE_TYPE_D3D12; -- cgit v1.2.3