From ac1fe7c2b0a03fa8a0e5445e2d971e1730d15c48 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 13 Jan 2018 05:00:27 +0100 Subject: [PATCH] [d3d11] Optimized command submission --- src/d3d11/d3d11_context.cpp | 5 +++-- src/d3d11/d3d11_device.cpp | 35 ++++++++++++++++++++++------------- src/d3d11/d3d11_device.h | 9 +++++++++ 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index ebec365c..6251ee95 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -165,6 +165,7 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::Flush() { if (m_type == D3D11_DEVICE_CONTEXT_IMMEDIATE) { + m_parent->FlushInitContext(); m_executedDrawCalls = 0; m_device->submitCommandList( @@ -1553,8 +1554,8 @@ namespace dxvk { // number of draw calls since the last explicit flush, flush // the context in order to keep the GPU busy. We'll do this // here because we are going to start a new render pass anyway. - if (m_executedDrawCalls >= 500) - this->Flush(); +// if (m_executedDrawCalls >= 500) +// this->Flush(); for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) { D3D11RenderTargetView* view = nullptr; diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index deceb82f..49cf3fc2 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -36,7 +36,10 @@ namespace dxvk { m_presentDevice->SetDeviceLayer(this); m_context = new D3D11DeviceContext(this, m_dxvkDevice); + m_resourceInitContext = m_dxvkDevice->createContext(); + m_resourceInitContext->beginRecording( + m_dxvkDevice->createCommandList()); CreateCounterBuffer(); } @@ -1309,6 +1312,22 @@ namespace dxvk { } + void D3D11Device::FlushInitContext() { + auto lock = LockResourceInitContext(); + + if (m_resourceInitUsed) { + m_dxvkDevice->submitCommandList( + m_resourceInitContext->endRecording(), + nullptr, nullptr); + + m_resourceInitContext->beginRecording( + m_dxvkDevice->createCommandList()); + + m_resourceInitUsed = false; + } + } + + VkPipelineStageFlags D3D11Device::GetEnabledShaderStages() const { VkPipelineStageFlags enabledShaderPipelineStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT @@ -1427,17 +1446,13 @@ namespace dxvk { = pBuffer->GetBufferSlice(); if (pInitialData != nullptr) { - std::lock_guard lock(m_resourceInitMutex);; - m_resourceInitContext->beginRecording( - m_dxvkDevice->createCommandList()); + auto lock = LockResourceInitContext(); + m_resourceInitContext->updateBuffer( bufferSlice.buffer(), bufferSlice.offset(), bufferSlice.length(), pInitialData->pSysMem); - m_dxvkDevice->submitCommandList( - m_resourceInitContext->endRecording(), - nullptr, nullptr); } } @@ -1445,9 +1460,7 @@ namespace dxvk { void D3D11Device::InitTexture( const Rc& image, const D3D11_SUBRESOURCE_DATA* pInitialData) { - std::lock_guard lock(m_resourceInitMutex);; - m_resourceInitContext->beginRecording( - m_dxvkDevice->createCommandList()); + auto lock = LockResourceInitContext(); const DxvkFormatInfo* formatInfo = imageFormatInfo(image->info().format); @@ -1504,10 +1517,6 @@ namespace dxvk { image, value, subresources); } } - - m_dxvkDevice->submitCommandList( - m_resourceInitContext->endRecording(), - nullptr, nullptr); } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index ec1069fe..32c4a83c 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -238,6 +238,8 @@ namespace dxvk { void FreeCounterSlice(const DxvkBufferSlice& Slice); + void FlushInitContext(); + VkPipelineStageFlags GetEnabledShaderStages() const; DxgiFormatInfo STDMETHODCALLTYPE LookupFormat( @@ -274,6 +276,7 @@ namespace dxvk { std::mutex m_resourceInitMutex; Rc m_resourceInitContext; + bool m_resourceInitUsed = false; D3D11StateObjectSet m_bsStateObjects; D3D11StateObjectSet m_dsStateObjects; @@ -316,6 +319,12 @@ namespace dxvk { void CreateCounterBuffer(); + std::unique_lock LockResourceInitContext() { + auto lock = std::unique_lock(m_resourceInitMutex); + m_resourceInitUsed = true; + return lock; + } + }; }