diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 1fa53d8df..6ac4c4a51 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3350,7 +3350,7 @@ namespace dxvk { DxvkCsChunkRef D3D11DeviceContext::AllocCsChunk() { - return m_parent->AllocCsChunk(); + return m_parent->AllocCsChunk(0); } } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index c8fccffc8..0fe46678c 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -333,8 +333,8 @@ namespace dxvk { DXGI_FORMAT Format, DXGI_VK_FORMAT_MODE Mode) const; - DxvkCsChunkRef AllocCsChunk() { - DxvkCsChunk* chunk = m_csChunkPool.allocChunk(); + DxvkCsChunkRef AllocCsChunk(DxvkCsChunkFlags flags) { + DxvkCsChunk* chunk = m_csChunkPool.allocChunk(flags); return DxvkCsChunkRef(chunk, &m_csChunkPool); } diff --git a/src/dxvk/dxvk_cs.cpp b/src/dxvk/dxvk_cs.cpp index ff19f9b50..bdc4f0dad 100644 --- a/src/dxvk/dxvk_cs.cpp +++ b/src/dxvk/dxvk_cs.cpp @@ -12,12 +12,32 @@ namespace dxvk { } + void DxvkCsChunk::init(DxvkCsChunkFlags flags) { + m_flags = flags; + } + + void DxvkCsChunk::executeAll(DxvkContext* ctx) { auto cmd = m_head; - while (cmd != nullptr) { - cmd->exec(ctx); - cmd = cmd->next(); + if (m_flags.test(DxvkCsChunkFlag::SingleUse)) { + m_commandCount = 0; + m_commandOffset = 0; + + while (cmd != nullptr) { + auto next = cmd->next(); + cmd->exec(ctx); + cmd->~DxvkCsCmd(); + cmd = next; + } + + m_head = nullptr; + m_tail = nullptr; + } else { + while (cmd != nullptr) { + cmd->exec(ctx); + cmd = cmd->next(); + } } } @@ -25,15 +45,15 @@ namespace dxvk { void DxvkCsChunk::reset() { auto cmd = m_head; + m_commandCount = 0; + m_commandOffset = 0; + while (cmd != nullptr) { auto next = cmd->next(); cmd->~DxvkCsCmd(); cmd = next; } - m_commandCount = 0; - m_commandOffset = 0; - m_head = nullptr; m_tail = nullptr; } @@ -50,17 +70,22 @@ namespace dxvk { } - DxvkCsChunk* DxvkCsChunkPool::allocChunk() { + DxvkCsChunk* DxvkCsChunkPool::allocChunk(DxvkCsChunkFlags flags) { + DxvkCsChunk* chunk = nullptr; + { std::lock_guard lock(m_mutex); if (m_chunks.size() != 0) { - DxvkCsChunk* chunk = m_chunks.back(); + chunk = m_chunks.back(); m_chunks.pop_back(); - return chunk; } } - return new DxvkCsChunk(); + if (!chunk) + chunk = new DxvkCsChunk(); + + chunk->init(flags); + return chunk; } diff --git a/src/dxvk/dxvk_cs.h b/src/dxvk/dxvk_cs.h index 82113af8f..bbc54e177 100644 --- a/src/dxvk/dxvk_cs.h +++ b/src/dxvk/dxvk_cs.h @@ -82,6 +82,18 @@ namespace dxvk { }; + /** + * \brief Submission flags + */ + enum class DxvkCsChunkFlag : uint32_t { + /// Indicates that the submitted chunk will + /// no longer be needed after one submission. + SingleUse, + }; + + using DxvkCsChunkFlags = Flags; + + /** * \brief Command chunk * @@ -103,7 +115,7 @@ namespace dxvk { size_t commandCount() const { return m_commandCount; } - + /** * \brief Tries to add a command to the chunk * @@ -136,6 +148,12 @@ namespace dxvk { return true; } + /** + * \brief Initializes chunk for recording + * \param [in] flags Chunk flags + */ + void init(DxvkCsChunkFlags flags); + /** * \brief Executes all commands * @@ -161,6 +179,8 @@ namespace dxvk { DxvkCsCmd* m_head = nullptr; DxvkCsCmd* m_tail = nullptr; + + DxvkCsChunkFlags m_flags; alignas(64) char m_data[MaxBlockSize]; @@ -190,9 +210,10 @@ namespace dxvk { * * Takes an existing chunk from the pool, * or creates a new one if necessary. + * \param [in] flags Chunk flags * \returns Allocated chunk object */ - DxvkCsChunk* allocChunk(); + DxvkCsChunk* allocChunk(DxvkCsChunkFlags flags); /** * \brief Releases a chunk @@ -288,8 +309,8 @@ namespace dxvk { } }; - - + + /** * \brief Command stream thread *