diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index b3a077585..1c4637322 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -15,8 +15,8 @@ namespace dxvk { D3D11ImmediateContext::~D3D11ImmediateContext() { Flush(); - SynchronizeCs(); - Synchronize(); + SynchronizeCsThread(); + SynchronizeDevice(); } @@ -114,15 +114,14 @@ namespace dxvk { } else if (MapType != D3D11_MAP_WRITE_NO_OVERWRITE) { // Synchronize with CS thread so that we know whether // the buffer is currently in use by the GPU or not - SynchronizeCs(); + SynchronizeCsThread(); if (buffer->isInUse()) { if (MapFlags & D3D11_MAP_FLAG_DO_NOT_WAIT) return DXGI_ERROR_WAS_STILL_DRAWING; Flush(); - SynchronizeCs(); - Synchronize(); + SynchronizeDevice(); } } @@ -200,8 +199,8 @@ namespace dxvk { }); Flush(); - SynchronizeCs(); - Synchronize(); + SynchronizeCsThread(); + SynchronizeDevice(); physicalSlice = textureInfo->imageBuffer->slice(); } @@ -249,7 +248,16 @@ namespace dxvk { } - void D3D11ImmediateContext::Synchronize() { + void D3D11ImmediateContext::SynchronizeCsThread() { + // Dispatch current chunk so that all commands + // recorded prior to this function will be run + EmitCsChunk(); + + m_csThread.synchronize(); + } + + + void D3D11ImmediateContext::SynchronizeDevice() { // FIXME waiting until the device finished executing *all* // pending commands is too pessimistic. Instead we should // wait for individual command submissions to complete. @@ -258,13 +266,6 @@ namespace dxvk { } - void D3D11ImmediateContext::SynchronizeCs() { - EmitCsChunk(); - - m_csThread.synchronize(); - } - - void D3D11ImmediateContext::EmitCsChunk() { if (m_csChunk->commandCount() > 0) m_csChunk = m_csThread.dispatchChunk(std::move(m_csChunk)); diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 92fcb1bcf..fa8dcdf45 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -42,13 +42,13 @@ namespace dxvk { ID3D11Resource* pResource, UINT Subresource) final; + void SynchronizeCsThread(); private: DxvkCsThread m_csThread; - void Synchronize(); - void SynchronizeCs(); + void SynchronizeDevice(); void EmitCsChunk(); diff --git a/src/d3d11/d3d11_present.cpp b/src/d3d11/d3d11_present.cpp index dfaa98994..88376338e 100644 --- a/src/d3d11/d3d11_present.cpp +++ b/src/d3d11/d3d11_present.cpp @@ -1,4 +1,5 @@ #include "d3d11_device.h" +#include "d3d11_context_imm.h" #include "d3d11_present.h" namespace dxvk { @@ -57,7 +58,11 @@ namespace dxvk { Com deviceContext = nullptr; m_device->GetImmediateContext(&deviceContext); - deviceContext->Flush(); + // The presentation code is run from the main rendering thread + // rather than the command stream thread, so we synchronize. + auto immediateContext = static_cast(deviceContext.ptr()); + immediateContext->Flush(); + immediateContext->SynchronizeCsThread(); return S_OK; }