Fix GPU synchronization on D3D12

This commit is contained in:
Wojtek Figat
2021-06-07 14:53:53 +02:00
parent 4b42e17372
commit f7957be3e7
8 changed files with 27 additions and 108 deletions

View File

@@ -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:
/// <summary>
/// Gets the current fence value.
/// </summary>
/// <returns>The current fence value.</returns>
FORCE_INLINE uint64 GetCurrentValue() const
{
return _currentValue;
}
/// <summary>
/// Gets the last signaled fence value.
/// </summary>
/// <returns>The last signaled fence value.</returns>
FORCE_INLINE uint64 GetLastSignaledValue() const
{
return _lastSignaledValue;
}
/// <summary>
/// Gets the last completed fence value.
/// </summary>
/// <returns>The last completed fence value.</returns>
FORCE_INLINE uint64 GetLastCompletedValue() const
{
return _lastCompletedValue;
@@ -146,42 +133,21 @@ private:
public:
/// <summary>
/// Init
/// </summary>
/// <param name="device">Graphics Device handle</param>
/// <param name="type">Command queue type</param>
CommandQueueDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE type);
/// <summary>
/// Destructor
/// </summary>
~CommandQueueDX12();
public:
/// <summary>
/// Checks if command queue is ready for work
/// </summary>
/// <returns>True if is ready for work</returns>
FORCE_INLINE bool IsReady() const
{
return _commandQueue != nullptr;
}
/// <summary>
/// Gets DirectX 12 command queue object
/// </summary>
/// <returns>DirectX 12 command queue</returns>
FORCE_INLINE ID3D12CommandQueue* GetCommandQueue() const
{
return _commandQueue;
}
/// <summary>
/// Gets the command lists allocator pool.
/// </summary>
/// <returns>The allocator.</returns>
FORCE_INLINE CommandAllocatorPoolDX12& GetAllocatorPool()
{
return _allocatorPool;

View File

@@ -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;

View File

@@ -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:
/// <summary>
/// Gets DirectX 12 heap object
/// </summary>
/// <returns>Heap object</returns>
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:

View File

@@ -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();
}

View File

@@ -68,29 +68,18 @@ private:
public:
/// <summary>
/// Init
/// </summary>
/// <param name="device">Graphics device</param>
/// <param name="type">Context type</param>
GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE type);
/// <summary>
/// Destructor
/// </summary>
~GPUContextDX12();
public:
/// <summary>
/// Gets command list
/// </summary>
/// <returns>Command list to use</returns>
FORCE_INLINE ID3D12GraphicsCommandList* GetCommandList() const
{
return _commandList;
}
uint64 FrameFenceValues[2];
public:
/// <summary>

View File

@@ -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();

View File

@@ -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)

View File

@@ -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;