Fix GPU synchronization on D3D12
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user