diff --git a/src/d3d11/d3d11_cmdlist.cpp b/src/d3d11/d3d11_cmdlist.cpp index a202fc247..f3be6f5a1 100644 --- a/src/d3d11/d3d11_cmdlist.cpp +++ b/src/d3d11/d3d11_cmdlist.cpp @@ -34,4 +34,23 @@ namespace dxvk { return m_contextFlags; } + + void D3D11CommandList::AddChunk(Rc&& Chunk) { + m_chunks.push_back(std::move(Chunk)); + } + + + void D3D11CommandList::EmitToCommandList(ID3D11CommandList* pCommandList) { + auto cmdList = static_cast(pCommandList); + + for (auto chunk : m_chunks) + cmdList->m_chunks.push_back(chunk); + } + + + void D3D11CommandList::EmitToCsThread(const Rc& CsThread) { + for (auto chunk : m_chunks) + CsThread->dispatchChunk(Rc(chunk)); + } + } \ No newline at end of file diff --git a/src/d3d11/d3d11_cmdlist.h b/src/d3d11/d3d11_cmdlist.h index 091c60150..541638a09 100644 --- a/src/d3d11/d3d11_cmdlist.h +++ b/src/d3d11/d3d11_cmdlist.h @@ -1,11 +1,9 @@ #pragma once -#include "d3d11_device_child.h" +#include "d3d11_context.h" namespace dxvk { - class D3D11Device; - class D3D11CommandList : public D3D11DeviceChild { public: @@ -25,11 +23,21 @@ namespace dxvk { UINT GetContextFlags(); + void AddChunk(Rc&& Chunk); + + void EmitToCommandList( + ID3D11CommandList* pCommandList); + + void EmitToCsThread( + const Rc& CsThread); + private: D3D11Device* const m_device; UINT const m_contextFlags; + std::vector> m_chunks; + }; } \ No newline at end of file diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index ddf1cec2e..1247c656c 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -568,12 +568,21 @@ namespace dxvk { template void EmitCs(Cmd&& command) { if (!m_csChunk->push(command)) { - EmitCsChunk(); + EmitCsChunk(std::move(m_csChunk)); + + m_csChunk = new DxvkCsChunk(); m_csChunk->push(command); } } - virtual void EmitCsChunk() = 0; + void FlushCsChunk() { + if (m_csChunk->commandCount() != 0) { + EmitCsChunk(std::move(m_csChunk)); + m_csChunk = new DxvkCsChunk(); + } + } + + virtual void EmitCsChunk(Rc&& chunk) = 0; }; diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 957e9d14b..d527078cc 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -7,7 +7,8 @@ namespace dxvk { Rc Device, UINT ContextFlags) : D3D11DeviceContext(pParent, Device), - m_contextFlags(ContextFlags) { + m_contextFlags(ContextFlags), + m_commandList (CreateCommandList()) { } @@ -60,8 +61,13 @@ namespace dxvk { } - void D3D11DeferredContext::EmitCsChunk() { - + Com D3D11DeferredContext::CreateCommandList() { + return new D3D11CommandList(m_parent, m_contextFlags); + } + + + void D3D11DeferredContext::EmitCsChunk(Rc&& chunk) { + m_commandList->AddChunk(std::move(chunk)); } } \ No newline at end of file diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index a29fb6535..e8d48f8a8 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -1,5 +1,6 @@ #pragma once +#include "d3d11_cmdlist.h" #include "d3d11_context.h" namespace dxvk { @@ -42,7 +43,11 @@ namespace dxvk { const UINT m_contextFlags; - void EmitCsChunk() final; + Com m_commandList; + + Com CreateCommandList(); + + void EmitCsChunk(Rc&& chunk) final; }; diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 36915b3ed..f98802368 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -55,7 +55,7 @@ namespace dxvk { dev->createCommandList()); }); - EmitCsChunk(); + FlushCsChunk(); } @@ -251,7 +251,7 @@ namespace dxvk { void D3D11ImmediateContext::SynchronizeCsThread() { // Dispatch current chunk so that all commands // recorded prior to this function will be run - EmitCsChunk(); + FlushCsChunk(); m_csThread.synchronize(); } @@ -266,9 +266,8 @@ namespace dxvk { } - void D3D11ImmediateContext::EmitCsChunk() { - if (m_csChunk->commandCount() > 0) - m_csChunk = m_csThread.dispatchChunk(std::move(m_csChunk)); + void D3D11ImmediateContext::EmitCsChunk(Rc&& chunk) { + m_csThread.dispatchChunk(std::move(chunk)); } } \ No newline at end of file diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 57f9879f5..948e0d01d 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -50,7 +50,7 @@ namespace dxvk { void SynchronizeDevice(); - void EmitCsChunk() final; + void EmitCsChunk(Rc&& chunk) final; }; diff --git a/src/dxvk/dxvk_cs.cpp b/src/dxvk/dxvk_cs.cpp index 2250cf684..a15cd6783 100644 --- a/src/dxvk/dxvk_cs.cpp +++ b/src/dxvk/dxvk_cs.cpp @@ -40,9 +40,7 @@ namespace dxvk { } - Rc DxvkCsThread::dispatchChunk(Rc&& chunk) { - Rc nextChunk = nullptr; - + void DxvkCsThread::dispatchChunk(Rc&& chunk) { { std::unique_lock lock(m_mutex); m_chunksQueued.push(std::move(chunk)); m_chunksPending += 1; @@ -56,21 +54,10 @@ namespace dxvk { || (m_stopped.load()); }); } - - if (m_chunksUnused.size() != 0) { - nextChunk = std::move(m_chunksUnused.front()); - m_chunksUnused.pop(); - } } // Wake CS thread m_condOnAdd.notify_one(); - - // Allocate new chunk if needed - if (nextChunk == nullptr) - nextChunk = new DxvkCsChunk(); - - return nextChunk; } @@ -90,8 +77,6 @@ namespace dxvk { { std::unique_lock lock(m_mutex); if (chunk != nullptr) { m_chunksPending -= 1; - m_chunksUnused.push(std::move(chunk)); - m_condOnSync.notify_one(); } diff --git a/src/dxvk/dxvk_cs.h b/src/dxvk/dxvk_cs.h index 7f4fd16ba..fec6194b5 100644 --- a/src/dxvk/dxvk_cs.h +++ b/src/dxvk/dxvk_cs.h @@ -152,9 +152,8 @@ namespace dxvk { * Can be used to efficiently play back large * command lists recorded on another thread. * \param [in] chunk The chunk to dispatch - * \returns New chunk for the next submissions */ - Rc dispatchChunk(Rc&& chunk); + void dispatchChunk(Rc&& chunk); /** * \brief Synchronizes with the thread @@ -175,7 +174,6 @@ namespace dxvk { std::condition_variable m_condOnAdd; std::condition_variable m_condOnSync; std::queue> m_chunksQueued; - std::queue> m_chunksUnused; std::thread m_thread; uint32_t m_chunksPending = 0;