From f7957be3e70e8274bd5ab480b65e68cf8a79c7ec Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 7 Jun 2021 14:53:53 +0200 Subject: [PATCH] Fix GPU synchronization on D3D12 --- .../DirectX/DX12/CommandQueueDX12.h | 34 ----------- .../DirectX/DX12/DescriptorHeapDX12.cpp | 10 ++-- .../DirectX/DX12/DescriptorHeapDX12.h | 56 +++---------------- .../DirectX/DX12/GPUContextDX12.cpp | 7 ++- .../DirectX/DX12/GPUContextDX12.h | 15 +---- .../DirectX/DX12/GPUDeviceDX12.cpp | 9 +-- .../DirectX/DX12/GPUPipelineStateDX12.cpp | 2 +- .../DirectX/DX12/UploadBufferDX12.h | 2 +- 8 files changed, 27 insertions(+), 108 deletions(-) diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/CommandQueueDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/CommandQueueDX12.h index e92a3b819..882277125 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/CommandQueueDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/CommandQueueDX12.h @@ -3,7 +3,6 @@ #pragma once #include "Engine/Core/Types/BaseTypes.h" -#include "Engine/Platform/Platform.h" #include "Engine/Platform/CriticalSection.h" #include "CommandAllocatorPoolDX12.h" #include "../IncludeDirectXHeaders.h" @@ -35,28 +34,16 @@ public: public: - /// - /// Gets the current fence value. - /// - /// The current fence value. FORCE_INLINE uint64 GetCurrentValue() const { return _currentValue; } - /// - /// Gets the last signaled fence value. - /// - /// The last signaled fence value. FORCE_INLINE uint64 GetLastSignaledValue() const { return _lastSignaledValue; } - /// - /// Gets the last completed fence value. - /// - /// The last completed fence value. FORCE_INLINE uint64 GetLastCompletedValue() const { return _lastCompletedValue; @@ -146,42 +133,21 @@ private: public: - /// - /// Init - /// - /// Graphics Device handle - /// Command queue type CommandQueueDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE type); - - /// - /// Destructor - /// ~CommandQueueDX12(); public: - /// - /// Checks if command queue is ready for work - /// - /// True if is ready for work FORCE_INLINE bool IsReady() const { return _commandQueue != nullptr; } - /// - /// Gets DirectX 12 command queue object - /// - /// DirectX 12 command queue FORCE_INLINE ID3D12CommandQueue* GetCommandQueue() const { return _commandQueue; } - /// - /// Gets the command lists allocator pool. - /// - /// The allocator. FORCE_INLINE CommandAllocatorPoolDX12& GetAllocatorPool() { return _allocatorPool; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp index dcfaff53a..bc1e0d922 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.cpp @@ -128,6 +128,11 @@ void DescriptorHeapWithSlotsDX12::ReleaseSlot(uint32 index) value &= ~mask; } +GPUResource::ResourceType DescriptorHeapWithSlotsDX12::GetResourceType() const +{ + return ResourceType::Descriptor; +} + DescriptorHeapPoolDX12::DescriptorHeapPoolDX12(GPUDeviceDX12* device, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 descriptorsCountPerHeap, bool shaderVisible) : _device(device) , _type(type) @@ -184,14 +189,12 @@ DescriptorHeapRingBufferDX12::DescriptorHeapRingBufferDX12(GPUDeviceDX12* device bool DescriptorHeapRingBufferDX12::Init() { - // Create description + // Create heap D3D12_DESCRIPTOR_HEAP_DESC desc; desc.Type = _type; desc.NumDescriptors = _descriptorsCount; desc.Flags = _shaderVisible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : D3D12_DESCRIPTOR_HEAP_FLAG_NONE; desc.NodeMask = 0; - - // Create heap const HRESULT result = _device->GetDevice()->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&_heap)); LOG_DIRECTX_RESULT_WITH_RETURN(result); @@ -203,7 +206,6 @@ bool DescriptorHeapRingBufferDX12::Init() else _beginGPU.ptr = 0; _incrementSize = _device->GetDevice()->GetDescriptorHandleIncrementSize(desc.Type); - _memoryUsage = 1; return false; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.h index e77893b0b..7b9bf20a2 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/DescriptorHeapDX12.h @@ -63,36 +63,6 @@ public: public: - // Get heap - FORCE_INLINE operator ID3D12DescriptorHeap*() const - { - return _heap; - } - -public: - - // Create heap data - // @param type Heap data type - // @param descriptorsCount Amount of descriptors to use - // @param shaderVisible True if allow shaders to access heap data - bool Create(D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 descriptorsCount, bool shaderVisible = false); - -public: - - // Tries to find free descriptor slot - // @param index Result index to use - // @returns True if can assign descriptor to the heap - bool TryToGetUnusedSlot(uint32& index); - - // Release descriptor slot - // @param index Descriptor index in the heap - void ReleaseSlot(uint32 index); - -public: - - // Get handle to the CPU view at given index - // @param index Descriptor index - // @returns CPU address FORCE_INLINE D3D12_CPU_DESCRIPTOR_HANDLE CPU(uint32 index) { D3D12_CPU_DESCRIPTOR_HANDLE handle; @@ -100,9 +70,6 @@ public: return handle; } - // Get handle to the GPU view at given index - // @param index Descriptor index - // @returns GPU address FORCE_INLINE D3D12_GPU_DESCRIPTOR_HANDLE GPU(uint32 index) { D3D12_GPU_DESCRIPTOR_HANDLE handle; @@ -110,13 +77,16 @@ public: return handle; } +public: + + bool Create(D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 descriptorsCount, bool shaderVisible = false); + bool TryToGetUnusedSlot(uint32& index); + void ReleaseSlot(uint32 index); + public: // [GPUResourceDX12] - ResourceType GetResourceType() const final override - { - return ResourceType::Descriptor; - } + ResourceType GetResourceType() const final override; protected: @@ -188,24 +158,12 @@ public: public: - /// - /// Gets DirectX 12 heap object - /// - /// Heap object FORCE_INLINE ID3D12DescriptorHeap* GetHeap() const { return _heap; } -public: - - // Setup heap - // @returns True if cannot setup heap, otherwise false bool Init(); - - // Allocate memory for descriptors table - // @param numDesc Amount of descriptors in table - // @returns Allocated data (GPU param is valid only for shader visible heaps) Allocation AllocateTable(uint32 numDesc); public: diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp index 0e40f89f6..c99340496 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp @@ -79,6 +79,8 @@ GPUContextDX12::GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE ty , _rtDepth(nullptr) , _ibHandle(nullptr) { + FrameFenceValues[0] = 0; + FrameFenceValues[1] = 0; _currentAllocator = _device->GetCommandQueue()->RequestAllocator(); VALIDATE_DIRECTX_RESULT(device->GetDevice()->CreateCommandList(0, type, _currentAllocator, nullptr, IID_PPV_ARGS(&_commandList))); #if GPU_ENABLE_RESOURCE_NAMING @@ -592,7 +594,8 @@ void GPUContextDX12::FrameEnd() GPUContext::FrameEnd(); // Execute command (but don't wait for them) - Execute(false); + FrameFenceValues[1] = FrameFenceValues[0]; + FrameFenceValues[0] = Execute(false); } #if GPU_ALLOW_PROFILE_EVENTS @@ -1080,7 +1083,7 @@ void GPUContextDX12::Flush() return; // Flush GPU commands - Execute(); + Execute(true); Reset(); } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h index 30e64ec3d..7e9994add 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h @@ -68,29 +68,18 @@ private: public: - /// - /// Init - /// - /// Graphics device - /// Context type GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE type); - - /// - /// Destructor - /// ~GPUContextDX12(); public: - /// - /// Gets command list - /// - /// Command list to use FORCE_INLINE ID3D12GraphicsCommandList* GetCommandList() const { return _commandList; } + uint64 FrameFenceValues[2]; + public: /// diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp index 9563c58fc..6b6cf5d49 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUDeviceDX12.cpp @@ -169,7 +169,7 @@ GPUDeviceDX12::GPUDeviceDX12(IDXGIFactory4* dxgiFactory, GPUAdapterDX* adapter) , Heap_CBV_SRV_UAV(this, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 4 * 1024, false) , Heap_RTV(this, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1 * 1024, false) , Heap_DSV(this, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 64, false) - , RingHeap_CBV_SRV_UAV(this, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 64 * 1024, true) + , RingHeap_CBV_SRV_UAV(this, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 512 * 1024, true) { } @@ -620,10 +620,11 @@ bool GPUDeviceDX12::Init() void GPUDeviceDX12::DrawBegin() { - /*{ + { PROFILE_CPU_NAMED("Wait For GPU"); - _commandQueue->WaitForGPU(); - }*/ + //_commandQueue->WaitForGPU(); + _commandQueue->WaitForFence(_mainContext->FrameFenceValues[1]); + } // Base GPUDeviceDX::DrawBegin(); diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUPipelineStateDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUPipelineStateDX12.cpp index 50940d46d..08928e94b 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUPipelineStateDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUPipelineStateDX12.cpp @@ -64,7 +64,7 @@ ID3D12PipelineState* GPUPipelineStateDX12::GetState(GPUTextureViewDX12* depth, i LOG_DIRECTX_RESULT(result); if (FAILED(result)) return nullptr; -#if GPU_ENABLE_RESOURCE_NAMING +#if GPU_ENABLE_RESOURCE_NAMING && BUILD_DEBUG char name[200]; int32 nameLen = 0; if (DebugDesc.VS) diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/UploadBufferDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/UploadBufferDX12.h index 605d3268c..7f1723cb5 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/UploadBufferDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/UploadBufferDX12.h @@ -13,7 +13,7 @@ #define DX12_UPLOAD_PAGE_GEN_TIMEOUT DX12_BACK_BUFFER_COUNT // Upload buffer pages that are not used for a few frames are disposed -#define DX12_UPLOAD_PAGE_NOT_USED_FRAME_TIMEOUT 8 +#define DX12_UPLOAD_PAGE_NOT_USED_FRAME_TIMEOUT 60 class GPUTextureDX12;