diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index fff3efb5..6f1e8488 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1553,6 +1553,7 @@ namespace dxvk { // Optimization: If the number of draw and dispatch calls issued // prior to the previous context flush is above a certain threshold, // submit the current command buffer in order to keep the GPU busy. + // This also helps keep the command buffers at a reasonable size. if (m_drawCount >= 500) this->Flush(); diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 49cf3fc2..f1a36d6d 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1313,18 +1313,10 @@ 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; - } + LockResourceInitContext(); + if (m_resourceInitCommands != 0) + SubmitResourceInitCommands(); + UnlockResourceInitContext(0); } @@ -1446,13 +1438,15 @@ namespace dxvk { = pBuffer->GetBufferSlice(); if (pInitialData != nullptr) { - auto lock = LockResourceInitContext(); + LockResourceInitContext(); m_resourceInitContext->updateBuffer( bufferSlice.buffer(), bufferSlice.offset(), bufferSlice.length(), pInitialData->pSysMem); + + UnlockResourceInitContext(1); } } @@ -1460,11 +1454,11 @@ namespace dxvk { void D3D11Device::InitTexture( const Rc& image, const D3D11_SUBRESOURCE_DATA* pInitialData) { - auto lock = LockResourceInitContext(); - const DxvkFormatInfo* formatInfo = imageFormatInfo(image->info().format); if (pInitialData != nullptr) { + LockResourceInitContext(); + // pInitialData is an array that stores an entry for // every single subresource. Since we will define all // subresources, this counts as initialization. @@ -1491,7 +1485,13 @@ namespace dxvk { pInitialData[id].SysMemSlicePitch); } } + + const uint32_t subresourceCount = + image->info().numLayers * image->info().mipLevels; + UnlockResourceInitContext(subresourceCount); } else { + LockResourceInitContext(); + // While the Microsoft docs state that resource contents // are undefined if no initial data is provided, some // applications expect a resource to be pre-cleared. @@ -1516,6 +1516,8 @@ namespace dxvk { m_resourceInitContext->clearDepthStencilImage( image, value, subresources); } + + UnlockResourceInitContext(1); } } @@ -1822,4 +1824,31 @@ namespace dxvk { m_counterSlices[i] = MaxCounterStructs - i - 1; } + + void D3D11Device::LockResourceInitContext() { + m_resourceInitMutex.lock(); + } + + + void D3D11Device::UnlockResourceInitContext(uint64_t CommandCount) { + m_resourceInitCommands += CommandCount; + + if (m_resourceInitCommands >= InitCommandThreshold) + SubmitResourceInitCommands(); + + m_resourceInitMutex.unlock(); + } + + + void D3D11Device::SubmitResourceInitCommands() { + m_dxvkDevice->submitCommandList( + m_resourceInitContext->endRecording(), + nullptr, nullptr); + + m_resourceInitContext->beginRecording( + m_dxvkDevice->createCommandList()); + + m_resourceInitCommands = 0; + } + } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 32c4a83c..42275bf2 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -28,7 +28,8 @@ namespace dxvk { class D3D11Texture3D; class D3D11Device : public ComObject { - + /// Maximum number of resource init commands per command buffer + constexpr static uint64_t InitCommandThreshold = 50; public: D3D11Device( @@ -276,7 +277,7 @@ namespace dxvk { std::mutex m_resourceInitMutex; Rc m_resourceInitContext; - bool m_resourceInitUsed = false; + uint64_t m_resourceInitCommands = 0; D3D11StateObjectSet m_bsStateObjects; D3D11StateObjectSet m_dsStateObjects; @@ -319,11 +320,9 @@ namespace dxvk { void CreateCounterBuffer(); - std::unique_lock LockResourceInitContext() { - auto lock = std::unique_lock(m_resourceInitMutex); - m_resourceInitUsed = true; - return lock; - } + void LockResourceInitContext(); + void UnlockResourceInitContext(uint64_t CommandCount); + void SubmitResourceInitCommands(); };