d3d12: Record command while gpu is busy rendering previous frame + cleaning fixes

This commit is contained in:
vlj 2015-05-22 23:24:49 +02:00 committed by Vincent Lejeune
parent 71b9caf65a
commit 727f54dd32
2 changed files with 40 additions and 27 deletions

View File

@ -40,11 +40,11 @@ void D3D12GSRender::ResourceStorage::Reset()
void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device) void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device)
{ {
m_queueCompletion = 0;
// Create a global command allocator // Create a global command allocator
device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocator)); device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocator));
device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_textureUploadCommandAllocator)); device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_textureUploadCommandAllocator));
// Create heap for vertex buffers // Create heap for vertex buffers
D3D12_HEAP_DESC vertexBufferHeapDesc = {}; D3D12_HEAP_DESC vertexBufferHeapDesc = {};
// 16 MB wide // 16 MB wide
@ -135,6 +135,27 @@ void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device)
check(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap))); check(device->CreateDescriptorHeap(&textureDescriptorDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap)));
} }
void D3D12GSRender::ResourceStorage::Release()
{
// NOTE: Should be released only if no command are in flight !
m_backbufferAsRendertarget->Release();
m_constantsBufferDescriptorsHeap->Release();
m_scaleOffsetDescriptorHeap->Release();
m_constantsVertexBuffer->Release();
m_constantsFragmentBuffer->Release();
m_scaleOffsetBuffer->Release();
m_vertexBuffersHeap->Release();
m_backBuffer->Release();
for (auto tmp : m_inflightVertexBuffers)
tmp->Release();
m_textureDescriptorsHeap->Release();
m_textureStorage->Release();
m_uploadTextureHeap->Release();
m_samplerDescriptorHeap->Release();
for (auto tmp : m_inflightCommandList)
tmp->Release();
m_commandAllocator->Release();
}
D3D12GSRender::D3D12GSRender() D3D12GSRender::D3D12GSRender()
: GSRender(), m_fbo(nullptr), m_PSO(nullptr) : GSRender(), m_fbo(nullptr), m_PSO(nullptr)
@ -249,31 +270,15 @@ D3D12GSRender::D3D12GSRender()
D3D12GSRender::~D3D12GSRender() D3D12GSRender::~D3D12GSRender()
{ {
// NOTE: Should be released only if no command are in flight ! m_perFrameStorage[0].Release();
/* m_commandAllocator->Release(); m_perFrameStorage[1].Release();
m_commandQueueGraphic->Release(); m_commandQueueGraphic->Release();
m_commandQueueCopy->Release(); m_commandQueueCopy->Release();
m_backbufferAsRendertarget[0]->Release();
m_backbufferAsRendertarget[1]->Release();
m_constantsBufferDescriptorsHeap->Release();
m_scaleOffsetDescriptorHeap->Release();
m_constantsVertexBuffer->Release();
m_constantsFragmentBuffer->Release();
m_scaleOffsetBuffer->Release();
m_vertexBuffersHeap->Release();
if (m_fbo) if (m_fbo)
delete m_fbo; delete m_fbo;
for (auto tmp : m_inflightVertexBuffers)
tmp->Release();
m_textureDescriptorsHeap->Release();
m_textureStorage->Release();
m_uploadTextureHeap->Release();
m_samplerDescriptorHeap->Release();
m_rootSignature->Release(); m_rootSignature->Release();
m_backBuffer[0]->Release();
m_backBuffer[1]->Release();
m_swapChain->Release(); m_swapChain->Release();
m_device->Release();*/ m_device->Release();
} }
D3D12GSRender::ResourceStorage &D3D12GSRender::getCurrentResourceStorage() D3D12GSRender::ResourceStorage &D3D12GSRender::getCurrentResourceStorage()
@ -1217,16 +1222,20 @@ void D3D12GSRender::Flip()
} }
check(m_swapChain->Present(Ini.GSVSyncEnable.GetValue() ? 1 : 0, 0)); check(m_swapChain->Present(Ini.GSVSyncEnable.GetValue() ? 1 : 0, 0));
// Wait execution is over // Add an event signaling queue completion
// TODO: It's suboptimal, we should use 2 command allocator
Microsoft::WRL::ComPtr<ID3D12Fence> fence; Microsoft::WRL::ComPtr<ID3D12Fence> fence;
m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
HANDLE gfxqueuecompletion = CreateEvent(0, 0, 0, 0); getCurrentResourceStorage().m_queueCompletion = CreateEvent(0, 0, 0, 0);
fence->SetEventOnCompletion(1, gfxqueuecompletion); fence->SetEventOnCompletion(1, getCurrentResourceStorage().m_queueCompletion);
m_commandQueueGraphic->Signal(fence.Get(), 1); m_commandQueueGraphic->Signal(fence.Get(), 1);
WaitForSingleObject(gfxqueuecompletion, INFINITE);
CloseHandle(gfxqueuecompletion); // Wait execution is over
getNonCurrentResourceStorage().Reset(); if (getNonCurrentResourceStorage().m_queueCompletion)
{
WaitForSingleObject(getNonCurrentResourceStorage().m_queueCompletion, INFINITE);
CloseHandle(getNonCurrentResourceStorage().m_queueCompletion);
getNonCurrentResourceStorage().Reset();
}
m_currentResourceStorageIndex = 1 - m_currentResourceStorageIndex; m_currentResourceStorageIndex = 1 - m_currentResourceStorageIndex;
m_frame->Flip(nullptr); m_frame->Flip(nullptr);

View File

@ -83,8 +83,12 @@ private:
ID3D12Resource* m_backBuffer; ID3D12Resource* m_backBuffer;
ID3D12DescriptorHeap *m_backbufferAsRendertarget; ID3D12DescriptorHeap *m_backbufferAsRendertarget;
// Fence
HANDLE m_queueCompletion;
void Reset(); void Reset();
void Init(ID3D12Device *device); void Init(ID3D12Device *device);
void Release();
}; };
ResourceStorage m_perFrameStorage[2]; ResourceStorage m_perFrameStorage[2];