mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +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 {
|
namespace dxvk {
|
||||||
|
|
||||||
D3D11CommandList::D3D11CommandList(
|
D3D11CommandList::D3D11CommandList(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
UINT ContextFlags)
|
D3D11CommandListAllocator* pAllocator)
|
||||||
: m_device (pDevice),
|
: m_device(pDevice), m_allocator(pAllocator) {
|
||||||
m_contextFlags(ContextFlags) { }
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
D3D11CommandList::~D3D11CommandList() {
|
D3D11CommandList::~D3D11CommandList() {
|
||||||
@ -25,8 +26,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
ULONG STDMETHODCALLTYPE D3D11CommandList::Release() {
|
ULONG STDMETHODCALLTYPE D3D11CommandList::Release() {
|
||||||
ULONG refCount = --m_refCount;
|
ULONG refCount = --m_refCount;
|
||||||
if (!refCount)
|
|
||||||
|
if (!refCount) {
|
||||||
|
Reset();
|
||||||
|
|
||||||
|
m_allocator->RecycleCommandList(this);
|
||||||
m_device->Release();
|
m_device->Release();
|
||||||
|
}
|
||||||
|
|
||||||
return refCount;
|
return refCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,6 +88,15 @@ namespace dxvk {
|
|||||||
|
|
||||||
MarkSubmitted();
|
MarkSubmitted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11CommandList::Reset() {
|
||||||
|
m_chunks.clear();
|
||||||
|
|
||||||
|
m_contextFlags = 0;
|
||||||
|
m_submitted = false;
|
||||||
|
m_warned = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11CommandList::MarkSubmitted() {
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "d3d11_context.h"
|
#include "d3d11_context.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
|
class D3D11CommandListAllocator;
|
||||||
|
|
||||||
class D3D11CommandList : public D3D11DeviceChild<ID3D11CommandList, NoWrapper> {
|
class D3D11CommandList : public D3D11DeviceChild<ID3D11CommandList, NoWrapper> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D11CommandList(
|
D3D11CommandList(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
UINT ContextFlags);
|
D3D11CommandListAllocator* pAllocator);
|
||||||
|
|
||||||
~D3D11CommandList();
|
~D3D11CommandList();
|
||||||
|
|
||||||
@ -26,6 +31,10 @@ namespace dxvk {
|
|||||||
ID3D11Device **ppDevice) final;
|
ID3D11Device **ppDevice) final;
|
||||||
|
|
||||||
UINT STDMETHODCALLTYPE GetContextFlags() final;
|
UINT STDMETHODCALLTYPE GetContextFlags() final;
|
||||||
|
|
||||||
|
void SetContextFlags(UINT ContextFlags) {
|
||||||
|
m_contextFlags = ContextFlags;
|
||||||
|
}
|
||||||
|
|
||||||
void AddChunk(
|
void AddChunk(
|
||||||
DxvkCsChunkRef&& Chunk);
|
DxvkCsChunkRef&& Chunk);
|
||||||
@ -38,9 +47,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
D3D11Device* const m_device;
|
D3D11Device* m_device;
|
||||||
UINT const m_contextFlags;
|
D3D11CommandListAllocator* m_allocator;
|
||||||
|
|
||||||
|
uint32_t m_contextFlags = 0;
|
||||||
|
|
||||||
std::vector<DxvkCsChunkRef> m_chunks;
|
std::vector<DxvkCsChunkRef> m_chunks;
|
||||||
|
|
||||||
std::atomic<bool> m_submitted = { false };
|
std::atomic<bool> m_submitted = { false };
|
||||||
@ -48,8 +59,56 @@ namespace dxvk {
|
|||||||
|
|
||||||
std::atomic<uint32_t> m_refCount = { 0u };
|
std::atomic<uint32_t> m_refCount = { 0u };
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
void MarkSubmitted();
|
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() {
|
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_dxvkAdapter (m_dxvkDevice->adapter()),
|
||||||
m_d3d11Formats (m_dxvkAdapter),
|
m_d3d11Formats (m_dxvkAdapter),
|
||||||
m_d3d11Options (m_dxvkAdapter->instance()->config()),
|
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_initializer = new D3D11Initializer(this);
|
||||||
m_context = new D3D11ImmediateContext(this, m_dxvkDevice);
|
m_context = new D3D11ImmediateContext(this, m_dxvkDevice);
|
||||||
m_d3d10Device = new D3D10Device(this, m_context);
|
m_d3d10Device = new D3D10Device(this, m_context);
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "../util/com/com_private_data.h"
|
#include "../util/com/com_private_data.h"
|
||||||
|
|
||||||
|
#include "d3d11_cmdlist.h"
|
||||||
#include "d3d11_counter_buffer.h"
|
#include "d3d11_counter_buffer.h"
|
||||||
#include "d3d11_initializer.h"
|
#include "d3d11_initializer.h"
|
||||||
#include "d3d11_interfaces.h"
|
#include "d3d11_interfaces.h"
|
||||||
@ -411,6 +412,10 @@ namespace dxvk {
|
|||||||
DxvkCsChunk* chunk = m_csChunkPool.allocChunk(flags);
|
DxvkCsChunk* chunk = m_csChunkPool.allocChunk(flags);
|
||||||
return DxvkCsChunkRef(chunk, &m_csChunkPool);
|
return DxvkCsChunkRef(chunk, &m_csChunkPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3D11CommandList* AllocCommandList(UINT ContextFlags) {
|
||||||
|
return m_commandListAllocator.AllocCommandList(ContextFlags);
|
||||||
|
}
|
||||||
|
|
||||||
const D3D11Options* GetOptions() const {
|
const D3D11Options* GetOptions() const {
|
||||||
return &m_d3d11Options;
|
return &m_d3d11Options;
|
||||||
@ -465,6 +470,7 @@ namespace dxvk {
|
|||||||
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
|
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
|
||||||
D3D11StateObjectSet<D3D11SamplerState> m_samplerObjects;
|
D3D11StateObjectSet<D3D11SamplerState> m_samplerObjects;
|
||||||
D3D11ShaderModuleSet m_shaderModules;
|
D3D11ShaderModuleSet m_shaderModules;
|
||||||
|
D3D11CommandListAllocator m_commandListAllocator;
|
||||||
|
|
||||||
Rc<D3D11CounterBuffer> CreateUAVCounterBuffer();
|
Rc<D3D11CounterBuffer> CreateUAVCounterBuffer();
|
||||||
Rc<D3D11CounterBuffer> CreateXFBCounterBuffer();
|
Rc<D3D11CounterBuffer> CreateXFBCounterBuffer();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user