Fix GPU synchronization on D3D12
This commit is contained in:
@@ -3,7 +3,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Engine/Core/Types/BaseTypes.h"
|
#include "Engine/Core/Types/BaseTypes.h"
|
||||||
#include "Engine/Platform/Platform.h"
|
|
||||||
#include "Engine/Platform/CriticalSection.h"
|
#include "Engine/Platform/CriticalSection.h"
|
||||||
#include "CommandAllocatorPoolDX12.h"
|
#include "CommandAllocatorPoolDX12.h"
|
||||||
#include "../IncludeDirectXHeaders.h"
|
#include "../IncludeDirectXHeaders.h"
|
||||||
@@ -35,28 +34,16 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current fence value.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The current fence value.</returns>
|
|
||||||
FORCE_INLINE uint64 GetCurrentValue() const
|
FORCE_INLINE uint64 GetCurrentValue() const
|
||||||
{
|
{
|
||||||
return _currentValue;
|
return _currentValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the last signaled fence value.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The last signaled fence value.</returns>
|
|
||||||
FORCE_INLINE uint64 GetLastSignaledValue() const
|
FORCE_INLINE uint64 GetLastSignaledValue() const
|
||||||
{
|
{
|
||||||
return _lastSignaledValue;
|
return _lastSignaledValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the last completed fence value.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The last completed fence value.</returns>
|
|
||||||
FORCE_INLINE uint64 GetLastCompletedValue() const
|
FORCE_INLINE uint64 GetLastCompletedValue() const
|
||||||
{
|
{
|
||||||
return _lastCompletedValue;
|
return _lastCompletedValue;
|
||||||
@@ -146,42 +133,21 @@ private:
|
|||||||
|
|
||||||
public:
|
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);
|
CommandQueueDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE type);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Destructor
|
|
||||||
/// </summary>
|
|
||||||
~CommandQueueDX12();
|
~CommandQueueDX12();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if command queue is ready for work
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if is ready for work</returns>
|
|
||||||
FORCE_INLINE bool IsReady() const
|
FORCE_INLINE bool IsReady() const
|
||||||
{
|
{
|
||||||
return _commandQueue != nullptr;
|
return _commandQueue != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets DirectX 12 command queue object
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>DirectX 12 command queue</returns>
|
|
||||||
FORCE_INLINE ID3D12CommandQueue* GetCommandQueue() const
|
FORCE_INLINE ID3D12CommandQueue* GetCommandQueue() const
|
||||||
{
|
{
|
||||||
return _commandQueue;
|
return _commandQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the command lists allocator pool.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The allocator.</returns>
|
|
||||||
FORCE_INLINE CommandAllocatorPoolDX12& GetAllocatorPool()
|
FORCE_INLINE CommandAllocatorPoolDX12& GetAllocatorPool()
|
||||||
{
|
{
|
||||||
return _allocatorPool;
|
return _allocatorPool;
|
||||||
|
|||||||
@@ -128,6 +128,11 @@ void DescriptorHeapWithSlotsDX12::ReleaseSlot(uint32 index)
|
|||||||
value &= ~mask;
|
value &= ~mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPUResource::ResourceType DescriptorHeapWithSlotsDX12::GetResourceType() const
|
||||||
|
{
|
||||||
|
return ResourceType::Descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
DescriptorHeapPoolDX12::DescriptorHeapPoolDX12(GPUDeviceDX12* device, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 descriptorsCountPerHeap, bool shaderVisible)
|
DescriptorHeapPoolDX12::DescriptorHeapPoolDX12(GPUDeviceDX12* device, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 descriptorsCountPerHeap, bool shaderVisible)
|
||||||
: _device(device)
|
: _device(device)
|
||||||
, _type(type)
|
, _type(type)
|
||||||
@@ -184,14 +189,12 @@ DescriptorHeapRingBufferDX12::DescriptorHeapRingBufferDX12(GPUDeviceDX12* device
|
|||||||
|
|
||||||
bool DescriptorHeapRingBufferDX12::Init()
|
bool DescriptorHeapRingBufferDX12::Init()
|
||||||
{
|
{
|
||||||
// Create description
|
// Create heap
|
||||||
D3D12_DESCRIPTOR_HEAP_DESC desc;
|
D3D12_DESCRIPTOR_HEAP_DESC desc;
|
||||||
desc.Type = _type;
|
desc.Type = _type;
|
||||||
desc.NumDescriptors = _descriptorsCount;
|
desc.NumDescriptors = _descriptorsCount;
|
||||||
desc.Flags = _shaderVisible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
desc.Flags = _shaderVisible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||||
desc.NodeMask = 0;
|
desc.NodeMask = 0;
|
||||||
|
|
||||||
// Create heap
|
|
||||||
const HRESULT result = _device->GetDevice()->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&_heap));
|
const HRESULT result = _device->GetDevice()->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&_heap));
|
||||||
LOG_DIRECTX_RESULT_WITH_RETURN(result);
|
LOG_DIRECTX_RESULT_WITH_RETURN(result);
|
||||||
|
|
||||||
@@ -203,7 +206,6 @@ bool DescriptorHeapRingBufferDX12::Init()
|
|||||||
else
|
else
|
||||||
_beginGPU.ptr = 0;
|
_beginGPU.ptr = 0;
|
||||||
_incrementSize = _device->GetDevice()->GetDescriptorHandleIncrementSize(desc.Type);
|
_incrementSize = _device->GetDevice()->GetDescriptorHandleIncrementSize(desc.Type);
|
||||||
|
|
||||||
_memoryUsage = 1;
|
_memoryUsage = 1;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -63,36 +63,6 @@ public:
|
|||||||
|
|
||||||
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)
|
FORCE_INLINE D3D12_CPU_DESCRIPTOR_HANDLE CPU(uint32 index)
|
||||||
{
|
{
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE handle;
|
D3D12_CPU_DESCRIPTOR_HANDLE handle;
|
||||||
@@ -100,9 +70,6 @@ public:
|
|||||||
return handle;
|
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)
|
FORCE_INLINE D3D12_GPU_DESCRIPTOR_HANDLE GPU(uint32 index)
|
||||||
{
|
{
|
||||||
D3D12_GPU_DESCRIPTOR_HANDLE handle;
|
D3D12_GPU_DESCRIPTOR_HANDLE handle;
|
||||||
@@ -110,13 +77,16 @@ public:
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool Create(D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 descriptorsCount, bool shaderVisible = false);
|
||||||
|
bool TryToGetUnusedSlot(uint32& index);
|
||||||
|
void ReleaseSlot(uint32 index);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// [GPUResourceDX12]
|
// [GPUResourceDX12]
|
||||||
ResourceType GetResourceType() const final override
|
ResourceType GetResourceType() const final override;
|
||||||
{
|
|
||||||
return ResourceType::Descriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@@ -188,24 +158,12 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets DirectX 12 heap object
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Heap object</returns>
|
|
||||||
FORCE_INLINE ID3D12DescriptorHeap* GetHeap() const
|
FORCE_INLINE ID3D12DescriptorHeap* GetHeap() const
|
||||||
{
|
{
|
||||||
return _heap;
|
return _heap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Setup heap
|
|
||||||
// @returns True if cannot setup heap, otherwise false
|
|
||||||
bool Init();
|
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);
|
Allocation AllocateTable(uint32 numDesc);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ GPUContextDX12::GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE ty
|
|||||||
, _rtDepth(nullptr)
|
, _rtDepth(nullptr)
|
||||||
, _ibHandle(nullptr)
|
, _ibHandle(nullptr)
|
||||||
{
|
{
|
||||||
|
FrameFenceValues[0] = 0;
|
||||||
|
FrameFenceValues[1] = 0;
|
||||||
_currentAllocator = _device->GetCommandQueue()->RequestAllocator();
|
_currentAllocator = _device->GetCommandQueue()->RequestAllocator();
|
||||||
VALIDATE_DIRECTX_RESULT(device->GetDevice()->CreateCommandList(0, type, _currentAllocator, nullptr, IID_PPV_ARGS(&_commandList)));
|
VALIDATE_DIRECTX_RESULT(device->GetDevice()->CreateCommandList(0, type, _currentAllocator, nullptr, IID_PPV_ARGS(&_commandList)));
|
||||||
#if GPU_ENABLE_RESOURCE_NAMING
|
#if GPU_ENABLE_RESOURCE_NAMING
|
||||||
@@ -592,7 +594,8 @@ void GPUContextDX12::FrameEnd()
|
|||||||
GPUContext::FrameEnd();
|
GPUContext::FrameEnd();
|
||||||
|
|
||||||
// Execute command (but don't wait for them)
|
// Execute command (but don't wait for them)
|
||||||
Execute(false);
|
FrameFenceValues[1] = FrameFenceValues[0];
|
||||||
|
FrameFenceValues[0] = Execute(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GPU_ALLOW_PROFILE_EVENTS
|
#if GPU_ALLOW_PROFILE_EVENTS
|
||||||
@@ -1080,7 +1083,7 @@ void GPUContextDX12::Flush()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Flush GPU commands
|
// Flush GPU commands
|
||||||
Execute();
|
Execute(true);
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,29 +68,18 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Init
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="device">Graphics device</param>
|
|
||||||
/// <param name="type">Context type</param>
|
|
||||||
GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE type);
|
GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE type);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Destructor
|
|
||||||
/// </summary>
|
|
||||||
~GPUContextDX12();
|
~GPUContextDX12();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets command list
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Command list to use</returns>
|
|
||||||
FORCE_INLINE ID3D12GraphicsCommandList* GetCommandList() const
|
FORCE_INLINE ID3D12GraphicsCommandList* GetCommandList() const
|
||||||
{
|
{
|
||||||
return _commandList;
|
return _commandList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64 FrameFenceValues[2];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -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_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_RTV(this, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1 * 1024, false)
|
||||||
, Heap_DSV(this, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 64, 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()
|
void GPUDeviceDX12::DrawBegin()
|
||||||
{
|
{
|
||||||
/*{
|
{
|
||||||
PROFILE_CPU_NAMED("Wait For GPU");
|
PROFILE_CPU_NAMED("Wait For GPU");
|
||||||
_commandQueue->WaitForGPU();
|
//_commandQueue->WaitForGPU();
|
||||||
}*/
|
_commandQueue->WaitForFence(_mainContext->FrameFenceValues[1]);
|
||||||
|
}
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
GPUDeviceDX::DrawBegin();
|
GPUDeviceDX::DrawBegin();
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ ID3D12PipelineState* GPUPipelineStateDX12::GetState(GPUTextureViewDX12* depth, i
|
|||||||
LOG_DIRECTX_RESULT(result);
|
LOG_DIRECTX_RESULT(result);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#if GPU_ENABLE_RESOURCE_NAMING
|
#if GPU_ENABLE_RESOURCE_NAMING && BUILD_DEBUG
|
||||||
char name[200];
|
char name[200];
|
||||||
int32 nameLen = 0;
|
int32 nameLen = 0;
|
||||||
if (DebugDesc.VS)
|
if (DebugDesc.VS)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#define DX12_UPLOAD_PAGE_GEN_TIMEOUT DX12_BACK_BUFFER_COUNT
|
#define DX12_UPLOAD_PAGE_GEN_TIMEOUT DX12_BACK_BUFFER_COUNT
|
||||||
|
|
||||||
// Upload buffer pages that are not used for a few frames are disposed
|
// 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;
|
class GPUTextureDX12;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user