From 38ad2d5cb659074ad9b4bde16bcbf71481719b94 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 26 Jan 2020 13:44:37 -0800 Subject: Renamed .h -> .hpp in GraphicsEngine, GraphicsEngineD3DBase, GraphicsEningeD3D11, and GraphicsEningeD3D12 projects --- Graphics/GraphicsEngineD3D12/CMakeLists.txt | 56 +- .../GraphicsEngineD3D12/include/BufferD3D12Impl.h | 123 ----- .../include/BufferD3D12Impl.hpp | 123 +++++ .../include/BufferViewD3D12Impl.h | 67 --- .../include/BufferViewD3D12Impl.hpp | 67 +++ .../GraphicsEngineD3D12/include/CommandContext.h | 435 --------------- .../GraphicsEngineD3D12/include/CommandContext.hpp | 435 +++++++++++++++ .../include/CommandListD3D12Impl.h | 88 --- .../include/CommandListD3D12Impl.hpp | 88 +++ .../include/CommandListManager.h | 81 --- .../include/CommandListManager.hpp | 81 +++ .../include/CommandQueueD3D12Impl.h | 88 --- .../include/CommandQueueD3D12Impl.hpp | 88 +++ .../GraphicsEngineD3D12/include/D3D12DynamicHeap.h | 208 -------- .../include/D3D12DynamicHeap.hpp | 208 ++++++++ Graphics/GraphicsEngineD3D12/include/D3D12Loader.h | 57 -- .../GraphicsEngineD3D12/include/D3D12Loader.hpp | 57 ++ .../include/D3D12ResourceBase.h | 49 -- .../include/D3D12ResourceBase.hpp | 49 ++ .../GraphicsEngineD3D12/include/DescriptorHeap.h | 569 -------------------- .../GraphicsEngineD3D12/include/DescriptorHeap.hpp | 569 ++++++++++++++++++++ .../include/DeviceContextD3D12Impl.h | 404 -------------- .../include/DeviceContextD3D12Impl.hpp | 404 ++++++++++++++ .../GraphicsEngineD3D12/include/FenceD3D12Impl.h | 72 --- .../GraphicsEngineD3D12/include/FenceD3D12Impl.hpp | 72 +++ .../GraphicsEngineD3D12/include/GenerateMips.h | 66 --- .../GraphicsEngineD3D12/include/GenerateMips.hpp | 66 +++ .../include/PipelineStateD3D12Impl.h | 135 ----- .../include/PipelineStateD3D12Impl.hpp | 135 +++++ .../GraphicsEngineD3D12/include/QueryD3D12Impl.h | 79 --- .../GraphicsEngineD3D12/include/QueryD3D12Impl.hpp | 79 +++ .../include/QueryManagerD3D12.h | 90 ---- .../include/QueryManagerD3D12.hpp | 90 ++++ .../include/RenderDeviceD3D12Impl.h | 163 ------ .../include/RenderDeviceD3D12Impl.hpp | 163 ++++++ .../GraphicsEngineD3D12/include/RootSignature.h | 591 --------------------- .../GraphicsEngineD3D12/include/RootSignature.hpp | 591 +++++++++++++++++++++ .../GraphicsEngineD3D12/include/SamplerD3D12Impl.h | 66 --- .../include/SamplerD3D12Impl.hpp | 66 +++ .../GraphicsEngineD3D12/include/ShaderD3D12Impl.h | 87 --- .../include/ShaderD3D12Impl.hpp | 87 +++ .../include/ShaderResourceBindingD3D12Impl.h | 88 --- .../include/ShaderResourceBindingD3D12Impl.hpp | 88 +++ .../include/ShaderResourceCacheD3D12.h | 354 ------------ .../include/ShaderResourceCacheD3D12.hpp | 354 ++++++++++++ .../include/ShaderResourceLayoutD3D12.h | 360 ------------- .../include/ShaderResourceLayoutD3D12.hpp | 360 +++++++++++++ .../include/ShaderResourcesD3D12.h | 105 ---- .../include/ShaderResourcesD3D12.hpp | 105 ++++ .../include/ShaderVariableD3D12.h | 222 -------- .../include/ShaderVariableD3D12.hpp | 222 ++++++++ .../include/SwapChainD3D12Impl.h | 87 --- .../include/SwapChainD3D12Impl.hpp | 87 +++ .../GraphicsEngineD3D12/include/TextureD3D12Impl.h | 105 ---- .../include/TextureD3D12Impl.hpp | 105 ++++ .../include/TextureViewD3D12Impl.h | 90 ---- .../include/TextureViewD3D12Impl.hpp | 90 ++++ Graphics/GraphicsEngineD3D12/include/pch.h | 6 +- .../GraphicsEngineD3D12/src/BufferD3D12Impl.cpp | 8 +- .../src/BufferViewD3D12Impl.cpp | 2 +- .../GraphicsEngineD3D12/src/CommandContext.cpp | 8 +- .../GraphicsEngineD3D12/src/CommandListManager.cpp | 4 +- .../src/CommandQueueD3D12Impl.cpp | 2 +- .../GraphicsEngineD3D12/src/D3D12DynamicHeap.cpp | 4 +- Graphics/GraphicsEngineD3D12/src/D3D12Loader.cpp | 2 +- .../src/D3D12TypeConversions.cpp | 4 +- .../GraphicsEngineD3D12/src/DescriptorHeap.cpp | 4 +- .../src/DeviceContextD3D12Impl.cpp | 18 +- .../GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp | 10 +- .../GraphicsEngineD3D12/src/FenceD3D12Impl.cpp | 4 +- Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp | 10 +- .../src/PipelineStateD3D12Impl.cpp | 12 +- .../GraphicsEngineD3D12/src/QueryD3D12Impl.cpp | 6 +- .../GraphicsEngineD3D12/src/QueryManagerD3D12.cpp | 4 +- .../src/RenderDeviceD3D12Impl.cpp | 20 +- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 12 +- .../GraphicsEngineD3D12/src/SamplerD3D12Impl.cpp | 4 +- .../GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp | 4 +- .../src/ShaderResourceBindingD3D12Impl.cpp | 8 +- .../src/ShaderResourceCacheD3D12.cpp | 4 +- .../src/ShaderResourceLayoutD3D12.cpp | 20 +- .../src/ShaderResourcesD3D12.cpp | 6 +- .../src/ShaderVariableD3D12.cpp | 4 +- .../GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp | 8 +- .../GraphicsEngineD3D12/src/TextureD3D12Impl.cpp | 8 +- .../src/TextureViewD3D12Impl.cpp | 4 +- 86 files changed, 5062 insertions(+), 5062 deletions(-) delete mode 100644 Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/BufferViewD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/BufferViewD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/CommandContext.h create mode 100644 Graphics/GraphicsEngineD3D12/include/CommandContext.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/CommandListManager.h create mode 100644 Graphics/GraphicsEngineD3D12/include/CommandListManager.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/D3D12DynamicHeap.h create mode 100644 Graphics/GraphicsEngineD3D12/include/D3D12DynamicHeap.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/D3D12Loader.h create mode 100644 Graphics/GraphicsEngineD3D12/include/D3D12Loader.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.h create mode 100644 Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/DescriptorHeap.h create mode 100644 Graphics/GraphicsEngineD3D12/include/DescriptorHeap.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/FenceD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/FenceD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/GenerateMips.h create mode 100644 Graphics/GraphicsEngineD3D12/include/GenerateMips.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/QueryManagerD3D12.h create mode 100644 Graphics/GraphicsEngineD3D12/include/QueryManagerD3D12.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/RootSignature.h create mode 100644 Graphics/GraphicsEngineD3D12/include/RootSignature.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/SamplerD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/SamplerD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h create mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h create mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.h create mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.h create mode 100644 Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.hpp delete mode 100644 Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.h create mode 100644 Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.hpp (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/CMakeLists.txt b/Graphics/GraphicsEngineD3D12/CMakeLists.txt index a8b744e8..fa3b4b70 100644 --- a/Graphics/GraphicsEngineD3D12/CMakeLists.txt +++ b/Graphics/GraphicsEngineD3D12/CMakeLists.txt @@ -3,38 +3,38 @@ cmake_minimum_required (VERSION 3.10) project(Diligent-GraphicsEngineD3D12 CXX) set(INCLUDE - include/BufferD3D12Impl.h - include/BufferViewD3D12Impl.h - include/CommandContext.h - include/CommandListD3D12Impl.h - include/CommandListManager.h - include/CommandQueueD3D12Impl.h - include/D3D12ResourceBase.h + include/BufferD3D12Impl.hpp + include/BufferViewD3D12Impl.hpp + include/CommandContext.hpp + include/CommandListD3D12Impl.hpp + include/CommandListManager.hpp + include/CommandQueueD3D12Impl.hpp + include/D3D12ResourceBase.hpp include/D3D12TypeConversions.h include/D3D12TypeDefinitions.h include/D3D12Utils.h include/d3dx12_win.h - include/DescriptorHeap.h - include/DeviceContextD3D12Impl.h - include/D3D12DynamicHeap.h - include/FenceD3D12Impl.h - include/GenerateMips.h + include/DescriptorHeap.hpp + include/DeviceContextD3D12Impl.hpp + include/D3D12DynamicHeap.hpp + include/FenceD3D12Impl.hpp + include/GenerateMips.hpp include/pch.h - include/PipelineStateD3D12Impl.h - include/QueryD3D12Impl.h - include/QueryManagerD3D12.h - include/RenderDeviceD3D12Impl.h - include/RootSignature.h - include/SamplerD3D12Impl.h - include/ShaderD3D12Impl.h - include/ShaderResourceBindingD3D12Impl.h - include/ShaderResourceCacheD3D12.h - include/ShaderResourceLayoutD3D12.h - include/ShaderResourcesD3D12.h - include/ShaderVariableD3D12.h - include/SwapChainD3D12Impl.h - include/TextureD3D12Impl.h - include/TextureViewD3D12Impl.h + include/PipelineStateD3D12Impl.hpp + include/QueryD3D12Impl.hpp + include/QueryManagerD3D12.hpp + include/RenderDeviceD3D12Impl.hpp + include/RootSignature.hpp + include/SamplerD3D12Impl.hpp + include/ShaderD3D12Impl.hpp + include/ShaderResourceBindingD3D12Impl.hpp + include/ShaderResourceCacheD3D12.hpp + include/ShaderResourceLayoutD3D12.hpp + include/ShaderResourcesD3D12.hpp + include/ShaderVariableD3D12.hpp + include/SwapChainD3D12Impl.hpp + include/TextureD3D12Impl.hpp + include/TextureViewD3D12Impl.hpp ) set(INTERFACE @@ -88,7 +88,7 @@ set(SRC ) if(PLATFORM_WIN32) - list(APPEND INCLUDE include/D3D12Loader.h) + list(APPEND INCLUDE include/D3D12Loader.hpp) list(APPEND SRC src/D3D12Loader.cpp) set(USE_D3D12_LOADER 1) else() diff --git a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h deleted file mode 100644 index adb24766..00000000 --- a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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::BufferD3D12Impl class - -#include "BufferD3D12.h" -#include "RenderDeviceD3D12.h" -#include "BufferBase.h" -#include "BufferViewD3D12Impl.h" -#include "D3D12ResourceBase.h" -#include "D3D12DynamicHeap.h" -#include "RenderDeviceD3D12Impl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Buffer object implementation in Direct3D12 backend. -class BufferD3D12Impl final : public BufferBase, public D3D12ResourceBase -{ -public: - using TBufferBase = BufferBase; - - BufferD3D12Impl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& BuffViewObjMemAllocator, - class RenderDeviceD3D12Impl* pDeviceD3D12, - const BufferDesc& BuffDesc, - const BufferData* pBuffData = nullptr); - - BufferD3D12Impl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& BuffViewObjMemAllocator, - class RenderDeviceD3D12Impl* pDeviceD3D12, - const BufferDesc& BuffDesc, - RESOURCE_STATE InitialState, - ID3D12Resource* pd3d12Buffer); - ~BufferD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - -#ifdef DEVELOPMENT - void DvpVerifyDynamicAllocation(class DeviceContextD3D12Impl* pCtx) const; -#endif - - /// Implementation of IBufferD3D12::GetD3D12Buffer(). - virtual ID3D12Resource* GetD3D12Buffer(Uint64& DataStartByteOffset, IDeviceContext* pContext) override final; - - /// Implementation of IBuffer::GetNativeHandle(). - virtual void* GetNativeHandle() override final - { - VERIFY(GetD3D12Resource() != nullptr, "The buffer is dynamic and has no pointer to D3D12 resource"); - Uint64 DataStartByteOffset = 0; - auto* pd3d12Buffer = GetD3D12Buffer(DataStartByteOffset, 0); - VERIFY(DataStartByteOffset == 0, "0 offset expected"); - return pd3d12Buffer; - } - - /// Implementation of IBufferD3D12::SetD3D12ResourceState(). - virtual void SetD3D12ResourceState(D3D12_RESOURCE_STATES state) override final; - - /// Implementation of IBufferD3D12::GetD3D12ResourceState(). - virtual D3D12_RESOURCE_STATES GetD3D12ResourceState() const override final; - - __forceinline D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress(Uint32 ContextId, class DeviceContextD3D12Impl* pCtx) - { - if (m_Desc.Usage == USAGE_DYNAMIC) - { -#ifdef DEVELOPMENT - DvpVerifyDynamicAllocation(pCtx); -#endif - return m_DynamicData[ContextId].GPUAddress; - } - else - { - return GetD3D12Resource()->GetGPUVirtualAddress(); - } - } - - D3D12_CPU_DESCRIPTOR_HANDLE GetCBVHandle() { return m_CBVDescriptorAllocation.GetCpuHandle(); } - -private: - virtual void CreateViewInternal(const struct BufferViewDesc& ViewDesc, IBufferView** ppView, bool bIsDefaultView) override; - - void CreateUAV(struct BufferViewDesc& UAVDesc, D3D12_CPU_DESCRIPTOR_HANDLE UAVDescriptor); - void CreateSRV(struct BufferViewDesc& SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVDescriptor); - void CreateCBV(D3D12_CPU_DESCRIPTOR_HANDLE CBVDescriptor); - - DescriptorHeapAllocation m_CBVDescriptorAllocation; - - friend class DeviceContextD3D12Impl; - // Array of dynamic allocations for every device context - // sizeof(D3D12DynamicAllocation) == 40 (x64) - std::vector> m_DynamicData; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp new file mode 100644 index 00000000..70513071 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.hpp @@ -0,0 +1,123 @@ +/* + * 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::BufferD3D12Impl class + +#include "BufferD3D12.h" +#include "RenderDeviceD3D12.h" +#include "BufferBase.hpp" +#include "BufferViewD3D12Impl.hpp" +#include "D3D12ResourceBase.hpp" +#include "D3D12DynamicHeap.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Buffer object implementation in Direct3D12 backend. +class BufferD3D12Impl final : public BufferBase, public D3D12ResourceBase +{ +public: + using TBufferBase = BufferBase; + + BufferD3D12Impl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& BuffViewObjMemAllocator, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const BufferDesc& BuffDesc, + const BufferData* pBuffData = nullptr); + + BufferD3D12Impl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& BuffViewObjMemAllocator, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const BufferDesc& BuffDesc, + RESOURCE_STATE InitialState, + ID3D12Resource* pd3d12Buffer); + ~BufferD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + +#ifdef DEVELOPMENT + void DvpVerifyDynamicAllocation(class DeviceContextD3D12Impl* pCtx) const; +#endif + + /// Implementation of IBufferD3D12::GetD3D12Buffer(). + virtual ID3D12Resource* GetD3D12Buffer(Uint64& DataStartByteOffset, IDeviceContext* pContext) override final; + + /// Implementation of IBuffer::GetNativeHandle(). + virtual void* GetNativeHandle() override final + { + VERIFY(GetD3D12Resource() != nullptr, "The buffer is dynamic and has no pointer to D3D12 resource"); + Uint64 DataStartByteOffset = 0; + auto* pd3d12Buffer = GetD3D12Buffer(DataStartByteOffset, 0); + VERIFY(DataStartByteOffset == 0, "0 offset expected"); + return pd3d12Buffer; + } + + /// Implementation of IBufferD3D12::SetD3D12ResourceState(). + virtual void SetD3D12ResourceState(D3D12_RESOURCE_STATES state) override final; + + /// Implementation of IBufferD3D12::GetD3D12ResourceState(). + virtual D3D12_RESOURCE_STATES GetD3D12ResourceState() const override final; + + __forceinline D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress(Uint32 ContextId, class DeviceContextD3D12Impl* pCtx) + { + if (m_Desc.Usage == USAGE_DYNAMIC) + { +#ifdef DEVELOPMENT + DvpVerifyDynamicAllocation(pCtx); +#endif + return m_DynamicData[ContextId].GPUAddress; + } + else + { + return GetD3D12Resource()->GetGPUVirtualAddress(); + } + } + + D3D12_CPU_DESCRIPTOR_HANDLE GetCBVHandle() { return m_CBVDescriptorAllocation.GetCpuHandle(); } + +private: + virtual void CreateViewInternal(const struct BufferViewDesc& ViewDesc, IBufferView** ppView, bool bIsDefaultView) override; + + void CreateUAV(struct BufferViewDesc& UAVDesc, D3D12_CPU_DESCRIPTOR_HANDLE UAVDescriptor); + void CreateSRV(struct BufferViewDesc& SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVDescriptor); + void CreateCBV(D3D12_CPU_DESCRIPTOR_HANDLE CBVDescriptor); + + DescriptorHeapAllocation m_CBVDescriptorAllocation; + + friend class DeviceContextD3D12Impl; + // Array of dynamic allocations for every device context + // sizeof(D3D12DynamicAllocation) == 40 (x64) + std::vector> m_DynamicData; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/BufferViewD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/BufferViewD3D12Impl.h deleted file mode 100644 index abf715eb..00000000 --- a/Graphics/GraphicsEngineD3D12/include/BufferViewD3D12Impl.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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::BufferViewD3D12Impl class - -#include "BufferViewD3D12.h" -#include "RenderDeviceD3D12.h" -#include "BufferViewBase.h" -#include "DescriptorHeap.h" -#include "RenderDeviceD3D12Impl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Buffer view implementation in Direct3D12 backend. -class BufferViewD3D12Impl final : public BufferViewBase -{ -public: - using TBufferViewBase = BufferViewBase; - - BufferViewD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pDevice, - const BufferViewDesc& ViewDesc, - class IBuffer* pBuffer, - DescriptorHeapAllocation&& HandleAlloc, - bool bIsDefaultView); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IBufferViewD3D12::GetCPUDescriptorHandle(). - virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() override final { return m_DescriptorHandle.GetCpuHandle(); } - -protected: - // Allocation in a CPU-only descriptor heap - DescriptorHeapAllocation m_DescriptorHandle; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/BufferViewD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/BufferViewD3D12Impl.hpp new file mode 100644 index 00000000..62cb6294 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/BufferViewD3D12Impl.hpp @@ -0,0 +1,67 @@ +/* + * 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::BufferViewD3D12Impl class + +#include "BufferViewD3D12.h" +#include "RenderDeviceD3D12.h" +#include "BufferViewBase.hpp" +#include "DescriptorHeap.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Buffer view implementation in Direct3D12 backend. +class BufferViewD3D12Impl final : public BufferViewBase +{ +public: + using TBufferViewBase = BufferViewBase; + + BufferViewD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + const BufferViewDesc& ViewDesc, + class IBuffer* pBuffer, + DescriptorHeapAllocation&& HandleAlloc, + bool bIsDefaultView); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IBufferViewD3D12::GetCPUDescriptorHandle(). + virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() override final { return m_DescriptorHandle.GetCpuHandle(); } + +protected: + // Allocation in a CPU-only descriptor heap + DescriptorHeapAllocation m_DescriptorHandle; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.h b/Graphics/GraphicsEngineD3D12/include/CommandContext.h deleted file mode 100644 index ed8824c5..00000000 --- a/Graphics/GraphicsEngineD3D12/include/CommandContext.h +++ /dev/null @@ -1,435 +0,0 @@ -/* - * 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 - -#include - -#include "D3D12ResourceBase.h" -#include "TextureViewD3D12.h" -#include "TextureD3D12.h" -#include "BufferD3D12.h" -#include "DescriptorHeap.h" - -namespace Diligent -{ - - -struct DWParam -{ - // clang-format off - DWParam( FLOAT f ) : Float{f} {} - DWParam( UINT u ) : Uint {u} {} - DWParam( INT i ) : Int {i} {} - - void operator= ( FLOAT f ) { Float = f; } - void operator= ( UINT u ) { Uint = u; } - void operator= ( INT i ) { Int = i; } - // clang-format on - - union - { - FLOAT Float; - UINT Uint; - INT Int; - }; -}; - - -class CommandContext -{ -public: - CommandContext(class CommandListManager& CmdListManager); - - // clang-format off - CommandContext (const CommandContext&) = delete; - CommandContext& operator = (const CommandContext&) = delete; - CommandContext ( CommandContext&&) = delete; - CommandContext& operator = ( CommandContext&&) = delete; - // clang-format on - - ~CommandContext(); - - // Submit the command buffer and reset it. This is encouraged to keep the GPU busy and reduce latency. - // Taking too long to build command lists and submit them can idle the GPU. - ID3D12GraphicsCommandList* Close(CComPtr& pAllocator); - void Reset(CommandListManager& CmdListManager); - - class GraphicsContext& AsGraphicsContext(); - class ComputeContext& AsComputeContext(); - - void ClearUAVFloat(D3D12_GPU_DESCRIPTOR_HANDLE GpuHandle, - D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle, - ID3D12Resource* pd3d12Resource, - const float* Color) - { - FlushResourceBarriers(); - m_pCommandList->ClearUnorderedAccessViewFloat(GpuHandle, CpuHandle, pd3d12Resource, Color, 0, nullptr); - } - - void ClearUAVUint(D3D12_GPU_DESCRIPTOR_HANDLE GpuHandle, - D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle, - ID3D12Resource* pd3d12Resource, - const UINT* Color) - { - FlushResourceBarriers(); - m_pCommandList->ClearUnorderedAccessViewUint(GpuHandle, CpuHandle, pd3d12Resource, Color, 0, nullptr); - } - - void CopyResource(ID3D12Resource* pDstRes, ID3D12Resource* pSrcRes) - { - m_pCommandList->CopyResource(pDstRes, pSrcRes); - } - - void TransitionResource(ITextureD3D12* pTexture, RESOURCE_STATE NewState); - void TransitionResource(IBufferD3D12* pBuffer, RESOURCE_STATE NewState); - void TransitionResource(const StateTransitionDesc& Barrier); - //void BeginResourceTransition(GpuResource& Resource, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false); - - void ResolveSubresource(ID3D12Resource* pDstResource, - UINT DstSubresource, - ID3D12Resource* pSrcResource, - UINT SrcSubresource, - DXGI_FORMAT Format) - { - FlushResourceBarriers(); - m_pCommandList->ResolveSubresource(pDstResource, DstSubresource, pSrcResource, SrcSubresource, Format); - } - - void FlushResourceBarriers() - { - if (!m_PendingResourceBarriers.empty()) - { - m_pCommandList->ResourceBarrier(static_cast(m_PendingResourceBarriers.size()), m_PendingResourceBarriers.data()); - m_PendingResourceBarriers.clear(); - } - } - - - struct ShaderDescriptorHeaps - { - ID3D12DescriptorHeap* pSrvCbvUavHeap; - ID3D12DescriptorHeap* pSamplerHeap; - ShaderDescriptorHeaps(ID3D12DescriptorHeap* _pSrvCbvUavHeap = nullptr, ID3D12DescriptorHeap* _pSamplerHeap = nullptr) : - pSrvCbvUavHeap{_pSrvCbvUavHeap}, - pSamplerHeap{_pSamplerHeap} - {} - bool operator==(const ShaderDescriptorHeaps& rhs) const - { - return pSrvCbvUavHeap == rhs.pSrvCbvUavHeap && pSamplerHeap == rhs.pSamplerHeap; - } - operator bool() const - { - return pSrvCbvUavHeap != nullptr || pSamplerHeap != nullptr; - } - }; - void SetDescriptorHeaps(ShaderDescriptorHeaps& Heaps); - - void ExecuteIndirect(ID3D12CommandSignature* pCmdSignature, ID3D12Resource* pBuff, Uint64 ArgsOffset) - { - FlushResourceBarriers(); - m_pCommandList->ExecuteIndirect(pCmdSignature, 1, pBuff, ArgsOffset, nullptr, 0); - } - - void SetID(const Char* ID) { m_ID = ID; } - ID3D12GraphicsCommandList* GetCommandList() { return m_pCommandList; } - - DescriptorHeapAllocation AllocateDynamicGPUVisibleDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1) - { - VERIFY(m_DynamicGPUDescriptorAllocators != nullptr, "Dynamic GPU descriptor llocators have not been initialized. Did you forget to call SetDynamicGPUDescriptorAllocators() after resetting the context?"); - VERIFY(Type >= D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && Type <= D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, "Invalid heap type"); - return m_DynamicGPUDescriptorAllocators[Type].Allocate(Count); - } - - void InsertUAVBarrier(ID3D12Resource* pd3d12Resource); - - void SetPipelineState(ID3D12PipelineState* pPSO) - { - if (pPSO != m_pCurPipelineState) - { - m_pCommandList->SetPipelineState(m_pCurPipelineState = pPSO); - } - } - - void SetDynamicGPUDescriptorAllocators(DynamicSuballocationsManager* Allocators) - { - m_DynamicGPUDescriptorAllocators = Allocators; - } - - void BeginQuery(ID3D12QueryHeap* pQueryHeap, D3D12_QUERY_TYPE Type, UINT Index) - { - m_pCommandList->BeginQuery(pQueryHeap, Type, Index); - } - - void EndQuery(ID3D12QueryHeap* pQueryHeap, D3D12_QUERY_TYPE Type, UINT Index) - { - m_pCommandList->EndQuery(pQueryHeap, Type, Index); - } - - void ResolveQueryData(ID3D12QueryHeap* pQueryHeap, - D3D12_QUERY_TYPE Type, - UINT StartIndex, - UINT NumQueries, - ID3D12Resource* pDestinationBuffer, - UINT64 AlignedDestinationBufferOffset) - { - m_pCommandList->ResolveQueryData(pQueryHeap, Type, StartIndex, NumQueries, pDestinationBuffer, AlignedDestinationBufferOffset); - } - -protected: - void InsertAliasBarrier(D3D12ResourceBase& Before, D3D12ResourceBase& After, bool FlushImmediate = false); - - CComPtr m_pCommandList; - CComPtr m_pCurrentAllocator; - - ID3D12PipelineState* m_pCurPipelineState = nullptr; - ID3D12RootSignature* m_pCurGraphicsRootSignature = nullptr; - ID3D12RootSignature* m_pCurComputeRootSignature = nullptr; - - static constexpr int MaxPendingBarriers = 16; - - std::vector> m_PendingResourceBarriers; - - ShaderDescriptorHeaps m_BoundDescriptorHeaps; - - DynamicSuballocationsManager* m_DynamicGPUDescriptorAllocators = nullptr; - - String m_ID; - - D3D12_PRIMITIVE_TOPOLOGY m_PrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; -}; - - -class GraphicsContext : public CommandContext -{ -public: - void ClearRenderTarget(D3D12_CPU_DESCRIPTOR_HANDLE RTV, const float* Color) - { - FlushResourceBarriers(); - m_pCommandList->ClearRenderTargetView(RTV, Color, 0, nullptr); - } - - void ClearDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE DSV, D3D12_CLEAR_FLAGS ClearFlags, float Depth, UINT8 Stencil) - { - FlushResourceBarriers(); - m_pCommandList->ClearDepthStencilView(DSV, ClearFlags, Depth, Stencil, 0, nullptr); - } - - void SetRootSignature(ID3D12RootSignature* pRootSig) - { - if (pRootSig != m_pCurGraphicsRootSignature) - { - m_pCommandList->SetGraphicsRootSignature(m_pCurGraphicsRootSignature = pRootSig); - } - } - - void SetViewports(UINT NumVPs, const D3D12_VIEWPORT* pVPs) - { - m_pCommandList->RSSetViewports(NumVPs, pVPs); - } - - void SetScissorRects(UINT NumRects, const D3D12_RECT* pRects) - { - m_pCommandList->RSSetScissorRects(NumRects, pRects); - } - - void SetStencilRef(UINT StencilRef) - { - m_pCommandList->OMSetStencilRef(StencilRef); - } - - void SetBlendFactor(const float* BlendFactor) - { - m_pCommandList->OMSetBlendFactor(BlendFactor); - } - - void SetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY Topology) - { - if (m_PrimitiveTopology != Topology) - { - m_PrimitiveTopology = Topology; - m_pCommandList->IASetPrimitiveTopology(Topology); - } - } - - 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); - } - - void SetVertexBuffers(UINT StartSlot, UINT Count, const D3D12_VERTEX_BUFFER_VIEW VBViews[]) - { - m_pCommandList->IASetVertexBuffers(StartSlot, Count, VBViews); - } - - void Draw(UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation) - { - FlushResourceBarriers(); - m_pCommandList->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); - } - - void DrawIndexed(UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation, INT BaseVertexLocation, UINT StartInstanceLocation) - { - FlushResourceBarriers(); - m_pCommandList->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); - } -}; - -class ComputeContext : public CommandContext -{ -public: - void SetRootSignature(ID3D12RootSignature* pRootSig) - { - if (pRootSig != m_pCurComputeRootSignature) - { - m_pCommandList->SetComputeRootSignature(m_pCurComputeRootSignature = pRootSig); - } - } - - 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) - { - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0); - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Y.Uint, 1); - } - - void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z) - { - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0); - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Y.Uint, 1); - m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Z.Uint, 2); - } - - void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z, DWParam W) - { - 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); - } - - - void SetConstantBuffer(UINT RootIndex, D3D12_GPU_VIRTUAL_ADDRESS CBV) - { - m_pCommandList->SetComputeRootConstantBufferView(RootIndex, CBV); - } - - void SetDescriptorTable(UINT RootIndex, D3D12_GPU_DESCRIPTOR_HANDLE FirstHandle) - { - m_pCommandList->SetComputeRootDescriptorTable(RootIndex, FirstHandle); - } - - void Dispatch(size_t GroupCountX = 1, size_t GroupCountY = 1, size_t GroupCountZ = 1) - { - FlushResourceBarriers(); - m_pCommandList->Dispatch((UINT)GroupCountX, (UINT)GroupCountY, (UINT)GroupCountZ); - } -}; - -inline GraphicsContext& CommandContext::AsGraphicsContext() -{ - return static_cast(*this); -} - -inline ComputeContext& CommandContext::AsComputeContext() -{ - return static_cast(*this); -} - -inline void CommandContext::SetDescriptorHeaps(ShaderDescriptorHeaps& Heaps) -{ -#ifdef _DEBUG - VERIFY(Heaps.pSrvCbvUavHeap != nullptr || Heaps.pSamplerHeap != nullptr, "At least one heap is expected to be set"); - VERIFY(Heaps.pSrvCbvUavHeap == nullptr || Heaps.pSrvCbvUavHeap->GetDesc().Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, "Invalid heap type provided in pSrvCbvUavHeap"); - VERIFY(Heaps.pSamplerHeap == nullptr || Heaps.pSamplerHeap->GetDesc().Type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, "Invalid heap type provided in pSamplerHeap"); -#endif - - if (!(Heaps == m_BoundDescriptorHeaps)) - { - m_BoundDescriptorHeaps = Heaps; - - ID3D12DescriptorHeap** ppHeaps = reinterpret_cast(&Heaps); - UINT NumHeaps = (ppHeaps[0] != nullptr ? 1 : 0) + (ppHeaps[1] != nullptr ? 1 : 0); - if (ppHeaps[0] == nullptr) - ++ppHeaps; - - m_pCommandList->SetDescriptorHeaps(NumHeaps, ppHeaps); - } -} - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp new file mode 100644 index 00000000..30134445 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp @@ -0,0 +1,435 @@ +/* + * 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 + +#include + +#include "D3D12ResourceBase.hpp" +#include "TextureViewD3D12.h" +#include "TextureD3D12.h" +#include "BufferD3D12.h" +#include "DescriptorHeap.hpp" + +namespace Diligent +{ + + +struct DWParam +{ + // clang-format off + DWParam( FLOAT f ) : Float{f} {} + DWParam( UINT u ) : Uint {u} {} + DWParam( INT i ) : Int {i} {} + + void operator= ( FLOAT f ) { Float = f; } + void operator= ( UINT u ) { Uint = u; } + void operator= ( INT i ) { Int = i; } + // clang-format on + + union + { + FLOAT Float; + UINT Uint; + INT Int; + }; +}; + + +class CommandContext +{ +public: + CommandContext(class CommandListManager& CmdListManager); + + // clang-format off + CommandContext (const CommandContext&) = delete; + CommandContext& operator = (const CommandContext&) = delete; + CommandContext ( CommandContext&&) = delete; + CommandContext& operator = ( CommandContext&&) = delete; + // clang-format on + + ~CommandContext(); + + // Submit the command buffer and reset it. This is encouraged to keep the GPU busy and reduce latency. + // Taking too long to build command lists and submit them can idle the GPU. + ID3D12GraphicsCommandList* Close(CComPtr& pAllocator); + void Reset(CommandListManager& CmdListManager); + + class GraphicsContext& AsGraphicsContext(); + class ComputeContext& AsComputeContext(); + + void ClearUAVFloat(D3D12_GPU_DESCRIPTOR_HANDLE GpuHandle, + D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle, + ID3D12Resource* pd3d12Resource, + const float* Color) + { + FlushResourceBarriers(); + m_pCommandList->ClearUnorderedAccessViewFloat(GpuHandle, CpuHandle, pd3d12Resource, Color, 0, nullptr); + } + + void ClearUAVUint(D3D12_GPU_DESCRIPTOR_HANDLE GpuHandle, + D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle, + ID3D12Resource* pd3d12Resource, + const UINT* Color) + { + FlushResourceBarriers(); + m_pCommandList->ClearUnorderedAccessViewUint(GpuHandle, CpuHandle, pd3d12Resource, Color, 0, nullptr); + } + + void CopyResource(ID3D12Resource* pDstRes, ID3D12Resource* pSrcRes) + { + m_pCommandList->CopyResource(pDstRes, pSrcRes); + } + + void TransitionResource(ITextureD3D12* pTexture, RESOURCE_STATE NewState); + void TransitionResource(IBufferD3D12* pBuffer, RESOURCE_STATE NewState); + void TransitionResource(const StateTransitionDesc& Barrier); + //void BeginResourceTransition(GpuResource& Resource, D3D12_RESOURCE_STATES NewState, bool FlushImmediate = false); + + void ResolveSubresource(ID3D12Resource* pDstResource, + UINT DstSubresource, + ID3D12Resource* pSrcResource, + UINT SrcSubresource, + DXGI_FORMAT Format) + { + FlushResourceBarriers(); + m_pCommandList->ResolveSubresource(pDstResource, DstSubresource, pSrcResource, SrcSubresource, Format); + } + + void FlushResourceBarriers() + { + if (!m_PendingResourceBarriers.empty()) + { + m_pCommandList->ResourceBarrier(static_cast(m_PendingResourceBarriers.size()), m_PendingResourceBarriers.data()); + m_PendingResourceBarriers.clear(); + } + } + + + struct ShaderDescriptorHeaps + { + ID3D12DescriptorHeap* pSrvCbvUavHeap; + ID3D12DescriptorHeap* pSamplerHeap; + ShaderDescriptorHeaps(ID3D12DescriptorHeap* _pSrvCbvUavHeap = nullptr, ID3D12DescriptorHeap* _pSamplerHeap = nullptr) : + pSrvCbvUavHeap{_pSrvCbvUavHeap}, + pSamplerHeap{_pSamplerHeap} + {} + bool operator==(const ShaderDescriptorHeaps& rhs) const + { + return pSrvCbvUavHeap == rhs.pSrvCbvUavHeap && pSamplerHeap == rhs.pSamplerHeap; + } + operator bool() const + { + return pSrvCbvUavHeap != nullptr || pSamplerHeap != nullptr; + } + }; + void SetDescriptorHeaps(ShaderDescriptorHeaps& Heaps); + + void ExecuteIndirect(ID3D12CommandSignature* pCmdSignature, ID3D12Resource* pBuff, Uint64 ArgsOffset) + { + FlushResourceBarriers(); + m_pCommandList->ExecuteIndirect(pCmdSignature, 1, pBuff, ArgsOffset, nullptr, 0); + } + + void SetID(const Char* ID) { m_ID = ID; } + ID3D12GraphicsCommandList* GetCommandList() { return m_pCommandList; } + + DescriptorHeapAllocation AllocateDynamicGPUVisibleDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1) + { + VERIFY(m_DynamicGPUDescriptorAllocators != nullptr, "Dynamic GPU descriptor llocators have not been initialized. Did you forget to call SetDynamicGPUDescriptorAllocators() after resetting the context?"); + VERIFY(Type >= D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && Type <= D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, "Invalid heap type"); + return m_DynamicGPUDescriptorAllocators[Type].Allocate(Count); + } + + void InsertUAVBarrier(ID3D12Resource* pd3d12Resource); + + void SetPipelineState(ID3D12PipelineState* pPSO) + { + if (pPSO != m_pCurPipelineState) + { + m_pCommandList->SetPipelineState(m_pCurPipelineState = pPSO); + } + } + + void SetDynamicGPUDescriptorAllocators(DynamicSuballocationsManager* Allocators) + { + m_DynamicGPUDescriptorAllocators = Allocators; + } + + void BeginQuery(ID3D12QueryHeap* pQueryHeap, D3D12_QUERY_TYPE Type, UINT Index) + { + m_pCommandList->BeginQuery(pQueryHeap, Type, Index); + } + + void EndQuery(ID3D12QueryHeap* pQueryHeap, D3D12_QUERY_TYPE Type, UINT Index) + { + m_pCommandList->EndQuery(pQueryHeap, Type, Index); + } + + void ResolveQueryData(ID3D12QueryHeap* pQueryHeap, + D3D12_QUERY_TYPE Type, + UINT StartIndex, + UINT NumQueries, + ID3D12Resource* pDestinationBuffer, + UINT64 AlignedDestinationBufferOffset) + { + m_pCommandList->ResolveQueryData(pQueryHeap, Type, StartIndex, NumQueries, pDestinationBuffer, AlignedDestinationBufferOffset); + } + +protected: + void InsertAliasBarrier(D3D12ResourceBase& Before, D3D12ResourceBase& After, bool FlushImmediate = false); + + CComPtr m_pCommandList; + CComPtr m_pCurrentAllocator; + + ID3D12PipelineState* m_pCurPipelineState = nullptr; + ID3D12RootSignature* m_pCurGraphicsRootSignature = nullptr; + ID3D12RootSignature* m_pCurComputeRootSignature = nullptr; + + static constexpr int MaxPendingBarriers = 16; + + std::vector> m_PendingResourceBarriers; + + ShaderDescriptorHeaps m_BoundDescriptorHeaps; + + DynamicSuballocationsManager* m_DynamicGPUDescriptorAllocators = nullptr; + + String m_ID; + + D3D12_PRIMITIVE_TOPOLOGY m_PrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; +}; + + +class GraphicsContext : public CommandContext +{ +public: + void ClearRenderTarget(D3D12_CPU_DESCRIPTOR_HANDLE RTV, const float* Color) + { + FlushResourceBarriers(); + m_pCommandList->ClearRenderTargetView(RTV, Color, 0, nullptr); + } + + void ClearDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE DSV, D3D12_CLEAR_FLAGS ClearFlags, float Depth, UINT8 Stencil) + { + FlushResourceBarriers(); + m_pCommandList->ClearDepthStencilView(DSV, ClearFlags, Depth, Stencil, 0, nullptr); + } + + void SetRootSignature(ID3D12RootSignature* pRootSig) + { + if (pRootSig != m_pCurGraphicsRootSignature) + { + m_pCommandList->SetGraphicsRootSignature(m_pCurGraphicsRootSignature = pRootSig); + } + } + + void SetViewports(UINT NumVPs, const D3D12_VIEWPORT* pVPs) + { + m_pCommandList->RSSetViewports(NumVPs, pVPs); + } + + void SetScissorRects(UINT NumRects, const D3D12_RECT* pRects) + { + m_pCommandList->RSSetScissorRects(NumRects, pRects); + } + + void SetStencilRef(UINT StencilRef) + { + m_pCommandList->OMSetStencilRef(StencilRef); + } + + void SetBlendFactor(const float* BlendFactor) + { + m_pCommandList->OMSetBlendFactor(BlendFactor); + } + + void SetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY Topology) + { + if (m_PrimitiveTopology != Topology) + { + m_PrimitiveTopology = Topology; + m_pCommandList->IASetPrimitiveTopology(Topology); + } + } + + 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); + } + + void SetVertexBuffers(UINT StartSlot, UINT Count, const D3D12_VERTEX_BUFFER_VIEW VBViews[]) + { + m_pCommandList->IASetVertexBuffers(StartSlot, Count, VBViews); + } + + void Draw(UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation) + { + FlushResourceBarriers(); + m_pCommandList->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); + } + + void DrawIndexed(UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation, INT BaseVertexLocation, UINT StartInstanceLocation) + { + FlushResourceBarriers(); + m_pCommandList->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); + } +}; + +class ComputeContext : public CommandContext +{ +public: + void SetRootSignature(ID3D12RootSignature* pRootSig) + { + if (pRootSig != m_pCurComputeRootSignature) + { + m_pCommandList->SetComputeRootSignature(m_pCurComputeRootSignature = pRootSig); + } + } + + 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) + { + m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0); + m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Y.Uint, 1); + } + + void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z) + { + m_pCommandList->SetComputeRoot32BitConstant(RootIndex, X.Uint, 0); + m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Y.Uint, 1); + m_pCommandList->SetComputeRoot32BitConstant(RootIndex, Z.Uint, 2); + } + + void SetConstants(UINT RootIndex, DWParam X, DWParam Y, DWParam Z, DWParam W) + { + 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); + } + + + void SetConstantBuffer(UINT RootIndex, D3D12_GPU_VIRTUAL_ADDRESS CBV) + { + m_pCommandList->SetComputeRootConstantBufferView(RootIndex, CBV); + } + + void SetDescriptorTable(UINT RootIndex, D3D12_GPU_DESCRIPTOR_HANDLE FirstHandle) + { + m_pCommandList->SetComputeRootDescriptorTable(RootIndex, FirstHandle); + } + + void Dispatch(size_t GroupCountX = 1, size_t GroupCountY = 1, size_t GroupCountZ = 1) + { + FlushResourceBarriers(); + m_pCommandList->Dispatch((UINT)GroupCountX, (UINT)GroupCountY, (UINT)GroupCountZ); + } +}; + +inline GraphicsContext& CommandContext::AsGraphicsContext() +{ + return static_cast(*this); +} + +inline ComputeContext& CommandContext::AsComputeContext() +{ + return static_cast(*this); +} + +inline void CommandContext::SetDescriptorHeaps(ShaderDescriptorHeaps& Heaps) +{ +#ifdef _DEBUG + VERIFY(Heaps.pSrvCbvUavHeap != nullptr || Heaps.pSamplerHeap != nullptr, "At least one heap is expected to be set"); + VERIFY(Heaps.pSrvCbvUavHeap == nullptr || Heaps.pSrvCbvUavHeap->GetDesc().Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, "Invalid heap type provided in pSrvCbvUavHeap"); + VERIFY(Heaps.pSamplerHeap == nullptr || Heaps.pSamplerHeap->GetDesc().Type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, "Invalid heap type provided in pSamplerHeap"); +#endif + + if (!(Heaps == m_BoundDescriptorHeaps)) + { + m_BoundDescriptorHeaps = Heaps; + + ID3D12DescriptorHeap** ppHeaps = reinterpret_cast(&Heaps); + UINT NumHeaps = (ppHeaps[0] != nullptr ? 1 : 0) + (ppHeaps[1] != nullptr ? 1 : 0); + if (ppHeaps[0] == nullptr) + ++ppHeaps; + + m_pCommandList->SetDescriptorHeaps(NumHeaps, ppHeaps); + } +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.h deleted file mode 100644 index 4066dc63..00000000 --- a/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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::CommandListD3D12Impl class - -#include "CommandListBase.h" -#include "RenderDeviceD3D12Impl.h" - -namespace Diligent -{ - -class DeviceContextD3D12Impl; -class CommandContext; - -/// Command list implementation in Direct3D12 backend. -class CommandListD3D12Impl final : public CommandListBase -{ -public: - using TCommandListBase = CommandListBase; - - CommandListD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pDevice, - DeviceContextD3D12Impl* pDeferredCtx, - RenderDeviceD3D12Impl::PooledCommandContext&& pCmdContext) : - // clang-format off - TCommandListBase - { - pRefCounters, - pDevice - }, - m_pDeferredCtx {pDeferredCtx }, - m_pCmdContext {std::move(pCmdContext)} - // clang-format on - { - } - - ~CommandListD3D12Impl() - { - if (m_pCmdContext != nullptr) - { - LOG_WARNING_MESSAGE("Destroying command list that has not been executed"); - m_pDevice->DisposeCommandContext(std::move(m_pCmdContext)); - } - else - { - VERIFY_EXPR(m_pDeferredCtx == nullptr); - } - } - - RenderDeviceD3D12Impl::PooledCommandContext Close(RefCntAutoPtr& pDeferredCtx) - { - pDeferredCtx = std::move(m_pDeferredCtx); - return std::move(m_pCmdContext); - } - -private: - RefCntAutoPtr m_pDeferredCtx; - RenderDeviceD3D12Impl::PooledCommandContext m_pCmdContext; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.hpp new file mode 100644 index 00000000..47319ded --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.hpp @@ -0,0 +1,88 @@ +/* + * 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::CommandListD3D12Impl class + +#include "CommandListBase.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +class DeviceContextD3D12Impl; +class CommandContext; + +/// Command list implementation in Direct3D12 backend. +class CommandListD3D12Impl final : public CommandListBase +{ +public: + using TCommandListBase = CommandListBase; + + CommandListD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + DeviceContextD3D12Impl* pDeferredCtx, + RenderDeviceD3D12Impl::PooledCommandContext&& pCmdContext) : + // clang-format off + TCommandListBase + { + pRefCounters, + pDevice + }, + m_pDeferredCtx {pDeferredCtx }, + m_pCmdContext {std::move(pCmdContext)} + // clang-format on + { + } + + ~CommandListD3D12Impl() + { + if (m_pCmdContext != nullptr) + { + LOG_WARNING_MESSAGE("Destroying command list that has not been executed"); + m_pDevice->DisposeCommandContext(std::move(m_pCmdContext)); + } + else + { + VERIFY_EXPR(m_pDeferredCtx == nullptr); + } + } + + RenderDeviceD3D12Impl::PooledCommandContext Close(RefCntAutoPtr& pDeferredCtx) + { + pDeferredCtx = std::move(m_pDeferredCtx); + return std::move(m_pCmdContext); + } + +private: + RefCntAutoPtr m_pDeferredCtx; + RenderDeviceD3D12Impl::PooledCommandContext m_pCmdContext; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/CommandListManager.h b/Graphics/GraphicsEngineD3D12/include/CommandListManager.h deleted file mode 100644 index 6548a637..00000000 --- a/Graphics/GraphicsEngineD3D12/include/CommandListManager.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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 - -#include -#include -#include - -namespace Diligent -{ - -class RenderDeviceD3D12Impl; - -class CommandListManager -{ -public: - CommandListManager(RenderDeviceD3D12Impl& DeviceD3D12Impl); - ~CommandListManager(); - - // clang-format off - CommandListManager (const CommandListManager&) = delete; - CommandListManager ( CommandListManager&&) = delete; - CommandListManager& operator = (const CommandListManager&) = delete; - CommandListManager& operator = ( CommandListManager&&) = delete; - // clang-format on - - void CreateNewCommandList(ID3D12GraphicsCommandList** ppList, ID3D12CommandAllocator** ppAllocator); - - void RequestAllocator(ID3D12CommandAllocator** ppAllocator); - void ReleaseAllocator(CComPtr&& Allocator, Uint32 CmdQueue, Uint64 FenceValue); - - // Returns allocator to the list of available allocators. The GPU must have finished using the - // allocator - void FreeAllocator(CComPtr&& Allocator); - -#ifdef DEVELOPMENT - Atomics::Long GetAllocatorCounter() const - { - return m_AllocatorCounter; - } -#endif - -private: - std::mutex m_AllocatorMutex; - std::vector, STDAllocatorRawMem>> m_FreeAllocators; - - RenderDeviceD3D12Impl& m_DeviceD3D12Impl; - - Atomics::AtomicLong m_NumAllocators = 0; // For debug purposes only - -#ifdef DEVELOPMENT - Atomics::AtomicLong m_AllocatorCounter = 0; -#endif -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/CommandListManager.hpp b/Graphics/GraphicsEngineD3D12/include/CommandListManager.hpp new file mode 100644 index 00000000..6548a637 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/CommandListManager.hpp @@ -0,0 +1,81 @@ +/* + * 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 + +#include +#include +#include + +namespace Diligent +{ + +class RenderDeviceD3D12Impl; + +class CommandListManager +{ +public: + CommandListManager(RenderDeviceD3D12Impl& DeviceD3D12Impl); + ~CommandListManager(); + + // clang-format off + CommandListManager (const CommandListManager&) = delete; + CommandListManager ( CommandListManager&&) = delete; + CommandListManager& operator = (const CommandListManager&) = delete; + CommandListManager& operator = ( CommandListManager&&) = delete; + // clang-format on + + void CreateNewCommandList(ID3D12GraphicsCommandList** ppList, ID3D12CommandAllocator** ppAllocator); + + void RequestAllocator(ID3D12CommandAllocator** ppAllocator); + void ReleaseAllocator(CComPtr&& Allocator, Uint32 CmdQueue, Uint64 FenceValue); + + // Returns allocator to the list of available allocators. The GPU must have finished using the + // allocator + void FreeAllocator(CComPtr&& Allocator); + +#ifdef DEVELOPMENT + Atomics::Long GetAllocatorCounter() const + { + return m_AllocatorCounter; + } +#endif + +private: + std::mutex m_AllocatorMutex; + std::vector, STDAllocatorRawMem>> m_FreeAllocators; + + RenderDeviceD3D12Impl& m_DeviceD3D12Impl; + + Atomics::AtomicLong m_NumAllocators = 0; // For debug purposes only + +#ifdef DEVELOPMENT + Atomics::AtomicLong m_AllocatorCounter = 0; +#endif +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.h deleted file mode 100644 index 478f5139..00000000 --- a/Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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::CommandQueueD3D12Impl class - -#include "CommandQueueD3D12.h" -#include "ObjectBase.h" -#include - -namespace Diligent -{ - -/// Implementation of the Diligent::ICommandQueueD3D12 interface -class CommandQueueD3D12Impl final : public ObjectBase -{ -public: - using TBase = ObjectBase; - - CommandQueueD3D12Impl(IReferenceCounters* pRefCounters, ID3D12CommandQueue* pd3d12NativeCmdQueue, ID3D12Fence* pd3d12Fence); - ~CommandQueueD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - // Implementation of ICommandQueueD3D12::GetNextFenceValue(). - virtual Uint64 GetNextFenceValue() const override final { return m_NextFenceValue; } - - // Implementation of ICommandQueueD3D12::Submit(). - virtual Uint64 Submit(ID3D12GraphicsCommandList* commandList) override final; - - // Implementation of ICommandQueueD3D12::GetD3D12CommandQueue(). - virtual ID3D12CommandQueue* GetD3D12CommandQueue() override final { return m_pd3d12CmdQueue; } - - // Implementation of ICommandQueueD3D12::WaitForIdle(). - virtual Uint64 WaitForIdle() override final; - - // Implementation of ICommandQueueD3D12::GetCompletedFenceValue(). - virtual Uint64 GetCompletedFenceValue() override final; - - // Implementation of ICommandQueueD3D12::SignalFence(). - virtual void SignalFence(ID3D12Fence* pFence, Uint64 Value) override final; - -private: - // A value that will be signaled by the command queue next - Atomics::AtomicInt64 m_NextFenceValue; - - // Last fence value completed by the GPU - volatile Uint64 m_LastCompletedFenceValue = 0; - - std::mutex m_QueueMtx; - CComPtr m_pd3d12CmdQueue; - - // The fence is signaled right after the command list has been - // submitted to the command queue for execution. - // All command lists with fence value less or equal to the signaled value - // are guaranteed to be finished by the GPU - CComPtr m_d3d12Fence; - - HANDLE m_WaitForGPUEventHandle = {}; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.hpp new file mode 100644 index 00000000..478f5139 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.hpp @@ -0,0 +1,88 @@ +/* + * 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::CommandQueueD3D12Impl class + +#include "CommandQueueD3D12.h" +#include "ObjectBase.h" +#include + +namespace Diligent +{ + +/// Implementation of the Diligent::ICommandQueueD3D12 interface +class CommandQueueD3D12Impl final : public ObjectBase +{ +public: + using TBase = ObjectBase; + + CommandQueueD3D12Impl(IReferenceCounters* pRefCounters, ID3D12CommandQueue* pd3d12NativeCmdQueue, ID3D12Fence* pd3d12Fence); + ~CommandQueueD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + // Implementation of ICommandQueueD3D12::GetNextFenceValue(). + virtual Uint64 GetNextFenceValue() const override final { return m_NextFenceValue; } + + // Implementation of ICommandQueueD3D12::Submit(). + virtual Uint64 Submit(ID3D12GraphicsCommandList* commandList) override final; + + // Implementation of ICommandQueueD3D12::GetD3D12CommandQueue(). + virtual ID3D12CommandQueue* GetD3D12CommandQueue() override final { return m_pd3d12CmdQueue; } + + // Implementation of ICommandQueueD3D12::WaitForIdle(). + virtual Uint64 WaitForIdle() override final; + + // Implementation of ICommandQueueD3D12::GetCompletedFenceValue(). + virtual Uint64 GetCompletedFenceValue() override final; + + // Implementation of ICommandQueueD3D12::SignalFence(). + virtual void SignalFence(ID3D12Fence* pFence, Uint64 Value) override final; + +private: + // A value that will be signaled by the command queue next + Atomics::AtomicInt64 m_NextFenceValue; + + // Last fence value completed by the GPU + volatile Uint64 m_LastCompletedFenceValue = 0; + + std::mutex m_QueueMtx; + CComPtr m_pd3d12CmdQueue; + + // The fence is signaled right after the command list has been + // submitted to the command queue for execution. + // All command lists with fence value less or equal to the signaled value + // are guaranteed to be finished by the GPU + CComPtr m_d3d12Fence; + + HANDLE m_WaitForGPUEventHandle = {}; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12DynamicHeap.h b/Graphics/GraphicsEngineD3D12/include/D3D12DynamicHeap.h deleted file mode 100644 index cc0b1a9e..00000000 --- a/Graphics/GraphicsEngineD3D12/include/D3D12DynamicHeap.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * 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 - -#include -#include -#include -#include - -namespace Diligent -{ - -class RenderDeviceD3D12Impl; - -struct D3D12DynamicAllocation -{ - D3D12DynamicAllocation() noexcept {} - D3D12DynamicAllocation(ID3D12Resource* pBuff, - Uint64 _Offset, - Uint64 _Size, - void* _CPUAddress, - D3D12_GPU_VIRTUAL_ADDRESS _GPUAddress -#ifdef DEVELOPMENT - , - Uint64 _DvpCtxFrameNumber -#endif - ) noexcept : - // clang-format off - pBuffer {pBuff }, - Offset {_Offset }, - Size {_Size }, - CPUAddress {_CPUAddress }, - GPUAddress {_GPUAddress } -#ifdef DEVELOPMENT - , DvpCtxFrameNumber(_DvpCtxFrameNumber) -#endif - // clang-format on - {} - - ID3D12Resource* pBuffer = nullptr; // The D3D buffer associated with this memory. - Uint64 Offset = 0; // Offset from start of buffer resource - Uint64 Size = 0; // Reserved size of this allocation - void* CPUAddress = nullptr; // The CPU-writeable address - D3D12_GPU_VIRTUAL_ADDRESS GPUAddress = 0; // The GPU-visible address -#ifdef DEVELOPMENT - Uint64 DvpCtxFrameNumber = static_cast(-1); -#endif -}; - - -class D3D12DynamicPage -{ -public: - D3D12DynamicPage(ID3D12Device* pd3d12Device, Uint64 Size); - - // clang-format off - D3D12DynamicPage (const D3D12DynamicPage&) = delete; - D3D12DynamicPage ( D3D12DynamicPage&&) = default; - D3D12DynamicPage& operator= (const D3D12DynamicPage&) = delete; - D3D12DynamicPage& operator= ( D3D12DynamicPage&&) = delete; - // clang-format on - - void* GetCPUAddress(Uint64 Offset) - { - VERIFY_EXPR(m_pd3d12Buffer); - VERIFY(Offset < GetSize(), "Offset (", Offset, ") exceeds buffer size (", GetSize(), ")"); - return reinterpret_cast(m_CPUVirtualAddress) + Offset; - } - - D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress(Uint64 Offset) - { - VERIFY_EXPR(m_pd3d12Buffer); - VERIFY(Offset < GetSize(), "Offset (", Offset, ") exceeds buffer size (", GetSize(), ")"); - return m_GPUVirtualAddress + Offset; - } - - ID3D12Resource* GetD3D12Buffer() - { - return m_pd3d12Buffer; - } - - Uint64 GetSize() const - { - VERIFY_EXPR(m_pd3d12Buffer); - return m_pd3d12Buffer->GetDesc().Width; - } - - bool IsValid() const { return m_pd3d12Buffer != nullptr; } - -private: - CComPtr m_pd3d12Buffer; - void* m_CPUVirtualAddress = nullptr; // The CPU-writeable address - D3D12_GPU_VIRTUAL_ADDRESS m_GPUVirtualAddress = 0; // The GPU-visible address -}; - - -class D3D12DynamicMemoryManager -{ -public: - D3D12DynamicMemoryManager(IMemoryAllocator& Allocator, - RenderDeviceD3D12Impl& DeviceD3D12Impl, - Uint32 NumPagesToReserve, - Uint64 PageSize); - ~D3D12DynamicMemoryManager(); - - // clang-format off - D3D12DynamicMemoryManager (const D3D12DynamicMemoryManager&) = delete; - D3D12DynamicMemoryManager ( D3D12DynamicMemoryManager&&) = delete; - D3D12DynamicMemoryManager& operator= (const D3D12DynamicMemoryManager&) = delete; - D3D12DynamicMemoryManager& operator= ( D3D12DynamicMemoryManager&&) = delete; - // clang-format on - - void ReleasePages(std::vector& Pages, Uint64 QueueMask); - - void Destroy(); - - D3D12DynamicPage AllocatePage(Uint64 SizeInBytes); - -#ifdef DEVELOPMENT - int32_t GetAllocatedPageCounter() const - { - return m_AllocatedPageCounter; - } -#endif - -private: - RenderDeviceD3D12Impl& m_DeviceD3D12Impl; - - std::mutex m_AvailablePagesMtx; - using AvailablePagesMapElemType = std::pair; - std::multimap, STDAllocatorRawMem> m_AvailablePages; - -#ifdef DEVELOPMENT - std::atomic_int32_t m_AllocatedPageCounter = 0; -#endif -}; - - -class D3D12DynamicHeap -{ -public: - D3D12DynamicHeap(D3D12DynamicMemoryManager& DynamicMemMgr, std::string HeapName, Uint64 PageSize) : - m_GlobalDynamicMemMgr{DynamicMemMgr}, - m_HeapName{std::move(HeapName)}, - m_PageSize{PageSize} - {} - - // clang-format off - D3D12DynamicHeap (const D3D12DynamicHeap&) = delete; - D3D12DynamicHeap (D3D12DynamicHeap&&) = delete; - D3D12DynamicHeap& operator= (const D3D12DynamicHeap&) = delete; - D3D12DynamicHeap& operator= (D3D12DynamicHeap&&) = delete; - // clang-format on - - ~D3D12DynamicHeap(); - - D3D12DynamicAllocation Allocate(Uint64 SizeInBytes, Uint64 Alignment, Uint64 DvpCtxFrameNumber); - void ReleaseAllocatedPages(Uint64 QueueMask); - - static constexpr Uint64 InvalidOffset = static_cast(-1); - - size_t GetAllocatedPagesCount() const { return m_AllocatedPages.size(); } - -private: - D3D12DynamicMemoryManager& m_GlobalDynamicMemMgr; - const std::string m_HeapName; - - std::vector m_AllocatedPages; - - const Uint64 m_PageSize; - - Uint64 m_CurrOffset = InvalidOffset; - Uint64 m_AvailableSize = 0; - - Uint64 m_CurrAllocatedSize = 0; - Uint64 m_CurrUsedSize = 0; - Uint64 m_CurrAlignedSize = 0; - Uint64 m_PeakAllocatedSize = 0; - Uint64 m_PeakUsedSize = 0; - Uint64 m_PeakAlignedSize = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12DynamicHeap.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12DynamicHeap.hpp new file mode 100644 index 00000000..cc0b1a9e --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/D3D12DynamicHeap.hpp @@ -0,0 +1,208 @@ +/* + * 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 + +#include +#include +#include +#include + +namespace Diligent +{ + +class RenderDeviceD3D12Impl; + +struct D3D12DynamicAllocation +{ + D3D12DynamicAllocation() noexcept {} + D3D12DynamicAllocation(ID3D12Resource* pBuff, + Uint64 _Offset, + Uint64 _Size, + void* _CPUAddress, + D3D12_GPU_VIRTUAL_ADDRESS _GPUAddress +#ifdef DEVELOPMENT + , + Uint64 _DvpCtxFrameNumber +#endif + ) noexcept : + // clang-format off + pBuffer {pBuff }, + Offset {_Offset }, + Size {_Size }, + CPUAddress {_CPUAddress }, + GPUAddress {_GPUAddress } +#ifdef DEVELOPMENT + , DvpCtxFrameNumber(_DvpCtxFrameNumber) +#endif + // clang-format on + {} + + ID3D12Resource* pBuffer = nullptr; // The D3D buffer associated with this memory. + Uint64 Offset = 0; // Offset from start of buffer resource + Uint64 Size = 0; // Reserved size of this allocation + void* CPUAddress = nullptr; // The CPU-writeable address + D3D12_GPU_VIRTUAL_ADDRESS GPUAddress = 0; // The GPU-visible address +#ifdef DEVELOPMENT + Uint64 DvpCtxFrameNumber = static_cast(-1); +#endif +}; + + +class D3D12DynamicPage +{ +public: + D3D12DynamicPage(ID3D12Device* pd3d12Device, Uint64 Size); + + // clang-format off + D3D12DynamicPage (const D3D12DynamicPage&) = delete; + D3D12DynamicPage ( D3D12DynamicPage&&) = default; + D3D12DynamicPage& operator= (const D3D12DynamicPage&) = delete; + D3D12DynamicPage& operator= ( D3D12DynamicPage&&) = delete; + // clang-format on + + void* GetCPUAddress(Uint64 Offset) + { + VERIFY_EXPR(m_pd3d12Buffer); + VERIFY(Offset < GetSize(), "Offset (", Offset, ") exceeds buffer size (", GetSize(), ")"); + return reinterpret_cast(m_CPUVirtualAddress) + Offset; + } + + D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress(Uint64 Offset) + { + VERIFY_EXPR(m_pd3d12Buffer); + VERIFY(Offset < GetSize(), "Offset (", Offset, ") exceeds buffer size (", GetSize(), ")"); + return m_GPUVirtualAddress + Offset; + } + + ID3D12Resource* GetD3D12Buffer() + { + return m_pd3d12Buffer; + } + + Uint64 GetSize() const + { + VERIFY_EXPR(m_pd3d12Buffer); + return m_pd3d12Buffer->GetDesc().Width; + } + + bool IsValid() const { return m_pd3d12Buffer != nullptr; } + +private: + CComPtr m_pd3d12Buffer; + void* m_CPUVirtualAddress = nullptr; // The CPU-writeable address + D3D12_GPU_VIRTUAL_ADDRESS m_GPUVirtualAddress = 0; // The GPU-visible address +}; + + +class D3D12DynamicMemoryManager +{ +public: + D3D12DynamicMemoryManager(IMemoryAllocator& Allocator, + RenderDeviceD3D12Impl& DeviceD3D12Impl, + Uint32 NumPagesToReserve, + Uint64 PageSize); + ~D3D12DynamicMemoryManager(); + + // clang-format off + D3D12DynamicMemoryManager (const D3D12DynamicMemoryManager&) = delete; + D3D12DynamicMemoryManager ( D3D12DynamicMemoryManager&&) = delete; + D3D12DynamicMemoryManager& operator= (const D3D12DynamicMemoryManager&) = delete; + D3D12DynamicMemoryManager& operator= ( D3D12DynamicMemoryManager&&) = delete; + // clang-format on + + void ReleasePages(std::vector& Pages, Uint64 QueueMask); + + void Destroy(); + + D3D12DynamicPage AllocatePage(Uint64 SizeInBytes); + +#ifdef DEVELOPMENT + int32_t GetAllocatedPageCounter() const + { + return m_AllocatedPageCounter; + } +#endif + +private: + RenderDeviceD3D12Impl& m_DeviceD3D12Impl; + + std::mutex m_AvailablePagesMtx; + using AvailablePagesMapElemType = std::pair; + std::multimap, STDAllocatorRawMem> m_AvailablePages; + +#ifdef DEVELOPMENT + std::atomic_int32_t m_AllocatedPageCounter = 0; +#endif +}; + + +class D3D12DynamicHeap +{ +public: + D3D12DynamicHeap(D3D12DynamicMemoryManager& DynamicMemMgr, std::string HeapName, Uint64 PageSize) : + m_GlobalDynamicMemMgr{DynamicMemMgr}, + m_HeapName{std::move(HeapName)}, + m_PageSize{PageSize} + {} + + // clang-format off + D3D12DynamicHeap (const D3D12DynamicHeap&) = delete; + D3D12DynamicHeap (D3D12DynamicHeap&&) = delete; + D3D12DynamicHeap& operator= (const D3D12DynamicHeap&) = delete; + D3D12DynamicHeap& operator= (D3D12DynamicHeap&&) = delete; + // clang-format on + + ~D3D12DynamicHeap(); + + D3D12DynamicAllocation Allocate(Uint64 SizeInBytes, Uint64 Alignment, Uint64 DvpCtxFrameNumber); + void ReleaseAllocatedPages(Uint64 QueueMask); + + static constexpr Uint64 InvalidOffset = static_cast(-1); + + size_t GetAllocatedPagesCount() const { return m_AllocatedPages.size(); } + +private: + D3D12DynamicMemoryManager& m_GlobalDynamicMemMgr; + const std::string m_HeapName; + + std::vector m_AllocatedPages; + + const Uint64 m_PageSize; + + Uint64 m_CurrOffset = InvalidOffset; + Uint64 m_AvailableSize = 0; + + Uint64 m_CurrAllocatedSize = 0; + Uint64 m_CurrUsedSize = 0; + Uint64 m_CurrAlignedSize = 0; + Uint64 m_PeakAllocatedSize = 0; + Uint64 m_PeakUsedSize = 0; + Uint64 m_PeakAlignedSize = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12Loader.h b/Graphics/GraphicsEngineD3D12/include/D3D12Loader.h deleted file mode 100644 index 8e5b346d..00000000 --- a/Graphics/GraphicsEngineD3D12/include/D3D12Loader.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 - -#include - -namespace Diligent -{ - -using D3D12CreateDeviceProcType = HRESULT(WINAPI*)( - _In_opt_ IUnknown* pAdapter, - D3D_FEATURE_LEVEL MinimumFeatureLevel, - _In_ REFIID riid, - _COM_Outptr_opt_ void** ppDevice); - -using D3D12GetDebugInterfaceProcType = HRESULT(WINAPI*)( - _In_ REFIID riid, - _COM_Outptr_opt_ void** ppvDebug); - -using D3D12SerializeRootSignatureProcType = HRESULT(WINAPI*)( - _In_ const D3D12_ROOT_SIGNATURE_DESC* pRootSignature, - _In_ D3D_ROOT_SIGNATURE_VERSION Version, - _Out_ ID3DBlob** ppBlob, - _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob); - -extern D3D12CreateDeviceProcType D3D12CreateDevice; -extern D3D12GetDebugInterfaceProcType D3D12GetDebugInterface; -extern D3D12SerializeRootSignatureProcType D3D12SerializeRootSignature; - -HMODULE LoadD3D12Dll(const char* DLLPath = "d3d12.dll"); - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12Loader.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12Loader.hpp new file mode 100644 index 00000000..8e5b346d --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/D3D12Loader.hpp @@ -0,0 +1,57 @@ +/* + * 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 + +#include + +namespace Diligent +{ + +using D3D12CreateDeviceProcType = HRESULT(WINAPI*)( + _In_opt_ IUnknown* pAdapter, + D3D_FEATURE_LEVEL MinimumFeatureLevel, + _In_ REFIID riid, + _COM_Outptr_opt_ void** ppDevice); + +using D3D12GetDebugInterfaceProcType = HRESULT(WINAPI*)( + _In_ REFIID riid, + _COM_Outptr_opt_ void** ppvDebug); + +using D3D12SerializeRootSignatureProcType = HRESULT(WINAPI*)( + _In_ const D3D12_ROOT_SIGNATURE_DESC* pRootSignature, + _In_ D3D_ROOT_SIGNATURE_VERSION Version, + _Out_ ID3DBlob** ppBlob, + _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob); + +extern D3D12CreateDeviceProcType D3D12CreateDevice; +extern D3D12GetDebugInterfaceProcType D3D12GetDebugInterface; +extern D3D12SerializeRootSignatureProcType D3D12SerializeRootSignature; + +HMODULE LoadD3D12Dll(const char* DLLPath = "d3d12.dll"); + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.h b/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.h deleted file mode 100644 index 240ea165..00000000 --- a/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 -/// Implementation of the Diligent::D3D12ResourceBase class - -namespace Diligent -{ - -/// Base implementation of a D3D12 resource -class D3D12ResourceBase -{ -public: - D3D12ResourceBase() - {} - - ID3D12Resource* GetD3D12Resource() { return m_pd3d12Resource; } - -protected: - CComPtr m_pd3d12Resource; ///< D3D12 buffer object -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp b/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp new file mode 100644 index 00000000..240ea165 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/D3D12ResourceBase.hpp @@ -0,0 +1,49 @@ +/* + * 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 +/// Implementation of the Diligent::D3D12ResourceBase class + +namespace Diligent +{ + +/// Base implementation of a D3D12 resource +class D3D12ResourceBase +{ +public: + D3D12ResourceBase() + {} + + ID3D12Resource* GetD3D12Resource() { return m_pd3d12Resource; } + +protected: + CComPtr m_pd3d12Resource; ///< D3D12 buffer object +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/DescriptorHeap.h b/Graphics/GraphicsEngineD3D12/include/DescriptorHeap.h deleted file mode 100644 index d8108c06..00000000 --- a/Graphics/GraphicsEngineD3D12/include/DescriptorHeap.h +++ /dev/null @@ -1,569 +0,0 @@ -/* - * 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. - */ - -// Descriptor heap management utilities. -// See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-descriptor-heaps/ for details - -#pragma once - -#include -#include -#include -#include -#include -#include -#include "ObjectBase.h" -#include "VariableSizeAllocationsManager.hpp" - -namespace Diligent -{ - -class DescriptorHeapAllocation; -class DescriptorHeapAllocationManager; -class RenderDeviceD3D12Impl; - -class IDescriptorAllocator -{ -public: - // Allocate Count descriptors - virtual DescriptorHeapAllocation Allocate(uint32_t Count) = 0; - virtual void Free(DescriptorHeapAllocation&& Allocation, Uint64 CmdQueueMask) = 0; - virtual Uint32 GetDescriptorSize() const = 0; -}; - - -// The class represents descriptor heap allocation (continuous descriptor range in a descriptor heap) -// -// m_FirstCpuHandle -// | -// | ~ ~ ~ ~ ~ X X X X X X X ~ ~ ~ ~ ~ ~ | D3D12 Descriptor Heap -// | -// m_FirstGpuHandle -// -class DescriptorHeapAllocation -{ -public: - // Creates null allocation - DescriptorHeapAllocation() noexcept : - // clang-format off - m_NumHandles {1 }, // One null descriptor handle - m_pDescriptorHeap {nullptr}, - m_DescriptorSize {0 } - // clang-format on - { - m_FirstCpuHandle.ptr = 0; - m_FirstGpuHandle.ptr = 0; - } - - // Initializes non-null allocation - DescriptorHeapAllocation(IDescriptorAllocator& Allocator, - ID3D12DescriptorHeap* pHeap, - D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle, - D3D12_GPU_DESCRIPTOR_HANDLE GpuHandle, - Uint32 NHandles, - Uint16 AllocationManagerId) noexcept : - // clang-format off - m_FirstCpuHandle {CpuHandle }, - m_FirstGpuHandle {GpuHandle }, - m_pAllocator {&Allocator }, - m_NumHandles {NHandles }, - m_pDescriptorHeap {pHeap }, - m_AllocationManagerId {AllocationManagerId} - // clang-format on - { - VERIFY_EXPR(m_pAllocator != nullptr && m_pDescriptorHeap != nullptr); - auto DescriptorSize = m_pAllocator->GetDescriptorSize(); - VERIFY(DescriptorSize < std::numeric_limits::max(), "DescriptorSize exceeds allowed limit"); - m_DescriptorSize = static_cast(DescriptorSize); - } - - // Move constructor (copy is not allowed) - DescriptorHeapAllocation(DescriptorHeapAllocation&& Allocation) noexcept : - // clang-format off - m_FirstCpuHandle {std::move(Allocation.m_FirstCpuHandle) }, - m_FirstGpuHandle {std::move(Allocation.m_FirstGpuHandle) }, - m_NumHandles {std::move(Allocation.m_NumHandles) }, - m_pAllocator {std::move(Allocation.m_pAllocator) }, - m_AllocationManagerId {std::move(Allocation.m_AllocationManagerId)}, - m_pDescriptorHeap {std::move(Allocation.m_pDescriptorHeap) }, - m_DescriptorSize {std::move(Allocation.m_DescriptorSize) } - // clang-format on - { - Allocation.Reset(); - } - - // Move assignment (assignment is not allowed) - DescriptorHeapAllocation& operator=(DescriptorHeapAllocation&& Allocation) noexcept - { - m_FirstCpuHandle = std::move(Allocation.m_FirstCpuHandle); - m_FirstGpuHandle = std::move(Allocation.m_FirstGpuHandle); - m_NumHandles = std::move(Allocation.m_NumHandles); - m_pAllocator = std::move(Allocation.m_pAllocator); - m_AllocationManagerId = std::move(Allocation.m_AllocationManagerId); - m_pDescriptorHeap = std::move(Allocation.m_pDescriptorHeap); - m_DescriptorSize = std::move(Allocation.m_DescriptorSize); - - Allocation.Reset(); - - return *this; - } - - void Reset() - { - m_FirstCpuHandle.ptr = 0; - m_FirstGpuHandle.ptr = 0; - m_pAllocator = nullptr; - m_pDescriptorHeap = nullptr; - m_NumHandles = 0; - m_AllocationManagerId = static_cast(-1); - m_DescriptorSize = 0; - } - - // clang-format off - DescriptorHeapAllocation (const DescriptorHeapAllocation&) = delete; - DescriptorHeapAllocation& operator=(const DescriptorHeapAllocation&) = delete; - // clang-format on - - - // Destructor automatically releases this allocation through the allocator - ~DescriptorHeapAllocation() - { - if (!IsNull() && m_pAllocator) - m_pAllocator->Free(std::move(*this), ~Uint64{0}); - // Allocation must have been disposed by the allocator - VERIFY(IsNull(), "Non-null descriptor is being destroyed"); - } - - // Returns CPU descriptor handle at the specified offset - D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Uint32 Offset = 0) const - { - VERIFY_EXPR(Offset >= 0 && Offset < m_NumHandles); - - D3D12_CPU_DESCRIPTOR_HANDLE CPUHandle = m_FirstCpuHandle; - CPUHandle.ptr += m_DescriptorSize * Offset; - - return CPUHandle; - } - - // Returns GPU descriptor handle at the specified offset - D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(Uint32 Offset = 0) const - { - VERIFY_EXPR(Offset >= 0 && Offset < m_NumHandles); - D3D12_GPU_DESCRIPTOR_HANDLE GPUHandle = m_FirstGpuHandle; - GPUHandle.ptr += m_DescriptorSize * Offset; - - return GPUHandle; - } - - // Returns pointer to D3D12 descriptor heap that contains this allocation - ID3D12DescriptorHeap* GetDescriptorHeap() { return m_pDescriptorHeap; } - - - // clang-format off - size_t GetNumHandles() const { return m_NumHandles; } - bool IsNull() const { return m_FirstCpuHandle.ptr == 0; } - bool IsShaderVisible() const { return m_FirstGpuHandle.ptr != 0; } - size_t GetAllocationManagerId() const { return m_AllocationManagerId; } - UINT GetDescriptorSize() const { return m_DescriptorSize; } - // clang-format on - -private: - // First CPU descriptor handle in this allocation - D3D12_CPU_DESCRIPTOR_HANDLE m_FirstCpuHandle = {0}; - - // First GPU descriptor handle in this allocation - D3D12_GPU_DESCRIPTOR_HANDLE m_FirstGpuHandle = {0}; - - // Keep strong reference to the parent heap to make sure it is alive while allocation is alive - TOO EXPENSIVE - //RefCntAutoPtr m_pAllocator; - - // Pointer to the descriptor heap allocator that created this allocation - IDescriptorAllocator* m_pAllocator = nullptr; - - // Pointer to the D3D12 descriptor heap that contains descriptors in this allocation - ID3D12DescriptorHeap* m_pDescriptorHeap = nullptr; - - // Number of descriptors in the allocation - Uint32 m_NumHandles = 0; - - // Allocation manager ID. One allocator may support several - // allocation managers. This field is required to identify - // the manager within the allocator that was used to create - // this allocation - Uint16 m_AllocationManagerId = static_cast(-1); - - // Descriptor size - Uint16 m_DescriptorSize = 0; -}; - - -// The class performs suballocations within one D3D12 descriptor heap. -// It uses VariableSizeAllocationsManager to manage free space in the heap -// -// | X X X X O O O X X O O X O O O O | D3D12 descriptor heap -// -// X - used descriptor -// O - available descriptor -// -class DescriptorHeapAllocationManager -{ -public: - // Creates a new D3D12 descriptor heap - DescriptorHeapAllocationManager(IMemoryAllocator& Allocator, - RenderDeviceD3D12Impl& DeviceD3D12Impl, - IDescriptorAllocator& ParentAllocator, - size_t ThisManagerId, - const D3D12_DESCRIPTOR_HEAP_DESC& HeapDesc); - - // Uses subrange of descriptors in the existing D3D12 descriptor heap - // that starts at offset FirstDescriptor and uses NumDescriptors descriptors - DescriptorHeapAllocationManager(IMemoryAllocator& Allocator, - RenderDeviceD3D12Impl& DeviceD3D12Impl, - IDescriptorAllocator& ParentAllocator, - size_t ThisManagerId, - ID3D12DescriptorHeap* pd3d12DescriptorHeap, - Uint32 FirstDescriptor, - Uint32 NumDescriptors); - - - // = default causes compiler error when instantiating std::vector::emplace_back() in Visual Studio 2015 (Version 14.0.23107.0 D14REL) - DescriptorHeapAllocationManager(DescriptorHeapAllocationManager&& rhs) noexcept : - // clang-format off - m_ParentAllocator {rhs.m_ParentAllocator }, - m_DeviceD3D12Impl {rhs.m_DeviceD3D12Impl }, - m_ThisManagerId {rhs.m_ThisManagerId }, - m_HeapDesc {rhs.m_HeapDesc }, - m_DescriptorSize {rhs.m_DescriptorSize }, - m_NumDescriptorsInAllocation{rhs.m_NumDescriptorsInAllocation}, - m_FirstCPUHandle {rhs.m_FirstCPUHandle }, - m_FirstGPUHandle {rhs.m_FirstGPUHandle }, - m_MaxAllocatedSize {rhs.m_MaxAllocatedSize }, - // Mutex is not movable - //m_FreeBlockManagerMutex (std::move(rhs.m_FreeBlockManagerMutex)) - m_FreeBlockManager {std::move(rhs.m_FreeBlockManager) }, - m_pd3d12DescriptorHeap {std::move(rhs.m_pd3d12DescriptorHeap)} - // clang-format on - { - rhs.m_NumDescriptorsInAllocation = 0; // Must be set to zero so that debug check in dtor passes - rhs.m_ThisManagerId = static_cast(-1); - rhs.m_FirstCPUHandle.ptr = 0; - rhs.m_FirstGPUHandle.ptr = 0; - rhs.m_MaxAllocatedSize = 0; -#ifdef DEVELOPMENT - m_AllocationsCounter.store(rhs.m_AllocationsCounter.load()); - rhs.m_AllocationsCounter = 0; -#endif - } - - // clang-format off - // No copies or move-assignments - DescriptorHeapAllocationManager& operator = (DescriptorHeapAllocationManager&&) = delete; - DescriptorHeapAllocationManager (const DescriptorHeapAllocationManager&) = delete; - DescriptorHeapAllocationManager& operator = (const DescriptorHeapAllocationManager&) = delete; - // clang-format on - - ~DescriptorHeapAllocationManager(); - - // Allocates Count descriptors - DescriptorHeapAllocation Allocate(uint32_t Count); - void FreeAllocation(DescriptorHeapAllocation&& Allocation); - - // clang-format off - size_t GetNumAvailableDescriptors()const { return m_FreeBlockManager.GetFreeSize(); } - Uint32 GetMaxDescriptors() const { return m_NumDescriptorsInAllocation; } - size_t GetMaxAllocatedSize() const { return m_MaxAllocatedSize; } - // clang-format on - -#ifdef DEVELOPMENT - int32_t DvpGetAllocationsCounter() const - { - return m_AllocationsCounter; - } -#endif - -private: - IDescriptorAllocator& m_ParentAllocator; - RenderDeviceD3D12Impl& m_DeviceD3D12Impl; - - // External ID assigned to this descriptor allocations manager - size_t m_ThisManagerId = static_cast(-1); - - // Heap description - const D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc; - - const UINT m_DescriptorSize = 0; - - // Number of descriptors in the allocation. - // If this manager was initialized as a subrange in the existing heap, - // this value may be different from m_HeapDesc.NumDescriptors - Uint32 m_NumDescriptorsInAllocation = 0; - - // Allocations manager used to handle descriptor allocations within the heap - std::mutex m_FreeBlockManagerMutex; - VariableSizeAllocationsManager m_FreeBlockManager; - - // Strong reference to D3D12 descriptor heap object - CComPtr m_pd3d12DescriptorHeap; - - // First CPU descriptor handle in the available descriptor range - D3D12_CPU_DESCRIPTOR_HANDLE m_FirstCPUHandle = {0}; - - // First GPU descriptor handle in the available descriptor range - D3D12_GPU_DESCRIPTOR_HANDLE m_FirstGPUHandle = {0}; - - size_t m_MaxAllocatedSize = 0; - -#ifdef DEVELOPMENT - std::atomic_int32_t m_AllocationsCounter = 0; -#endif - - // Note: when adding new members, do not forget to update move ctor -}; - -// CPU descriptor heap is intended to provide storage for resource view descriptor handles. -// It contains a pool of DescriptorHeapAllocationManager object instances, where every instance manages -// its own CPU-only D3D12 descriptor heap: -// -// m_HeapPool[0] m_HeapPool[1] m_HeapPool[2] -// | X X X X X X X X |, | X X X O O X X O |, | X O O O O O O O | -// -// X - used descriptor m_AvailableHeaps = {1,2} -// O - available descriptor -// -// Allocation routine goes through the list of managers that have available descriptors and tries to process -// the request using every manager. If there are no available managers or no manager was able to handle the request, -// the function creates a new descriptor heap manager and lets it handle the request -// -// Render device contains four CPUDescriptorHeap object instances (one for each D3D12 heap type). The heaps are accessed -// when a texture or a buffer view is created. -// -class CPUDescriptorHeap final : public IDescriptorAllocator -{ -public: - // Initializes the heap - CPUDescriptorHeap(IMemoryAllocator& Allocator, - RenderDeviceD3D12Impl& DeviceD3D12Impl, - Uint32 NumDescriptorsInHeap, - D3D12_DESCRIPTOR_HEAP_TYPE Type, - D3D12_DESCRIPTOR_HEAP_FLAGS Flags); - - // clang-format off - CPUDescriptorHeap (const CPUDescriptorHeap&) = delete; - CPUDescriptorHeap (CPUDescriptorHeap&&) = delete; - CPUDescriptorHeap& operator = (const CPUDescriptorHeap&) = delete; - CPUDescriptorHeap& operator = (CPUDescriptorHeap&&) = delete; - // clang-format on - - ~CPUDescriptorHeap(); - - virtual DescriptorHeapAllocation Allocate(uint32_t Count) override final; - virtual void Free(DescriptorHeapAllocation&& Allocation, Uint64 CmdQueueMask) override final; - virtual Uint32 GetDescriptorSize() const override final { return m_DescriptorSize; } - -#ifdef DEVELOPMENT - int32_t DvpGetTotalAllocationCount(); -#endif - -private: - void FreeAllocation(DescriptorHeapAllocation&& Allocation); - - IMemoryAllocator& m_MemAllocator; - RenderDeviceD3D12Impl& m_DeviceD3D12Impl; - - // Pool of descriptor heap managers - std::mutex m_HeapPoolMutex; - std::vector> m_HeapPool; - // Indices of available descriptor heap managers - std::unordered_set, std::equal_to, STDAllocatorRawMem> m_AvailableHeaps; - - D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc; - const UINT m_DescriptorSize = 0; - - // Maximum heap size during the application lifetime - for statistic purposes - Uint32 m_MaxSize = 0; - Uint32 m_CurrentSize = 0; -}; - -// GPU descriptor heap provides storage for shader-visible descriptors -// The heap contains single D3D12 descriptor heap that is split into two parts. -// The first part stores static and mutable resource descriptor handles. -// The second part is intended to provide temporary storage for dynamic resources. -// Space for dynamic resources is allocated in chunks, and then descriptors are suballocated within every -// chunk. DynamicSuballocationsManager facilitates this process. -// -// -// static and mutable handles || dynamic space -// || chunk 0 chunk 1 chunk 2 unused -// | X O O X X O X O O O O X X X X O || | X X X O | | X X O O | | O O O O | O O O O || -// | | -// suballocation suballocation -// within chunk 0 within chunk 1 -// -// Render device contains two GPUDescriptorHeap instances (CBV_SRV_UAV and SAMPLER). The heaps -// are used to allocate GPU-visible descriptors for shader resource binding objects. The heaps -// are also used by the command contexts (through DynamicSuballocationsManager to allocated dynamic descriptors) -// -// _______________________________________________________________________________________________________________________________ -// | Render Device | -// | | -// | m_CPUDescriptorHeaps[CBV_SRV_UAV] | X X X X X X X X |, | X X X X X X X X |, | X O O X O O O O | | -// | m_CPUDescriptorHeaps[SAMPLER] | X X X X O O O X |, | X O O X O O O O | | -// | m_CPUDescriptorHeaps[RTV] | X X X O O O O O |, | O O O O O O O O | | -// | m_CPUDescriptorHeaps[DSV] | X X X O X O X O | | -// | ctx1 ctx2 | -// | m_GPUDescriptorHeaps[CBV_SRV_UAV] | X O O X X O X O O O O X X X X O || | X X X O | | X X O O | | O O O O | O O O O || | -// | m_GPUDescriptorHeaps[SAMPLER] | X X O O X O X X X O O X O O O O || | X X O O | | X O O O | | O O O O | O O O O || | -// | | -// |_______________________________________________________________________________________________________________________________| -// -// ________________________________________________ ________________________________________________ -// |Device Context 1 | |Device Context 2 | -// | | | | -// | m_DynamicGPUDescriptorAllocator[CBV_SRV_UAV] | | m_DynamicGPUDescriptorAllocator[CBV_SRV_UAV] | -// | m_DynamicGPUDescriptorAllocator[SAMPLER] | | m_DynamicGPUDescriptorAllocator[SAMPLER] | -// |________________________________________________| |________________________________________________| -// -class GPUDescriptorHeap final : public IDescriptorAllocator -{ -public: - GPUDescriptorHeap(IMemoryAllocator& Allocator, - RenderDeviceD3D12Impl& Device, - Uint32 NumDescriptorsInHeap, - Uint32 NumDynamicDescriptors, - D3D12_DESCRIPTOR_HEAP_TYPE Type, - D3D12_DESCRIPTOR_HEAP_FLAGS Flags); - - // clang-format off - GPUDescriptorHeap (const GPUDescriptorHeap&) = delete; - GPUDescriptorHeap (GPUDescriptorHeap&&) = delete; - GPUDescriptorHeap& operator = (const GPUDescriptorHeap&) = delete; - GPUDescriptorHeap& operator = (GPUDescriptorHeap&&) = delete; - // clang-format on - - ~GPUDescriptorHeap(); - - virtual DescriptorHeapAllocation Allocate(uint32_t Count) override final - { - return m_HeapAllocationManager.Allocate(Count); - } - - virtual void Free(DescriptorHeapAllocation&& Allocation, Uint64 CmdQueueMask) override final; - virtual Uint32 GetDescriptorSize() const override final { return m_DescriptorSize; } - - DescriptorHeapAllocation AllocateDynamic(uint32_t Count) - { - return m_DynamicAllocationsManager.Allocate(Count); - } - - const D3D12_DESCRIPTOR_HEAP_DESC& GetHeapDesc() const { return m_HeapDesc; } - Uint32 GetMaxStaticDescriptors() const { return m_HeapAllocationManager.GetMaxDescriptors(); } - Uint32 GetMaxDynamicDescriptors() const { return m_DynamicAllocationsManager.GetMaxDescriptors(); } - -#ifdef DEVELOPMENT - int32_t DvpGetTotalAllocationCount() const - { - return m_HeapAllocationManager.DvpGetAllocationsCounter() + - m_DynamicAllocationsManager.DvpGetAllocationsCounter(); - } -#endif - -protected: - RenderDeviceD3D12Impl& m_DeviceD3D12Impl; - - const D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc; - CComPtr m_pd3d12DescriptorHeap; - - const UINT m_DescriptorSize; - - // Allocation manager for static/mutable part - DescriptorHeapAllocationManager m_HeapAllocationManager; - - // Allocation manager for dynamic part - DescriptorHeapAllocationManager m_DynamicAllocationsManager; -}; - - -// The class facilitates allocation of dynamic descriptor handles. It requests a chunk of heap -// from the master GPU descriptor heap and then performs linear suballocation within the chunk -// At the end of the frame all allocations are disposed. - -// static and mutable handles || dynamic space -// || chunk 0 chunk 2 -// | || | X X X O | | O O O O | || GPU Descriptor Heap -// | | -// m_Suballocations[0] m_Suballocations[1] -// -class DynamicSuballocationsManager final : public IDescriptorAllocator -{ -public: - DynamicSuballocationsManager(IMemoryAllocator& Allocator, - GPUDescriptorHeap& ParentGPUHeap, - Uint32 DynamicChunkSize, - String ManagerName); - - // clang-format off - DynamicSuballocationsManager (const DynamicSuballocationsManager&) = delete; - DynamicSuballocationsManager (DynamicSuballocationsManager&&) = delete; - DynamicSuballocationsManager& operator = (const DynamicSuballocationsManager&) = delete; - DynamicSuballocationsManager& operator = (DynamicSuballocationsManager&&) = delete; - // clang-format on - - ~DynamicSuballocationsManager(); - - void ReleaseAllocations(Uint64 CmdQueueMask); - - virtual DescriptorHeapAllocation Allocate(Uint32 Count) override final; - virtual void Free(DescriptorHeapAllocation&& Allocation, Uint64 CmdQueueMask) override final - { - // Do nothing. Dynamic allocations are not disposed individually, but as whole chunks - // at the end of the frame by ReleaseAllocations() - Allocation.Reset(); - } - - virtual Uint32 GetDescriptorSize() const override final { return m_ParentGPUHeap.GetDescriptorSize(); } - - size_t GetSuballocationCount() const { return m_Suballocations.size(); } - -private: - // Parent GPU descriptor heap that is used to allocate chunks - GPUDescriptorHeap& m_ParentGPUHeap; - const String m_ManagerName; - - // List of chunks allocated from the master GPU descriptor heap. All chunks are disposed at the end - // of the frame - std::vector> m_Suballocations; - - Uint32 m_CurrentSuballocationOffset = 0; - Uint32 m_DynamicChunkSize = 0; - - Uint32 m_CurrDescriptorCount = 0; - Uint32 m_PeakDescriptorCount = 0; - Uint32 m_CurrSuballocationsTotalSize = 0; - Uint32 m_PeakSuballocationsTotalSize = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/DescriptorHeap.hpp b/Graphics/GraphicsEngineD3D12/include/DescriptorHeap.hpp new file mode 100644 index 00000000..d8108c06 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/DescriptorHeap.hpp @@ -0,0 +1,569 @@ +/* + * 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. + */ + +// Descriptor heap management utilities. +// See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-descriptor-heaps/ for details + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "ObjectBase.h" +#include "VariableSizeAllocationsManager.hpp" + +namespace Diligent +{ + +class DescriptorHeapAllocation; +class DescriptorHeapAllocationManager; +class RenderDeviceD3D12Impl; + +class IDescriptorAllocator +{ +public: + // Allocate Count descriptors + virtual DescriptorHeapAllocation Allocate(uint32_t Count) = 0; + virtual void Free(DescriptorHeapAllocation&& Allocation, Uint64 CmdQueueMask) = 0; + virtual Uint32 GetDescriptorSize() const = 0; +}; + + +// The class represents descriptor heap allocation (continuous descriptor range in a descriptor heap) +// +// m_FirstCpuHandle +// | +// | ~ ~ ~ ~ ~ X X X X X X X ~ ~ ~ ~ ~ ~ | D3D12 Descriptor Heap +// | +// m_FirstGpuHandle +// +class DescriptorHeapAllocation +{ +public: + // Creates null allocation + DescriptorHeapAllocation() noexcept : + // clang-format off + m_NumHandles {1 }, // One null descriptor handle + m_pDescriptorHeap {nullptr}, + m_DescriptorSize {0 } + // clang-format on + { + m_FirstCpuHandle.ptr = 0; + m_FirstGpuHandle.ptr = 0; + } + + // Initializes non-null allocation + DescriptorHeapAllocation(IDescriptorAllocator& Allocator, + ID3D12DescriptorHeap* pHeap, + D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle, + D3D12_GPU_DESCRIPTOR_HANDLE GpuHandle, + Uint32 NHandles, + Uint16 AllocationManagerId) noexcept : + // clang-format off + m_FirstCpuHandle {CpuHandle }, + m_FirstGpuHandle {GpuHandle }, + m_pAllocator {&Allocator }, + m_NumHandles {NHandles }, + m_pDescriptorHeap {pHeap }, + m_AllocationManagerId {AllocationManagerId} + // clang-format on + { + VERIFY_EXPR(m_pAllocator != nullptr && m_pDescriptorHeap != nullptr); + auto DescriptorSize = m_pAllocator->GetDescriptorSize(); + VERIFY(DescriptorSize < std::numeric_limits::max(), "DescriptorSize exceeds allowed limit"); + m_DescriptorSize = static_cast(DescriptorSize); + } + + // Move constructor (copy is not allowed) + DescriptorHeapAllocation(DescriptorHeapAllocation&& Allocation) noexcept : + // clang-format off + m_FirstCpuHandle {std::move(Allocation.m_FirstCpuHandle) }, + m_FirstGpuHandle {std::move(Allocation.m_FirstGpuHandle) }, + m_NumHandles {std::move(Allocation.m_NumHandles) }, + m_pAllocator {std::move(Allocation.m_pAllocator) }, + m_AllocationManagerId {std::move(Allocation.m_AllocationManagerId)}, + m_pDescriptorHeap {std::move(Allocation.m_pDescriptorHeap) }, + m_DescriptorSize {std::move(Allocation.m_DescriptorSize) } + // clang-format on + { + Allocation.Reset(); + } + + // Move assignment (assignment is not allowed) + DescriptorHeapAllocation& operator=(DescriptorHeapAllocation&& Allocation) noexcept + { + m_FirstCpuHandle = std::move(Allocation.m_FirstCpuHandle); + m_FirstGpuHandle = std::move(Allocation.m_FirstGpuHandle); + m_NumHandles = std::move(Allocation.m_NumHandles); + m_pAllocator = std::move(Allocation.m_pAllocator); + m_AllocationManagerId = std::move(Allocation.m_AllocationManagerId); + m_pDescriptorHeap = std::move(Allocation.m_pDescriptorHeap); + m_DescriptorSize = std::move(Allocation.m_DescriptorSize); + + Allocation.Reset(); + + return *this; + } + + void Reset() + { + m_FirstCpuHandle.ptr = 0; + m_FirstGpuHandle.ptr = 0; + m_pAllocator = nullptr; + m_pDescriptorHeap = nullptr; + m_NumHandles = 0; + m_AllocationManagerId = static_cast(-1); + m_DescriptorSize = 0; + } + + // clang-format off + DescriptorHeapAllocation (const DescriptorHeapAllocation&) = delete; + DescriptorHeapAllocation& operator=(const DescriptorHeapAllocation&) = delete; + // clang-format on + + + // Destructor automatically releases this allocation through the allocator + ~DescriptorHeapAllocation() + { + if (!IsNull() && m_pAllocator) + m_pAllocator->Free(std::move(*this), ~Uint64{0}); + // Allocation must have been disposed by the allocator + VERIFY(IsNull(), "Non-null descriptor is being destroyed"); + } + + // Returns CPU descriptor handle at the specified offset + D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Uint32 Offset = 0) const + { + VERIFY_EXPR(Offset >= 0 && Offset < m_NumHandles); + + D3D12_CPU_DESCRIPTOR_HANDLE CPUHandle = m_FirstCpuHandle; + CPUHandle.ptr += m_DescriptorSize * Offset; + + return CPUHandle; + } + + // Returns GPU descriptor handle at the specified offset + D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(Uint32 Offset = 0) const + { + VERIFY_EXPR(Offset >= 0 && Offset < m_NumHandles); + D3D12_GPU_DESCRIPTOR_HANDLE GPUHandle = m_FirstGpuHandle; + GPUHandle.ptr += m_DescriptorSize * Offset; + + return GPUHandle; + } + + // Returns pointer to D3D12 descriptor heap that contains this allocation + ID3D12DescriptorHeap* GetDescriptorHeap() { return m_pDescriptorHeap; } + + + // clang-format off + size_t GetNumHandles() const { return m_NumHandles; } + bool IsNull() const { return m_FirstCpuHandle.ptr == 0; } + bool IsShaderVisible() const { return m_FirstGpuHandle.ptr != 0; } + size_t GetAllocationManagerId() const { return m_AllocationManagerId; } + UINT GetDescriptorSize() const { return m_DescriptorSize; } + // clang-format on + +private: + // First CPU descriptor handle in this allocation + D3D12_CPU_DESCRIPTOR_HANDLE m_FirstCpuHandle = {0}; + + // First GPU descriptor handle in this allocation + D3D12_GPU_DESCRIPTOR_HANDLE m_FirstGpuHandle = {0}; + + // Keep strong reference to the parent heap to make sure it is alive while allocation is alive - TOO EXPENSIVE + //RefCntAutoPtr m_pAllocator; + + // Pointer to the descriptor heap allocator that created this allocation + IDescriptorAllocator* m_pAllocator = nullptr; + + // Pointer to the D3D12 descriptor heap that contains descriptors in this allocation + ID3D12DescriptorHeap* m_pDescriptorHeap = nullptr; + + // Number of descriptors in the allocation + Uint32 m_NumHandles = 0; + + // Allocation manager ID. One allocator may support several + // allocation managers. This field is required to identify + // the manager within the allocator that was used to create + // this allocation + Uint16 m_AllocationManagerId = static_cast(-1); + + // Descriptor size + Uint16 m_DescriptorSize = 0; +}; + + +// The class performs suballocations within one D3D12 descriptor heap. +// It uses VariableSizeAllocationsManager to manage free space in the heap +// +// | X X X X O O O X X O O X O O O O | D3D12 descriptor heap +// +// X - used descriptor +// O - available descriptor +// +class DescriptorHeapAllocationManager +{ +public: + // Creates a new D3D12 descriptor heap + DescriptorHeapAllocationManager(IMemoryAllocator& Allocator, + RenderDeviceD3D12Impl& DeviceD3D12Impl, + IDescriptorAllocator& ParentAllocator, + size_t ThisManagerId, + const D3D12_DESCRIPTOR_HEAP_DESC& HeapDesc); + + // Uses subrange of descriptors in the existing D3D12 descriptor heap + // that starts at offset FirstDescriptor and uses NumDescriptors descriptors + DescriptorHeapAllocationManager(IMemoryAllocator& Allocator, + RenderDeviceD3D12Impl& DeviceD3D12Impl, + IDescriptorAllocator& ParentAllocator, + size_t ThisManagerId, + ID3D12DescriptorHeap* pd3d12DescriptorHeap, + Uint32 FirstDescriptor, + Uint32 NumDescriptors); + + + // = default causes compiler error when instantiating std::vector::emplace_back() in Visual Studio 2015 (Version 14.0.23107.0 D14REL) + DescriptorHeapAllocationManager(DescriptorHeapAllocationManager&& rhs) noexcept : + // clang-format off + m_ParentAllocator {rhs.m_ParentAllocator }, + m_DeviceD3D12Impl {rhs.m_DeviceD3D12Impl }, + m_ThisManagerId {rhs.m_ThisManagerId }, + m_HeapDesc {rhs.m_HeapDesc }, + m_DescriptorSize {rhs.m_DescriptorSize }, + m_NumDescriptorsInAllocation{rhs.m_NumDescriptorsInAllocation}, + m_FirstCPUHandle {rhs.m_FirstCPUHandle }, + m_FirstGPUHandle {rhs.m_FirstGPUHandle }, + m_MaxAllocatedSize {rhs.m_MaxAllocatedSize }, + // Mutex is not movable + //m_FreeBlockManagerMutex (std::move(rhs.m_FreeBlockManagerMutex)) + m_FreeBlockManager {std::move(rhs.m_FreeBlockManager) }, + m_pd3d12DescriptorHeap {std::move(rhs.m_pd3d12DescriptorHeap)} + // clang-format on + { + rhs.m_NumDescriptorsInAllocation = 0; // Must be set to zero so that debug check in dtor passes + rhs.m_ThisManagerId = static_cast(-1); + rhs.m_FirstCPUHandle.ptr = 0; + rhs.m_FirstGPUHandle.ptr = 0; + rhs.m_MaxAllocatedSize = 0; +#ifdef DEVELOPMENT + m_AllocationsCounter.store(rhs.m_AllocationsCounter.load()); + rhs.m_AllocationsCounter = 0; +#endif + } + + // clang-format off + // No copies or move-assignments + DescriptorHeapAllocationManager& operator = (DescriptorHeapAllocationManager&&) = delete; + DescriptorHeapAllocationManager (const DescriptorHeapAllocationManager&) = delete; + DescriptorHeapAllocationManager& operator = (const DescriptorHeapAllocationManager&) = delete; + // clang-format on + + ~DescriptorHeapAllocationManager(); + + // Allocates Count descriptors + DescriptorHeapAllocation Allocate(uint32_t Count); + void FreeAllocation(DescriptorHeapAllocation&& Allocation); + + // clang-format off + size_t GetNumAvailableDescriptors()const { return m_FreeBlockManager.GetFreeSize(); } + Uint32 GetMaxDescriptors() const { return m_NumDescriptorsInAllocation; } + size_t GetMaxAllocatedSize() const { return m_MaxAllocatedSize; } + // clang-format on + +#ifdef DEVELOPMENT + int32_t DvpGetAllocationsCounter() const + { + return m_AllocationsCounter; + } +#endif + +private: + IDescriptorAllocator& m_ParentAllocator; + RenderDeviceD3D12Impl& m_DeviceD3D12Impl; + + // External ID assigned to this descriptor allocations manager + size_t m_ThisManagerId = static_cast(-1); + + // Heap description + const D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc; + + const UINT m_DescriptorSize = 0; + + // Number of descriptors in the allocation. + // If this manager was initialized as a subrange in the existing heap, + // this value may be different from m_HeapDesc.NumDescriptors + Uint32 m_NumDescriptorsInAllocation = 0; + + // Allocations manager used to handle descriptor allocations within the heap + std::mutex m_FreeBlockManagerMutex; + VariableSizeAllocationsManager m_FreeBlockManager; + + // Strong reference to D3D12 descriptor heap object + CComPtr m_pd3d12DescriptorHeap; + + // First CPU descriptor handle in the available descriptor range + D3D12_CPU_DESCRIPTOR_HANDLE m_FirstCPUHandle = {0}; + + // First GPU descriptor handle in the available descriptor range + D3D12_GPU_DESCRIPTOR_HANDLE m_FirstGPUHandle = {0}; + + size_t m_MaxAllocatedSize = 0; + +#ifdef DEVELOPMENT + std::atomic_int32_t m_AllocationsCounter = 0; +#endif + + // Note: when adding new members, do not forget to update move ctor +}; + +// CPU descriptor heap is intended to provide storage for resource view descriptor handles. +// It contains a pool of DescriptorHeapAllocationManager object instances, where every instance manages +// its own CPU-only D3D12 descriptor heap: +// +// m_HeapPool[0] m_HeapPool[1] m_HeapPool[2] +// | X X X X X X X X |, | X X X O O X X O |, | X O O O O O O O | +// +// X - used descriptor m_AvailableHeaps = {1,2} +// O - available descriptor +// +// Allocation routine goes through the list of managers that have available descriptors and tries to process +// the request using every manager. If there are no available managers or no manager was able to handle the request, +// the function creates a new descriptor heap manager and lets it handle the request +// +// Render device contains four CPUDescriptorHeap object instances (one for each D3D12 heap type). The heaps are accessed +// when a texture or a buffer view is created. +// +class CPUDescriptorHeap final : public IDescriptorAllocator +{ +public: + // Initializes the heap + CPUDescriptorHeap(IMemoryAllocator& Allocator, + RenderDeviceD3D12Impl& DeviceD3D12Impl, + Uint32 NumDescriptorsInHeap, + D3D12_DESCRIPTOR_HEAP_TYPE Type, + D3D12_DESCRIPTOR_HEAP_FLAGS Flags); + + // clang-format off + CPUDescriptorHeap (const CPUDescriptorHeap&) = delete; + CPUDescriptorHeap (CPUDescriptorHeap&&) = delete; + CPUDescriptorHeap& operator = (const CPUDescriptorHeap&) = delete; + CPUDescriptorHeap& operator = (CPUDescriptorHeap&&) = delete; + // clang-format on + + ~CPUDescriptorHeap(); + + virtual DescriptorHeapAllocation Allocate(uint32_t Count) override final; + virtual void Free(DescriptorHeapAllocation&& Allocation, Uint64 CmdQueueMask) override final; + virtual Uint32 GetDescriptorSize() const override final { return m_DescriptorSize; } + +#ifdef DEVELOPMENT + int32_t DvpGetTotalAllocationCount(); +#endif + +private: + void FreeAllocation(DescriptorHeapAllocation&& Allocation); + + IMemoryAllocator& m_MemAllocator; + RenderDeviceD3D12Impl& m_DeviceD3D12Impl; + + // Pool of descriptor heap managers + std::mutex m_HeapPoolMutex; + std::vector> m_HeapPool; + // Indices of available descriptor heap managers + std::unordered_set, std::equal_to, STDAllocatorRawMem> m_AvailableHeaps; + + D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc; + const UINT m_DescriptorSize = 0; + + // Maximum heap size during the application lifetime - for statistic purposes + Uint32 m_MaxSize = 0; + Uint32 m_CurrentSize = 0; +}; + +// GPU descriptor heap provides storage for shader-visible descriptors +// The heap contains single D3D12 descriptor heap that is split into two parts. +// The first part stores static and mutable resource descriptor handles. +// The second part is intended to provide temporary storage for dynamic resources. +// Space for dynamic resources is allocated in chunks, and then descriptors are suballocated within every +// chunk. DynamicSuballocationsManager facilitates this process. +// +// +// static and mutable handles || dynamic space +// || chunk 0 chunk 1 chunk 2 unused +// | X O O X X O X O O O O X X X X O || | X X X O | | X X O O | | O O O O | O O O O || +// | | +// suballocation suballocation +// within chunk 0 within chunk 1 +// +// Render device contains two GPUDescriptorHeap instances (CBV_SRV_UAV and SAMPLER). The heaps +// are used to allocate GPU-visible descriptors for shader resource binding objects. The heaps +// are also used by the command contexts (through DynamicSuballocationsManager to allocated dynamic descriptors) +// +// _______________________________________________________________________________________________________________________________ +// | Render Device | +// | | +// | m_CPUDescriptorHeaps[CBV_SRV_UAV] | X X X X X X X X |, | X X X X X X X X |, | X O O X O O O O | | +// | m_CPUDescriptorHeaps[SAMPLER] | X X X X O O O X |, | X O O X O O O O | | +// | m_CPUDescriptorHeaps[RTV] | X X X O O O O O |, | O O O O O O O O | | +// | m_CPUDescriptorHeaps[DSV] | X X X O X O X O | | +// | ctx1 ctx2 | +// | m_GPUDescriptorHeaps[CBV_SRV_UAV] | X O O X X O X O O O O X X X X O || | X X X O | | X X O O | | O O O O | O O O O || | +// | m_GPUDescriptorHeaps[SAMPLER] | X X O O X O X X X O O X O O O O || | X X O O | | X O O O | | O O O O | O O O O || | +// | | +// |_______________________________________________________________________________________________________________________________| +// +// ________________________________________________ ________________________________________________ +// |Device Context 1 | |Device Context 2 | +// | | | | +// | m_DynamicGPUDescriptorAllocator[CBV_SRV_UAV] | | m_DynamicGPUDescriptorAllocator[CBV_SRV_UAV] | +// | m_DynamicGPUDescriptorAllocator[SAMPLER] | | m_DynamicGPUDescriptorAllocator[SAMPLER] | +// |________________________________________________| |________________________________________________| +// +class GPUDescriptorHeap final : public IDescriptorAllocator +{ +public: + GPUDescriptorHeap(IMemoryAllocator& Allocator, + RenderDeviceD3D12Impl& Device, + Uint32 NumDescriptorsInHeap, + Uint32 NumDynamicDescriptors, + D3D12_DESCRIPTOR_HEAP_TYPE Type, + D3D12_DESCRIPTOR_HEAP_FLAGS Flags); + + // clang-format off + GPUDescriptorHeap (const GPUDescriptorHeap&) = delete; + GPUDescriptorHeap (GPUDescriptorHeap&&) = delete; + GPUDescriptorHeap& operator = (const GPUDescriptorHeap&) = delete; + GPUDescriptorHeap& operator = (GPUDescriptorHeap&&) = delete; + // clang-format on + + ~GPUDescriptorHeap(); + + virtual DescriptorHeapAllocation Allocate(uint32_t Count) override final + { + return m_HeapAllocationManager.Allocate(Count); + } + + virtual void Free(DescriptorHeapAllocation&& Allocation, Uint64 CmdQueueMask) override final; + virtual Uint32 GetDescriptorSize() const override final { return m_DescriptorSize; } + + DescriptorHeapAllocation AllocateDynamic(uint32_t Count) + { + return m_DynamicAllocationsManager.Allocate(Count); + } + + const D3D12_DESCRIPTOR_HEAP_DESC& GetHeapDesc() const { return m_HeapDesc; } + Uint32 GetMaxStaticDescriptors() const { return m_HeapAllocationManager.GetMaxDescriptors(); } + Uint32 GetMaxDynamicDescriptors() const { return m_DynamicAllocationsManager.GetMaxDescriptors(); } + +#ifdef DEVELOPMENT + int32_t DvpGetTotalAllocationCount() const + { + return m_HeapAllocationManager.DvpGetAllocationsCounter() + + m_DynamicAllocationsManager.DvpGetAllocationsCounter(); + } +#endif + +protected: + RenderDeviceD3D12Impl& m_DeviceD3D12Impl; + + const D3D12_DESCRIPTOR_HEAP_DESC m_HeapDesc; + CComPtr m_pd3d12DescriptorHeap; + + const UINT m_DescriptorSize; + + // Allocation manager for static/mutable part + DescriptorHeapAllocationManager m_HeapAllocationManager; + + // Allocation manager for dynamic part + DescriptorHeapAllocationManager m_DynamicAllocationsManager; +}; + + +// The class facilitates allocation of dynamic descriptor handles. It requests a chunk of heap +// from the master GPU descriptor heap and then performs linear suballocation within the chunk +// At the end of the frame all allocations are disposed. + +// static and mutable handles || dynamic space +// || chunk 0 chunk 2 +// | || | X X X O | | O O O O | || GPU Descriptor Heap +// | | +// m_Suballocations[0] m_Suballocations[1] +// +class DynamicSuballocationsManager final : public IDescriptorAllocator +{ +public: + DynamicSuballocationsManager(IMemoryAllocator& Allocator, + GPUDescriptorHeap& ParentGPUHeap, + Uint32 DynamicChunkSize, + String ManagerName); + + // clang-format off + DynamicSuballocationsManager (const DynamicSuballocationsManager&) = delete; + DynamicSuballocationsManager (DynamicSuballocationsManager&&) = delete; + DynamicSuballocationsManager& operator = (const DynamicSuballocationsManager&) = delete; + DynamicSuballocationsManager& operator = (DynamicSuballocationsManager&&) = delete; + // clang-format on + + ~DynamicSuballocationsManager(); + + void ReleaseAllocations(Uint64 CmdQueueMask); + + virtual DescriptorHeapAllocation Allocate(Uint32 Count) override final; + virtual void Free(DescriptorHeapAllocation&& Allocation, Uint64 CmdQueueMask) override final + { + // Do nothing. Dynamic allocations are not disposed individually, but as whole chunks + // at the end of the frame by ReleaseAllocations() + Allocation.Reset(); + } + + virtual Uint32 GetDescriptorSize() const override final { return m_ParentGPUHeap.GetDescriptorSize(); } + + size_t GetSuballocationCount() const { return m_Suballocations.size(); } + +private: + // Parent GPU descriptor heap that is used to allocate chunks + GPUDescriptorHeap& m_ParentGPUHeap; + const String m_ManagerName; + + // List of chunks allocated from the master GPU descriptor heap. All chunks are disposed at the end + // of the frame + std::vector> m_Suballocations; + + Uint32 m_CurrentSuballocationOffset = 0; + Uint32 m_DynamicChunkSize = 0; + + Uint32 m_CurrDescriptorCount = 0; + Uint32 m_PeakDescriptorCount = 0; + Uint32 m_CurrSuballocationsTotalSize = 0; + Uint32 m_PeakSuballocationsTotalSize = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h deleted file mode 100644 index 2253dbc2..00000000 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h +++ /dev/null @@ -1,404 +0,0 @@ -/* - * 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::DeviceContextD3D12Impl class - -#include - -#include "DeviceContextD3D12.h" -#include "DeviceContextNextGenBase.h" -#include "BufferD3D12Impl.h" -#include "TextureD3D12Impl.h" -#include "QueryD3D12Impl.h" -#include "PipelineStateD3D12Impl.h" -#include "D3D12DynamicHeap.h" - -namespace Diligent -{ - -class RenderDeviceD3D12Impl; - -struct DeviceContextD3D12ImplTraits -{ - using BufferType = BufferD3D12Impl; - using TextureType = TextureD3D12Impl; - using PipelineStateType = PipelineStateD3D12Impl; - using DeviceType = RenderDeviceD3D12Impl; - using ICommandQueueType = ICommandQueueD3D12; - using QueryType = QueryD3D12Impl; -}; - -/// Device context implementation in Direct3D12 backend. -class DeviceContextD3D12Impl final : public DeviceContextNextGenBase -{ -public: - using TDeviceContextBase = DeviceContextNextGenBase; - - DeviceContextD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pDevice, - bool bIsDeferred, - const EngineD3D12CreateInfo& EngineCI, - Uint32 ContextId, - Uint32 CommandQueueId); - ~DeviceContextD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IDeviceContext::SetPipelineState() in Direct3D12 backend. - virtual void SetPipelineState(IPipelineState* pPipelineState) override final; - - /// Implementation of IDeviceContext::TransitionShaderResources() in Direct3D12 backend. - virtual void TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) override final; - - /// Implementation of IDeviceContext::CommitShaderResources() in Direct3D12 backend. - virtual void CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - /// Implementation of IDeviceContext::SetStencilRef() in Direct3D12 backend. - virtual void SetStencilRef(Uint32 StencilRef) override final; - - /// Implementation of IDeviceContext::SetBlendFactors() in Direct3D12 backend. - virtual void SetBlendFactors(const float* pBlendFactors = nullptr) override final; - - /// Implementation of IDeviceContext::SetVertexBuffers() in Direct3D12 backend. - virtual void SetVertexBuffers(Uint32 StartSlot, - Uint32 NumBuffersSet, - IBuffer** ppBuffers, - Uint32* pOffsets, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode, - SET_VERTEX_BUFFERS_FLAGS Flags) override final; - - /// Implementation of IDeviceContext::InvalidateState() in Direct3D12 backend. - virtual void InvalidateState() override final; - - /// Implementation of IDeviceContext::SetIndexBuffer() in Direct3D12 backend. - virtual void SetIndexBuffer(IBuffer* pIndexBuffer, Uint32 ByteOffset, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - /// Implementation of IDeviceContext::SetViewports() in Direct3D12 backend. - virtual void SetViewports(Uint32 NumViewports, const Viewport* pViewports, Uint32 RTWidth, Uint32 RTHeight) override final; - - /// Implementation of IDeviceContext::SetScissorRects() in Direct3D12 backend. - virtual void SetScissorRects(Uint32 NumRects, const Rect* pRects, Uint32 RTWidth, Uint32 RTHeight) override final; - - /// Implementation of IDeviceContext::SetRenderTargets() in Direct3D12 backend. - virtual void SetRenderTargets(Uint32 NumRenderTargets, - ITextureView* ppRenderTargets[], - ITextureView* pDepthStencil, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - // clang-format off - /// Implementation of IDeviceContext::Draw() in Direct3D12 backend. - virtual void Draw (const DrawAttribs& Attribs) override final; - /// Implementation of IDeviceContext::DrawIndexed() in Direct3D12 backend. - virtual void DrawIndexed (const DrawIndexedAttribs& Attribs) override final; - /// Implementation of IDeviceContext::DrawIndirect() in Direct3D12 backend. - virtual void DrawIndirect (const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; - /// Implementation of IDeviceContext::DrawIndexedIndirect() in Direct3D12 backend. - virtual void DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; - - - /// Implementation of IDeviceContext::DispatchCompute() in Direct3D12 backend. - virtual void DispatchCompute (const DispatchComputeAttribs& Attribs) override final; - /// Implementation of IDeviceContext::DispatchComputeIndirect() in Direct3D12 backend. - virtual void DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; - // clang-format on - - /// Implementation of IDeviceContext::ClearDepthStencil() in Direct3D12 backend. - virtual void ClearDepthStencil(ITextureView* pView, - CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, - float fDepth, - Uint8 Stencil, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - /// Implementation of IDeviceContext::ClearRenderTarget() in Direct3D12 backend. - virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - /// Implementation of IDeviceContext::UpdateBuffer() in Direct3D12 backend. - virtual void UpdateBuffer(IBuffer* pBuffer, - Uint32 Offset, - Uint32 Size, - const void* pData, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - /// Implementation of IDeviceContext::CopyBuffer() in Direct3D12 backend. - virtual void CopyBuffer(IBuffer* pSrcBuffer, - Uint32 SrcOffset, - RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, - IBuffer* pDstBuffer, - Uint32 DstOffset, - Uint32 Size, - RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) override final; - - /// Implementation of IDeviceContext::MapBuffer() in Direct3D12 backend. - virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData) override final; - - /// Implementation of IDeviceContext::UnmapBuffer() in Direct3D12 backend. - virtual void UnmapBuffer(IBuffer* pBuffer, MAP_TYPE MapType) override final; - - /// Implementation of IDeviceContext::UpdateTexture() in Direct3D12 backend. - virtual void UpdateTexture(ITexture* pTexture, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData, - RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, - RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode) override final; - - /// Implementation of IDeviceContext::CopyTexture() in Direct3D12 backend. - virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs) override final; - - /// Implementation of IDeviceContext::MapTextureSubresource() in Direct3D12 backend. - virtual void MapTextureSubresource(ITexture* pTexture, - Uint32 MipLevel, - Uint32 ArraySlice, - MAP_TYPE MapType, - MAP_FLAGS MapFlags, - const Box* pMapRegion, - MappedTextureSubresource& MappedData) override final; - - /// Implementation of IDeviceContext::UnmapTextureSubresource() in Direct3D12 backend. - virtual void UnmapTextureSubresource(ITexture* pTexture, Uint32 MipLevel, Uint32 ArraySlice) override final; - - /// Implementation of IDeviceContext::FinishFrame() in Direct3D12 backend. - virtual void FinishFrame() override final; - - /// Implementation of IDeviceContext::TransitionResourceStates() in Direct3D12 backend. - virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) override final; - - /// Implementation of IDeviceContext::ResolveTextureSubresource() in Direct3D12 backend. - virtual void ResolveTextureSubresource(ITexture* pSrcTexture, - ITexture* pDstTexture, - const ResolveTextureSubresourceAttribs& ResolveAttribs) override final; - - /// Implementation of IDeviceContext::FinishCommandList() in Direct3D12 backend. - virtual void FinishCommandList(class ICommandList** ppCommandList) override final; - - /// Implementation of IDeviceContext::ExecuteCommandList() in Direct3D12 backend. - virtual void ExecuteCommandList(class ICommandList* pCommandList) override final; - - /// Implementation of IDeviceContext::SignalFence() in Direct3D12 backend. - virtual void SignalFence(IFence* pFence, Uint64 Value) override final; - - /// Implementation of IDeviceContext::WaitForFence() in Direct3D12 backend. - virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext) override final; - - /// Implementation of IDeviceContext::WaitForIdle() in Direct3D12 backend. - virtual void WaitForIdle() override final; - - /// Implementation of IDeviceContext::BeginQuery() in Direct3D12 backend. - virtual void BeginQuery(IQuery* pQuery) override final; - - /// Implementation of IDeviceContext::EndQuery() in Direct3D12 backend. - virtual void EndQuery(IQuery* pQuery) override final; - - /// Implementation of IDeviceContext::Flush() in Direct3D12 backend. - virtual void Flush() override final; - - /// Implementation of IDeviceContext::TransitionTextureState() in Direct3D12 backend. - virtual void TransitionTextureState(ITexture* pTexture, D3D12_RESOURCE_STATES State) override final; - - /// Implementation of IDeviceContext::TransitionBufferState() in Direct3D12 backend. - virtual void TransitionBufferState(IBuffer* pBuffer, D3D12_RESOURCE_STATES State) override final; - - /// Implementation of IDeviceContextD3D12::ID3D12GraphicsCommandList() in Direct3D12 backend. - virtual ID3D12GraphicsCommandList* GetD3D12CommandList() override final; - - ///// Number of different shader types (Vertex, Pixel, Geometry, Domain, Hull, Compute) - //static constexpr int NumShaderTypes = 6; - - void UpdateBufferRegion(class BufferD3D12Impl* pBuffD3D12, - D3D12DynamicAllocation& Allocation, - Uint64 DstOffset, - Uint64 NumBytes, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode); - - void CopyTextureRegion(class TextureD3D12Impl* pSrcTexture, - Uint32 SrcSubResIndex, - const D3D12_BOX* pD3D12SrcBox, - RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode, - class TextureD3D12Impl* pDstTexture, - Uint32 DstSubResIndex, - Uint32 DstX, - Uint32 DstY, - Uint32 DstZ, - RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode); - - void CopyTextureRegion(IBuffer* pSrcBuffer, - Uint32 SrcOffset, - Uint32 SrcStride, - Uint32 SrcDepthStride, - class TextureD3D12Impl& TextureD3D12, - Uint32 DstSubResIndex, - const Box& DstBox, - RESOURCE_STATE_TRANSITION_MODE BufferTransitionMode, - RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode); - void CopyTextureRegion(ID3D12Resource* pd3d12Buffer, - Uint32 SrcOffset, - Uint32 SrcStride, - Uint32 SrcDepthStride, - Uint32 BufferSize, - class TextureD3D12Impl& TextureD3D12, - Uint32 DstSubResIndex, - const Box& DstBox, - RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode); - - void UpdateTextureRegion(const void* pSrcData, - Uint32 SrcStride, - Uint32 SrcDepthStride, - class TextureD3D12Impl& TextureD3D12, - Uint32 DstSubResIndex, - const Box& DstBox, - RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode); - - virtual void GenerateMips(ITextureView* pTexView) override final; - - D3D12DynamicAllocation AllocateDynamicSpace(size_t NumBytes, size_t Alignment); - - Uint32 GetContextId() const { return m_ContextId; } - - size_t GetNumCommandsInCtx() const { return m_State.NumCommands; } - - Int64 GetCurrentFrameNumber() const { return m_ContextFrameNumber; } - -private: - void CommitD3D12IndexBuffer(GraphicsContext& GraphCtx, VALUE_TYPE IndexType); - void CommitD3D12VertexBuffers(class GraphicsContext& GraphCtx); - void CommitRenderTargets(RESOURCE_STATE_TRANSITION_MODE StateTransitionMode); - void CommitViewports(); - void CommitScissorRects(class GraphicsContext& GraphCtx, bool ScissorEnable); - void Flush(bool RequestNewCmdCtx); - - __forceinline void RequestCommandContext(RenderDeviceD3D12Impl* pDeviceD3D12Impl); - - __forceinline void TransitionOrVerifyBufferState(CommandContext& CmdCtx, - BufferD3D12Impl& Buffer, - RESOURCE_STATE_TRANSITION_MODE TransitionMode, - RESOURCE_STATE RequiredState, - const char* OperationName); - __forceinline void TransitionOrVerifyTextureState(CommandContext& CmdCtx, - TextureD3D12Impl& Texture, - 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 PrepareDrawIndirectBuffer(GraphicsContext& GraphCtx, - IBuffer* pAttribsBuffer, - RESOURCE_STATE_TRANSITION_MODE BufferStateTransitionMode, - ID3D12Resource*& pd3d12ArgsBuff, - Uint64& BuffDataStartByteOffset); - - struct TextureUploadSpace - { - D3D12DynamicAllocation Allocation; - Uint32 AlignedOffset = 0; - Uint32 Stride = 0; - Uint32 DepthStride = 0; - Uint32 RowSize = 0; - Uint32 RowCount = 0; - Box Region; - }; - TextureUploadSpace AllocateTextureUploadSpace(TEXTURE_FORMAT TexFmt, - const Box& Region); - - - friend class SwapChainD3D12Impl; - inline class CommandContext& GetCmdContext() - { - // Make sure that the number of commands in the context is at least one, - // so that the context cannot be disposed by Flush() - m_State.NumCommands = m_State.NumCommands != 0 ? m_State.NumCommands : 1; - return *m_CurrCmdCtx; - } - std::unique_ptr> m_CurrCmdCtx; - - struct State - { - size_t NumCommands = 0; - - CComPtr CommittedD3D12IndexBuffer; - VALUE_TYPE CommittedIBFormat = VT_UNDEFINED; - Uint64 CommittedD3D12IndexDataStartOffset = 0; - - // Indicates if currently committed D3D12 vertex buffers are up to date - bool bCommittedD3D12VBsUpToDate = false; - - // Indicates if currently committed D3D11 index buffer is up to date - bool bCommittedD3D12IBUpToDate = false; - - // Indicates if root views have been committed since the time SRB - // has been committed. - bool bRootViewsCommitted = false; - - class ShaderResourceCacheD3D12* pCommittedResourceCache = nullptr; - } m_State; - - CComPtr m_pDrawIndirectSignature; - CComPtr m_pDrawIndexedIndirectSignature; - CComPtr m_pDispatchIndirectSignature; - - D3D12DynamicHeap m_DynamicHeap; - - // Every context must use its own allocator that maintains individual list of retired descriptor heaps to - // avoid interference with other command contexts - // The allocations in heaps are discarded at the end of the frame. - DynamicSuballocationsManager m_DynamicGPUDescriptorAllocator[2]; - - FixedBlockMemoryAllocator m_CmdListAllocator; - - std::vector>> m_PendingFences; - - struct MappedTextureKey - { - TextureD3D12Impl* const Texture; - UINT const Subresource; - - bool operator==(const MappedTextureKey& rhs) const - { - return Texture == rhs.Texture && Subresource == rhs.Subresource; - } - struct Hasher - { - size_t operator()(const MappedTextureKey& Key) const - { - return ComputeHash(Key.Texture, Key.Subresource); - } - }; - }; - std::unordered_map m_MappedTextures; - - Int32 m_ActiveQueriesCounter = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp new file mode 100644 index 00000000..6971d8a8 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp @@ -0,0 +1,404 @@ +/* + * 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::DeviceContextD3D12Impl class + +#include + +#include "DeviceContextD3D12.h" +#include "DeviceContextNextGenBase.h" +#include "BufferD3D12Impl.hpp" +#include "TextureD3D12Impl.hpp" +#include "QueryD3D12Impl.hpp" +#include "PipelineStateD3D12Impl.hpp" +#include "D3D12DynamicHeap.hpp" + +namespace Diligent +{ + +class RenderDeviceD3D12Impl; + +struct DeviceContextD3D12ImplTraits +{ + using BufferType = BufferD3D12Impl; + using TextureType = TextureD3D12Impl; + using PipelineStateType = PipelineStateD3D12Impl; + using DeviceType = RenderDeviceD3D12Impl; + using ICommandQueueType = ICommandQueueD3D12; + using QueryType = QueryD3D12Impl; +}; + +/// Device context implementation in Direct3D12 backend. +class DeviceContextD3D12Impl final : public DeviceContextNextGenBase +{ +public: + using TDeviceContextBase = DeviceContextNextGenBase; + + DeviceContextD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + bool bIsDeferred, + const EngineD3D12CreateInfo& EngineCI, + Uint32 ContextId, + Uint32 CommandQueueId); + ~DeviceContextD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IDeviceContext::SetPipelineState() in Direct3D12 backend. + virtual void SetPipelineState(IPipelineState* pPipelineState) override final; + + /// Implementation of IDeviceContext::TransitionShaderResources() in Direct3D12 backend. + virtual void TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) override final; + + /// Implementation of IDeviceContext::CommitShaderResources() in Direct3D12 backend. + virtual void CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + /// Implementation of IDeviceContext::SetStencilRef() in Direct3D12 backend. + virtual void SetStencilRef(Uint32 StencilRef) override final; + + /// Implementation of IDeviceContext::SetBlendFactors() in Direct3D12 backend. + virtual void SetBlendFactors(const float* pBlendFactors = nullptr) override final; + + /// Implementation of IDeviceContext::SetVertexBuffers() in Direct3D12 backend. + virtual void SetVertexBuffers(Uint32 StartSlot, + Uint32 NumBuffersSet, + IBuffer** ppBuffers, + Uint32* pOffsets, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode, + SET_VERTEX_BUFFERS_FLAGS Flags) override final; + + /// Implementation of IDeviceContext::InvalidateState() in Direct3D12 backend. + virtual void InvalidateState() override final; + + /// Implementation of IDeviceContext::SetIndexBuffer() in Direct3D12 backend. + virtual void SetIndexBuffer(IBuffer* pIndexBuffer, Uint32 ByteOffset, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + /// Implementation of IDeviceContext::SetViewports() in Direct3D12 backend. + virtual void SetViewports(Uint32 NumViewports, const Viewport* pViewports, Uint32 RTWidth, Uint32 RTHeight) override final; + + /// Implementation of IDeviceContext::SetScissorRects() in Direct3D12 backend. + virtual void SetScissorRects(Uint32 NumRects, const Rect* pRects, Uint32 RTWidth, Uint32 RTHeight) override final; + + /// Implementation of IDeviceContext::SetRenderTargets() in Direct3D12 backend. + virtual void SetRenderTargets(Uint32 NumRenderTargets, + ITextureView* ppRenderTargets[], + ITextureView* pDepthStencil, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + // clang-format off + /// Implementation of IDeviceContext::Draw() in Direct3D12 backend. + virtual void Draw (const DrawAttribs& Attribs) override final; + /// Implementation of IDeviceContext::DrawIndexed() in Direct3D12 backend. + virtual void DrawIndexed (const DrawIndexedAttribs& Attribs) override final; + /// Implementation of IDeviceContext::DrawIndirect() in Direct3D12 backend. + virtual void DrawIndirect (const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; + /// Implementation of IDeviceContext::DrawIndexedIndirect() in Direct3D12 backend. + virtual void DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; + + + /// Implementation of IDeviceContext::DispatchCompute() in Direct3D12 backend. + virtual void DispatchCompute (const DispatchComputeAttribs& Attribs) override final; + /// Implementation of IDeviceContext::DispatchComputeIndirect() in Direct3D12 backend. + virtual void DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; + // clang-format on + + /// Implementation of IDeviceContext::ClearDepthStencil() in Direct3D12 backend. + virtual void ClearDepthStencil(ITextureView* pView, + CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, + float fDepth, + Uint8 Stencil, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + /// Implementation of IDeviceContext::ClearRenderTarget() in Direct3D12 backend. + virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + /// Implementation of IDeviceContext::UpdateBuffer() in Direct3D12 backend. + virtual void UpdateBuffer(IBuffer* pBuffer, + Uint32 Offset, + Uint32 Size, + const void* pData, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + /// Implementation of IDeviceContext::CopyBuffer() in Direct3D12 backend. + virtual void CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) override final; + + /// Implementation of IDeviceContext::MapBuffer() in Direct3D12 backend. + virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData) override final; + + /// Implementation of IDeviceContext::UnmapBuffer() in Direct3D12 backend. + virtual void UnmapBuffer(IBuffer* pBuffer, MAP_TYPE MapType) override final; + + /// Implementation of IDeviceContext::UpdateTexture() in Direct3D12 backend. + virtual void UpdateTexture(ITexture* pTexture, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode) override final; + + /// Implementation of IDeviceContext::CopyTexture() in Direct3D12 backend. + virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs) override final; + + /// Implementation of IDeviceContext::MapTextureSubresource() in Direct3D12 backend. + virtual void MapTextureSubresource(ITexture* pTexture, + Uint32 MipLevel, + Uint32 ArraySlice, + MAP_TYPE MapType, + MAP_FLAGS MapFlags, + const Box* pMapRegion, + MappedTextureSubresource& MappedData) override final; + + /// Implementation of IDeviceContext::UnmapTextureSubresource() in Direct3D12 backend. + virtual void UnmapTextureSubresource(ITexture* pTexture, Uint32 MipLevel, Uint32 ArraySlice) override final; + + /// Implementation of IDeviceContext::FinishFrame() in Direct3D12 backend. + virtual void FinishFrame() override final; + + /// Implementation of IDeviceContext::TransitionResourceStates() in Direct3D12 backend. + virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) override final; + + /// Implementation of IDeviceContext::ResolveTextureSubresource() in Direct3D12 backend. + virtual void ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs) override final; + + /// Implementation of IDeviceContext::FinishCommandList() in Direct3D12 backend. + virtual void FinishCommandList(class ICommandList** ppCommandList) override final; + + /// Implementation of IDeviceContext::ExecuteCommandList() in Direct3D12 backend. + virtual void ExecuteCommandList(class ICommandList* pCommandList) override final; + + /// Implementation of IDeviceContext::SignalFence() in Direct3D12 backend. + virtual void SignalFence(IFence* pFence, Uint64 Value) override final; + + /// Implementation of IDeviceContext::WaitForFence() in Direct3D12 backend. + virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext) override final; + + /// Implementation of IDeviceContext::WaitForIdle() in Direct3D12 backend. + virtual void WaitForIdle() override final; + + /// Implementation of IDeviceContext::BeginQuery() in Direct3D12 backend. + virtual void BeginQuery(IQuery* pQuery) override final; + + /// Implementation of IDeviceContext::EndQuery() in Direct3D12 backend. + virtual void EndQuery(IQuery* pQuery) override final; + + /// Implementation of IDeviceContext::Flush() in Direct3D12 backend. + virtual void Flush() override final; + + /// Implementation of IDeviceContext::TransitionTextureState() in Direct3D12 backend. + virtual void TransitionTextureState(ITexture* pTexture, D3D12_RESOURCE_STATES State) override final; + + /// Implementation of IDeviceContext::TransitionBufferState() in Direct3D12 backend. + virtual void TransitionBufferState(IBuffer* pBuffer, D3D12_RESOURCE_STATES State) override final; + + /// Implementation of IDeviceContextD3D12::ID3D12GraphicsCommandList() in Direct3D12 backend. + virtual ID3D12GraphicsCommandList* GetD3D12CommandList() override final; + + ///// Number of different shader types (Vertex, Pixel, Geometry, Domain, Hull, Compute) + //static constexpr int NumShaderTypes = 6; + + void UpdateBufferRegion(class BufferD3D12Impl* pBuffD3D12, + D3D12DynamicAllocation& Allocation, + Uint64 DstOffset, + Uint64 NumBytes, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode); + + void CopyTextureRegion(class TextureD3D12Impl* pSrcTexture, + Uint32 SrcSubResIndex, + const D3D12_BOX* pD3D12SrcBox, + RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode, + class TextureD3D12Impl* pDstTexture, + Uint32 DstSubResIndex, + Uint32 DstX, + Uint32 DstY, + Uint32 DstZ, + RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode); + + void CopyTextureRegion(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + Uint32 SrcStride, + Uint32 SrcDepthStride, + class TextureD3D12Impl& TextureD3D12, + Uint32 DstSubResIndex, + const Box& DstBox, + RESOURCE_STATE_TRANSITION_MODE BufferTransitionMode, + RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode); + void CopyTextureRegion(ID3D12Resource* pd3d12Buffer, + Uint32 SrcOffset, + Uint32 SrcStride, + Uint32 SrcDepthStride, + Uint32 BufferSize, + class TextureD3D12Impl& TextureD3D12, + Uint32 DstSubResIndex, + const Box& DstBox, + RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode); + + void UpdateTextureRegion(const void* pSrcData, + Uint32 SrcStride, + Uint32 SrcDepthStride, + class TextureD3D12Impl& TextureD3D12, + Uint32 DstSubResIndex, + const Box& DstBox, + RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode); + + virtual void GenerateMips(ITextureView* pTexView) override final; + + D3D12DynamicAllocation AllocateDynamicSpace(size_t NumBytes, size_t Alignment); + + Uint32 GetContextId() const { return m_ContextId; } + + size_t GetNumCommandsInCtx() const { return m_State.NumCommands; } + + Int64 GetCurrentFrameNumber() const { return m_ContextFrameNumber; } + +private: + void CommitD3D12IndexBuffer(GraphicsContext& GraphCtx, VALUE_TYPE IndexType); + void CommitD3D12VertexBuffers(class GraphicsContext& GraphCtx); + void CommitRenderTargets(RESOURCE_STATE_TRANSITION_MODE StateTransitionMode); + void CommitViewports(); + void CommitScissorRects(class GraphicsContext& GraphCtx, bool ScissorEnable); + void Flush(bool RequestNewCmdCtx); + + __forceinline void RequestCommandContext(RenderDeviceD3D12Impl* pDeviceD3D12Impl); + + __forceinline void TransitionOrVerifyBufferState(CommandContext& CmdCtx, + BufferD3D12Impl& Buffer, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + const char* OperationName); + __forceinline void TransitionOrVerifyTextureState(CommandContext& CmdCtx, + TextureD3D12Impl& Texture, + 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 PrepareDrawIndirectBuffer(GraphicsContext& GraphCtx, + IBuffer* pAttribsBuffer, + RESOURCE_STATE_TRANSITION_MODE BufferStateTransitionMode, + ID3D12Resource*& pd3d12ArgsBuff, + Uint64& BuffDataStartByteOffset); + + struct TextureUploadSpace + { + D3D12DynamicAllocation Allocation; + Uint32 AlignedOffset = 0; + Uint32 Stride = 0; + Uint32 DepthStride = 0; + Uint32 RowSize = 0; + Uint32 RowCount = 0; + Box Region; + }; + TextureUploadSpace AllocateTextureUploadSpace(TEXTURE_FORMAT TexFmt, + const Box& Region); + + + friend class SwapChainD3D12Impl; + inline class CommandContext& GetCmdContext() + { + // Make sure that the number of commands in the context is at least one, + // so that the context cannot be disposed by Flush() + m_State.NumCommands = m_State.NumCommands != 0 ? m_State.NumCommands : 1; + return *m_CurrCmdCtx; + } + std::unique_ptr> m_CurrCmdCtx; + + struct State + { + size_t NumCommands = 0; + + CComPtr CommittedD3D12IndexBuffer; + VALUE_TYPE CommittedIBFormat = VT_UNDEFINED; + Uint64 CommittedD3D12IndexDataStartOffset = 0; + + // Indicates if currently committed D3D12 vertex buffers are up to date + bool bCommittedD3D12VBsUpToDate = false; + + // Indicates if currently committed D3D11 index buffer is up to date + bool bCommittedD3D12IBUpToDate = false; + + // Indicates if root views have been committed since the time SRB + // has been committed. + bool bRootViewsCommitted = false; + + class ShaderResourceCacheD3D12* pCommittedResourceCache = nullptr; + } m_State; + + CComPtr m_pDrawIndirectSignature; + CComPtr m_pDrawIndexedIndirectSignature; + CComPtr m_pDispatchIndirectSignature; + + D3D12DynamicHeap m_DynamicHeap; + + // Every context must use its own allocator that maintains individual list of retired descriptor heaps to + // avoid interference with other command contexts + // The allocations in heaps are discarded at the end of the frame. + DynamicSuballocationsManager m_DynamicGPUDescriptorAllocator[2]; + + FixedBlockMemoryAllocator m_CmdListAllocator; + + std::vector>> m_PendingFences; + + struct MappedTextureKey + { + TextureD3D12Impl* const Texture; + UINT const Subresource; + + bool operator==(const MappedTextureKey& rhs) const + { + return Texture == rhs.Texture && Subresource == rhs.Subresource; + } + struct Hasher + { + size_t operator()(const MappedTextureKey& Key) const + { + return ComputeHash(Key.Texture, Key.Subresource); + } + }; + }; + std::unordered_map m_MappedTextures; + + Int32 m_ActiveQueriesCounter = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/FenceD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/FenceD3D12Impl.h deleted file mode 100644 index cacc1e11..00000000 --- a/Graphics/GraphicsEngineD3D12/include/FenceD3D12Impl.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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::FenceD3D12Impl class - -#include "FenceD3D12.h" -#include "RenderDeviceD3D12.h" -#include "FenceBase.h" -#include "RenderDeviceD3D12Impl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Fence implementation in Direct3D12 backend. -class FenceD3D12Impl final : public FenceBase -{ -public: - using TFenceBase = FenceBase; - - FenceD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pDevice, - const FenceDesc& Desc); - ~FenceD3D12Impl(); - - IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_FenceD3D12, TFenceBase); - - /// Implementation of IFence::GetCompletedValue() in Direct3D12 backend. - virtual Uint64 GetCompletedValue() override final; - - /// Implementation of IFence::GetCompletedValue() in Direct3D12 backend. - virtual void Reset(Uint64 Value) override final; - - /// Implementation of IFenceD3D12::GetD3D12Fence(). - ID3D12Fence* GetD3D12Fence() override final { return m_pd3d12Fence; } - - /// Implementation of IFenceD3D12::WaitForCompletion(). - virtual void WaitForCompletion(Uint64 Value) override final; - -private: - CComPtr m_pd3d12Fence; ///< D3D12 Fence object -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/FenceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/FenceD3D12Impl.hpp new file mode 100644 index 00000000..1549e584 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/FenceD3D12Impl.hpp @@ -0,0 +1,72 @@ +/* + * 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::FenceD3D12Impl class + +#include "FenceD3D12.h" +#include "RenderDeviceD3D12.h" +#include "FenceBase.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Fence implementation in Direct3D12 backend. +class FenceD3D12Impl final : public FenceBase +{ +public: + using TFenceBase = FenceBase; + + FenceD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + const FenceDesc& Desc); + ~FenceD3D12Impl(); + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_FenceD3D12, TFenceBase); + + /// Implementation of IFence::GetCompletedValue() in Direct3D12 backend. + virtual Uint64 GetCompletedValue() override final; + + /// Implementation of IFence::GetCompletedValue() in Direct3D12 backend. + virtual void Reset(Uint64 Value) override final; + + /// Implementation of IFenceD3D12::GetD3D12Fence(). + ID3D12Fence* GetD3D12Fence() override final { return m_pd3d12Fence; } + + /// Implementation of IFenceD3D12::WaitForCompletion(). + virtual void WaitForCompletion(Uint64 Value) override final; + +private: + CComPtr m_pd3d12Fence; ///< D3D12 Fence object +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/GenerateMips.h b/Graphics/GraphicsEngineD3D12/include/GenerateMips.h deleted file mode 100644 index a62f9665..00000000 --- a/Graphics/GraphicsEngineD3D12/include/GenerateMips.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - */ - - -// The source code in this file is derived from ColorBuffer.h and GraphicsCore.h developed by Minigraph -// Original source files header: - -// -// Copyright (c) Microsoft. All rights reserved. -// This code is licensed under the MIT License (MIT). -// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF -// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY -// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR -// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. -// -// Developed by Minigraph -// -// Author: James Stanard -// - - -#pragma once - -/// \file -/// Implementation of mipmap generation routines - - -namespace Diligent -{ -class GenerateMipsHelper -{ -public: - GenerateMipsHelper(ID3D12Device* pd3d12Device); - - void GenerateMips(ID3D12Device* pd3d12Device, class TextureViewD3D12Impl* pTexView, class CommandContext& Ctx) const; - -private: - CComPtr m_pGenerateMipsRS; - CComPtr m_pGenerateMipsLinearPSO[4]; - CComPtr m_pGenerateMipsGammaPSO[4]; -}; -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/GenerateMips.hpp b/Graphics/GraphicsEngineD3D12/include/GenerateMips.hpp new file mode 100644 index 00000000..a62f9665 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/GenerateMips.hpp @@ -0,0 +1,66 @@ +/* + * 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. + */ + + +// The source code in this file is derived from ColorBuffer.h and GraphicsCore.h developed by Minigraph +// Original source files header: + +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: James Stanard +// + + +#pragma once + +/// \file +/// Implementation of mipmap generation routines + + +namespace Diligent +{ +class GenerateMipsHelper +{ +public: + GenerateMipsHelper(ID3D12Device* pd3d12Device); + + void GenerateMips(ID3D12Device* pd3d12Device, class TextureViewD3D12Impl* pTexView, class CommandContext& Ctx) const; + +private: + CComPtr m_pGenerateMipsRS; + CComPtr m_pGenerateMipsLinearPSO[4]; + CComPtr m_pGenerateMipsGammaPSO[4]; +}; +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h deleted file mode 100644 index d23d54e1..00000000 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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::PipelineStateD3D12Impl class - -#include "RenderDeviceD3D12.h" -#include "PipelineStateD3D12.h" -#include "PipelineStateBase.h" -#include "RootSignature.h" -#include "ShaderResourceLayoutD3D12.h" -#include "SRBMemoryAllocator.hpp" -#include "RenderDeviceD3D12Impl.h" -#include "ShaderVariableD3D12.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Pipeline state object implementation in Direct3D12 backend. -class PipelineStateD3D12Impl final : public PipelineStateBase -{ -public: - using TPipelineStateBase = PipelineStateBase; - - PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const PipelineStateDesc& PipelineDesc); - ~PipelineStateD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IPipelineState::BindStaticResources() in Direct3D12 backend. - virtual void BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) override final; - - /// Implementation of IPipelineState::GetStaticVariableCount() in Direct3D12 backend. - virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; - - /// Implementation of IPipelineState::GetStaticVariableByName() in Direct3D12 backend. - virtual IShaderResourceVariable* GetStaticVariableByName(SHADER_TYPE ShaderType, const Char* Name) override final; - - /// Implementation of IPipelineState::GetStaticVariableByIndex() in Direct3D12 backend. - virtual IShaderResourceVariable* GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; - - /// Implementation of IPipelineState::CreateShaderResourceBinding() in Direct3D12 backend. - virtual void CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) override final; - - /// Implementation of IPipelineState::IsCompatibleWith() in Direct3D12 backend. - virtual bool IsCompatibleWith(const IPipelineState* pPSO) const override final; - - /// Implementation of IPipelineStateD3D12::GetD3D12PipelineState(). - virtual ID3D12PipelineState* GetD3D12PipelineState() const override final { return m_pd3d12PSO; } - - /// Implementation of IPipelineStateD3D12::GetD3D12RootSignature(). - virtual ID3D12RootSignature* GetD3D12RootSignature() const override final { return m_RootSig.GetD3D12RootSignature(); } - - struct CommitAndTransitionResourcesAttribs - { - Uint32 CtxId = 0; - IShaderResourceBinding* pShaderResourceBinding = nullptr; - bool CommitResources = false; - bool TransitionResources = false; - bool ValidateStates = false; - }; - ShaderResourceCacheD3D12* CommitAndTransitionShaderResources(class DeviceContextD3D12Impl* pDeviceCtx, - class CommandContext& CmdCtx, - CommitAndTransitionResourcesAttribs& Attrib) const; - - const RootSignature& GetRootSignature() const { return m_RootSig; } - - const ShaderResourceLayoutD3D12& GetShaderResLayout(Uint32 ShaderInd) const - { - VERIFY_EXPR(ShaderInd < m_NumShaders); - return m_pShaderResourceLayouts[ShaderInd]; - } - - const ShaderResourceLayoutD3D12& GetStaticShaderResLayout(Uint32 ShaderInd) const - { - VERIFY_EXPR(ShaderInd < m_NumShaders); - return m_pShaderResourceLayouts[m_NumShaders + ShaderInd]; - } - - ShaderResourceCacheD3D12& GetStaticShaderResCache(Uint32 ShaderInd) const - { - VERIFY_EXPR(ShaderInd < m_NumShaders); - return m_pStaticResourceCaches[ShaderInd]; - } - - bool ContainsShaderResources() const; - - SRBMemoryAllocator& GetSRBMemoryAllocator() - { - return m_SRBMemAllocator; - } - -private: - CComPtr m_pd3d12PSO; - RootSignature m_RootSig; - - // Must be defined before default SRB - SRBMemoryAllocator m_SRBMemAllocator; - - ShaderResourceLayoutD3D12* m_pShaderResourceLayouts = nullptr; - ShaderResourceCacheD3D12* m_pStaticResourceCaches = nullptr; - ShaderVariableManagerD3D12* m_pStaticVarManagers = nullptr; - // Resource layout index in m_ResourceLayouts[] array for every shader stage - Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp new file mode 100644 index 00000000..9431d2f4 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -0,0 +1,135 @@ +/* + * 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::PipelineStateD3D12Impl class + +#include "RenderDeviceD3D12.h" +#include "PipelineStateD3D12.h" +#include "PipelineStateBase.hpp" +#include "RootSignature.hpp" +#include "ShaderResourceLayoutD3D12.hpp" +#include "SRBMemoryAllocator.hpp" +#include "RenderDeviceD3D12Impl.hpp" +#include "ShaderVariableD3D12.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Pipeline state object implementation in Direct3D12 backend. +class PipelineStateD3D12Impl final : public PipelineStateBase +{ +public: + using TPipelineStateBase = PipelineStateBase; + + PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const PipelineStateDesc& PipelineDesc); + ~PipelineStateD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IPipelineState::BindStaticResources() in Direct3D12 backend. + virtual void BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) override final; + + /// Implementation of IPipelineState::GetStaticVariableCount() in Direct3D12 backend. + virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; + + /// Implementation of IPipelineState::GetStaticVariableByName() in Direct3D12 backend. + virtual IShaderResourceVariable* GetStaticVariableByName(SHADER_TYPE ShaderType, const Char* Name) override final; + + /// Implementation of IPipelineState::GetStaticVariableByIndex() in Direct3D12 backend. + virtual IShaderResourceVariable* GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; + + /// Implementation of IPipelineState::CreateShaderResourceBinding() in Direct3D12 backend. + virtual void CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) override final; + + /// Implementation of IPipelineState::IsCompatibleWith() in Direct3D12 backend. + virtual bool IsCompatibleWith(const IPipelineState* pPSO) const override final; + + /// Implementation of IPipelineStateD3D12::GetD3D12PipelineState(). + virtual ID3D12PipelineState* GetD3D12PipelineState() const override final { return m_pd3d12PSO; } + + /// Implementation of IPipelineStateD3D12::GetD3D12RootSignature(). + virtual ID3D12RootSignature* GetD3D12RootSignature() const override final { return m_RootSig.GetD3D12RootSignature(); } + + struct CommitAndTransitionResourcesAttribs + { + Uint32 CtxId = 0; + IShaderResourceBinding* pShaderResourceBinding = nullptr; + bool CommitResources = false; + bool TransitionResources = false; + bool ValidateStates = false; + }; + ShaderResourceCacheD3D12* CommitAndTransitionShaderResources(class DeviceContextD3D12Impl* pDeviceCtx, + class CommandContext& CmdCtx, + CommitAndTransitionResourcesAttribs& Attrib) const; + + const RootSignature& GetRootSignature() const { return m_RootSig; } + + const ShaderResourceLayoutD3D12& GetShaderResLayout(Uint32 ShaderInd) const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_pShaderResourceLayouts[ShaderInd]; + } + + const ShaderResourceLayoutD3D12& GetStaticShaderResLayout(Uint32 ShaderInd) const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_pShaderResourceLayouts[m_NumShaders + ShaderInd]; + } + + ShaderResourceCacheD3D12& GetStaticShaderResCache(Uint32 ShaderInd) const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_pStaticResourceCaches[ShaderInd]; + } + + bool ContainsShaderResources() const; + + SRBMemoryAllocator& GetSRBMemoryAllocator() + { + return m_SRBMemAllocator; + } + +private: + CComPtr m_pd3d12PSO; + RootSignature m_RootSig; + + // Must be defined before default SRB + SRBMemoryAllocator m_SRBMemAllocator; + + ShaderResourceLayoutD3D12* m_pShaderResourceLayouts = nullptr; + ShaderResourceCacheD3D12* m_pStaticResourceCaches = nullptr; + ShaderVariableManagerD3D12* m_pStaticVarManagers = nullptr; + // Resource layout index in m_ResourceLayouts[] array for every shader stage + Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.h deleted file mode 100644 index 0c47565e..00000000 --- a/Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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::QueryD3D12Impl class - -#include "QueryD3D12.h" -#include "QueryBase.h" -#include "RenderDeviceD3D12Impl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -// https://microsoft.github.io/DirectX-Specs/d3d/CountersAndQueries.html#queries - -/// Query implementation in Direct3D12 backend. -class QueryD3D12Impl final : public QueryBase -{ -public: - using TQueryBase = QueryBase; - - QueryD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pDevice, - const QueryDesc& Desc); - ~QueryD3D12Impl(); - - IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_QueryD3D12, TQueryBase); - - /// Implementation of IQuery::GetData(). - virtual bool GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) override final; - - /// Implementation of IQueryD3D12::GetD3D12QueryHeap(). - virtual ID3D12QueryHeap* GetD3D12QueryHeap() override final - { - return m_pDevice->GetQueryManager().GetQueryHeap(m_Desc.Type); - } - - /// Implementation of IQueryD3D12::GetQueryHeapIndex(). - virtual Uint32 GetQueryHeapIndex() const override final - { - return m_QueryHeapIndex; - } - - bool OnEndQuery(IDeviceContext* pContext); - -private: - Uint32 m_QueryHeapIndex = static_cast(-1); - Uint64 m_QueryEndFenceValue = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.hpp new file mode 100644 index 00000000..129e0307 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/QueryD3D12Impl.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::QueryD3D12Impl class + +#include "QueryD3D12.h" +#include "QueryBase.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +// https://microsoft.github.io/DirectX-Specs/d3d/CountersAndQueries.html#queries + +/// Query implementation in Direct3D12 backend. +class QueryD3D12Impl final : public QueryBase +{ +public: + using TQueryBase = QueryBase; + + QueryD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + const QueryDesc& Desc); + ~QueryD3D12Impl(); + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_QueryD3D12, TQueryBase); + + /// Implementation of IQuery::GetData(). + virtual bool GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) override final; + + /// Implementation of IQueryD3D12::GetD3D12QueryHeap(). + virtual ID3D12QueryHeap* GetD3D12QueryHeap() override final + { + return m_pDevice->GetQueryManager().GetQueryHeap(m_Desc.Type); + } + + /// Implementation of IQueryD3D12::GetQueryHeapIndex(). + virtual Uint32 GetQueryHeapIndex() const override final + { + return m_QueryHeapIndex; + } + + bool OnEndQuery(IDeviceContext* pContext); + +private: + Uint32 m_QueryHeapIndex = static_cast(-1); + Uint64 m_QueryEndFenceValue = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/QueryManagerD3D12.h b/Graphics/GraphicsEngineD3D12/include/QueryManagerD3D12.h deleted file mode 100644 index 13337696..00000000 --- a/Graphics/GraphicsEngineD3D12/include/QueryManagerD3D12.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 - -#include -#include -#include -#include - -#include "Query.h" - -namespace Diligent -{ - -class CommandContext; - -// https://microsoft.github.io/DirectX-Specs/d3d/CountersAndQueries.html#queries - -class QueryManagerD3D12 -{ -public: - QueryManagerD3D12(ID3D12Device* pd3d12Device, - const Uint32 QueryHeapSizes[]); - ~QueryManagerD3D12(); - - // clang-format off - QueryManagerD3D12 (const QueryManagerD3D12&) = delete; - QueryManagerD3D12 ( QueryManagerD3D12&&) = delete; - QueryManagerD3D12& operator = (const QueryManagerD3D12&) = delete; - QueryManagerD3D12& operator = ( QueryManagerD3D12&&) = delete; - // clang-format on - - static constexpr Uint32 InvalidIndex = static_cast(-1); - - Uint32 AllocateQuery(QUERY_TYPE Type); - void ReleaseQuery(QUERY_TYPE Type, Uint32 Index); - - ID3D12QueryHeap* GetQueryHeap(QUERY_TYPE Type) - { - return m_Heaps[Type].pd3d12QueryHeap; - } - - void BeginQuery(CommandContext& Ctx, QUERY_TYPE Type, Uint32 Index); - void EndQuery(CommandContext& Ctx, QUERY_TYPE Type, Uint32 Index); - void ReadQueryData(QUERY_TYPE Type, Uint32 Index, void* pDataPtr, Uint32 DataSize) const; - -private: - struct QueryHeapInfo - { - CComPtr pd3d12QueryHeap; - std::deque AvailableQueries; - std::vector ResolveBufferOffsets; - - Uint32 HeapSize = 0; - Uint32 MaxAllocatedQueries = 0; - }; - - std::mutex m_HeapMutex; - std::array m_Heaps; - - // Readback buffer that will contain the query data. - CComPtr m_pd3d12ResolveBuffer; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/QueryManagerD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/QueryManagerD3D12.hpp new file mode 100644 index 00000000..13337696 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/QueryManagerD3D12.hpp @@ -0,0 +1,90 @@ +/* + * 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 + +#include +#include +#include +#include + +#include "Query.h" + +namespace Diligent +{ + +class CommandContext; + +// https://microsoft.github.io/DirectX-Specs/d3d/CountersAndQueries.html#queries + +class QueryManagerD3D12 +{ +public: + QueryManagerD3D12(ID3D12Device* pd3d12Device, + const Uint32 QueryHeapSizes[]); + ~QueryManagerD3D12(); + + // clang-format off + QueryManagerD3D12 (const QueryManagerD3D12&) = delete; + QueryManagerD3D12 ( QueryManagerD3D12&&) = delete; + QueryManagerD3D12& operator = (const QueryManagerD3D12&) = delete; + QueryManagerD3D12& operator = ( QueryManagerD3D12&&) = delete; + // clang-format on + + static constexpr Uint32 InvalidIndex = static_cast(-1); + + Uint32 AllocateQuery(QUERY_TYPE Type); + void ReleaseQuery(QUERY_TYPE Type, Uint32 Index); + + ID3D12QueryHeap* GetQueryHeap(QUERY_TYPE Type) + { + return m_Heaps[Type].pd3d12QueryHeap; + } + + void BeginQuery(CommandContext& Ctx, QUERY_TYPE Type, Uint32 Index); + void EndQuery(CommandContext& Ctx, QUERY_TYPE Type, Uint32 Index); + void ReadQueryData(QUERY_TYPE Type, Uint32 Index, void* pDataPtr, Uint32 DataSize) const; + +private: + struct QueryHeapInfo + { + CComPtr pd3d12QueryHeap; + std::deque AvailableQueries; + std::vector ResolveBufferOffsets; + + Uint32 HeapSize = 0; + Uint32 MaxAllocatedQueries = 0; + }; + + std::mutex m_HeapMutex; + std::array m_Heaps; + + // Readback buffer that will contain the query data. + CComPtr m_pd3d12ResolveBuffer; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h deleted file mode 100644 index 922a4c22..00000000 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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::RenderDeviceD3D12Impl class -#include "RenderDeviceD3D12.h" -#include "RenderDeviceD3DBase.h" -#include "RenderDeviceNextGenBase.h" -#include "DescriptorHeap.h" -#include "CommandListManager.h" -#include "CommandContext.h" -#include "D3D12DynamicHeap.h" -#include "Atomics.h" -#include "CommandQueueD3D12.h" -#include "GenerateMips.h" -#include "QueryManagerD3D12.h" - -namespace Diligent -{ - -/// Render device implementation in Direct3D12 backend. -class RenderDeviceD3D12Impl final : public RenderDeviceNextGenBase, ICommandQueueD3D12> -{ -public: - using TRenderDeviceBase = RenderDeviceNextGenBase, ICommandQueueD3D12>; - - RenderDeviceD3D12Impl(IReferenceCounters* pRefCounters, - IMemoryAllocator& RawMemAllocator, - IEngineFactory* pEngineFactory, - const EngineD3D12CreateInfo& EngineCI, - ID3D12Device* pD3D12Device, - size_t CommandQueueCount, - ICommandQueueD3D12** ppCmdQueues); - ~RenderDeviceD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IRenderDevice::CreatePipelineState() in Direct3D12 backend. - virtual void CreatePipelineState(const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState) override final; - - /// Implementation of IRenderDevice::CreateBuffer() in Direct3D12 backend. - virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer** ppBuffer) override final; - - /// Implementation of IRenderDevice::CreateShader() in Direct3D12 backend. - virtual void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader) override final; - - /// Implementation of IRenderDevice::CreateTexture() in Direct3D12 backend. - virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture** ppTexture) override final; - - void CreateTexture(const TextureDesc& TexDesc, ID3D12Resource* pd3d12Texture, RESOURCE_STATE InitialState, class TextureD3D12Impl** ppTexture); - - /// Implementation of IRenderDevice::CreateSampler() in Direct3D12 backend. - virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler) override final; - - /// Implementation of IRenderDevice::CreateFence() in Direct3D12 backend. - virtual void CreateFence(const FenceDesc& Desc, IFence** ppFence) override final; - - /// Implementation of IRenderDevice::CreateQuery() in Direct3D12 backend. - virtual void CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) override final; - - /// Implementation of IRenderDeviceD3D12::GetD3D12Device(). - virtual ID3D12Device* GetD3D12Device() override final { return m_pd3d12Device; } - - /// Implementation of IRenderDeviceD3D12::CreateTextureFromD3DResource(). - virtual void CreateTextureFromD3DResource(ID3D12Resource* pd3d12Texture, RESOURCE_STATE InitialState, ITexture** ppTexture) override final; - - /// Implementation of IRenderDeviceD3D12::CreateBufferFromD3DResource(). - virtual void CreateBufferFromD3DResource(ID3D12Resource* pd3d12Buffer, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer) override final; - - DescriptorHeapAllocation AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1); - DescriptorHeapAllocation AllocateGPUDescriptors(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1); - - /// Implementation of IRenderDevice::IdleGPU() in Direct3D12 backend. - virtual void IdleGPU() override final; - - using PooledCommandContext = std::unique_ptr>; - PooledCommandContext AllocateCommandContext(const Char* ID = ""); - - void CloseAndExecuteTransientCommandContext(Uint32 CommandQueueIndex, PooledCommandContext&& Ctx); - - Uint64 CloseAndExecuteCommandContext(Uint32 QueueIndex, - PooledCommandContext&& Ctx, - bool DiscardStaleObjects, - std::vector>>* pSignalFences); - - void SignalFences(Uint32 QueueIndex, std::vector>>& SignalFences); - - // Disposes an unused command context - void DisposeCommandContext(PooledCommandContext&& Ctx); - - void FlushStaleResources(Uint32 CmdQueueIndex); - - /// Implementation of IRenderDevice::() in Direct3D12 backend. - virtual void ReleaseStaleResources(bool ForceRelease = false) override final; - - D3D12DynamicMemoryManager& GetDynamicMemoryManager() { return m_DynamicMemoryManager; } - - GPUDescriptorHeap& GetGPUDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE Type) - { - VERIFY_EXPR(Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || Type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); - return m_GPUDescriptorHeaps[Type]; - } - - const GenerateMipsHelper& GetMipsGenerator() const { return m_MipsGenerator; } - QueryManagerD3D12& GetQueryManager() { return m_QueryMgr; } - - D3D_FEATURE_LEVEL GetD3DFeatureLevel() const; - -private: - virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final; - void FreeCommandContext(PooledCommandContext&& Ctx); - - CComPtr m_pd3d12Device; - - EngineD3D12CreateInfo m_EngineAttribs; - - CPUDescriptorHeap m_CPUDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; - GPUDescriptorHeap m_GPUDescriptorHeaps[2]; // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV == 0 - // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER == 1 - - CommandListManager m_CmdListManager; - - std::mutex m_ContextPoolMutex; - std::vector> m_ContextPool; -#ifdef DEVELOPMENT - Atomics::AtomicLong m_AllocatedCtxCounter = 0; -#endif - - D3D12DynamicMemoryManager m_DynamicMemoryManager; - - // Note: mips generator must be released after the device has been idled - GenerateMipsHelper m_MipsGenerator; - - QueryManagerD3D12 m_QueryMgr; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp new file mode 100644 index 00000000..3c4746c8 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -0,0 +1,163 @@ +/* + * 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::RenderDeviceD3D12Impl class +#include "RenderDeviceD3D12.h" +#include "RenderDeviceD3DBase.hpp" +#include "RenderDeviceNextGenBase.h" +#include "DescriptorHeap.hpp" +#include "CommandListManager.hpp" +#include "CommandContext.hpp" +#include "D3D12DynamicHeap.hpp" +#include "Atomics.h" +#include "CommandQueueD3D12.h" +#include "GenerateMips.hpp" +#include "QueryManagerD3D12.hpp" + +namespace Diligent +{ + +/// Render device implementation in Direct3D12 backend. +class RenderDeviceD3D12Impl final : public RenderDeviceNextGenBase, ICommandQueueD3D12> +{ +public: + using TRenderDeviceBase = RenderDeviceNextGenBase, ICommandQueueD3D12>; + + RenderDeviceD3D12Impl(IReferenceCounters* pRefCounters, + IMemoryAllocator& RawMemAllocator, + IEngineFactory* pEngineFactory, + const EngineD3D12CreateInfo& EngineCI, + ID3D12Device* pD3D12Device, + size_t CommandQueueCount, + ICommandQueueD3D12** ppCmdQueues); + ~RenderDeviceD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IRenderDevice::CreatePipelineState() in Direct3D12 backend. + virtual void CreatePipelineState(const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState) override final; + + /// Implementation of IRenderDevice::CreateBuffer() in Direct3D12 backend. + virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer** ppBuffer) override final; + + /// Implementation of IRenderDevice::CreateShader() in Direct3D12 backend. + virtual void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader) override final; + + /// Implementation of IRenderDevice::CreateTexture() in Direct3D12 backend. + virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture** ppTexture) override final; + + void CreateTexture(const TextureDesc& TexDesc, ID3D12Resource* pd3d12Texture, RESOURCE_STATE InitialState, class TextureD3D12Impl** ppTexture); + + /// Implementation of IRenderDevice::CreateSampler() in Direct3D12 backend. + virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler) override final; + + /// Implementation of IRenderDevice::CreateFence() in Direct3D12 backend. + virtual void CreateFence(const FenceDesc& Desc, IFence** ppFence) override final; + + /// Implementation of IRenderDevice::CreateQuery() in Direct3D12 backend. + virtual void CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) override final; + + /// Implementation of IRenderDeviceD3D12::GetD3D12Device(). + virtual ID3D12Device* GetD3D12Device() override final { return m_pd3d12Device; } + + /// Implementation of IRenderDeviceD3D12::CreateTextureFromD3DResource(). + virtual void CreateTextureFromD3DResource(ID3D12Resource* pd3d12Texture, RESOURCE_STATE InitialState, ITexture** ppTexture) override final; + + /// Implementation of IRenderDeviceD3D12::CreateBufferFromD3DResource(). + virtual void CreateBufferFromD3DResource(ID3D12Resource* pd3d12Buffer, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer) override final; + + DescriptorHeapAllocation AllocateDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1); + DescriptorHeapAllocation AllocateGPUDescriptors(D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1); + + /// Implementation of IRenderDevice::IdleGPU() in Direct3D12 backend. + virtual void IdleGPU() override final; + + using PooledCommandContext = std::unique_ptr>; + PooledCommandContext AllocateCommandContext(const Char* ID = ""); + + void CloseAndExecuteTransientCommandContext(Uint32 CommandQueueIndex, PooledCommandContext&& Ctx); + + Uint64 CloseAndExecuteCommandContext(Uint32 QueueIndex, + PooledCommandContext&& Ctx, + bool DiscardStaleObjects, + std::vector>>* pSignalFences); + + void SignalFences(Uint32 QueueIndex, std::vector>>& SignalFences); + + // Disposes an unused command context + void DisposeCommandContext(PooledCommandContext&& Ctx); + + void FlushStaleResources(Uint32 CmdQueueIndex); + + /// Implementation of IRenderDevice::() in Direct3D12 backend. + virtual void ReleaseStaleResources(bool ForceRelease = false) override final; + + D3D12DynamicMemoryManager& GetDynamicMemoryManager() { return m_DynamicMemoryManager; } + + GPUDescriptorHeap& GetGPUDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE Type) + { + VERIFY_EXPR(Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || Type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + return m_GPUDescriptorHeaps[Type]; + } + + const GenerateMipsHelper& GetMipsGenerator() const { return m_MipsGenerator; } + QueryManagerD3D12& GetQueryManager() { return m_QueryMgr; } + + D3D_FEATURE_LEVEL GetD3DFeatureLevel() const; + +private: + virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final; + void FreeCommandContext(PooledCommandContext&& Ctx); + + CComPtr m_pd3d12Device; + + EngineD3D12CreateInfo m_EngineAttribs; + + CPUDescriptorHeap m_CPUDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; + GPUDescriptorHeap m_GPUDescriptorHeaps[2]; // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV == 0 + // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER == 1 + + CommandListManager m_CmdListManager; + + std::mutex m_ContextPoolMutex; + std::vector> m_ContextPool; +#ifdef DEVELOPMENT + Atomics::AtomicLong m_AllocatedCtxCounter = 0; +#endif + + D3D12DynamicMemoryManager m_DynamicMemoryManager; + + // Note: mips generator must be released after the device has been idled + GenerateMipsHelper m_MipsGenerator; + + QueryManagerD3D12 m_QueryMgr; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.h b/Graphics/GraphicsEngineD3D12/include/RootSignature.h deleted file mode 100644 index fd2aff02..00000000 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.h +++ /dev/null @@ -1,591 +0,0 @@ -/* - * 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::RootSignature class -#include -#include "ShaderD3DBase.h" -#include "ShaderResourceLayoutD3D12.h" -#include "BufferD3D12Impl.h" - -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); - -class RootParameter -{ -public: - RootParameter(D3D12_ROOT_PARAMETER_TYPE ParameterType, - Uint32 RootIndex, - UINT Register, - UINT RegisterSpace, - D3D12_SHADER_VISIBILITY Visibility, - SHADER_RESOURCE_VARIABLE_TYPE VarType) noexcept : - // clang-format off - m_RootIndex {RootIndex}, - m_ShaderVarType{VarType } - // clang-format on - { - VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV || ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV || ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV, "Unexpected parameter type - verify argument list"); - m_RootParam.ParameterType = ParameterType; - m_RootParam.ShaderVisibility = Visibility; - m_RootParam.Descriptor.ShaderRegister = Register; - m_RootParam.Descriptor.RegisterSpace = RegisterSpace; - } - - RootParameter(D3D12_ROOT_PARAMETER_TYPE ParameterType, - Uint32 RootIndex, - UINT Register, - UINT RegisterSpace, - UINT NumDwords, - D3D12_SHADER_VISIBILITY Visibility, - SHADER_RESOURCE_VARIABLE_TYPE VarType) noexcept : - // clang-format off - m_RootIndex {RootIndex}, - m_ShaderVarType{VarType } - // clang-format on - { - VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, "Unexpected parameter type - verify argument list"); - m_RootParam.ParameterType = ParameterType; - m_RootParam.ShaderVisibility = Visibility; - m_RootParam.Constants.Num32BitValues = NumDwords; - m_RootParam.Constants.ShaderRegister = Register; - m_RootParam.Constants.RegisterSpace = RegisterSpace; - } - - RootParameter(D3D12_ROOT_PARAMETER_TYPE ParameterType, - Uint32 RootIndex, - UINT NumRanges, - D3D12_DESCRIPTOR_RANGE* pRanges, - D3D12_SHADER_VISIBILITY Visibility, - SHADER_RESOURCE_VARIABLE_TYPE VarType) noexcept : - // clang-format off - m_RootIndex {RootIndex}, - m_ShaderVarType{VarType } - // clang-format on - { - VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Unexpected parameter type - verify argument list"); - VERIFY_EXPR(pRanges != nullptr); - m_RootParam.ParameterType = ParameterType; - m_RootParam.ShaderVisibility = Visibility; - m_RootParam.DescriptorTable.NumDescriptorRanges = NumRanges; - m_RootParam.DescriptorTable.pDescriptorRanges = pRanges; -#ifdef _DEBUG - for (Uint32 r = 0; r < NumRanges; ++r) - pRanges[r].RangeType = static_cast(-1); -#endif - } - - RootParameter(const RootParameter& RP) noexcept : - // clang-format off - m_RootParam {RP.m_RootParam }, - m_DescriptorTableSize{RP.m_DescriptorTableSize}, - m_ShaderVarType {RP.m_ShaderVarType }, - m_RootIndex {RP.m_RootIndex } - // clang-format on - { - VERIFY(m_RootParam.ParameterType != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Use another constructor to copy descriptor table"); - } - - RootParameter(const RootParameter& RP, - UINT NumRanges, - D3D12_DESCRIPTOR_RANGE* pRanges) noexcept : - // clang-format off - m_RootParam {RP.m_RootParam }, - m_DescriptorTableSize{RP.m_DescriptorTableSize}, - m_ShaderVarType {RP.m_ShaderVarType }, - m_RootIndex {RP.m_RootIndex } - // clang-format on - { - VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table"); - VERIFY(NumRanges >= m_RootParam.DescriptorTable.NumDescriptorRanges, "New table must be larger than source one"); - auto& DstTbl = m_RootParam.DescriptorTable; - DstTbl.NumDescriptorRanges = NumRanges; - DstTbl.pDescriptorRanges = pRanges; - const auto& SrcTbl = RP.m_RootParam.DescriptorTable; - memcpy(pRanges, SrcTbl.pDescriptorRanges, SrcTbl.NumDescriptorRanges * sizeof(D3D12_DESCRIPTOR_RANGE)); -#ifdef _DEBUG - { - Uint32 dbgTableSize = 0; - for (Uint32 r = 0; r < SrcTbl.NumDescriptorRanges; ++r) - { - const auto& Range = SrcTbl.pDescriptorRanges[r]; - dbgTableSize = std::max(dbgTableSize, Range.OffsetInDescriptorsFromTableStart + Range.NumDescriptors); - } - VERIFY(dbgTableSize == m_DescriptorTableSize, "Incorrect descriptor table size"); - - for (Uint32 r = SrcTbl.NumDescriptorRanges; r < DstTbl.NumDescriptorRanges; ++r) - pRanges[r].RangeType = static_cast(-1); - } -#endif - } - - RootParameter& operator=(const RootParameter&) = delete; - RootParameter& operator=(RootParameter&&) = delete; - - void SetDescriptorRange(UINT RangeIndex, - D3D12_DESCRIPTOR_RANGE_TYPE Type, - UINT Register, - UINT Count, - UINT Space = 0, - UINT OffsetFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) - { - VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected"); - auto& Tbl = m_RootParam.DescriptorTable; - VERIFY(RangeIndex < Tbl.NumDescriptorRanges, "Invalid descriptor range index"); - D3D12_DESCRIPTOR_RANGE& range = const_cast(Tbl.pDescriptorRanges[RangeIndex]); - VERIFY(range.RangeType == static_cast(-1), "Descriptor range has already been initialized. m_DescriptorTableSize may be updated incorrectly"); - range.RangeType = Type; - range.NumDescriptors = Count; - range.BaseShaderRegister = Register; - range.RegisterSpace = Space; - range.OffsetInDescriptorsFromTableStart = OffsetFromTableStart; - m_DescriptorTableSize = std::max(m_DescriptorTableSize, OffsetFromTableStart + Count); - } - - SHADER_RESOURCE_VARIABLE_TYPE GetShaderVariableType() const { return m_ShaderVarType; } - - Uint32 GetDescriptorTableSize() const - { - VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected"); - return m_DescriptorTableSize; - } - - D3D12_SHADER_VISIBILITY GetShaderVisibility() const { return m_RootParam.ShaderVisibility; } - D3D12_ROOT_PARAMETER_TYPE GetParameterType() const { return m_RootParam.ParameterType; } - - Uint32 GetRootIndex() const { return m_RootIndex; } - - operator const D3D12_ROOT_PARAMETER&() const { return m_RootParam; } - - bool operator==(const RootParameter& rhs) const - { - if (m_ShaderVarType != rhs.m_ShaderVarType || - m_DescriptorTableSize != rhs.m_DescriptorTableSize || - m_RootIndex != rhs.m_RootIndex) - return false; - - if (m_RootParam.ParameterType != rhs.m_RootParam.ParameterType || - m_RootParam.ShaderVisibility != rhs.m_RootParam.ShaderVisibility) - return false; - - switch (m_RootParam.ParameterType) - { - case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: - { - const auto& tbl0 = m_RootParam.DescriptorTable; - const auto& tbl1 = rhs.m_RootParam.DescriptorTable; - if (tbl0.NumDescriptorRanges != tbl1.NumDescriptorRanges) - return false; - for (UINT r = 0; r < tbl0.NumDescriptorRanges; ++r) - { - const auto& rng0 = tbl0.pDescriptorRanges[r]; - const auto& rng1 = tbl1.pDescriptorRanges[r]; - if (memcmp(&rng0, &rng1, sizeof(rng0)) != 0) - return false; - } - } - break; - - case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: - { - const auto& cnst0 = m_RootParam.Constants; - const auto& cnst1 = rhs.m_RootParam.Constants; - if (memcmp(&cnst0, &cnst1, sizeof(cnst0)) != 0) - return false; - } - break; - - case D3D12_ROOT_PARAMETER_TYPE_CBV: - case D3D12_ROOT_PARAMETER_TYPE_SRV: - case D3D12_ROOT_PARAMETER_TYPE_UAV: - { - const auto& dscr0 = m_RootParam.Descriptor; - const auto& dscr1 = rhs.m_RootParam.Descriptor; - if (memcmp(&dscr0, &dscr1, sizeof(dscr0)) != 0) - return false; - } - break; - - default: UNEXPECTED("Unexpected root parameter type"); - } - - return true; - } - - bool operator!=(const RootParameter& rhs) const - { - return !(*this == rhs); - } - - size_t GetHash() const - { - size_t hash = ComputeHash(m_ShaderVarType, m_DescriptorTableSize, m_RootIndex); - HashCombine(hash, m_RootParam.ParameterType, m_RootParam.ShaderVisibility); - - switch (m_RootParam.ParameterType) - { - case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: - { - const auto& tbl = m_RootParam.DescriptorTable; - HashCombine(hash, tbl.NumDescriptorRanges); - for (UINT r = 0; r < tbl.NumDescriptorRanges; ++r) - { - const auto& rng = tbl.pDescriptorRanges[r]; - HashCombine(hash, rng.BaseShaderRegister, rng.NumDescriptors, rng.OffsetInDescriptorsFromTableStart, rng.RangeType, rng.RegisterSpace); - } - } - break; - - case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: - { - const auto& cnst = m_RootParam.Constants; - HashCombine(hash, cnst.Num32BitValues, cnst.RegisterSpace, cnst.ShaderRegister); - } - break; - - case D3D12_ROOT_PARAMETER_TYPE_CBV: - case D3D12_ROOT_PARAMETER_TYPE_SRV: - case D3D12_ROOT_PARAMETER_TYPE_UAV: - { - const auto& dscr = m_RootParam.Descriptor; - HashCombine(hash, dscr.RegisterSpace, dscr.ShaderRegister); - } - break; - - default: UNEXPECTED("Unexpected root parameter type"); - } - - return hash; - } - -private: - SHADER_RESOURCE_VARIABLE_TYPE m_ShaderVarType = static_cast(-1); - D3D12_ROOT_PARAMETER m_RootParam = {}; - Uint32 m_DescriptorTableSize = 0; - Uint32 m_RootIndex = static_cast(-1); -}; - - - -/// Implementation of the Diligent::RootSignature class -class RootSignature -{ -public: - RootSignature(); - - void AllocateStaticSamplers(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 InitStaticSampler(SHADER_TYPE ShaderType, - const char* SamplerName, - const char* SamplerSuffix, - const D3DShaderResourceAttribs& ShaderResAttribs); - - void AllocateResourceSlot(SHADER_TYPE ShaderType, - const D3DShaderResourceAttribs& ShaderResAttribs, - SHADER_RESOURCE_VARIABLE_TYPE VariableType, - D3D12_DESCRIPTOR_RANGE_TYPE RangeType, - 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, - class CommandContext& Ctx, - bool IsCompute, - bool ValidateStates) const = nullptr; - - void (RootSignature::*TransitionAndCommitDescriptorHandles)(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, - ShaderResourceCacheD3D12& ResourceCache, - class CommandContext& Ctx, - bool IsCompute, - bool ValidateStates) const = nullptr; - - void TransitionResources(ShaderResourceCacheD3D12& ResourceCache, - class CommandContext& Ctx) const; - - __forceinline void CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, - class CommandContext& CmdCtx, - bool IsCompute, - Uint32 DeviceCtxId, - class DeviceContextD3D12Impl* pDeviceCtx, - bool CommitViews, - bool ProcessDynamicBuffers, - bool ProcessNonDynamicBuffers, - bool TransitionStates, - bool ValidateStates) const; - - Uint32 GetTotalSrvCbvUavSlots(SHADER_RESOURCE_VARIABLE_TYPE VarType) const - { - return m_TotalSrvCbvUavSlots[VarType]; - } - Uint32 GetTotalSamplerSlots(SHADER_RESOURCE_VARIABLE_TYPE VarType) const - { - return m_TotalSamplerSlots[VarType]; - } - Uint32 GetTotalRootViews(SHADER_RESOURCE_VARIABLE_TYPE VarType) const - { - return m_TotalRootViews[VarType]; - } - - bool IsSameAs(const RootSignature& RS) const - { - return m_RootParams == RS.m_RootParams; - } - size_t GetHash() const - { - return m_RootParams.GetHash(); - } - -private: -#ifdef _DEBUG - void dbgVerifyRootParameters() const; -#endif - -#ifdef DEVELOPMENT - static void DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resource& Res, - D3D12_DESCRIPTOR_RANGE_TYPE RangeType); -#endif - - std::vector> GetCacheTableSizes() const; - - std::array m_TotalSrvCbvUavSlots = {}; - std::array m_TotalSamplerSlots = {}; - std::array m_TotalRootViews = {}; - - CComPtr m_pd3d12RootSignature; - - class RootParamsManager - { - public: - RootParamsManager(IMemoryAllocator& MemAllocator); - - // clang-format off - RootParamsManager (const RootParamsManager&) = delete; - RootParamsManager& operator=(const RootParamsManager&) = delete; - RootParamsManager (RootParamsManager&&) = delete; - RootParamsManager& operator=(RootParamsManager&&) = delete; - // clang-format on - - Uint32 GetNumRootTables() const { return m_NumRootTables; } - Uint32 GetNumRootViews() const { return m_NumRootViews; } - - const RootParameter& GetRootTable(Uint32 TableInd) const - { - VERIFY_EXPR(TableInd < m_NumRootTables); - return m_pRootTables[TableInd]; - } - - RootParameter& GetRootTable(Uint32 TableInd) - { - VERIFY_EXPR(TableInd < m_NumRootTables); - return m_pRootTables[TableInd]; - } - - const RootParameter& GetRootView(Uint32 ViewInd) const - { - VERIFY_EXPR(ViewInd < m_NumRootViews); - return m_pRootViews[ViewInd]; - } - - RootParameter& GetRootView(Uint32 ViewInd) - { - VERIFY_EXPR(ViewInd < m_NumRootViews); - return m_pRootViews[ViewInd]; - } - - void AddRootView(D3D12_ROOT_PARAMETER_TYPE ParameterType, - Uint32 RootIndex, - UINT Register, - D3D12_SHADER_VISIBILITY Visibility, - SHADER_RESOURCE_VARIABLE_TYPE VarType); - - void AddRootTable(Uint32 RootIndex, - D3D12_SHADER_VISIBILITY Visibility, - SHADER_RESOURCE_VARIABLE_TYPE VarType, - Uint32 NumRangesInNewTable = 1); - - void AddDescriptorRanges(Uint32 RootTableInd, Uint32 NumExtraRanges = 1); - - template - void ProcessRootTables(TOperation) const; - - bool operator==(const RootParamsManager& RootParams) const; - size_t GetHash() const; - - private: - size_t GetRequiredMemorySize(Uint32 NumExtraRootTables, - Uint32 NumExtraRootViews, - Uint32 NumExtraDescriptorRanges) const; - - D3D12_DESCRIPTOR_RANGE* Extend(Uint32 NumExtraRootTables, - Uint32 NumExtraRootViews, - Uint32 NumExtraDescriptorRanges, - Uint32 RootTableToAddRanges = static_cast(-1)); - - IMemoryAllocator& m_MemAllocator; - std::unique_ptr> m_pMemory; - Uint32 m_NumRootTables = 0; - Uint32 m_NumRootViews = 0; - Uint32 m_TotalDescriptorRanges = 0; - RootParameter* m_pRootTables = nullptr; - RootParameter* m_pRootViews = nullptr; - }; - - static constexpr Uint8 InvalidRootTableIndex = static_cast(-1); - - // The array below contains array index of a CBV/SRV/UAV root table - // in m_RootParams (NOT the Root Index!), for every variable type - // (static, mutable, dynamic) and every shader type, - // or -1, if the table is not yet assigned to the combination - std::array m_SrvCbvUavRootTablesMap; - // This array contains the same data for Sampler root table - std::array m_SamplerRootTablesMap; - - RootParamsManager m_RootParams; - - struct StaticSamplerAttribs - { - StaticSamplerDesc SamplerDesc; - UINT ShaderRegister = static_cast(-1); - UINT ArraySize = 0; - UINT RegisterSpace = 0; - D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast(-1); - - StaticSamplerAttribs() noexcept {} - StaticSamplerAttribs(const StaticSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility) noexcept : - SamplerDesc(SamDesc), - ShaderVisibility(Visibility) - {} - }; - // Note: sizeof(m_StaticSamplers) == 56 (MS compiler, release x64) - std::vector> m_StaticSamplers; - - IMemoryAllocator& m_MemAllocator; - - // Commits descriptor handles for static and mutable variables - template - void CommitDescriptorHandlesInternal_SM(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, - ShaderResourceCacheD3D12& ResourceCache, - class CommandContext& Ctx, - bool IsCompute, - bool ValidateStates) const; - template - // Commits descriptor handles for static, mutable, and dynamic variables - void CommitDescriptorHandlesInternal_SMD(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, - ShaderResourceCacheD3D12& ResourceCache, - class CommandContext& Ctx, - bool IsCompute, - bool ValidateStates) const; -}; - -void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, - CommandContext& CmdCtx, - bool IsCompute, - Uint32 DeviceCtxId, - DeviceContextD3D12Impl* pDeviceCtx, - bool CommitViews, - bool ProcessDynamicBuffers, - bool ProcessNonDynamicBuffers, - bool TransitionStates, - bool ValidateStates) const -{ - for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) - { - auto& RootView = m_RootParams.GetRootView(rv); - auto RootInd = RootView.GetRootIndex(); - - SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; -#ifdef _DEBUG - { - auto& Param = static_cast(RootView); - VERIFY_EXPR(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV); - dbgShaderType = ShaderTypeFromShaderVisibility(Param.ShaderVisibility); - } -#endif - - auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType); - if (auto* pBuffToTransition = Res.pObject.RawPtr()) - { - bool IsDynamic = pBuffToTransition->GetDesc().Usage == USAGE_DYNAMIC; - if (IsDynamic && ProcessDynamicBuffers || !IsDynamic && ProcessNonDynamicBuffers) - { - if (IsDynamic) - { -#ifdef _DEBUG - if (pBuffToTransition->IsInKnownState()) - { - VERIFY(pBuffToTransition->CheckState(RESOURCE_STATE_CONSTANT_BUFFER), - "Dynamic buffers must always have RESOURCE_STATE_CONSTANT_BUFFER state flag set"); - } -#endif - } - else - { - if (TransitionStates) - { - if (pBuffToTransition->IsInKnownState() && !pBuffToTransition->CheckState(RESOURCE_STATE_CONSTANT_BUFFER)) - { - CmdCtx.TransitionResource(pBuffToTransition, RESOURCE_STATE_CONSTANT_BUFFER); - } - } -#ifdef DEVELOPMENT - else if (ValidateStates) - { - - DvpVerifyResourceState(Res, D3D12_DESCRIPTOR_RANGE_TYPE_CBV); - } -#endif - } - - if (CommitViews) - { - D3D12_GPU_VIRTUAL_ADDRESS CBVAddress = pBuffToTransition->GetGPUAddress(DeviceCtxId, pDeviceCtx); - if (IsCompute) - CmdCtx.GetCommandList()->SetComputeRootConstantBufferView(RootInd, CBVAddress); - else - CmdCtx.GetCommandList()->SetGraphicsRootConstantBufferView(RootInd, CBVAddress); - } - } - } - } -} - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp new file mode 100644 index 00000000..e723896a --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -0,0 +1,591 @@ +/* + * 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::RootSignature class +#include +#include "ShaderD3DBase.hpp" +#include "ShaderResourceLayoutD3D12.hpp" +#include "BufferD3D12Impl.hpp" + +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); + +class RootParameter +{ +public: + RootParameter(D3D12_ROOT_PARAMETER_TYPE ParameterType, + Uint32 RootIndex, + UINT Register, + UINT RegisterSpace, + D3D12_SHADER_VISIBILITY Visibility, + SHADER_RESOURCE_VARIABLE_TYPE VarType) noexcept : + // clang-format off + m_RootIndex {RootIndex}, + m_ShaderVarType{VarType } + // clang-format on + { + VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV || ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV || ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV, "Unexpected parameter type - verify argument list"); + m_RootParam.ParameterType = ParameterType; + m_RootParam.ShaderVisibility = Visibility; + m_RootParam.Descriptor.ShaderRegister = Register; + m_RootParam.Descriptor.RegisterSpace = RegisterSpace; + } + + RootParameter(D3D12_ROOT_PARAMETER_TYPE ParameterType, + Uint32 RootIndex, + UINT Register, + UINT RegisterSpace, + UINT NumDwords, + D3D12_SHADER_VISIBILITY Visibility, + SHADER_RESOURCE_VARIABLE_TYPE VarType) noexcept : + // clang-format off + m_RootIndex {RootIndex}, + m_ShaderVarType{VarType } + // clang-format on + { + VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, "Unexpected parameter type - verify argument list"); + m_RootParam.ParameterType = ParameterType; + m_RootParam.ShaderVisibility = Visibility; + m_RootParam.Constants.Num32BitValues = NumDwords; + m_RootParam.Constants.ShaderRegister = Register; + m_RootParam.Constants.RegisterSpace = RegisterSpace; + } + + RootParameter(D3D12_ROOT_PARAMETER_TYPE ParameterType, + Uint32 RootIndex, + UINT NumRanges, + D3D12_DESCRIPTOR_RANGE* pRanges, + D3D12_SHADER_VISIBILITY Visibility, + SHADER_RESOURCE_VARIABLE_TYPE VarType) noexcept : + // clang-format off + m_RootIndex {RootIndex}, + m_ShaderVarType{VarType } + // clang-format on + { + VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Unexpected parameter type - verify argument list"); + VERIFY_EXPR(pRanges != nullptr); + m_RootParam.ParameterType = ParameterType; + m_RootParam.ShaderVisibility = Visibility; + m_RootParam.DescriptorTable.NumDescriptorRanges = NumRanges; + m_RootParam.DescriptorTable.pDescriptorRanges = pRanges; +#ifdef _DEBUG + for (Uint32 r = 0; r < NumRanges; ++r) + pRanges[r].RangeType = static_cast(-1); +#endif + } + + RootParameter(const RootParameter& RP) noexcept : + // clang-format off + m_RootParam {RP.m_RootParam }, + m_DescriptorTableSize{RP.m_DescriptorTableSize}, + m_ShaderVarType {RP.m_ShaderVarType }, + m_RootIndex {RP.m_RootIndex } + // clang-format on + { + VERIFY(m_RootParam.ParameterType != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Use another constructor to copy descriptor table"); + } + + RootParameter(const RootParameter& RP, + UINT NumRanges, + D3D12_DESCRIPTOR_RANGE* pRanges) noexcept : + // clang-format off + m_RootParam {RP.m_RootParam }, + m_DescriptorTableSize{RP.m_DescriptorTableSize}, + m_ShaderVarType {RP.m_ShaderVarType }, + m_RootIndex {RP.m_RootIndex } + // clang-format on + { + VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table"); + VERIFY(NumRanges >= m_RootParam.DescriptorTable.NumDescriptorRanges, "New table must be larger than source one"); + auto& DstTbl = m_RootParam.DescriptorTable; + DstTbl.NumDescriptorRanges = NumRanges; + DstTbl.pDescriptorRanges = pRanges; + const auto& SrcTbl = RP.m_RootParam.DescriptorTable; + memcpy(pRanges, SrcTbl.pDescriptorRanges, SrcTbl.NumDescriptorRanges * sizeof(D3D12_DESCRIPTOR_RANGE)); +#ifdef _DEBUG + { + Uint32 dbgTableSize = 0; + for (Uint32 r = 0; r < SrcTbl.NumDescriptorRanges; ++r) + { + const auto& Range = SrcTbl.pDescriptorRanges[r]; + dbgTableSize = std::max(dbgTableSize, Range.OffsetInDescriptorsFromTableStart + Range.NumDescriptors); + } + VERIFY(dbgTableSize == m_DescriptorTableSize, "Incorrect descriptor table size"); + + for (Uint32 r = SrcTbl.NumDescriptorRanges; r < DstTbl.NumDescriptorRanges; ++r) + pRanges[r].RangeType = static_cast(-1); + } +#endif + } + + RootParameter& operator=(const RootParameter&) = delete; + RootParameter& operator=(RootParameter&&) = delete; + + void SetDescriptorRange(UINT RangeIndex, + D3D12_DESCRIPTOR_RANGE_TYPE Type, + UINT Register, + UINT Count, + UINT Space = 0, + UINT OffsetFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { + VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected"); + auto& Tbl = m_RootParam.DescriptorTable; + VERIFY(RangeIndex < Tbl.NumDescriptorRanges, "Invalid descriptor range index"); + D3D12_DESCRIPTOR_RANGE& range = const_cast(Tbl.pDescriptorRanges[RangeIndex]); + VERIFY(range.RangeType == static_cast(-1), "Descriptor range has already been initialized. m_DescriptorTableSize may be updated incorrectly"); + range.RangeType = Type; + range.NumDescriptors = Count; + range.BaseShaderRegister = Register; + range.RegisterSpace = Space; + range.OffsetInDescriptorsFromTableStart = OffsetFromTableStart; + m_DescriptorTableSize = std::max(m_DescriptorTableSize, OffsetFromTableStart + Count); + } + + SHADER_RESOURCE_VARIABLE_TYPE GetShaderVariableType() const { return m_ShaderVarType; } + + Uint32 GetDescriptorTableSize() const + { + VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected"); + return m_DescriptorTableSize; + } + + D3D12_SHADER_VISIBILITY GetShaderVisibility() const { return m_RootParam.ShaderVisibility; } + D3D12_ROOT_PARAMETER_TYPE GetParameterType() const { return m_RootParam.ParameterType; } + + Uint32 GetRootIndex() const { return m_RootIndex; } + + operator const D3D12_ROOT_PARAMETER&() const { return m_RootParam; } + + bool operator==(const RootParameter& rhs) const + { + if (m_ShaderVarType != rhs.m_ShaderVarType || + m_DescriptorTableSize != rhs.m_DescriptorTableSize || + m_RootIndex != rhs.m_RootIndex) + return false; + + if (m_RootParam.ParameterType != rhs.m_RootParam.ParameterType || + m_RootParam.ShaderVisibility != rhs.m_RootParam.ShaderVisibility) + return false; + + switch (m_RootParam.ParameterType) + { + case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + { + const auto& tbl0 = m_RootParam.DescriptorTable; + const auto& tbl1 = rhs.m_RootParam.DescriptorTable; + if (tbl0.NumDescriptorRanges != tbl1.NumDescriptorRanges) + return false; + for (UINT r = 0; r < tbl0.NumDescriptorRanges; ++r) + { + const auto& rng0 = tbl0.pDescriptorRanges[r]; + const auto& rng1 = tbl1.pDescriptorRanges[r]; + if (memcmp(&rng0, &rng1, sizeof(rng0)) != 0) + return false; + } + } + break; + + case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: + { + const auto& cnst0 = m_RootParam.Constants; + const auto& cnst1 = rhs.m_RootParam.Constants; + if (memcmp(&cnst0, &cnst1, sizeof(cnst0)) != 0) + return false; + } + break; + + case D3D12_ROOT_PARAMETER_TYPE_CBV: + case D3D12_ROOT_PARAMETER_TYPE_SRV: + case D3D12_ROOT_PARAMETER_TYPE_UAV: + { + const auto& dscr0 = m_RootParam.Descriptor; + const auto& dscr1 = rhs.m_RootParam.Descriptor; + if (memcmp(&dscr0, &dscr1, sizeof(dscr0)) != 0) + return false; + } + break; + + default: UNEXPECTED("Unexpected root parameter type"); + } + + return true; + } + + bool operator!=(const RootParameter& rhs) const + { + return !(*this == rhs); + } + + size_t GetHash() const + { + size_t hash = ComputeHash(m_ShaderVarType, m_DescriptorTableSize, m_RootIndex); + HashCombine(hash, m_RootParam.ParameterType, m_RootParam.ShaderVisibility); + + switch (m_RootParam.ParameterType) + { + case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + { + const auto& tbl = m_RootParam.DescriptorTable; + HashCombine(hash, tbl.NumDescriptorRanges); + for (UINT r = 0; r < tbl.NumDescriptorRanges; ++r) + { + const auto& rng = tbl.pDescriptorRanges[r]; + HashCombine(hash, rng.BaseShaderRegister, rng.NumDescriptors, rng.OffsetInDescriptorsFromTableStart, rng.RangeType, rng.RegisterSpace); + } + } + break; + + case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: + { + const auto& cnst = m_RootParam.Constants; + HashCombine(hash, cnst.Num32BitValues, cnst.RegisterSpace, cnst.ShaderRegister); + } + break; + + case D3D12_ROOT_PARAMETER_TYPE_CBV: + case D3D12_ROOT_PARAMETER_TYPE_SRV: + case D3D12_ROOT_PARAMETER_TYPE_UAV: + { + const auto& dscr = m_RootParam.Descriptor; + HashCombine(hash, dscr.RegisterSpace, dscr.ShaderRegister); + } + break; + + default: UNEXPECTED("Unexpected root parameter type"); + } + + return hash; + } + +private: + SHADER_RESOURCE_VARIABLE_TYPE m_ShaderVarType = static_cast(-1); + D3D12_ROOT_PARAMETER m_RootParam = {}; + Uint32 m_DescriptorTableSize = 0; + Uint32 m_RootIndex = static_cast(-1); +}; + + + +/// Implementation of the Diligent::RootSignature class +class RootSignature +{ +public: + RootSignature(); + + void AllocateStaticSamplers(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 InitStaticSampler(SHADER_TYPE ShaderType, + const char* SamplerName, + const char* SamplerSuffix, + const D3DShaderResourceAttribs& ShaderResAttribs); + + void AllocateResourceSlot(SHADER_TYPE ShaderType, + const D3DShaderResourceAttribs& ShaderResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType, + 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, + class CommandContext& Ctx, + bool IsCompute, + bool ValidateStates) const = nullptr; + + void (RootSignature::*TransitionAndCommitDescriptorHandles)(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, + ShaderResourceCacheD3D12& ResourceCache, + class CommandContext& Ctx, + bool IsCompute, + bool ValidateStates) const = nullptr; + + void TransitionResources(ShaderResourceCacheD3D12& ResourceCache, + class CommandContext& Ctx) const; + + __forceinline void CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, + class CommandContext& CmdCtx, + bool IsCompute, + Uint32 DeviceCtxId, + class DeviceContextD3D12Impl* pDeviceCtx, + bool CommitViews, + bool ProcessDynamicBuffers, + bool ProcessNonDynamicBuffers, + bool TransitionStates, + bool ValidateStates) const; + + Uint32 GetTotalSrvCbvUavSlots(SHADER_RESOURCE_VARIABLE_TYPE VarType) const + { + return m_TotalSrvCbvUavSlots[VarType]; + } + Uint32 GetTotalSamplerSlots(SHADER_RESOURCE_VARIABLE_TYPE VarType) const + { + return m_TotalSamplerSlots[VarType]; + } + Uint32 GetTotalRootViews(SHADER_RESOURCE_VARIABLE_TYPE VarType) const + { + return m_TotalRootViews[VarType]; + } + + bool IsSameAs(const RootSignature& RS) const + { + return m_RootParams == RS.m_RootParams; + } + size_t GetHash() const + { + return m_RootParams.GetHash(); + } + +private: +#ifdef _DEBUG + void dbgVerifyRootParameters() const; +#endif + +#ifdef DEVELOPMENT + static void DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resource& Res, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType); +#endif + + std::vector> GetCacheTableSizes() const; + + std::array m_TotalSrvCbvUavSlots = {}; + std::array m_TotalSamplerSlots = {}; + std::array m_TotalRootViews = {}; + + CComPtr m_pd3d12RootSignature; + + class RootParamsManager + { + public: + RootParamsManager(IMemoryAllocator& MemAllocator); + + // clang-format off + RootParamsManager (const RootParamsManager&) = delete; + RootParamsManager& operator=(const RootParamsManager&) = delete; + RootParamsManager (RootParamsManager&&) = delete; + RootParamsManager& operator=(RootParamsManager&&) = delete; + // clang-format on + + Uint32 GetNumRootTables() const { return m_NumRootTables; } + Uint32 GetNumRootViews() const { return m_NumRootViews; } + + const RootParameter& GetRootTable(Uint32 TableInd) const + { + VERIFY_EXPR(TableInd < m_NumRootTables); + return m_pRootTables[TableInd]; + } + + RootParameter& GetRootTable(Uint32 TableInd) + { + VERIFY_EXPR(TableInd < m_NumRootTables); + return m_pRootTables[TableInd]; + } + + const RootParameter& GetRootView(Uint32 ViewInd) const + { + VERIFY_EXPR(ViewInd < m_NumRootViews); + return m_pRootViews[ViewInd]; + } + + RootParameter& GetRootView(Uint32 ViewInd) + { + VERIFY_EXPR(ViewInd < m_NumRootViews); + return m_pRootViews[ViewInd]; + } + + void AddRootView(D3D12_ROOT_PARAMETER_TYPE ParameterType, + Uint32 RootIndex, + UINT Register, + D3D12_SHADER_VISIBILITY Visibility, + SHADER_RESOURCE_VARIABLE_TYPE VarType); + + void AddRootTable(Uint32 RootIndex, + D3D12_SHADER_VISIBILITY Visibility, + SHADER_RESOURCE_VARIABLE_TYPE VarType, + Uint32 NumRangesInNewTable = 1); + + void AddDescriptorRanges(Uint32 RootTableInd, Uint32 NumExtraRanges = 1); + + template + void ProcessRootTables(TOperation) const; + + bool operator==(const RootParamsManager& RootParams) const; + size_t GetHash() const; + + private: + size_t GetRequiredMemorySize(Uint32 NumExtraRootTables, + Uint32 NumExtraRootViews, + Uint32 NumExtraDescriptorRanges) const; + + D3D12_DESCRIPTOR_RANGE* Extend(Uint32 NumExtraRootTables, + Uint32 NumExtraRootViews, + Uint32 NumExtraDescriptorRanges, + Uint32 RootTableToAddRanges = static_cast(-1)); + + IMemoryAllocator& m_MemAllocator; + std::unique_ptr> m_pMemory; + Uint32 m_NumRootTables = 0; + Uint32 m_NumRootViews = 0; + Uint32 m_TotalDescriptorRanges = 0; + RootParameter* m_pRootTables = nullptr; + RootParameter* m_pRootViews = nullptr; + }; + + static constexpr Uint8 InvalidRootTableIndex = static_cast(-1); + + // The array below contains array index of a CBV/SRV/UAV root table + // in m_RootParams (NOT the Root Index!), for every variable type + // (static, mutable, dynamic) and every shader type, + // or -1, if the table is not yet assigned to the combination + std::array m_SrvCbvUavRootTablesMap; + // This array contains the same data for Sampler root table + std::array m_SamplerRootTablesMap; + + RootParamsManager m_RootParams; + + struct StaticSamplerAttribs + { + StaticSamplerDesc SamplerDesc; + UINT ShaderRegister = static_cast(-1); + UINT ArraySize = 0; + UINT RegisterSpace = 0; + D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast(-1); + + StaticSamplerAttribs() noexcept {} + StaticSamplerAttribs(const StaticSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility) noexcept : + SamplerDesc(SamDesc), + ShaderVisibility(Visibility) + {} + }; + // Note: sizeof(m_StaticSamplers) == 56 (MS compiler, release x64) + std::vector> m_StaticSamplers; + + IMemoryAllocator& m_MemAllocator; + + // Commits descriptor handles for static and mutable variables + template + void CommitDescriptorHandlesInternal_SM(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, + ShaderResourceCacheD3D12& ResourceCache, + class CommandContext& Ctx, + bool IsCompute, + bool ValidateStates) const; + template + // Commits descriptor handles for static, mutable, and dynamic variables + void CommitDescriptorHandlesInternal_SMD(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, + ShaderResourceCacheD3D12& ResourceCache, + class CommandContext& Ctx, + bool IsCompute, + bool ValidateStates) const; +}; + +void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, + CommandContext& CmdCtx, + bool IsCompute, + Uint32 DeviceCtxId, + DeviceContextD3D12Impl* pDeviceCtx, + bool CommitViews, + bool ProcessDynamicBuffers, + bool ProcessNonDynamicBuffers, + bool TransitionStates, + bool ValidateStates) const +{ + for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + { + auto& RootView = m_RootParams.GetRootView(rv); + auto RootInd = RootView.GetRootIndex(); + + SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN; +#ifdef _DEBUG + { + auto& Param = static_cast(RootView); + VERIFY_EXPR(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV); + dbgShaderType = ShaderTypeFromShaderVisibility(Param.ShaderVisibility); + } +#endif + + auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType); + if (auto* pBuffToTransition = Res.pObject.RawPtr()) + { + bool IsDynamic = pBuffToTransition->GetDesc().Usage == USAGE_DYNAMIC; + if (IsDynamic && ProcessDynamicBuffers || !IsDynamic && ProcessNonDynamicBuffers) + { + if (IsDynamic) + { +#ifdef _DEBUG + if (pBuffToTransition->IsInKnownState()) + { + VERIFY(pBuffToTransition->CheckState(RESOURCE_STATE_CONSTANT_BUFFER), + "Dynamic buffers must always have RESOURCE_STATE_CONSTANT_BUFFER state flag set"); + } +#endif + } + else + { + if (TransitionStates) + { + if (pBuffToTransition->IsInKnownState() && !pBuffToTransition->CheckState(RESOURCE_STATE_CONSTANT_BUFFER)) + { + CmdCtx.TransitionResource(pBuffToTransition, RESOURCE_STATE_CONSTANT_BUFFER); + } + } +#ifdef DEVELOPMENT + else if (ValidateStates) + { + + DvpVerifyResourceState(Res, D3D12_DESCRIPTOR_RANGE_TYPE_CBV); + } +#endif + } + + if (CommitViews) + { + D3D12_GPU_VIRTUAL_ADDRESS CBVAddress = pBuffToTransition->GetGPUAddress(DeviceCtxId, pDeviceCtx); + if (IsCompute) + CmdCtx.GetCommandList()->SetComputeRootConstantBufferView(RootInd, CBVAddress); + else + CmdCtx.GetCommandList()->SetGraphicsRootConstantBufferView(RootInd, CBVAddress); + } + } + } + } +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/SamplerD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/SamplerD3D12Impl.h deleted file mode 100644 index c52f7c17..00000000 --- a/Graphics/GraphicsEngineD3D12/include/SamplerD3D12Impl.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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::SamplerD3D12Impl class - -#include "SamplerD3D12.h" -#include "RenderDeviceD3D12.h" -#include "SamplerBase.h" -#include "DescriptorHeap.h" -#include "RenderDeviceD3D12Impl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Sampler object implementation in Direct3D12 backend. -class SamplerD3D12Impl final : public SamplerBase -{ -public: - using TSamplerBase = SamplerBase; - - SamplerD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pRenderDeviceD3D12, - const SamplerDesc& SamplerDesc); - ~SamplerD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of ISamplerD3D12::GetCPUDescriptorHandle(). - virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() override { return m_Descriptor.GetCpuHandle(); } - -private: - friend class ShaderD3D12Impl; - /// D3D12 sampler - DescriptorHeapAllocation m_Descriptor; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/SamplerD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/SamplerD3D12Impl.hpp new file mode 100644 index 00000000..5633b5dc --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/SamplerD3D12Impl.hpp @@ -0,0 +1,66 @@ +/* + * 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::SamplerD3D12Impl class + +#include "SamplerD3D12.h" +#include "RenderDeviceD3D12.h" +#include "SamplerBase.hpp" +#include "DescriptorHeap.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Sampler object implementation in Direct3D12 backend. +class SamplerD3D12Impl final : public SamplerBase +{ +public: + using TSamplerBase = SamplerBase; + + SamplerD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pRenderDeviceD3D12, + const SamplerDesc& SamplerDesc); + ~SamplerD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of ISamplerD3D12::GetCPUDescriptorHandle(). + virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() override { return m_Descriptor.GetCpuHandle(); } + +private: + friend class ShaderD3D12Impl; + /// D3D12 sampler + DescriptorHeapAllocation m_Descriptor; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h deleted file mode 100644 index a5be1a03..00000000 --- a/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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::ShaderD3D12Impl class - -#include "RenderDeviceD3D12.h" -#include "ShaderD3D12.h" -#include "ShaderBase.h" -#include "ShaderD3DBase.h" -#include "ShaderResourceLayoutD3D12.h" -#include "RenderDeviceD3D12Impl.h" -#include "ShaderVariableD3D12.h" - -namespace Diligent -{ - -class ResourceMapping; - -/// Implementation of a shader object in Direct3D12 backend. -class ShaderD3D12Impl final : public ShaderBase, public ShaderD3DBase -{ -public: - using TShaderBase = ShaderBase; - - ShaderD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pRenderDeviceD3D12, - const ShaderCreateInfo& ShaderCI); - ~ShaderD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IShader::GetResourceCount() in Direct3D12 backend. - virtual Uint32 GetResourceCount() const override final - { - return m_pShaderResources->GetTotalResources(); - } - - /// Implementation of IShader::GetResource() in Direct3D12 backend. - virtual void GetResourceDesc(Uint32 Index, ShaderResourceDesc& ResourceDesc) const override final - { - ResourceDesc = GetHLSLResource(Index); - } - - /// Implementation of IShaderD3D::GetHLSLResource() in Direct3D12 backend. - virtual HLSLShaderResourceDesc GetHLSLResource(Uint32 Index) const override final - { - return m_pShaderResources->GetHLSLShaderResourceDesc(Index); - } - - ID3DBlob* GetShaderByteCode() { return m_pShaderByteCode; } - - const std::shared_ptr& GetShaderResources() const { return m_pShaderResources; } - -private: - // ShaderResources class instance must be referenced through the shared pointer, because - // it is referenced by ShaderResourceLayoutD3D12 class instances - std::shared_ptr m_pShaderResources; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.hpp new file mode 100644 index 00000000..6eb8e5d8 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.hpp @@ -0,0 +1,87 @@ +/* + * 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::ShaderD3D12Impl class + +#include "RenderDeviceD3D12.h" +#include "ShaderD3D12.h" +#include "ShaderBase.hpp" +#include "ShaderD3DBase.hpp" +#include "ShaderResourceLayoutD3D12.hpp" +#include "RenderDeviceD3D12Impl.hpp" +#include "ShaderVariableD3D12.hpp" + +namespace Diligent +{ + +class ResourceMapping; + +/// Implementation of a shader object in Direct3D12 backend. +class ShaderD3D12Impl final : public ShaderBase, public ShaderD3DBase +{ +public: + using TShaderBase = ShaderBase; + + ShaderD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pRenderDeviceD3D12, + const ShaderCreateInfo& ShaderCI); + ~ShaderD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IShader::GetResourceCount() in Direct3D12 backend. + virtual Uint32 GetResourceCount() const override final + { + return m_pShaderResources->GetTotalResources(); + } + + /// Implementation of IShader::GetResource() in Direct3D12 backend. + virtual void GetResourceDesc(Uint32 Index, ShaderResourceDesc& ResourceDesc) const override final + { + ResourceDesc = GetHLSLResource(Index); + } + + /// Implementation of IShaderD3D::GetHLSLResource() in Direct3D12 backend. + virtual HLSLShaderResourceDesc GetHLSLResource(Uint32 Index) const override final + { + return m_pShaderResources->GetHLSLShaderResourceDesc(Index); + } + + ID3DBlob* GetShaderByteCode() { return m_pShaderByteCode; } + + const std::shared_ptr& GetShaderResources() const { return m_pShaderResources; } + +private: + // ShaderResources class instance must be referenced through the shared pointer, because + // it is referenced by ShaderResourceLayoutD3D12 class instances + std::shared_ptr m_pShaderResources; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h deleted file mode 100644 index c89a31e7..00000000 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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::ShaderResourceBindingD3D12Impl class - -#include "ShaderResourceBindingD3D12.h" -#include "RenderDeviceD3D12.h" -#include "ShaderResourceBindingBase.h" -#include "ShaderBase.h" -#include "ShaderResourceCacheD3D12.h" -#include "ShaderResourceLayoutD3D12.h" -#include "ShaderVariableD3D12.h" - -namespace Diligent -{ - -/// Implementation of the Diligent::IShaderResourceBindingD3D12 interface -// sizeof(ShaderResourceBindingD3D12Impl) == 152 (x64, msvc, Release) -class ShaderResourceBindingD3D12Impl final : public ShaderResourceBindingBase -{ -public: - using TBase = ShaderResourceBindingBase; - - ShaderResourceBindingD3D12Impl(IReferenceCounters* pRefCounters, - class PipelineStateD3D12Impl* pPSO, - bool IsPSOInternal); - ~ShaderResourceBindingD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags) override; - - virtual IShaderResourceVariable* GetVariableByName(SHADER_TYPE ShaderType, const char* Name) override; - - virtual Uint32 GetVariableCount(SHADER_TYPE ShaderType) const override final; - - virtual IShaderResourceVariable* GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; - - virtual void InitializeStaticResources(const IPipelineState* pPipelineState) override final; - - ShaderResourceCacheD3D12& GetResourceCache() { return m_ShaderResourceCache; } - -#ifdef DEVELOPMENT - void dvpVerifyResourceBindings(const PipelineStateD3D12Impl* pPSO) const; -#endif - - bool StaticResourcesInitialized() const - { - return m_bStaticResourcesInitialized; - } - -private: - ShaderResourceCacheD3D12 m_ShaderResourceCache; - ShaderVariableManagerD3D12* m_pShaderVarMgrs = nullptr; - // Resource layout index in m_ResourceLayouts[] array for every shader stage - Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; - bool m_bStaticResourcesInitialized = false; - const Uint8 m_NumShaders = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp new file mode 100644 index 00000000..2fde8ed1 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp @@ -0,0 +1,88 @@ +/* + * 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::ShaderResourceBindingD3D12Impl class + +#include "ShaderResourceBindingD3D12.h" +#include "RenderDeviceD3D12.h" +#include "ShaderResourceBindingBase.hpp" +#include "ShaderBase.hpp" +#include "ShaderResourceCacheD3D12.hpp" +#include "ShaderResourceLayoutD3D12.hpp" +#include "ShaderVariableD3D12.hpp" + +namespace Diligent +{ + +/// Implementation of the Diligent::IShaderResourceBindingD3D12 interface +// sizeof(ShaderResourceBindingD3D12Impl) == 152 (x64, msvc, Release) +class ShaderResourceBindingD3D12Impl final : public ShaderResourceBindingBase +{ +public: + using TBase = ShaderResourceBindingBase; + + ShaderResourceBindingD3D12Impl(IReferenceCounters* pRefCounters, + class PipelineStateD3D12Impl* pPSO, + bool IsPSOInternal); + ~ShaderResourceBindingD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags) override; + + virtual IShaderResourceVariable* GetVariableByName(SHADER_TYPE ShaderType, const char* Name) override; + + virtual Uint32 GetVariableCount(SHADER_TYPE ShaderType) const override final; + + virtual IShaderResourceVariable* GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; + + virtual void InitializeStaticResources(const IPipelineState* pPipelineState) override final; + + ShaderResourceCacheD3D12& GetResourceCache() { return m_ShaderResourceCache; } + +#ifdef DEVELOPMENT + void dvpVerifyResourceBindings(const PipelineStateD3D12Impl* pPSO) const; +#endif + + bool StaticResourcesInitialized() const + { + return m_bStaticResourcesInitialized; + } + +private: + ShaderResourceCacheD3D12 m_ShaderResourceCache; + ShaderVariableManagerD3D12* m_pShaderVarMgrs = nullptr; + // Resource layout index in m_ResourceLayouts[] array for every shader stage + Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; + bool m_bStaticResourcesInitialized = false; + const Uint8 m_NumShaders = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h deleted file mode 100644 index 692214dc..00000000 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h +++ /dev/null @@ -1,354 +0,0 @@ -/* - * 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::ShaderResourceCacheD3D12 class - -// http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache/ - -// Shader resource cache stores D3D12 resources in a continuous chunk of memory: -// -// -// __________________________________________________________ -// m_pMemory | m_pResources, m_NumResources == m | -// | | | -// V | V -// | RootTable[0] | .... | RootTable[Nrt-1] | Res[0] | ... | Res[n-1] | .... | Res[0] | ... | Res[m-1] | -// | A \ -// | | \ -// |________________________________________________| \RefCntAutoPtr -// m_pResources, m_NumResources == n \_________ -// | Object | -// --------- -// -// Nrt = m_NumTables -// -// -// The cache is also assigned decriptor heap space to store shader visible descriptor handles (for non-dynamic resources). -// -// -// DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV -// | DescrptHndl[0] ... DescrptHndl[n-1] | DescrptHndl[0] ... DescrptHndl[m-1] | -// A A -// | | -// | TableStartOffset | TableStartOffset -// | | -// | RootTable[0] | RootTable[1] | RootTable[2] | .... | RootTable[Nrt] | -// | | -// | TableStartOffset | InvalidDescriptorOffset -// | | -// V V -// | DescrptHndl[0] ... DescrptHndl[n-1] | X -// DESCRIPTOR_HEAP_TYPE_SAMPLER -// -// -// -// The allocation is inexed by the offset from the beginning of the root table -// Each root table is assigned the space to store exactly m_NumResources resources -// Dynamic resources are not assigned space in the descriptor heap allocation. -// -// -// -// | RootTable[i] | Res[0] ... Res[n-1] | -// \ -// TableStartOffset\____ -// \ -// V -// ..... | DescrptHndl[0] ... DescrptHndl[n-1] | .... -// - -#include "DescriptorHeap.h" - -namespace Diligent -{ - -enum class CachedResourceType : Int32 -{ - Unknown = -1, - CBV = 0, - TexSRV, - BufSRV, - TexUAV, - BufUAV, - Sampler, - NumTypes -}; - -class ShaderResourceCacheD3D12 -{ -public: - // This enum is used for debug purposes only - enum DbgCacheContentType - { - StaticShaderResources, - SRBResources - }; - - ShaderResourceCacheD3D12(DbgCacheContentType dbgContentType) - // clang-format off -#ifdef _DEBUG - : m_DbgContentType - { - dbgContentType - } -#endif - // clang-format on - { - } - - ~ShaderResourceCacheD3D12(); - - static size_t GetRequiredMemorySize(Uint32 NumTables, - Uint32 TableSizes[]); - - void Initialize(IMemoryAllocator& MemAllocator, - Uint32 NumTables, - Uint32 TableSizes[]); - - static constexpr Uint32 InvalidDescriptorOffset = static_cast(-1); - - //http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Cache-Structure - struct Resource - { - Resource() noexcept {} - - CachedResourceType Type = CachedResourceType::Unknown; - // CPU descriptor handle of a cached resource in CPU-only descriptor heap - // Note that for dynamic resources, this is the only available CPU descriptor handle - D3D12_CPU_DESCRIPTOR_HANDLE CPUDescriptorHandle = {0}; - RefCntAutoPtr pObject; - }; - - class RootTable - { - public: - RootTable(Uint32 NumResources, Resource* pResources) noexcept : - // clang-format off - m_NumResources{NumResources}, - m_pResources {pResources } - // clang-format on - {} - - inline const Resource& GetResource(Uint32 OffsetFromTableStart) const - { - VERIFY(OffsetFromTableStart < m_NumResources, "Root table is not large enough to store descriptor at offset ", OffsetFromTableStart); - return m_pResources[OffsetFromTableStart]; - } - - inline const Resource& GetResource(Uint32 OffsetFromTableStart, - const D3D12_DESCRIPTOR_HEAP_TYPE dbgDescriptorHeapType, - const SHADER_TYPE dbgRefShaderType) const - { - VERIFY(m_dbgHeapType == dbgDescriptorHeapType, "Incosistent descriptor heap type"); - VERIFY(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]; - } - inline Resource& GetResource(Uint32 OffsetFromTableStart, - const D3D12_DESCRIPTOR_HEAP_TYPE dbgDescriptorHeapType, - const SHADER_TYPE dbgRefShaderType) - { - return const_cast(const_cast(this)->GetResource(OffsetFromTableStart, dbgDescriptorHeapType, dbgRefShaderType)); - } - - inline Uint32 GetSize() const { return m_NumResources; } - - // Offset from the start of the descriptor heap allocation to the start of the table - Uint32 m_TableStartOffset = InvalidDescriptorOffset; - -#ifdef _DEBUG - void SetDebugAttribs(Uint32 MaxOffset, - const D3D12_DESCRIPTOR_HEAP_TYPE dbgDescriptorHeapType, - const SHADER_TYPE dbgRefShaderType) - { - VERIFY_EXPR(m_NumResources == MaxOffset); - m_dbgHeapType = dbgDescriptorHeapType; - m_dbgShaderType = dbgRefShaderType; - } - - D3D12_DESCRIPTOR_HEAP_TYPE DbgGetHeapType() const { return m_dbgHeapType; } -#endif - - const Uint32 m_NumResources = 0; - - private: -#ifdef _DEBUG - D3D12_DESCRIPTOR_HEAP_TYPE m_dbgHeapType = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; - SHADER_TYPE m_dbgShaderType = SHADER_TYPE_UNKNOWN; -#endif - - Resource* const m_pResources = nullptr; - }; - - inline RootTable& GetRootTable(Uint32 RootIndex) - { - VERIFY_EXPR(RootIndex < m_NumTables); - return reinterpret_cast(m_pMemory)[RootIndex]; - } - inline const RootTable& GetRootTable(Uint32 RootIndex) const - { - VERIFY_EXPR(RootIndex < m_NumTables); - return reinterpret_cast(m_pMemory)[RootIndex]; - } - - inline Uint32 GetNumRootTables() const { return m_NumTables; } - - void SetDescriptorHeapSpace(DescriptorHeapAllocation&& CbcSrvUavHeapSpace, DescriptorHeapAllocation&& SamplerHeapSpace) - { - VERIFY(m_SamplerHeapSpace.GetCpuHandle().ptr == 0 && m_CbvSrvUavHeapSpace.GetCpuHandle().ptr == 0, "Space has already been allocated in GPU descriptor heaps"); -#ifdef _DEBUG - Uint32 NumSamplerDescriptors = 0, NumSrvCbvUavDescriptors = 0; - for (Uint32 rt = 0; rt < m_NumTables; ++rt) - { - auto& Tbl = GetRootTable(rt); - if (Tbl.m_TableStartOffset != InvalidDescriptorOffset) - { - if (Tbl.DbgGetHeapType() == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) - { - VERIFY(Tbl.m_TableStartOffset == NumSrvCbvUavDescriptors, "Descriptor space allocation is not continuous"); - NumSrvCbvUavDescriptors = std::max(NumSrvCbvUavDescriptors, Tbl.m_TableStartOffset + Tbl.GetSize()); - } - else - { - VERIFY(Tbl.m_TableStartOffset == NumSamplerDescriptors, "Descriptor space allocation is not continuous"); - NumSamplerDescriptors = std::max(NumSamplerDescriptors, Tbl.m_TableStartOffset + Tbl.GetSize()); - } - } - } - VERIFY(NumSrvCbvUavDescriptors == CbcSrvUavHeapSpace.GetNumHandles() || NumSrvCbvUavDescriptors == 0 && CbcSrvUavHeapSpace.GetCpuHandle(0).ptr == 0, "Unexpected descriptor heap allocation size"); - VERIFY(NumSamplerDescriptors == SamplerHeapSpace.GetNumHandles() || NumSamplerDescriptors == 0 && SamplerHeapSpace.GetCpuHandle(0).ptr == 0, "Unexpected descriptor heap allocation size"); -#endif - - m_CbvSrvUavHeapSpace = std::move(CbcSrvUavHeapSpace); - m_SamplerHeapSpace = std::move(SamplerHeapSpace); - } - - ID3D12DescriptorHeap* GetSrvCbvUavDescriptorHeap() { return m_CbvSrvUavHeapSpace.GetDescriptorHeap(); } - ID3D12DescriptorHeap* GetSamplerDescriptorHeap() { return m_SamplerHeapSpace.GetDescriptorHeap(); } - - // Returns CPU descriptor handle of a shader visible descriptor heap allocation - template - D3D12_CPU_DESCRIPTOR_HANDLE GetShaderVisibleTableCPUDescriptorHandle(Uint32 RootParamInd, Uint32 OffsetFromTableStart = 0) const - { - const auto& RootParam = GetRootTable(RootParamInd); - VERIFY(HeapType == RootParam.DbgGetHeapType(), "Invalid descriptor heap type"); - - D3D12_CPU_DESCRIPTOR_HANDLE CPUDescriptorHandle = {0}; - // Descriptor heap allocation is not assigned for dynamic resources or - // in a special case when resource cache is used to store static - // variable assignments for a shader. It is also not assigned to root views - if (RootParam.m_TableStartOffset != InvalidDescriptorOffset) - { - VERIFY(OffsetFromTableStart < RootParam.m_NumResources, "Offset is out of range"); - if (HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) - { - VERIFY_EXPR(!m_SamplerHeapSpace.IsNull()); - CPUDescriptorHandle = m_SamplerHeapSpace.GetCpuHandle(RootParam.m_TableStartOffset + OffsetFromTableStart); - } - else if (HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) - { - VERIFY_EXPR(!m_CbvSrvUavHeapSpace.IsNull()); - CPUDescriptorHandle = m_CbvSrvUavHeapSpace.GetCpuHandle(RootParam.m_TableStartOffset + OffsetFromTableStart); - } - else - { - UNEXPECTED("Unexpected descriptor heap type"); - } - } - - return CPUDescriptorHandle; - } - - // Returns GPU descriptor handle of a shader visible descriptor table - template - D3D12_GPU_DESCRIPTOR_HANDLE GetShaderVisibleTableGPUDescriptorHandle(Uint32 RootParamInd, Uint32 OffsetFromTableStart = 0) const - { - const auto& RootParam = GetRootTable(RootParamInd); - VERIFY(RootParam.m_TableStartOffset != InvalidDescriptorOffset, "GPU descriptor handle must never be requested for dynamic resources"); - VERIFY(OffsetFromTableStart < RootParam.m_NumResources, "Offset is out of range"); - - D3D12_GPU_DESCRIPTOR_HANDLE GPUDescriptorHandle = {0}; - VERIFY(HeapType == RootParam.DbgGetHeapType(), "Invalid descriptor heap type"); - if (HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) - { - VERIFY_EXPR(!m_SamplerHeapSpace.IsNull()); - GPUDescriptorHandle = m_SamplerHeapSpace.GetGpuHandle(RootParam.m_TableStartOffset + OffsetFromTableStart); - } - else if (HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) - { - VERIFY_EXPR(!m_CbvSrvUavHeapSpace.IsNull()); - GPUDescriptorHandle = m_CbvSrvUavHeapSpace.GetGpuHandle(RootParam.m_TableStartOffset + OffsetFromTableStart); - } - else - { - UNEXPECTED("Unexpected descriptor heap type"); - } - - return GPUDescriptorHandle; - } - - Uint32& GetBoundDynamicCBsCounter() { return m_NumDynamicCBsBound; } - - // Returns the number of dynamic constant buffers bound in the cache regardless of their variable types - Uint32 GetNumDynamicCBsBound() const { return m_NumDynamicCBsBound; } - -#ifdef _DEBUG - // Only for debug purposes: indicates what types of resources are stored in the cache - DbgCacheContentType DbgGetContentType() const { return m_DbgContentType; } - void DbgVerifyBoundDynamicCBsCounter() const; -#endif - -private: - // clang-format off - ShaderResourceCacheD3D12 (const ShaderResourceCacheD3D12&) = delete; - ShaderResourceCacheD3D12 (ShaderResourceCacheD3D12&&) = delete; - ShaderResourceCacheD3D12& operator = (const ShaderResourceCacheD3D12&) = delete; - ShaderResourceCacheD3D12& operator = (ShaderResourceCacheD3D12&&) = delete; - // clang-format on - - // Allocation in a GPU-visible sampler descriptor heap - DescriptorHeapAllocation m_SamplerHeapSpace; - - // Allocation in a GPU-visible CBV/SRV/UAV descriptor heap - DescriptorHeapAllocation m_CbvSrvUavHeapSpace; - - IMemoryAllocator* m_pAllocator = nullptr; - void* m_pMemory = nullptr; - Uint32 m_NumTables = 0; - // The number of the dynamic buffers bound in the resource cache regardless of their variable type - Uint32 m_NumDynamicCBsBound = 0; - -#ifdef _DEBUG - // Only for debug purposes: indicates what types of resources are stored in the cache - const DbgCacheContentType m_DbgContentType; -#endif -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp new file mode 100644 index 00000000..9f24d2d4 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp @@ -0,0 +1,354 @@ +/* + * 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::ShaderResourceCacheD3D12 class + +// http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache/ + +// Shader resource cache stores D3D12 resources in a continuous chunk of memory: +// +// +// __________________________________________________________ +// m_pMemory | m_pResources, m_NumResources == m | +// | | | +// V | V +// | RootTable[0] | .... | RootTable[Nrt-1] | Res[0] | ... | Res[n-1] | .... | Res[0] | ... | Res[m-1] | +// | A \ +// | | \ +// |________________________________________________| \RefCntAutoPtr +// m_pResources, m_NumResources == n \_________ +// | Object | +// --------- +// +// Nrt = m_NumTables +// +// +// The cache is also assigned decriptor heap space to store shader visible descriptor handles (for non-dynamic resources). +// +// +// DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV +// | DescrptHndl[0] ... DescrptHndl[n-1] | DescrptHndl[0] ... DescrptHndl[m-1] | +// A A +// | | +// | TableStartOffset | TableStartOffset +// | | +// | RootTable[0] | RootTable[1] | RootTable[2] | .... | RootTable[Nrt] | +// | | +// | TableStartOffset | InvalidDescriptorOffset +// | | +// V V +// | DescrptHndl[0] ... DescrptHndl[n-1] | X +// DESCRIPTOR_HEAP_TYPE_SAMPLER +// +// +// +// The allocation is inexed by the offset from the beginning of the root table +// Each root table is assigned the space to store exactly m_NumResources resources +// Dynamic resources are not assigned space in the descriptor heap allocation. +// +// +// +// | RootTable[i] | Res[0] ... Res[n-1] | +// \ +// TableStartOffset\____ +// \ +// V +// ..... | DescrptHndl[0] ... DescrptHndl[n-1] | .... +// + +#include "DescriptorHeap.hpp" + +namespace Diligent +{ + +enum class CachedResourceType : Int32 +{ + Unknown = -1, + CBV = 0, + TexSRV, + BufSRV, + TexUAV, + BufUAV, + Sampler, + NumTypes +}; + +class ShaderResourceCacheD3D12 +{ +public: + // This enum is used for debug purposes only + enum DbgCacheContentType + { + StaticShaderResources, + SRBResources + }; + + ShaderResourceCacheD3D12(DbgCacheContentType dbgContentType) + // clang-format off +#ifdef _DEBUG + : m_DbgContentType + { + dbgContentType + } +#endif + // clang-format on + { + } + + ~ShaderResourceCacheD3D12(); + + static size_t GetRequiredMemorySize(Uint32 NumTables, + Uint32 TableSizes[]); + + void Initialize(IMemoryAllocator& MemAllocator, + Uint32 NumTables, + Uint32 TableSizes[]); + + static constexpr Uint32 InvalidDescriptorOffset = static_cast(-1); + + //http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Cache-Structure + struct Resource + { + Resource() noexcept {} + + CachedResourceType Type = CachedResourceType::Unknown; + // CPU descriptor handle of a cached resource in CPU-only descriptor heap + // Note that for dynamic resources, this is the only available CPU descriptor handle + D3D12_CPU_DESCRIPTOR_HANDLE CPUDescriptorHandle = {0}; + RefCntAutoPtr pObject; + }; + + class RootTable + { + public: + RootTable(Uint32 NumResources, Resource* pResources) noexcept : + // clang-format off + m_NumResources{NumResources}, + m_pResources {pResources } + // clang-format on + {} + + inline const Resource& GetResource(Uint32 OffsetFromTableStart) const + { + VERIFY(OffsetFromTableStart < m_NumResources, "Root table is not large enough to store descriptor at offset ", OffsetFromTableStart); + return m_pResources[OffsetFromTableStart]; + } + + inline const Resource& GetResource(Uint32 OffsetFromTableStart, + const D3D12_DESCRIPTOR_HEAP_TYPE dbgDescriptorHeapType, + const SHADER_TYPE dbgRefShaderType) const + { + VERIFY(m_dbgHeapType == dbgDescriptorHeapType, "Incosistent descriptor heap type"); + VERIFY(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]; + } + inline Resource& GetResource(Uint32 OffsetFromTableStart, + const D3D12_DESCRIPTOR_HEAP_TYPE dbgDescriptorHeapType, + const SHADER_TYPE dbgRefShaderType) + { + return const_cast(const_cast(this)->GetResource(OffsetFromTableStart, dbgDescriptorHeapType, dbgRefShaderType)); + } + + inline Uint32 GetSize() const { return m_NumResources; } + + // Offset from the start of the descriptor heap allocation to the start of the table + Uint32 m_TableStartOffset = InvalidDescriptorOffset; + +#ifdef _DEBUG + void SetDebugAttribs(Uint32 MaxOffset, + const D3D12_DESCRIPTOR_HEAP_TYPE dbgDescriptorHeapType, + const SHADER_TYPE dbgRefShaderType) + { + VERIFY_EXPR(m_NumResources == MaxOffset); + m_dbgHeapType = dbgDescriptorHeapType; + m_dbgShaderType = dbgRefShaderType; + } + + D3D12_DESCRIPTOR_HEAP_TYPE DbgGetHeapType() const { return m_dbgHeapType; } +#endif + + const Uint32 m_NumResources = 0; + + private: +#ifdef _DEBUG + D3D12_DESCRIPTOR_HEAP_TYPE m_dbgHeapType = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; + SHADER_TYPE m_dbgShaderType = SHADER_TYPE_UNKNOWN; +#endif + + Resource* const m_pResources = nullptr; + }; + + inline RootTable& GetRootTable(Uint32 RootIndex) + { + VERIFY_EXPR(RootIndex < m_NumTables); + return reinterpret_cast(m_pMemory)[RootIndex]; + } + inline const RootTable& GetRootTable(Uint32 RootIndex) const + { + VERIFY_EXPR(RootIndex < m_NumTables); + return reinterpret_cast(m_pMemory)[RootIndex]; + } + + inline Uint32 GetNumRootTables() const { return m_NumTables; } + + void SetDescriptorHeapSpace(DescriptorHeapAllocation&& CbcSrvUavHeapSpace, DescriptorHeapAllocation&& SamplerHeapSpace) + { + VERIFY(m_SamplerHeapSpace.GetCpuHandle().ptr == 0 && m_CbvSrvUavHeapSpace.GetCpuHandle().ptr == 0, "Space has already been allocated in GPU descriptor heaps"); +#ifdef _DEBUG + Uint32 NumSamplerDescriptors = 0, NumSrvCbvUavDescriptors = 0; + for (Uint32 rt = 0; rt < m_NumTables; ++rt) + { + auto& Tbl = GetRootTable(rt); + if (Tbl.m_TableStartOffset != InvalidDescriptorOffset) + { + if (Tbl.DbgGetHeapType() == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) + { + VERIFY(Tbl.m_TableStartOffset == NumSrvCbvUavDescriptors, "Descriptor space allocation is not continuous"); + NumSrvCbvUavDescriptors = std::max(NumSrvCbvUavDescriptors, Tbl.m_TableStartOffset + Tbl.GetSize()); + } + else + { + VERIFY(Tbl.m_TableStartOffset == NumSamplerDescriptors, "Descriptor space allocation is not continuous"); + NumSamplerDescriptors = std::max(NumSamplerDescriptors, Tbl.m_TableStartOffset + Tbl.GetSize()); + } + } + } + VERIFY(NumSrvCbvUavDescriptors == CbcSrvUavHeapSpace.GetNumHandles() || NumSrvCbvUavDescriptors == 0 && CbcSrvUavHeapSpace.GetCpuHandle(0).ptr == 0, "Unexpected descriptor heap allocation size"); + VERIFY(NumSamplerDescriptors == SamplerHeapSpace.GetNumHandles() || NumSamplerDescriptors == 0 && SamplerHeapSpace.GetCpuHandle(0).ptr == 0, "Unexpected descriptor heap allocation size"); +#endif + + m_CbvSrvUavHeapSpace = std::move(CbcSrvUavHeapSpace); + m_SamplerHeapSpace = std::move(SamplerHeapSpace); + } + + ID3D12DescriptorHeap* GetSrvCbvUavDescriptorHeap() { return m_CbvSrvUavHeapSpace.GetDescriptorHeap(); } + ID3D12DescriptorHeap* GetSamplerDescriptorHeap() { return m_SamplerHeapSpace.GetDescriptorHeap(); } + + // Returns CPU descriptor handle of a shader visible descriptor heap allocation + template + D3D12_CPU_DESCRIPTOR_HANDLE GetShaderVisibleTableCPUDescriptorHandle(Uint32 RootParamInd, Uint32 OffsetFromTableStart = 0) const + { + const auto& RootParam = GetRootTable(RootParamInd); + VERIFY(HeapType == RootParam.DbgGetHeapType(), "Invalid descriptor heap type"); + + D3D12_CPU_DESCRIPTOR_HANDLE CPUDescriptorHandle = {0}; + // Descriptor heap allocation is not assigned for dynamic resources or + // in a special case when resource cache is used to store static + // variable assignments for a shader. It is also not assigned to root views + if (RootParam.m_TableStartOffset != InvalidDescriptorOffset) + { + VERIFY(OffsetFromTableStart < RootParam.m_NumResources, "Offset is out of range"); + if (HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) + { + VERIFY_EXPR(!m_SamplerHeapSpace.IsNull()); + CPUDescriptorHandle = m_SamplerHeapSpace.GetCpuHandle(RootParam.m_TableStartOffset + OffsetFromTableStart); + } + else if (HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) + { + VERIFY_EXPR(!m_CbvSrvUavHeapSpace.IsNull()); + CPUDescriptorHandle = m_CbvSrvUavHeapSpace.GetCpuHandle(RootParam.m_TableStartOffset + OffsetFromTableStart); + } + else + { + UNEXPECTED("Unexpected descriptor heap type"); + } + } + + return CPUDescriptorHandle; + } + + // Returns GPU descriptor handle of a shader visible descriptor table + template + D3D12_GPU_DESCRIPTOR_HANDLE GetShaderVisibleTableGPUDescriptorHandle(Uint32 RootParamInd, Uint32 OffsetFromTableStart = 0) const + { + const auto& RootParam = GetRootTable(RootParamInd); + VERIFY(RootParam.m_TableStartOffset != InvalidDescriptorOffset, "GPU descriptor handle must never be requested for dynamic resources"); + VERIFY(OffsetFromTableStart < RootParam.m_NumResources, "Offset is out of range"); + + D3D12_GPU_DESCRIPTOR_HANDLE GPUDescriptorHandle = {0}; + VERIFY(HeapType == RootParam.DbgGetHeapType(), "Invalid descriptor heap type"); + if (HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) + { + VERIFY_EXPR(!m_SamplerHeapSpace.IsNull()); + GPUDescriptorHandle = m_SamplerHeapSpace.GetGpuHandle(RootParam.m_TableStartOffset + OffsetFromTableStart); + } + else if (HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) + { + VERIFY_EXPR(!m_CbvSrvUavHeapSpace.IsNull()); + GPUDescriptorHandle = m_CbvSrvUavHeapSpace.GetGpuHandle(RootParam.m_TableStartOffset + OffsetFromTableStart); + } + else + { + UNEXPECTED("Unexpected descriptor heap type"); + } + + return GPUDescriptorHandle; + } + + Uint32& GetBoundDynamicCBsCounter() { return m_NumDynamicCBsBound; } + + // Returns the number of dynamic constant buffers bound in the cache regardless of their variable types + Uint32 GetNumDynamicCBsBound() const { return m_NumDynamicCBsBound; } + +#ifdef _DEBUG + // Only for debug purposes: indicates what types of resources are stored in the cache + DbgCacheContentType DbgGetContentType() const { return m_DbgContentType; } + void DbgVerifyBoundDynamicCBsCounter() const; +#endif + +private: + // clang-format off + ShaderResourceCacheD3D12 (const ShaderResourceCacheD3D12&) = delete; + ShaderResourceCacheD3D12 (ShaderResourceCacheD3D12&&) = delete; + ShaderResourceCacheD3D12& operator = (const ShaderResourceCacheD3D12&) = delete; + ShaderResourceCacheD3D12& operator = (ShaderResourceCacheD3D12&&) = delete; + // clang-format on + + // Allocation in a GPU-visible sampler descriptor heap + DescriptorHeapAllocation m_SamplerHeapSpace; + + // Allocation in a GPU-visible CBV/SRV/UAV descriptor heap + DescriptorHeapAllocation m_CbvSrvUavHeapSpace; + + IMemoryAllocator* m_pAllocator = nullptr; + void* m_pMemory = nullptr; + Uint32 m_NumTables = 0; + // The number of the dynamic buffers bound in the resource cache regardless of their variable type + Uint32 m_NumDynamicCBsBound = 0; + +#ifdef _DEBUG + // Only for debug purposes: indicates what types of resources are stored in the cache + const DbgCacheContentType m_DbgContentType; +#endif +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h deleted file mode 100644 index 75c2837f..00000000 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - * 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::ShaderResourceLayoutD3D12 class - -// http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout/ - -// All resources are stored in a single continuous chunk of memory using the following layout: -// -// m_ResourceBuffer -// | | | -// | D3D12Resource[0] ... | D3D12Resource[s] ... | D3D12Resource[s+m] ... | D3D12Resource[smd] ... | D3D12Resource[smd+s'] ... | D3D12Resource[smd+s'+m'] ... D3D12Resource[s+m+d+s'+m'+d'-1] || -// | | | | | | || -// | SRV/CBV/UAV - STATIC | SRV/CBV/UAV - MUTABLE | SRV/CBV/UAV - DYNAMIC | Samplers - STATIC | Samplers - MUTABLE | Samplers - DYNAMIC || -// | | | | -// -// s == NumCbvSrvUav[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] -// m == NumCbvSrvUav[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] -// d == NumCbvSrvUav[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] -// smd = s+m+d -// -// s' == NumSamplers[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] -// 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] | ... | -// |___________________________| |__________________|__________________|_______________|____________________|______________________|__________| -// A A | A A -// | \ |______________\____SamplerId________________________| -// | \ \ -// | Ref Ref -// | \ \_____ -// | \ \ -// ____________|_______________ ________\_______________________\__________________________________________ -// | | | | | | -// | ShaderVariableManagerD3D12 |---------------->| ShaderVariableD3D12Impl[0] | ShaderVariableD3D12Impl[1] | ... | -// |____________________________| |____________________________|____________________________|_________________| - -// -// http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Figure2 -// Resources in the resource cache are identified by the root index and offset in the descriptor table -// -// -// ShaderResourceLayoutD3D12 is used as follows: -// * Every pipeline state object (PipelineStateD3D12Impl) maintains shader resource layout for every active shader stage -// ** These resource layouts are used as reference layouts for shader resource binding objects -// ** All variable types are preserved -// ** Root indices and descriptor table offsets are assigned during the initialization -// * Every pipeline state object also contains shader resource layout that facilitates management of static shader resources -// ** The resource layout defines artificial layout where root index matches the resource type (CBV/SRV/UAV/SAM) -// ** Only static variables are referenced -// -// * Every shader resource binding object (ShaderResourceBindingD3D12Impl) encompasses shader variable -// manager (ShaderVariableManagerD3D12) for every active shader stage in the parent pipeline state that -// handles mutable and dynamic resources - -#include - -#include "ShaderBase.h" -#include "ShaderResourcesD3D12.h" -#include "ShaderResourceCacheD3D12.h" - -namespace Diligent -{ - -/// Diligent::ShaderResourceLayoutD3D12 class -// sizeof(ShaderResourceLayoutD3D12) == 64 (MS compiler, x64) -class ShaderResourceLayoutD3D12 final -{ -public: - // There are two modes a layout can be constructed: - // - initialize static resource layout and initialize shader resource cache to hold static resources - // - 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 - ShaderResourceLayoutD3D12(IObject& Owner, - ID3D12Device* pd3d12Device, - const PipelineResourceLayoutDesc& ResourceLayout, - std::shared_ptr pSrcResources, - IMemoryAllocator& LayoutDataAllocator, - const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheD3D12* pResourceCache, - class RootSignature* pRootSig); - - // clang-format off - ShaderResourceLayoutD3D12 (const ShaderResourceLayoutD3D12&) = delete; - ShaderResourceLayoutD3D12 (ShaderResourceLayoutD3D12&&) = delete; - ShaderResourceLayoutD3D12& operator =(const ShaderResourceLayoutD3D12&) = delete; - ShaderResourceLayoutD3D12& operator =(ShaderResourceLayoutD3D12&&) = delete; - // clang-format on - - ~ShaderResourceLayoutD3D12(); - - // sizeof(D3D12Resource) == 24 (x64) - struct D3D12Resource final - { - // clang-format off - - D3D12Resource (const D3D12Resource&) = delete; - D3D12Resource ( D3D12Resource&&) = delete; - D3D12Resource& operator = (const D3D12Resource&) = delete; - D3D12Resource& operator = ( D3D12Resource&&) = delete; - - static constexpr const Uint32 ResourceTypeBits = 3; - static constexpr const Uint32 VariableTypeBits = 2; - static constexpr const Uint32 RootIndexBits = 16 - ResourceTypeBits - VariableTypeBits; - - static constexpr const Uint32 InvalidRootIndex = (1 << RootIndexBits) - 1; - static constexpr const Uint32 MaxRootIndex = InvalidRootIndex - 1; - - 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"); - -/* 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 - - // clang-format on - - D3D12Resource(const ShaderResourceLayoutD3D12& _ParentLayout, - const D3DShaderResourceAttribs& _Attribs, - SHADER_RESOURCE_VARIABLE_TYPE _VariableType, - CachedResourceType _ResType, - Uint32 _RootIndex, - Uint32 _OffsetFromTableStart, - Uint32 _SamplerId) 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 } - // clang-format on - { - 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(_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"); - } - - bool IsBound(Uint32 ArrayIndex, - const ShaderResourceCacheD3D12& ResourceCache) const; - - void BindResource(IDeviceObject* pObject, - Uint32 ArrayIndex, - ShaderResourceCacheD3D12& ResourceCache) const; - - // clang-format off - bool ValidSamplerAssigned()const { return SamplerId != InvalidSamplerId; } - 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); } - - private: - void CacheCB(IDeviceObject* pBuffer, - ShaderResourceCacheD3D12::Resource& DstRes, - Uint32 ArrayInd, - D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle, - Uint32& BoundDynamicCBsCounter) const; - - template - void CacheResourceView(IDeviceObject* pView, - ShaderResourceCacheD3D12::Resource& DstRes, - Uint32 ArrayIndex, - D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle, - TViewTypeEnum dbgExpectedViewType, - TBindSamplerProcType BindSamplerProc) const; - - void CacheSampler(IDeviceObject* pSampler, - ShaderResourceCacheD3D12::Resource& DstSam, - Uint32 ArrayIndex, - D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const; - }; - - void CopyStaticResourceDesriptorHandles(const ShaderResourceCacheD3D12& SrcCache, - const ShaderResourceLayoutD3D12& DstLayout, - ShaderResourceCacheD3D12& DstCache) const; - -#ifdef DEVELOPMENT - bool dvpVerifyBindings(const ShaderResourceCacheD3D12& ResourceCache) const; -#endif - - IObject& GetOwner() - { - return m_Owner; - } - - Uint32 GetCbvSrvUavCount(SHADER_RESOURCE_VARIABLE_TYPE VarType) const - { - return m_CbvSrvUavOffsets[VarType + 1] - m_CbvSrvUavOffsets[VarType]; - } - Uint32 GetSamplerCount(SHADER_RESOURCE_VARIABLE_TYPE VarType) const - { - return m_SamplersOffsets[VarType + 1] - m_SamplersOffsets[VarType]; - } - - const D3D12Resource& GetSrvCbvUav(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const - { - VERIFY_EXPR(r < GetCbvSrvUavCount(VarType)); - return GetResource(GetSrvCbvUavOffset(VarType, r)); - } - const D3D12Resource& GetSampler(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 s) const - { - VERIFY_EXPR(s < GetSamplerCount(VarType)); - return GetResource(GetSamplerOffset(VarType, s)); - } - - const bool IsUsingSeparateSamplers() const { return !m_pResources->IsUsingCombinedTextureSamplers(); } - - SHADER_TYPE GetShaderType() const { return m_pResources->GetShaderType(); } - -private: - const D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv) const; - D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv); - - const Char* GetShaderName() const - { - return m_pResources->GetShaderName(); - } - - - Uint32 GetTotalSrvCbvUavCount() const - { - VERIFY_EXPR(m_CbvSrvUavOffsets[0] == 0); - return m_CbvSrvUavOffsets[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; - } - Uint32 GetTotalSamplerCount() const - { - return m_SamplersOffsets[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES] - m_SamplersOffsets[0]; - } - Uint32 GetTotalResourceCount() const - { - return m_SamplersOffsets[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; - } - - D3D12Resource& GetResource(Uint32 r) - { - VERIFY_EXPR(r < GetTotalResourceCount()); - auto* Resource = reinterpret_cast(m_ResourceBuffer.get()); - return Resource[r]; - } - const D3D12Resource& GetResource(Uint32 r) const - { - VERIFY_EXPR(r < GetTotalResourceCount()); - auto* Resource = reinterpret_cast(m_ResourceBuffer.get()); - return Resource[r]; - } - - Uint32 GetSrvCbvUavOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const - { - Uint32 Offset = m_CbvSrvUavOffsets[VarType] + r; - VERIFY_EXPR(Offset < m_CbvSrvUavOffsets[VarType + 1]); - return Offset; - } - D3D12Resource& GetSrvCbvUav(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) - { - VERIFY_EXPR(r < GetCbvSrvUavCount(VarType)); - return GetResource(GetSrvCbvUavOffset(VarType, r)); - } - - Uint32 GetSamplerOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 s) const - { - auto Offset = m_SamplersOffsets[VarType] + s; - VERIFY_EXPR(Offset < m_SamplersOffsets[VarType + 1]); - return Offset; - } - D3D12Resource& GetSampler(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 s) - { - VERIFY_EXPR(s < GetSamplerCount(VarType)); - return GetResource(GetSamplerOffset(VarType, s)); - } - const D3D12Resource& GetSampler(Uint32 s) const - { - VERIFY_EXPR(s < GetTotalSamplerCount()); - return GetResource(m_SamplersOffsets[0] + s); - } - - void AllocateMemory(IMemoryAllocator& Allocator, - const std::array& CbvSrvUavCount, - const std::array& SamplerCount); - // clang-format off - -/* 0 */ std::unique_ptr > m_ResourceBuffer; -/* 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; -/* 64 */ // End of data - - // clang-format on -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp new file mode 100644 index 00000000..56889271 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -0,0 +1,360 @@ +/* + * 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::ShaderResourceLayoutD3D12 class + +// http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout/ + +// All resources are stored in a single continuous chunk of memory using the following layout: +// +// m_ResourceBuffer +// | | | +// | D3D12Resource[0] ... | D3D12Resource[s] ... | D3D12Resource[s+m] ... | D3D12Resource[smd] ... | D3D12Resource[smd+s'] ... | D3D12Resource[smd+s'+m'] ... D3D12Resource[s+m+d+s'+m'+d'-1] || +// | | | | | | || +// | SRV/CBV/UAV - STATIC | SRV/CBV/UAV - MUTABLE | SRV/CBV/UAV - DYNAMIC | Samplers - STATIC | Samplers - MUTABLE | Samplers - DYNAMIC || +// | | | | +// +// s == NumCbvSrvUav[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] +// m == NumCbvSrvUav[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] +// d == NumCbvSrvUav[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] +// smd = s+m+d +// +// s' == NumSamplers[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] +// 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] | ... | +// |___________________________| |__________________|__________________|_______________|____________________|______________________|__________| +// A A | A A +// | \ |______________\____SamplerId________________________| +// | \ \ +// | Ref Ref +// | \ \_____ +// | \ \ +// ____________|_______________ ________\_______________________\__________________________________________ +// | | | | | | +// | ShaderVariableManagerD3D12 |---------------->| ShaderVariableD3D12Impl[0] | ShaderVariableD3D12Impl[1] | ... | +// |____________________________| |____________________________|____________________________|_________________| + +// +// http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Figure2 +// Resources in the resource cache are identified by the root index and offset in the descriptor table +// +// +// ShaderResourceLayoutD3D12 is used as follows: +// * Every pipeline state object (PipelineStateD3D12Impl) maintains shader resource layout for every active shader stage +// ** These resource layouts are used as reference layouts for shader resource binding objects +// ** All variable types are preserved +// ** Root indices and descriptor table offsets are assigned during the initialization +// * Every pipeline state object also contains shader resource layout that facilitates management of static shader resources +// ** The resource layout defines artificial layout where root index matches the resource type (CBV/SRV/UAV/SAM) +// ** Only static variables are referenced +// +// * Every shader resource binding object (ShaderResourceBindingD3D12Impl) encompasses shader variable +// manager (ShaderVariableManagerD3D12) for every active shader stage in the parent pipeline state that +// handles mutable and dynamic resources + +#include + +#include "ShaderBase.hpp" +#include "ShaderResourcesD3D12.hpp" +#include "ShaderResourceCacheD3D12.hpp" + +namespace Diligent +{ + +/// Diligent::ShaderResourceLayoutD3D12 class +// sizeof(ShaderResourceLayoutD3D12) == 64 (MS compiler, x64) +class ShaderResourceLayoutD3D12 final +{ +public: + // There are two modes a layout can be constructed: + // - initialize static resource layout and initialize shader resource cache to hold static resources + // - 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 + ShaderResourceLayoutD3D12(IObject& Owner, + ID3D12Device* pd3d12Device, + const PipelineResourceLayoutDesc& ResourceLayout, + std::shared_ptr pSrcResources, + IMemoryAllocator& LayoutDataAllocator, + const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheD3D12* pResourceCache, + class RootSignature* pRootSig); + + // clang-format off + ShaderResourceLayoutD3D12 (const ShaderResourceLayoutD3D12&) = delete; + ShaderResourceLayoutD3D12 (ShaderResourceLayoutD3D12&&) = delete; + ShaderResourceLayoutD3D12& operator =(const ShaderResourceLayoutD3D12&) = delete; + ShaderResourceLayoutD3D12& operator =(ShaderResourceLayoutD3D12&&) = delete; + // clang-format on + + ~ShaderResourceLayoutD3D12(); + + // sizeof(D3D12Resource) == 24 (x64) + struct D3D12Resource final + { + // clang-format off + + D3D12Resource (const D3D12Resource&) = delete; + D3D12Resource ( D3D12Resource&&) = delete; + D3D12Resource& operator = (const D3D12Resource&) = delete; + D3D12Resource& operator = ( D3D12Resource&&) = delete; + + static constexpr const Uint32 ResourceTypeBits = 3; + static constexpr const Uint32 VariableTypeBits = 2; + static constexpr const Uint32 RootIndexBits = 16 - ResourceTypeBits - VariableTypeBits; + + static constexpr const Uint32 InvalidRootIndex = (1 << RootIndexBits) - 1; + static constexpr const Uint32 MaxRootIndex = InvalidRootIndex - 1; + + 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"); + +/* 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 + + // clang-format on + + D3D12Resource(const ShaderResourceLayoutD3D12& _ParentLayout, + const D3DShaderResourceAttribs& _Attribs, + SHADER_RESOURCE_VARIABLE_TYPE _VariableType, + CachedResourceType _ResType, + Uint32 _RootIndex, + Uint32 _OffsetFromTableStart, + Uint32 _SamplerId) 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 } + // clang-format on + { + 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(_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"); + } + + bool IsBound(Uint32 ArrayIndex, + const ShaderResourceCacheD3D12& ResourceCache) const; + + void BindResource(IDeviceObject* pObject, + Uint32 ArrayIndex, + ShaderResourceCacheD3D12& ResourceCache) const; + + // clang-format off + bool ValidSamplerAssigned()const { return SamplerId != InvalidSamplerId; } + 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); } + + private: + void CacheCB(IDeviceObject* pBuffer, + ShaderResourceCacheD3D12::Resource& DstRes, + Uint32 ArrayInd, + D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle, + Uint32& BoundDynamicCBsCounter) const; + + template + void CacheResourceView(IDeviceObject* pView, + ShaderResourceCacheD3D12::Resource& DstRes, + Uint32 ArrayIndex, + D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle, + TViewTypeEnum dbgExpectedViewType, + TBindSamplerProcType BindSamplerProc) const; + + void CacheSampler(IDeviceObject* pSampler, + ShaderResourceCacheD3D12::Resource& DstSam, + Uint32 ArrayIndex, + D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const; + }; + + void CopyStaticResourceDesriptorHandles(const ShaderResourceCacheD3D12& SrcCache, + const ShaderResourceLayoutD3D12& DstLayout, + ShaderResourceCacheD3D12& DstCache) const; + +#ifdef DEVELOPMENT + bool dvpVerifyBindings(const ShaderResourceCacheD3D12& ResourceCache) const; +#endif + + IObject& GetOwner() + { + return m_Owner; + } + + Uint32 GetCbvSrvUavCount(SHADER_RESOURCE_VARIABLE_TYPE VarType) const + { + return m_CbvSrvUavOffsets[VarType + 1] - m_CbvSrvUavOffsets[VarType]; + } + Uint32 GetSamplerCount(SHADER_RESOURCE_VARIABLE_TYPE VarType) const + { + return m_SamplersOffsets[VarType + 1] - m_SamplersOffsets[VarType]; + } + + const D3D12Resource& GetSrvCbvUav(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const + { + VERIFY_EXPR(r < GetCbvSrvUavCount(VarType)); + return GetResource(GetSrvCbvUavOffset(VarType, r)); + } + const D3D12Resource& GetSampler(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 s) const + { + VERIFY_EXPR(s < GetSamplerCount(VarType)); + return GetResource(GetSamplerOffset(VarType, s)); + } + + const bool IsUsingSeparateSamplers() const { return !m_pResources->IsUsingCombinedTextureSamplers(); } + + SHADER_TYPE GetShaderType() const { return m_pResources->GetShaderType(); } + +private: + const D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv) const; + D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv); + + const Char* GetShaderName() const + { + return m_pResources->GetShaderName(); + } + + + Uint32 GetTotalSrvCbvUavCount() const + { + VERIFY_EXPR(m_CbvSrvUavOffsets[0] == 0); + return m_CbvSrvUavOffsets[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; + } + Uint32 GetTotalSamplerCount() const + { + return m_SamplersOffsets[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES] - m_SamplersOffsets[0]; + } + Uint32 GetTotalResourceCount() const + { + return m_SamplersOffsets[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; + } + + D3D12Resource& GetResource(Uint32 r) + { + VERIFY_EXPR(r < GetTotalResourceCount()); + auto* Resource = reinterpret_cast(m_ResourceBuffer.get()); + return Resource[r]; + } + const D3D12Resource& GetResource(Uint32 r) const + { + VERIFY_EXPR(r < GetTotalResourceCount()); + auto* Resource = reinterpret_cast(m_ResourceBuffer.get()); + return Resource[r]; + } + + Uint32 GetSrvCbvUavOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const + { + Uint32 Offset = m_CbvSrvUavOffsets[VarType] + r; + VERIFY_EXPR(Offset < m_CbvSrvUavOffsets[VarType + 1]); + return Offset; + } + D3D12Resource& GetSrvCbvUav(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) + { + VERIFY_EXPR(r < GetCbvSrvUavCount(VarType)); + return GetResource(GetSrvCbvUavOffset(VarType, r)); + } + + Uint32 GetSamplerOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 s) const + { + auto Offset = m_SamplersOffsets[VarType] + s; + VERIFY_EXPR(Offset < m_SamplersOffsets[VarType + 1]); + return Offset; + } + D3D12Resource& GetSampler(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 s) + { + VERIFY_EXPR(s < GetSamplerCount(VarType)); + return GetResource(GetSamplerOffset(VarType, s)); + } + const D3D12Resource& GetSampler(Uint32 s) const + { + VERIFY_EXPR(s < GetTotalSamplerCount()); + return GetResource(m_SamplersOffsets[0] + s); + } + + void AllocateMemory(IMemoryAllocator& Allocator, + const std::array& CbvSrvUavCount, + const std::array& SamplerCount); + // clang-format off + +/* 0 */ std::unique_ptr > m_ResourceBuffer; +/* 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; +/* 64 */ // End of data + + // clang-format on +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.h deleted file mode 100644 index e9672d10..00000000 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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::ShaderResourcesD3D12 class - -// ShaderResourcesD3D12 are created by ShaderD3D12Impl instances. They are then referenced by ShaderResourceLayoutD3D12 objects, which are in turn -// created by instances of PipelineStatesD3D12Impl and ShaderD3D12Impl -// -// _________________ -// | | -// | ShaderD3D12Impl | -// |_________________| -// | -// |shared_ptr -// ________V_____________ _____________________________________________________________________ -// | | unique_ptr | | | | | | | -// | ShaderResourcesD3D12 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | -// |______________________| |________|___________|___________|___________|___________|____________| -// A A A A -// | \ / \ -// |shared_ptr Ref Ref Ref -// ________|__________________ ________\________________________/_________________________\_________________________________________ -// | | unique_ptr | | | | | | | -// | ShaderResourceLayoutD3D12 |--------------->| SRV_CBV_UAV[0] | SRV_CBV_UAV[1] | ... | Sampler[0] | Sampler[1] | ... | -// |___________________________| |___________________|_________________|_______________|__________________|_________________|__________| -// A | A -// | |___________________SamplerId________________________| -// | -// __________|_____________ -// | | -// | 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.h" - -namespace Diligent -{ - -/// Diligent::ShaderResourcesD3D12 class -class ShaderResourcesD3D12 final : public ShaderResources -{ -public: - // Loads shader resources from the compiled shader bytecode - ShaderResourcesD3D12(ID3DBlob* pShaderBytecode, const ShaderDesc& ShdrDesc, const char* CombinedSamplerSuffix); - - // clang-format off - ShaderResourcesD3D12 (const ShaderResourcesD3D12&) = delete; - ShaderResourcesD3D12 ( ShaderResourcesD3D12&&) = delete; - ShaderResourcesD3D12& operator = (const ShaderResourcesD3D12&) = delete; - ShaderResourcesD3D12& operator = ( ShaderResourcesD3D12&&) = delete; - // clang-format on -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp new file mode 100644 index 00000000..23f9882b --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp @@ -0,0 +1,105 @@ +/* + * 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::ShaderResourcesD3D12 class + +// ShaderResourcesD3D12 are created by ShaderD3D12Impl instances. They are then referenced by ShaderResourceLayoutD3D12 objects, which are in turn +// created by instances of PipelineStatesD3D12Impl and ShaderD3D12Impl +// +// _________________ +// | | +// | ShaderD3D12Impl | +// |_________________| +// | +// |shared_ptr +// ________V_____________ _____________________________________________________________________ +// | | unique_ptr | | | | | | | +// | ShaderResourcesD3D12 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | +// |______________________| |________|___________|___________|___________|___________|____________| +// A A A A +// | \ / \ +// |shared_ptr Ref Ref Ref +// ________|__________________ ________\________________________/_________________________\_________________________________________ +// | | unique_ptr | | | | | | | +// | ShaderResourceLayoutD3D12 |--------------->| SRV_CBV_UAV[0] | SRV_CBV_UAV[1] | ... | Sampler[0] | Sampler[1] | ... | +// |___________________________| |___________________|_________________|_______________|__________________|_________________|__________| +// A | A +// | |___________________SamplerId________________________| +// | +// __________|_____________ +// | | +// | 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" + +namespace Diligent +{ + +/// Diligent::ShaderResourcesD3D12 class +class ShaderResourcesD3D12 final : public ShaderResources +{ +public: + // Loads shader resources from the compiled shader bytecode + ShaderResourcesD3D12(ID3DBlob* pShaderBytecode, const ShaderDesc& ShdrDesc, const char* CombinedSamplerSuffix); + + // clang-format off + ShaderResourcesD3D12 (const ShaderResourcesD3D12&) = delete; + ShaderResourcesD3D12 ( ShaderResourcesD3D12&&) = delete; + ShaderResourcesD3D12& operator = (const ShaderResourcesD3D12&) = delete; + ShaderResourcesD3D12& operator = ( ShaderResourcesD3D12&&) = delete; + // clang-format on +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.h deleted file mode 100644 index f7a1f8c8..00000000 --- a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * 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::ShaderVariableManagerD3D12 and Diligent::ShaderVariableD3D12Impl classes - -// -// * ShaderVariableManagerD3D12 keeps list of variables of specific types -// * Every ShaderVariableD3D12Impl references D3D12Resource from ShaderResourceLayoutD3D12 -// * ShaderVariableManagerD3D12 keeps pointer to ShaderResourceCacheD3D12 -// * ShaderVariableManagerD3D12 is used by PipelineStateD3D12Impl to manage static resources and by -// ShaderResourceBindingD3D12Impl to manage mutable and dynamic resources -// -// _____________________________ ________________________________________________________________________________ -// | | | | | | -// .----| ShaderVariableManagerD3D12 |---------------->| ShaderVariableD3D12Impl[0] | ShaderVariableD3D12Impl[1] | ... | -// | |_____________________________| |______________________________|_______________________________|_________________| -// | | \ | -// | | Ref Ref -// | | \ | -// | ___________V_______________ ______________________V_______________________V_____________________________ -// | | | unique_ptr | | | | | -// | | ShaderResourceLayoutD3D12 |--------------->| D3D12Resource[0] | D3D12Resource[1] | ... | D3D12Resource[s+m+d-1] | -// | |___________________________| |__________________|__________________|_____________|________________________| -// | | | -// | | | -// | | (RootTable, Offset) / (RootTable, Offset) -// | \ / -// | __________________________ ________V_______________________________________________________V_______ -// | | | | | -// '--->| ShaderResourceCacheD3D12 |---------------->| Resources | -// |__________________________| |________________________________________________________________________| -// -// Memory buffer is allocated through the allocator provided by the pipeline state. If allocation granularity > 1, fixed block -// memory allocator is used. This ensures that all resources from different shader resource bindings reside in -// continuous memory. If allocation granularity == 1, raw allocator is used. - -#include - -#include "ShaderResourceVariableD3D.h" -#include "ShaderResourceLayoutD3D12.h" -#include "ShaderResourceVariableBase.h" - -namespace Diligent -{ - -class ShaderVariableD3D12Impl; - -// sizeof(ShaderVariableManagerD3D12) == 32 (x64, msvc, Release) -class ShaderVariableManagerD3D12 -{ -public: - ShaderVariableManagerD3D12(IObject& Owner, - const ShaderResourceLayoutD3D12& Layout, - IMemoryAllocator& Allocator, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheD3D12& ResourceCache); - ~ShaderVariableManagerD3D12(); - - void Destroy(IMemoryAllocator& Allocator); - - ShaderVariableD3D12Impl* GetVariable(const Char* Name); - ShaderVariableD3D12Impl* GetVariable(Uint32 Index); - - void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags); - - static size_t GetRequiredMemorySize(const ShaderResourceLayoutD3D12& Layout, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - Uint32& NumVariables); - - Uint32 GetVariableCount() const { return m_NumVariables; } - -private: - friend ShaderVariableD3D12Impl; - - Uint32 GetVariableIndex(const ShaderVariableD3D12Impl& Variable); - - // clang-format off - - IObject& m_Owner; - - // Variable mgr is owned by either Pipeline state object (in which case m_ResourceCache references - // static resource cache owned by the same PSO object), or by SRB object (in which case - // m_ResourceCache references the cache in the SRB). Thus the cache and the resource layout - // (which the variables reference) are guaranteed to be alive while the manager is alive. - ShaderResourceCacheD3D12& m_ResourceCache; - - // Memory is allocated through the allocator provided by the pipeline state. If allocation granularity > 1, fixed block - // memory allocator is used. This ensures that all resources from different shader resource bindings reside in - // continuous memory. If allocation granularity == 1, raw allocator is used. - ShaderVariableD3D12Impl* m_pVariables = nullptr; - Uint32 m_NumVariables = 0; - -#ifdef _DEBUG - IMemoryAllocator& m_DbgAllocator; -#endif - // clang-format on -}; - -// sizeof(ShaderVariableD3D12Impl) == 24 (x64) -class ShaderVariableD3D12Impl final : public IShaderResourceVariableD3D -{ -public: - ShaderVariableD3D12Impl(ShaderVariableManagerD3D12& ParentManager, - const ShaderResourceLayoutD3D12::D3D12Resource& Resource) : - m_ParentManager{ParentManager}, - m_Resource{Resource} - {} - - // clang-format off - ShaderVariableD3D12Impl (const ShaderVariableD3D12Impl&) = delete; - ShaderVariableD3D12Impl (ShaderVariableD3D12Impl&&) = delete; - ShaderVariableD3D12Impl& operator= (const ShaderVariableD3D12Impl&) = delete; - ShaderVariableD3D12Impl& operator= (ShaderVariableD3D12Impl&&) = delete; - // clang-format on - - virtual IReferenceCounters* GetReferenceCounters() const override final - { - return m_ParentManager.m_Owner.GetReferenceCounters(); - } - - virtual Atomics::Long AddRef() override final - { - return m_ParentManager.m_Owner.AddRef(); - } - - virtual Atomics::Long Release() override final - { - return m_ParentManager.m_Owner.Release(); - } - - void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final - { - if (ppInterface == nullptr) - return; - - *ppInterface = nullptr; - if (IID == IID_ShaderResourceVariableD3D || IID == IID_ShaderResourceVariable || IID == IID_Unknown) - { - *ppInterface = this; - (*ppInterface)->AddRef(); - } - } - - virtual SHADER_RESOURCE_VARIABLE_TYPE GetType() const override final - { - return m_Resource.GetVariableType(); - } - - virtual void Set(IDeviceObject* pObject) override final - { - m_Resource.BindResource(pObject, 0, m_ParentManager.m_ResourceCache); - } - - virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final - { - 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); - } - - virtual void GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final - { - ResourceDesc = GetHLSLResourceDesc(); - } - - virtual HLSLShaderResourceDesc GetHLSLResourceDesc() const override final - { - return m_Resource.Attribs.GetHLSLResourceDesc(); - } - - virtual Uint32 GetIndex() const override final - { - return m_ParentManager.GetVariableIndex(*this); - } - - virtual bool IsBound(Uint32 ArrayIndex) const override final - { - return m_Resource.IsBound(ArrayIndex, m_ParentManager.m_ResourceCache); - } - - const ShaderResourceLayoutD3D12::D3D12Resource& GetResource() const - { - return m_Resource; - } - -private: - friend ShaderVariableManagerD3D12; - - ShaderVariableManagerD3D12& m_ParentManager; - const ShaderResourceLayoutD3D12::D3D12Resource& m_Resource; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp new file mode 100644 index 00000000..749de7f2 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp @@ -0,0 +1,222 @@ +/* + * 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::ShaderVariableManagerD3D12 and Diligent::ShaderVariableD3D12Impl classes + +// +// * ShaderVariableManagerD3D12 keeps list of variables of specific types +// * Every ShaderVariableD3D12Impl references D3D12Resource from ShaderResourceLayoutD3D12 +// * ShaderVariableManagerD3D12 keeps pointer to ShaderResourceCacheD3D12 +// * ShaderVariableManagerD3D12 is used by PipelineStateD3D12Impl to manage static resources and by +// ShaderResourceBindingD3D12Impl to manage mutable and dynamic resources +// +// _____________________________ ________________________________________________________________________________ +// | | | | | | +// .----| ShaderVariableManagerD3D12 |---------------->| ShaderVariableD3D12Impl[0] | ShaderVariableD3D12Impl[1] | ... | +// | |_____________________________| |______________________________|_______________________________|_________________| +// | | \ | +// | | Ref Ref +// | | \ | +// | ___________V_______________ ______________________V_______________________V_____________________________ +// | | | unique_ptr | | | | | +// | | ShaderResourceLayoutD3D12 |--------------->| D3D12Resource[0] | D3D12Resource[1] | ... | D3D12Resource[s+m+d-1] | +// | |___________________________| |__________________|__________________|_____________|________________________| +// | | | +// | | | +// | | (RootTable, Offset) / (RootTable, Offset) +// | \ / +// | __________________________ ________V_______________________________________________________V_______ +// | | | | | +// '--->| ShaderResourceCacheD3D12 |---------------->| Resources | +// |__________________________| |________________________________________________________________________| +// +// Memory buffer is allocated through the allocator provided by the pipeline state. If allocation granularity > 1, fixed block +// memory allocator is used. This ensures that all resources from different shader resource bindings reside in +// continuous memory. If allocation granularity == 1, raw allocator is used. + +#include + +#include "ShaderResourceVariableD3D.h" +#include "ShaderResourceLayoutD3D12.hpp" +#include "ShaderResourceVariableBase.hpp" + +namespace Diligent +{ + +class ShaderVariableD3D12Impl; + +// sizeof(ShaderVariableManagerD3D12) == 32 (x64, msvc, Release) +class ShaderVariableManagerD3D12 +{ +public: + ShaderVariableManagerD3D12(IObject& Owner, + const ShaderResourceLayoutD3D12& Layout, + IMemoryAllocator& Allocator, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheD3D12& ResourceCache); + ~ShaderVariableManagerD3D12(); + + void Destroy(IMemoryAllocator& Allocator); + + ShaderVariableD3D12Impl* GetVariable(const Char* Name); + ShaderVariableD3D12Impl* GetVariable(Uint32 Index); + + void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags); + + static size_t GetRequiredMemorySize(const ShaderResourceLayoutD3D12& Layout, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + Uint32& NumVariables); + + Uint32 GetVariableCount() const { return m_NumVariables; } + +private: + friend ShaderVariableD3D12Impl; + + Uint32 GetVariableIndex(const ShaderVariableD3D12Impl& Variable); + + // clang-format off + + IObject& m_Owner; + + // Variable mgr is owned by either Pipeline state object (in which case m_ResourceCache references + // static resource cache owned by the same PSO object), or by SRB object (in which case + // m_ResourceCache references the cache in the SRB). Thus the cache and the resource layout + // (which the variables reference) are guaranteed to be alive while the manager is alive. + ShaderResourceCacheD3D12& m_ResourceCache; + + // Memory is allocated through the allocator provided by the pipeline state. If allocation granularity > 1, fixed block + // memory allocator is used. This ensures that all resources from different shader resource bindings reside in + // continuous memory. If allocation granularity == 1, raw allocator is used. + ShaderVariableD3D12Impl* m_pVariables = nullptr; + Uint32 m_NumVariables = 0; + +#ifdef _DEBUG + IMemoryAllocator& m_DbgAllocator; +#endif + // clang-format on +}; + +// sizeof(ShaderVariableD3D12Impl) == 24 (x64) +class ShaderVariableD3D12Impl final : public IShaderResourceVariableD3D +{ +public: + ShaderVariableD3D12Impl(ShaderVariableManagerD3D12& ParentManager, + const ShaderResourceLayoutD3D12::D3D12Resource& Resource) : + m_ParentManager{ParentManager}, + m_Resource{Resource} + {} + + // clang-format off + ShaderVariableD3D12Impl (const ShaderVariableD3D12Impl&) = delete; + ShaderVariableD3D12Impl (ShaderVariableD3D12Impl&&) = delete; + ShaderVariableD3D12Impl& operator= (const ShaderVariableD3D12Impl&) = delete; + ShaderVariableD3D12Impl& operator= (ShaderVariableD3D12Impl&&) = delete; + // clang-format on + + virtual IReferenceCounters* GetReferenceCounters() const override final + { + return m_ParentManager.m_Owner.GetReferenceCounters(); + } + + virtual Atomics::Long AddRef() override final + { + return m_ParentManager.m_Owner.AddRef(); + } + + virtual Atomics::Long Release() override final + { + return m_ParentManager.m_Owner.Release(); + } + + void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final + { + if (ppInterface == nullptr) + return; + + *ppInterface = nullptr; + if (IID == IID_ShaderResourceVariableD3D || IID == IID_ShaderResourceVariable || IID == IID_Unknown) + { + *ppInterface = this; + (*ppInterface)->AddRef(); + } + } + + virtual SHADER_RESOURCE_VARIABLE_TYPE GetType() const override final + { + return m_Resource.GetVariableType(); + } + + virtual void Set(IDeviceObject* pObject) override final + { + m_Resource.BindResource(pObject, 0, m_ParentManager.m_ResourceCache); + } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final + { + 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); + } + + virtual void GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final + { + ResourceDesc = GetHLSLResourceDesc(); + } + + virtual HLSLShaderResourceDesc GetHLSLResourceDesc() const override final + { + return m_Resource.Attribs.GetHLSLResourceDesc(); + } + + virtual Uint32 GetIndex() const override final + { + return m_ParentManager.GetVariableIndex(*this); + } + + virtual bool IsBound(Uint32 ArrayIndex) const override final + { + return m_Resource.IsBound(ArrayIndex, m_ParentManager.m_ResourceCache); + } + + const ShaderResourceLayoutD3D12::D3D12Resource& GetResource() const + { + return m_Resource; + } + +private: + friend ShaderVariableManagerD3D12; + + ShaderVariableManagerD3D12& m_ParentManager; + const ShaderResourceLayoutD3D12::D3D12Resource& m_Resource; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h deleted file mode 100644 index 1b833029..00000000 --- a/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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::SwapChainD3D12Impl class - -#include -#include "SwapChainD3D12.h" -#include "SwapChainD3DBase.h" - -namespace Diligent -{ - -class ITextureViewD3D12; -class IMemoryAllocator; - -/// Swap chain implementation in Direct3D12 backend. -class SwapChainD3D12Impl final : public SwapChainD3DBase -{ -public: - using TSwapChainBase = SwapChainD3DBase; - - SwapChainD3D12Impl(IReferenceCounters* pRefCounters, - const SwapChainDesc& SwapChainDesc, - const FullScreenModeDesc& FSDesc, - class RenderDeviceD3D12Impl* pRenderDeviceD3D12, - class DeviceContextD3D12Impl* pDeviceContextD3D12, - void* pNativeWndHandle); - ~SwapChainD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of ISwapChain::Present() in Direct3D12 backend. - virtual void Present(Uint32 SyncInterval) override final; - - /// Implementation of ISwapChain::Resize() in Direct3D12 backend. - virtual void Resize(Uint32 NewWidth, Uint32 NewHeight) override final; - - /// Implementation of ISwapChainD3D12::GetDXGISwapChain(). - virtual IDXGISwapChain* GetDXGISwapChain() override final { return m_pSwapChain; } - - /// Implementation of ISwapChain::GetCurrentBackBufferRTV() in Direct3D12 backend. - virtual ITextureViewD3D12* GetCurrentBackBufferRTV() override final - { - auto CurrentBackBufferIndex = m_pSwapChain->GetCurrentBackBufferIndex(); - VERIFY_EXPR(CurrentBackBufferIndex >= 0 && CurrentBackBufferIndex < m_SwapChainDesc.BufferCount); - return m_pBackBufferRTV[CurrentBackBufferIndex]; - } - - /// Implementation of ISwapChain::GetDepthBufferDSV() in Direct3D12 backend. - virtual ITextureViewD3D12* GetDepthBufferDSV() override final { return m_pDepthBufferDSV; } - -private: - virtual void UpdateSwapChain(bool CreateNew) override final; - void InitBuffersAndViews(); - - std::vector, STDAllocatorRawMem>> m_pBackBufferRTV; - RefCntAutoPtr m_pDepthBufferDSV; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.hpp new file mode 100644 index 00000000..0c45d915 --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/SwapChainD3D12Impl.hpp @@ -0,0 +1,87 @@ +/* + * 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::SwapChainD3D12Impl class + +#include +#include "SwapChainD3D12.h" +#include "SwapChainD3DBase.hpp" + +namespace Diligent +{ + +class ITextureViewD3D12; +class IMemoryAllocator; + +/// Swap chain implementation in Direct3D12 backend. +class SwapChainD3D12Impl final : public SwapChainD3DBase +{ +public: + using TSwapChainBase = SwapChainD3DBase; + + SwapChainD3D12Impl(IReferenceCounters* pRefCounters, + const SwapChainDesc& SwapChainDesc, + const FullScreenModeDesc& FSDesc, + class RenderDeviceD3D12Impl* pRenderDeviceD3D12, + class DeviceContextD3D12Impl* pDeviceContextD3D12, + void* pNativeWndHandle); + ~SwapChainD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of ISwapChain::Present() in Direct3D12 backend. + virtual void Present(Uint32 SyncInterval) override final; + + /// Implementation of ISwapChain::Resize() in Direct3D12 backend. + virtual void Resize(Uint32 NewWidth, Uint32 NewHeight) override final; + + /// Implementation of ISwapChainD3D12::GetDXGISwapChain(). + virtual IDXGISwapChain* GetDXGISwapChain() override final { return m_pSwapChain; } + + /// Implementation of ISwapChain::GetCurrentBackBufferRTV() in Direct3D12 backend. + virtual ITextureViewD3D12* GetCurrentBackBufferRTV() override final + { + auto CurrentBackBufferIndex = m_pSwapChain->GetCurrentBackBufferIndex(); + VERIFY_EXPR(CurrentBackBufferIndex >= 0 && CurrentBackBufferIndex < m_SwapChainDesc.BufferCount); + return m_pBackBufferRTV[CurrentBackBufferIndex]; + } + + /// Implementation of ISwapChain::GetDepthBufferDSV() in Direct3D12 backend. + virtual ITextureViewD3D12* GetDepthBufferDSV() override final { return m_pDepthBufferDSV; } + +private: + virtual void UpdateSwapChain(bool CreateNew) override final; + void InitBuffersAndViews(); + + std::vector, STDAllocatorRawMem>> m_pBackBufferRTV; + RefCntAutoPtr m_pDepthBufferDSV; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h deleted file mode 100644 index a4ab0b08..00000000 --- a/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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::TextureD3D12Impl class - -#include "TextureD3D12.h" -#include "RenderDeviceD3D12.h" -#include "TextureBase.h" -#include "TextureViewD3D12Impl.h" -#include "D3D12ResourceBase.h" -#include "RenderDeviceD3D12Impl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Implementation of a texture object in Direct3D12 backend. -class TextureD3D12Impl final : public TextureBase, public D3D12ResourceBase -{ -public: - using TTextureBase = TextureBase; - using ViewImplType = TextureViewD3D12Impl; - - // Creates a new D3D12 resource - TextureD3D12Impl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceD3D12Impl* pDeviceD3D12, - const TextureDesc& TexDesc, - const TextureData* pInitData = nullptr); - - // Attaches to an existing D3D12 resource - TextureD3D12Impl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceD3D12Impl* pDeviceD3D12, - const TextureDesc& TexDesc, - RESOURCE_STATE InitialState, - ID3D12Resource* pTexture); - ~TextureD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of ITextureD3D12::GetD3D12Texture(). - virtual ID3D12Resource* GetD3D12Texture() override final { return GetD3D12Resource(); } - - /// Implementation of ITexture::GetNativeHandle() in Direct3D12 backend. - virtual void* GetNativeHandle() override final { return GetD3D12Texture(); } - - /// Implementation of ITextureD3D12::SetD3D12ResourceState(). - virtual void SetD3D12ResourceState(D3D12_RESOURCE_STATES state) override final; - - /// Implementation of ITextureD3D12::GetD3D12ResourceState(). - virtual D3D12_RESOURCE_STATES GetD3D12ResourceState() const override final; - - D3D12_RESOURCE_DESC GetD3D12TextureDesc() const; - - const D3D12_PLACED_SUBRESOURCE_FOOTPRINT& GetStagingFootprint(Uint32 Subresource) - { - VERIFY_EXPR(m_StagingFootprints != nullptr); - VERIFY_EXPR(Subresource <= (Uint32{m_Desc.MipLevels} * (m_Desc.Type == RESOURCE_DIM_TEX_3D ? 1 : Uint32{m_Desc.ArraySize}))); - return m_StagingFootprints[Subresource]; - } - -protected: - void CreateViewInternal(const struct TextureViewDesc& ViewDesc, ITextureView** ppView, bool bIsDefaultView) override final; - //void PrepareD3D12InitData(const TextureData &InitData, Uint32 NumSubresources, std::vector &D3D12InitData); - - void CreateSRV(TextureViewDesc& SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVHandle); - void CreateRTV(TextureViewDesc& RTVDesc, D3D12_CPU_DESCRIPTOR_HANDLE RTVHandle); - void CreateDSV(TextureViewDesc& DSVDesc, D3D12_CPU_DESCRIPTOR_HANDLE DSVHandle); - void CreateUAV(TextureViewDesc& UAVDesc, D3D12_CPU_DESCRIPTOR_HANDLE UAVHandle); - - D3D12_PLACED_SUBRESOURCE_FOOTPRINT* m_StagingFootprints = nullptr; - - friend class RenderDeviceD3D12Impl; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.hpp new file mode 100644 index 00000000..7c1c041b --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/TextureD3D12Impl.hpp @@ -0,0 +1,105 @@ +/* + * 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::TextureD3D12Impl class + +#include "TextureD3D12.h" +#include "RenderDeviceD3D12.h" +#include "TextureBase.hpp" +#include "TextureViewD3D12Impl.hpp" +#include "D3D12ResourceBase.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Implementation of a texture object in Direct3D12 backend. +class TextureD3D12Impl final : public TextureBase, public D3D12ResourceBase +{ +public: + using TTextureBase = TextureBase; + using ViewImplType = TextureViewD3D12Impl; + + // Creates a new D3D12 resource + TextureD3D12Impl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceD3D12Impl* pDeviceD3D12, + const TextureDesc& TexDesc, + const TextureData* pInitData = nullptr); + + // Attaches to an existing D3D12 resource + TextureD3D12Impl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceD3D12Impl* pDeviceD3D12, + const TextureDesc& TexDesc, + RESOURCE_STATE InitialState, + ID3D12Resource* pTexture); + ~TextureD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of ITextureD3D12::GetD3D12Texture(). + virtual ID3D12Resource* GetD3D12Texture() override final { return GetD3D12Resource(); } + + /// Implementation of ITexture::GetNativeHandle() in Direct3D12 backend. + virtual void* GetNativeHandle() override final { return GetD3D12Texture(); } + + /// Implementation of ITextureD3D12::SetD3D12ResourceState(). + virtual void SetD3D12ResourceState(D3D12_RESOURCE_STATES state) override final; + + /// Implementation of ITextureD3D12::GetD3D12ResourceState(). + virtual D3D12_RESOURCE_STATES GetD3D12ResourceState() const override final; + + D3D12_RESOURCE_DESC GetD3D12TextureDesc() const; + + const D3D12_PLACED_SUBRESOURCE_FOOTPRINT& GetStagingFootprint(Uint32 Subresource) + { + VERIFY_EXPR(m_StagingFootprints != nullptr); + VERIFY_EXPR(Subresource <= (Uint32{m_Desc.MipLevels} * (m_Desc.Type == RESOURCE_DIM_TEX_3D ? 1 : Uint32{m_Desc.ArraySize}))); + return m_StagingFootprints[Subresource]; + } + +protected: + void CreateViewInternal(const struct TextureViewDesc& ViewDesc, ITextureView** ppView, bool bIsDefaultView) override final; + //void PrepareD3D12InitData(const TextureData &InitData, Uint32 NumSubresources, std::vector &D3D12InitData); + + void CreateSRV(TextureViewDesc& SRVDesc, D3D12_CPU_DESCRIPTOR_HANDLE SRVHandle); + void CreateRTV(TextureViewDesc& RTVDesc, D3D12_CPU_DESCRIPTOR_HANDLE RTVHandle); + void CreateDSV(TextureViewDesc& DSVDesc, D3D12_CPU_DESCRIPTOR_HANDLE DSVHandle); + void CreateUAV(TextureViewDesc& UAVDesc, D3D12_CPU_DESCRIPTOR_HANDLE UAVHandle); + + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* m_StagingFootprints = nullptr; + + friend class RenderDeviceD3D12Impl; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.h deleted file mode 100644 index fb8b7499..00000000 --- a/Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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::TextureViewD3D12Impl class - -#include "TextureViewD3D12.h" -#include "RenderDeviceD3D12.h" -#include "TextureViewBase.h" -#include "DescriptorHeap.h" -#include "RenderDeviceD3D12Impl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Texture view object implementation in Direct3D12 backend. -class TextureViewD3D12Impl final : public TextureViewBase -{ -public: - using TTextureViewBase = TextureViewBase; - - TextureViewD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pDevice, - const TextureViewDesc& ViewDesc, - class ITexture* pTexture, - DescriptorHeapAllocation&& Descriptor, - DescriptorHeapAllocation&& TexArraySRVDescriptor, - DescriptorHeapAllocation&& MipLevelUAVDescriptors, - bool bIsDefaultView); - ~TextureViewD3D12Impl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of ITextureViewD3D12::GetCPUDescriptorHandle(). - virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() override final - { - return m_Descriptor.GetCpuHandle(); - } - - D3D12_CPU_DESCRIPTOR_HANDLE GetMipLevelUAV(Uint32 Mip) - { - VERIFY_EXPR((m_Desc.Flags & TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION) != 0 && m_MipGenerationDescriptors != nullptr && Mip < m_Desc.NumMipLevels); - return m_MipGenerationDescriptors[1].GetCpuHandle(Mip); - } - - D3D12_CPU_DESCRIPTOR_HANDLE GetTexArraySRV() - { - VERIFY_EXPR((m_Desc.Flags & TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION) != 0 && m_MipGenerationDescriptors != nullptr); - return m_MipGenerationDescriptors[0].GetCpuHandle(); - } - -protected: - /// D3D12 view descriptor handle - DescriptorHeapAllocation m_Descriptor; - - // Extra descriptors used for mipmap generation - // [0] == texture array SRV used for mipmap generation - // [1] == mip level UAVs used for mipmap generation - DescriptorHeapAllocation* m_MipGenerationDescriptors = nullptr; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.hpp new file mode 100644 index 00000000..2c2529ae --- /dev/null +++ b/Graphics/GraphicsEngineD3D12/include/TextureViewD3D12Impl.hpp @@ -0,0 +1,90 @@ +/* + * 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::TextureViewD3D12Impl class + +#include "TextureViewD3D12.h" +#include "RenderDeviceD3D12.h" +#include "TextureViewBase.hpp" +#include "DescriptorHeap.hpp" +#include "RenderDeviceD3D12Impl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Texture view object implementation in Direct3D12 backend. +class TextureViewD3D12Impl final : public TextureViewBase +{ +public: + using TTextureViewBase = TextureViewBase; + + TextureViewD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + const TextureViewDesc& ViewDesc, + class ITexture* pTexture, + DescriptorHeapAllocation&& Descriptor, + DescriptorHeapAllocation&& TexArraySRVDescriptor, + DescriptorHeapAllocation&& MipLevelUAVDescriptors, + bool bIsDefaultView); + ~TextureViewD3D12Impl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of ITextureViewD3D12::GetCPUDescriptorHandle(). + virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() override final + { + return m_Descriptor.GetCpuHandle(); + } + + D3D12_CPU_DESCRIPTOR_HANDLE GetMipLevelUAV(Uint32 Mip) + { + VERIFY_EXPR((m_Desc.Flags & TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION) != 0 && m_MipGenerationDescriptors != nullptr && Mip < m_Desc.NumMipLevels); + return m_MipGenerationDescriptors[1].GetCpuHandle(Mip); + } + + D3D12_CPU_DESCRIPTOR_HANDLE GetTexArraySRV() + { + VERIFY_EXPR((m_Desc.Flags & TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION) != 0 && m_MipGenerationDescriptors != nullptr); + return m_MipGenerationDescriptors[0].GetCpuHandle(); + } + +protected: + /// D3D12 view descriptor handle + DescriptorHeapAllocation m_Descriptor; + + // Extra descriptors used for mipmap generation + // [0] == texture array SRV used for mipmap generation + // [1] == mip level UAVs used for mipmap generation + DescriptorHeapAllocation* m_MipGenerationDescriptors = nullptr; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/include/pch.h b/Graphics/GraphicsEngineD3D12/include/pch.h index 101ffbdf..1554e6f6 100644 --- a/Graphics/GraphicsEngineD3D12/include/pch.h +++ b/Graphics/GraphicsEngineD3D12/include/pch.h @@ -50,13 +50,13 @@ #include "Errors.h" #include "RefCntAutoPtr.h" #include "DebugUtilities.h" -#include "D3DErrors.h" -#include "RenderDeviceBase.h" +#include "D3DErrors.hpp" +#include "RenderDeviceBase.hpp" #include "ValidatedCast.h" #include #if USE_D3D12_LOADER // On Win32 we manually load d3d12.dll and get entry points, // but UWP does not support that, so we link with d3d12.lib -# include "D3D12Loader.h" +# include "D3D12Loader.hpp" #endif diff --git a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp index dc23ff41..876a8bac 100644 --- a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp @@ -26,11 +26,11 @@ */ #include "pch.h" -#include "BufferD3D12Impl.h" -#include "RenderDeviceD3D12Impl.h" -#include "DeviceContextD3D12Impl.h" +#include "BufferD3D12Impl.hpp" +#include "RenderDeviceD3D12Impl.hpp" +#include "DeviceContextD3D12Impl.hpp" #include "D3D12TypeConversions.h" -#include "BufferViewD3D12Impl.h" +#include "BufferViewD3D12Impl.hpp" #include "GraphicsAccessories.hpp" #include "DXGITypeConversions.h" #include "EngineMemory.h" diff --git a/Graphics/GraphicsEngineD3D12/src/BufferViewD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferViewD3D12Impl.cpp index 1b394931..731d4da2 100644 --- a/Graphics/GraphicsEngineD3D12/src/BufferViewD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BufferViewD3D12Impl.cpp @@ -26,7 +26,7 @@ */ #include "pch.h" -#include "BufferViewD3D12Impl.h" +#include "BufferViewD3D12Impl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp index 2dbb5190..ebc46582 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp @@ -27,10 +27,10 @@ #include "pch.h" #include "d3dx12_win.h" -#include "CommandContext.h" -#include "TextureD3D12Impl.h" -#include "BufferD3D12Impl.h" -#include "CommandListManager.h" +#include "CommandContext.hpp" +#include "TextureD3D12Impl.hpp" +#include "BufferD3D12Impl.hpp" +#include "CommandListManager.hpp" #include "D3D12TypeConversions.h" diff --git a/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp b/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp index d1dadddc..53827add 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp @@ -26,8 +26,8 @@ */ #include "pch.h" -#include "CommandListManager.h" -#include "RenderDeviceD3D12Impl.h" +#include "CommandListManager.hpp" +#include "RenderDeviceD3D12Impl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp index 68a7d257..74e65559 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp @@ -26,7 +26,7 @@ */ #include "pch.h" -#include "CommandQueueD3D12Impl.h" +#include "CommandQueueD3D12Impl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12DynamicHeap.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12DynamicHeap.cpp index 0c27214a..2c010f84 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12DynamicHeap.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12DynamicHeap.cpp @@ -26,8 +26,8 @@ */ #include "pch.h" -#include "D3D12DynamicHeap.h" -#include "RenderDeviceD3D12Impl.h" +#include "D3D12DynamicHeap.hpp" +#include "RenderDeviceD3D12Impl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12Loader.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12Loader.cpp index f4f56281..f0cf9e3b 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12Loader.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12Loader.cpp @@ -26,7 +26,7 @@ */ -#include "D3D12Loader.h" +#include "D3D12Loader.hpp" #include "Errors.h" #ifndef NOMINMAX diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index e0e8d3f7..dfb01d88 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -33,8 +33,8 @@ #include "DXGITypeConversions.h" #include "D3D12TypeDefinitions.h" -#include "D3DTypeConversionImpl.h" -#include "D3DViewDescConversionImpl.h" +#include "D3DTypeConversionImpl.hpp" +#include "D3DViewDescConversionImpl.hpp" #include "PlatformMisc.h" namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/DescriptorHeap.cpp b/Graphics/GraphicsEngineD3D12/src/DescriptorHeap.cpp index 39d9d119..be598856 100644 --- a/Graphics/GraphicsEngineD3D12/src/DescriptorHeap.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DescriptorHeap.cpp @@ -26,8 +26,8 @@ */ #include "pch.h" -#include "DescriptorHeap.h" -#include "RenderDeviceD3D12Impl.h" +#include "DescriptorHeap.hpp" +#include "RenderDeviceD3D12Impl.hpp" #include "D3D12Utils.h" namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 51d4c945..ba509cd5 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -27,17 +27,17 @@ #include "pch.h" #include -#include "RenderDeviceD3D12Impl.h" -#include "DeviceContextD3D12Impl.h" -#include "PipelineStateD3D12Impl.h" -#include "CommandContext.h" -#include "TextureD3D12Impl.h" -#include "BufferD3D12Impl.h" -#include "FenceD3D12Impl.h" +#include "RenderDeviceD3D12Impl.hpp" +#include "DeviceContextD3D12Impl.hpp" +#include "PipelineStateD3D12Impl.hpp" +#include "CommandContext.hpp" +#include "TextureD3D12Impl.hpp" +#include "BufferD3D12Impl.hpp" +#include "FenceD3D12Impl.hpp" #include "D3D12TypeConversions.h" #include "d3dx12_win.h" -#include "D3D12DynamicHeap.h" -#include "CommandListD3D12Impl.h" +#include "D3D12DynamicHeap.hpp" +#include "CommandListD3D12Impl.hpp" #include "DXGITypeConversions.h" namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp index 5b7a555e..77f2805e 100644 --- a/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp @@ -34,14 +34,14 @@ #include #include "EngineFactoryD3D12.h" -#include "RenderDeviceD3D12Impl.h" -#include "DeviceContextD3D12Impl.h" -#include "SwapChainD3D12Impl.h" +#include "RenderDeviceD3D12Impl.hpp" +#include "DeviceContextD3D12Impl.hpp" +#include "SwapChainD3D12Impl.hpp" #include "D3D12TypeConversions.h" -#include "EngineFactoryD3DBase.h" +#include "EngineFactoryD3DBase.hpp" #include "StringTools.h" #include "EngineMemory.h" -#include "CommandQueueD3D12Impl.h" +#include "CommandQueueD3D12Impl.hpp" #ifndef NOMINMAX # define NOMINMAX diff --git a/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp index bf7703cd..a9e1c7d8 100644 --- a/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/FenceD3D12Impl.cpp @@ -29,9 +29,9 @@ #include #include -#include "FenceD3D12Impl.h" +#include "FenceD3D12Impl.hpp" #include "EngineMemory.h" -#include "RenderDeviceD3D12Impl.h" +#include "RenderDeviceD3D12Impl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp b/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp index 8518da94..be5c68eb 100644 --- a/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp +++ b/Graphics/GraphicsEngineD3D12/src/GenerateMips.cpp @@ -45,11 +45,11 @@ #include "pch.h" #include "d3dx12_win.h" -#include "RenderDeviceD3D12Impl.h" -#include "GenerateMips.h" -#include "CommandContext.h" -#include "TextureViewD3D12Impl.h" -#include "TextureD3D12Impl.h" +#include "RenderDeviceD3D12Impl.hpp" +#include "GenerateMips.hpp" +#include "CommandContext.hpp" +#include "TextureViewD3D12Impl.hpp" +#include "TextureD3D12Impl.hpp" #include "GenerateMips/GenerateMipsLinearCS.h" #include "GenerateMips/GenerateMipsLinearOddCS.h" diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 5d3c022b..ce1e2dc6 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -27,16 +27,16 @@ #include "pch.h" #include -#include "PipelineStateD3D12Impl.h" -#include "ShaderD3D12Impl.h" +#include "PipelineStateD3D12Impl.hpp" +#include "ShaderD3D12Impl.hpp" #include "D3D12TypeConversions.h" -#include "RenderDeviceD3D12Impl.h" +#include "RenderDeviceD3D12Impl.hpp" #include "DXGITypeConversions.h" -#include "ShaderResourceBindingD3D12Impl.h" -#include "CommandContext.h" +#include "ShaderResourceBindingD3D12Impl.hpp" +#include "CommandContext.hpp" #include "EngineMemory.h" #include "StringTools.h" -#include "ShaderVariableD3D12.h" +#include "ShaderVariableD3D12.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/QueryD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/QueryD3D12Impl.cpp index 2dd1a299..e7b5c1ee 100644 --- a/Graphics/GraphicsEngineD3D12/src/QueryD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/QueryD3D12Impl.cpp @@ -28,10 +28,10 @@ #include "pch.h" #include -#include "QueryD3D12Impl.h" -#include "RenderDeviceD3D12Impl.h" +#include "QueryD3D12Impl.hpp" +#include "RenderDeviceD3D12Impl.hpp" #include "GraphicsAccessories.hpp" -#include "DeviceContextD3D12Impl.h" +#include "DeviceContextD3D12Impl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/QueryManagerD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/QueryManagerD3D12.cpp index 4f542448..c8fd5110 100644 --- a/Graphics/GraphicsEngineD3D12/src/QueryManagerD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/QueryManagerD3D12.cpp @@ -28,10 +28,10 @@ #include "pch.h" #include -#include "QueryManagerD3D12.h" +#include "QueryManagerD3D12.hpp" #include "D3D12TypeConversions.h" #include "GraphicsAccessories.hpp" -#include "CommandContext.h" +#include "CommandContext.hpp" #include "Align.h" namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index 4b1474d7..73be3632 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -27,17 +27,17 @@ #include "pch.h" #include -#include "RenderDeviceD3D12Impl.h" -#include "PipelineStateD3D12Impl.h" -#include "ShaderD3D12Impl.h" -#include "TextureD3D12Impl.h" +#include "RenderDeviceD3D12Impl.hpp" +#include "PipelineStateD3D12Impl.hpp" +#include "ShaderD3D12Impl.hpp" +#include "TextureD3D12Impl.hpp" #include "DXGITypeConversions.h" -#include "SamplerD3D12Impl.h" -#include "BufferD3D12Impl.h" -#include "ShaderResourceBindingD3D12Impl.h" -#include "DeviceContextD3D12Impl.h" -#include "FenceD3D12Impl.h" -#include "QueryD3D12Impl.h" +#include "SamplerD3D12Impl.hpp" +#include "BufferD3D12Impl.hpp" +#include "ShaderResourceBindingD3D12Impl.hpp" +#include "DeviceContextD3D12Impl.hpp" +#include "FenceD3D12Impl.hpp" +#include "QueryD3D12Impl.hpp" #include "EngineMemory.h" namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index d80983cc..201a5354 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -27,12 +27,12 @@ #include "pch.h" -#include "RootSignature.h" -#include "ShaderResourceLayoutD3D12.h" -#include "ShaderD3D12Impl.h" -#include "CommandContext.h" -#include "RenderDeviceD3D12Impl.h" -#include "TextureD3D12Impl.h" +#include "RootSignature.hpp" +#include "ShaderResourceLayoutD3D12.hpp" +#include "ShaderD3D12Impl.hpp" +#include "CommandContext.hpp" +#include "RenderDeviceD3D12Impl.hpp" +#include "TextureD3D12Impl.hpp" #include "D3D12TypeConversions.h" #include "HashUtils.h" diff --git a/Graphics/GraphicsEngineD3D12/src/SamplerD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/SamplerD3D12Impl.cpp index 0c654cc7..e53fa1b5 100644 --- a/Graphics/GraphicsEngineD3D12/src/SamplerD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/SamplerD3D12Impl.cpp @@ -26,8 +26,8 @@ */ #include "pch.h" -#include "SamplerD3D12Impl.h" -#include "RenderDeviceD3D12Impl.h" +#include "SamplerD3D12Impl.hpp" +#include "RenderDeviceD3D12Impl.hpp" #include "D3D12TypeConversions.h" namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp index 89850809..e9729b80 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp @@ -29,8 +29,8 @@ #include -#include "ShaderD3D12Impl.h" -#include "RenderDeviceD3D12Impl.h" +#include "ShaderD3D12Impl.hpp" +#include "RenderDeviceD3D12Impl.hpp" #include "DataBlobImpl.h" namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp index 5ac1f492..93d444d7 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp @@ -26,10 +26,10 @@ */ #include "pch.h" -#include "ShaderResourceBindingD3D12Impl.h" -#include "PipelineStateD3D12Impl.h" -#include "ShaderD3D12Impl.h" -#include "RenderDeviceD3D12Impl.h" +#include "ShaderResourceBindingD3D12Impl.hpp" +#include "PipelineStateD3D12Impl.hpp" +#include "ShaderD3D12Impl.hpp" +#include "RenderDeviceD3D12Impl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp index a6679231..482443a7 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp @@ -27,8 +27,8 @@ #include "pch.h" -#include "ShaderResourceCacheD3D12.h" -#include "BufferD3D12Impl.h" +#include "ShaderResourceCacheD3D12.hpp" +#include "BufferD3D12Impl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 8316ff5e..ce7c81f8 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -27,17 +27,17 @@ #include "pch.h" -#include "ShaderResourceLayoutD3D12.h" -#include "ShaderResourceCacheD3D12.h" -#include "BufferD3D12Impl.h" +#include "ShaderResourceLayoutD3D12.hpp" +#include "ShaderResourceCacheD3D12.hpp" +#include "BufferD3D12Impl.hpp" #include "BufferViewD3D12.h" -#include "TextureD3D12Impl.h" -#include "TextureViewD3D12Impl.h" -#include "SamplerD3D12Impl.h" -#include "ShaderD3D12Impl.h" -#include "RootSignature.h" -#include "PipelineStateD3D12Impl.h" -#include "ShaderResourceVariableBase.h" +#include "TextureD3D12Impl.hpp" +#include "TextureViewD3D12Impl.hpp" +#include "SamplerD3D12Impl.hpp" +#include "ShaderD3D12Impl.hpp" +#include "RootSignature.hpp" +#include "PipelineStateD3D12Impl.hpp" +#include "ShaderResourceVariableBase.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp index f9a67288..edf818cc 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp @@ -28,9 +28,9 @@ #include "pch.h" #include -#include "ShaderResourcesD3D12.h" -#include "ShaderD3DBase.h" -#include "ShaderBase.h" +#include "ShaderResourcesD3D12.hpp" +#include "ShaderD3DBase.hpp" +#include "ShaderBase.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp index ecdf2bc7..1c825a15 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp @@ -27,8 +27,8 @@ #include "pch.h" -#include "ShaderVariableD3D12.h" -#include "ShaderResourceVariableBase.h" +#include "ShaderVariableD3D12.hpp" +#include "ShaderResourceVariableBase.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp index 531bf4c1..ac24533c 100644 --- a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp @@ -26,11 +26,11 @@ */ #include "pch.h" -#include "SwapChainD3D12Impl.h" -#include "RenderDeviceD3D12Impl.h" -#include "DeviceContextD3D12Impl.h" +#include "SwapChainD3D12Impl.hpp" +#include "RenderDeviceD3D12Impl.hpp" +#include "DeviceContextD3D12Impl.hpp" #include "DXGITypeConversions.h" -#include "TextureD3D12Impl.h" +#include "TextureD3D12Impl.hpp" #include "EngineMemory.h" namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp index be64e1db..90a583cc 100644 --- a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp @@ -26,11 +26,11 @@ */ #include "pch.h" -#include "TextureD3D12Impl.h" -#include "RenderDeviceD3D12Impl.h" -#include "DeviceContextD3D12Impl.h" +#include "TextureD3D12Impl.hpp" +#include "RenderDeviceD3D12Impl.hpp" +#include "DeviceContextD3D12Impl.hpp" #include "D3D12TypeConversions.h" -#include "TextureViewD3D12Impl.h" +#include "TextureViewD3D12Impl.hpp" #include "DXGITypeConversions.h" #include "d3dx12_win.h" #include "EngineMemory.h" diff --git a/Graphics/GraphicsEngineD3D12/src/TextureViewD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureViewD3D12Impl.cpp index dc871bf6..d1287c57 100644 --- a/Graphics/GraphicsEngineD3D12/src/TextureViewD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/TextureViewD3D12Impl.cpp @@ -26,8 +26,8 @@ */ #include "pch.h" -#include "TextureViewD3D12Impl.h" -#include "DeviceContextD3D12Impl.h" +#include "TextureViewD3D12Impl.hpp" +#include "DeviceContextD3D12Impl.hpp" namespace Diligent { -- cgit v1.2.3