mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[d3d11] Recycle command lists from deferred contexts
Can save a few memory allocations and deallocations at runtime.
This commit is contained in:
parent
7f66373a69
commit
4e3da45fde
@ -4,10 +4,11 @@
|
||||
namespace dxvk {
|
||||
|
||||
D3D11CommandList::D3D11CommandList(
|
||||
D3D11Device* pDevice,
|
||||
UINT ContextFlags)
|
||||
: m_device (pDevice),
|
||||
m_contextFlags(ContextFlags) { }
|
||||
D3D11Device* pDevice,
|
||||
D3D11CommandListAllocator* pAllocator)
|
||||
: m_device(pDevice), m_allocator(pAllocator) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
D3D11CommandList::~D3D11CommandList() {
|
||||
@ -25,8 +26,14 @@ namespace dxvk {
|
||||
|
||||
ULONG STDMETHODCALLTYPE D3D11CommandList::Release() {
|
||||
ULONG refCount = --m_refCount;
|
||||
if (!refCount)
|
||||
|
||||
if (!refCount) {
|
||||
Reset();
|
||||
|
||||
m_allocator->RecycleCommandList(this);
|
||||
m_device->Release();
|
||||
}
|
||||
|
||||
return refCount;
|
||||
}
|
||||
|
||||
@ -81,6 +88,15 @@ namespace dxvk {
|
||||
|
||||
MarkSubmitted();
|
||||
}
|
||||
|
||||
|
||||
void D3D11CommandList::Reset() {
|
||||
m_chunks.clear();
|
||||
|
||||
m_contextFlags = 0;
|
||||
m_submitted = false;
|
||||
m_warned = false;
|
||||
}
|
||||
|
||||
|
||||
void D3D11CommandList::MarkSubmitted() {
|
||||
@ -92,4 +108,42 @@ namespace dxvk {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
D3D11CommandListAllocator::D3D11CommandListAllocator(D3D11Device* pDevice)
|
||||
: m_device(pDevice) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
D3D11CommandListAllocator::~D3D11CommandListAllocator() {
|
||||
for (uint32_t i = 0; i < m_listCount; i++)
|
||||
delete m_lists[i];
|
||||
}
|
||||
|
||||
|
||||
D3D11CommandList* D3D11CommandListAllocator::AllocCommandList(
|
||||
UINT ContextFlags) {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
D3D11CommandList* result = nullptr;
|
||||
|
||||
if (m_listCount)
|
||||
result = m_lists[--m_listCount];
|
||||
else
|
||||
result = new D3D11CommandList(m_device, this);
|
||||
|
||||
result->SetContextFlags(ContextFlags);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void D3D11CommandListAllocator::RecycleCommandList(
|
||||
D3D11CommandList* pCommandList) {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
if (m_listCount < m_lists.size())
|
||||
m_lists[m_listCount++] = pCommandList;
|
||||
else
|
||||
delete pCommandList;
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "d3d11_context.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
class D3D11CommandListAllocator;
|
||||
|
||||
class D3D11CommandList : public D3D11DeviceChild<ID3D11CommandList, NoWrapper> {
|
||||
|
||||
public:
|
||||
|
||||
D3D11CommandList(
|
||||
D3D11Device* pDevice,
|
||||
UINT ContextFlags);
|
||||
D3D11Device* pDevice,
|
||||
D3D11CommandListAllocator* pAllocator);
|
||||
|
||||
~D3D11CommandList();
|
||||
|
||||
@ -26,6 +31,10 @@ namespace dxvk {
|
||||
ID3D11Device **ppDevice) final;
|
||||
|
||||
UINT STDMETHODCALLTYPE GetContextFlags() final;
|
||||
|
||||
void SetContextFlags(UINT ContextFlags) {
|
||||
m_contextFlags = ContextFlags;
|
||||
}
|
||||
|
||||
void AddChunk(
|
||||
DxvkCsChunkRef&& Chunk);
|
||||
@ -38,9 +47,11 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
D3D11Device* const m_device;
|
||||
UINT const m_contextFlags;
|
||||
|
||||
D3D11Device* m_device;
|
||||
D3D11CommandListAllocator* m_allocator;
|
||||
|
||||
uint32_t m_contextFlags = 0;
|
||||
|
||||
std::vector<DxvkCsChunkRef> m_chunks;
|
||||
|
||||
std::atomic<bool> m_submitted = { false };
|
||||
@ -48,8 +59,56 @@ namespace dxvk {
|
||||
|
||||
std::atomic<uint32_t> m_refCount = { 0u };
|
||||
|
||||
void Reset();
|
||||
|
||||
void MarkSubmitted();
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Command list allocator
|
||||
*
|
||||
* Creates and recycles command list instances
|
||||
* in order to reduce deferred context overhead.
|
||||
*/
|
||||
class D3D11CommandListAllocator {
|
||||
|
||||
public:
|
||||
|
||||
D3D11CommandListAllocator(
|
||||
D3D11Device* pDevice);
|
||||
|
||||
~D3D11CommandListAllocator();
|
||||
|
||||
/**
|
||||
* \brief Allocates a command list
|
||||
*
|
||||
* \param [in] ContextFlags Flags of the parent context
|
||||
* \returns The command list
|
||||
*/
|
||||
D3D11CommandList* AllocCommandList(
|
||||
UINT ContextFlags);
|
||||
|
||||
/**
|
||||
* \brief Recycles a command list
|
||||
*
|
||||
* Automatically called when the command list
|
||||
* in question reaches a ref count of zero.
|
||||
* \param [in] pCommandList The command list
|
||||
*/
|
||||
void RecycleCommandList(
|
||||
D3D11CommandList* pCommandList);
|
||||
|
||||
private:
|
||||
|
||||
D3D11Device* m_device;
|
||||
|
||||
std::mutex m_mutex;
|
||||
std::array<D3D11CommandList*, 64> m_lists;
|
||||
|
||||
uint32_t m_listCount = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -309,7 +309,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
Com<D3D11CommandList> D3D11DeferredContext::CreateCommandList() {
|
||||
return new D3D11CommandList(m_parent, m_contextFlags);
|
||||
return m_parent->AllocCommandList(m_contextFlags);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,7 +39,8 @@ namespace dxvk {
|
||||
m_dxvkAdapter (m_dxvkDevice->adapter()),
|
||||
m_d3d11Formats (m_dxvkAdapter),
|
||||
m_d3d11Options (m_dxvkAdapter->instance()->config()),
|
||||
m_dxbcOptions (m_dxvkDevice, m_d3d11Options) {
|
||||
m_dxbcOptions (m_dxvkDevice, m_d3d11Options),
|
||||
m_commandListAllocator(this) {
|
||||
m_initializer = new D3D11Initializer(this);
|
||||
m_context = new D3D11ImmediateContext(this, m_dxvkDevice);
|
||||
m_d3d10Device = new D3D10Device(this, m_context);
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "../util/com/com_private_data.h"
|
||||
|
||||
#include "d3d11_cmdlist.h"
|
||||
#include "d3d11_counter_buffer.h"
|
||||
#include "d3d11_initializer.h"
|
||||
#include "d3d11_interfaces.h"
|
||||
@ -411,6 +412,10 @@ namespace dxvk {
|
||||
DxvkCsChunk* chunk = m_csChunkPool.allocChunk(flags);
|
||||
return DxvkCsChunkRef(chunk, &m_csChunkPool);
|
||||
}
|
||||
|
||||
D3D11CommandList* AllocCommandList(UINT ContextFlags) {
|
||||
return m_commandListAllocator.AllocCommandList(ContextFlags);
|
||||
}
|
||||
|
||||
const D3D11Options* GetOptions() const {
|
||||
return &m_d3d11Options;
|
||||
@ -465,6 +470,7 @@ namespace dxvk {
|
||||
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
|
||||
D3D11StateObjectSet<D3D11SamplerState> m_samplerObjects;
|
||||
D3D11ShaderModuleSet m_shaderModules;
|
||||
D3D11CommandListAllocator m_commandListAllocator;
|
||||
|
||||
Rc<D3D11CounterBuffer> CreateUAVCounterBuffer();
|
||||
Rc<D3D11CounterBuffer> CreateXFBCounterBuffer();
|
||||
|
Loading…
x
Reference in New Issue
Block a user