diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index fd4b0a87..1e0e07ca 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -14,7 +14,6 @@ namespace dxvk { Rc device) : m_parent (parent), m_device (device), - m_context (m_device->createContext()), m_csChunk (new DxvkCsChunk()) { // Create default state objects. We won't ever return them // to the application, but we'll use them to apply state. diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 02a30558..1b230079 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -518,7 +518,6 @@ namespace dxvk { D3D11Device* const m_parent; Rc m_device; - Rc m_context; Rc m_csChunk; Rc m_defaultSampler; diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 1f359662..943fa137 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -7,13 +7,16 @@ namespace dxvk { D3D11ImmediateContext::D3D11ImmediateContext( D3D11Device* parent, Rc device) - : D3D11DeviceContext(parent, device) { + : D3D11DeviceContext(parent, device), + m_csThread(device->createContext()) { } D3D11ImmediateContext::~D3D11ImmediateContext() { - + Flush(); + SynchronizeCs(); + Synchronize(); } @@ -113,6 +116,7 @@ namespace dxvk { return DXGI_ERROR_WAS_STILL_DRAWING; Flush(); + SynchronizeCs(); Synchronize(); } } @@ -189,6 +193,7 @@ namespace dxvk { }); Flush(); + SynchronizeCs(); Synchronize(); physicalSlice = textureInfo->imageBuffer->slice(); @@ -247,16 +252,15 @@ namespace dxvk { void D3D11ImmediateContext::SynchronizeCs() { - // Dispatch recorded commands first, EmitCsChunk(); - // TODO synchronize with CS thread + m_csThread.synchronize(); } void D3D11ImmediateContext::EmitCsChunk() { if (m_csChunk->commandCount() > 0) { - m_csChunk->executeAll(m_context.ptr()); + m_csThread.dispatchChunk(std::move(m_csChunk)); m_csChunk = new DxvkCsChunk(); } } diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index d0903fe7..92fcb1bc 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -45,6 +45,8 @@ namespace dxvk { private: + DxvkCsThread m_csThread; + void Synchronize(); void SynchronizeCs(); diff --git a/src/dxvk/dxvk_cs.cpp b/src/dxvk/dxvk_cs.cpp index 041b4b84..aabcaea0 100644 --- a/src/dxvk/dxvk_cs.cpp +++ b/src/dxvk/dxvk_cs.cpp @@ -43,6 +43,7 @@ namespace dxvk { void DxvkCsThread::dispatchChunk(Rc&& chunk) { { std::unique_lock lock(m_mutex); m_chunks.push(std::move(chunk)); + m_chunksPending += 1; } m_condOnAdd.notify_one(); @@ -53,7 +54,7 @@ namespace dxvk { std::unique_lock lock(m_mutex); m_condOnSync.wait(lock, [this] { - return m_chunks.size() == 0; + return m_chunksPending == 0; }); } @@ -71,14 +72,20 @@ namespace dxvk { if (m_chunks.size() != 0) { chunk = std::move(m_chunks.front()); m_chunks.pop(); - - if (m_chunks.size() == 0) - m_condOnSync.notify_one(); } } - if (chunk != nullptr) + if (chunk != nullptr) { chunk->executeAll(m_context.ptr()); + + const bool doNotify = [this] { + std::unique_lock lock(m_mutex); + return --m_chunksPending == 0; + }(); + + if (doNotify) + m_condOnSync.notify_one(); + } } } diff --git a/src/dxvk/dxvk_cs.h b/src/dxvk/dxvk_cs.h index 2f9e6b1b..7e0d36e8 100644 --- a/src/dxvk/dxvk_cs.h +++ b/src/dxvk/dxvk_cs.h @@ -174,6 +174,8 @@ namespace dxvk { std::queue> m_chunks; std::thread m_thread; + uint32_t m_chunksPending = 0; + void threadFunc(); };