mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-11 19:24:11 +01:00
[dxvk] Introduce single-use mode for CS chunks
This allows us to reset the CS chunk immediately while executing it, which can reduce the overhead of the reset operation and may lead to resources being released earlier.
This commit is contained in:
parent
e744117042
commit
c61200d35f
@ -3350,7 +3350,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
DxvkCsChunkRef D3D11DeviceContext::AllocCsChunk() {
|
DxvkCsChunkRef D3D11DeviceContext::AllocCsChunk() {
|
||||||
return m_parent->AllocCsChunk();
|
return m_parent->AllocCsChunk(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -333,8 +333,8 @@ namespace dxvk {
|
|||||||
DXGI_FORMAT Format,
|
DXGI_FORMAT Format,
|
||||||
DXGI_VK_FORMAT_MODE Mode) const;
|
DXGI_VK_FORMAT_MODE Mode) const;
|
||||||
|
|
||||||
DxvkCsChunkRef AllocCsChunk() {
|
DxvkCsChunkRef AllocCsChunk(DxvkCsChunkFlags flags) {
|
||||||
DxvkCsChunk* chunk = m_csChunkPool.allocChunk();
|
DxvkCsChunk* chunk = m_csChunkPool.allocChunk(flags);
|
||||||
return DxvkCsChunkRef(chunk, &m_csChunkPool);
|
return DxvkCsChunkRef(chunk, &m_csChunkPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,12 +12,32 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkCsChunk::init(DxvkCsChunkFlags flags) {
|
||||||
|
m_flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkCsChunk::executeAll(DxvkContext* ctx) {
|
void DxvkCsChunk::executeAll(DxvkContext* ctx) {
|
||||||
auto cmd = m_head;
|
auto cmd = m_head;
|
||||||
|
|
||||||
while (cmd != nullptr) {
|
if (m_flags.test(DxvkCsChunkFlag::SingleUse)) {
|
||||||
cmd->exec(ctx);
|
m_commandCount = 0;
|
||||||
cmd = cmd->next();
|
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() {
|
void DxvkCsChunk::reset() {
|
||||||
auto cmd = m_head;
|
auto cmd = m_head;
|
||||||
|
|
||||||
|
m_commandCount = 0;
|
||||||
|
m_commandOffset = 0;
|
||||||
|
|
||||||
while (cmd != nullptr) {
|
while (cmd != nullptr) {
|
||||||
auto next = cmd->next();
|
auto next = cmd->next();
|
||||||
cmd->~DxvkCsCmd();
|
cmd->~DxvkCsCmd();
|
||||||
cmd = next;
|
cmd = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_commandCount = 0;
|
|
||||||
m_commandOffset = 0;
|
|
||||||
|
|
||||||
m_head = nullptr;
|
m_head = nullptr;
|
||||||
m_tail = nullptr;
|
m_tail = nullptr;
|
||||||
}
|
}
|
||||||
@ -50,17 +70,22 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkCsChunk* DxvkCsChunkPool::allocChunk() {
|
DxvkCsChunk* DxvkCsChunkPool::allocChunk(DxvkCsChunkFlags flags) {
|
||||||
|
DxvkCsChunk* chunk = nullptr;
|
||||||
|
|
||||||
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||||
|
|
||||||
if (m_chunks.size() != 0) {
|
if (m_chunks.size() != 0) {
|
||||||
DxvkCsChunk* chunk = m_chunks.back();
|
chunk = m_chunks.back();
|
||||||
m_chunks.pop_back();
|
m_chunks.pop_back();
|
||||||
return chunk;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DxvkCsChunk();
|
if (!chunk)
|
||||||
|
chunk = new DxvkCsChunk();
|
||||||
|
|
||||||
|
chunk->init(flags);
|
||||||
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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<DxvkCsChunkFlag>;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Command chunk
|
* \brief Command chunk
|
||||||
*
|
*
|
||||||
@ -103,7 +115,7 @@ namespace dxvk {
|
|||||||
size_t commandCount() const {
|
size_t commandCount() const {
|
||||||
return m_commandCount;
|
return m_commandCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Tries to add a command to the chunk
|
* \brief Tries to add a command to the chunk
|
||||||
*
|
*
|
||||||
@ -136,6 +148,12 @@ namespace dxvk {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initializes chunk for recording
|
||||||
|
* \param [in] flags Chunk flags
|
||||||
|
*/
|
||||||
|
void init(DxvkCsChunkFlags flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Executes all commands
|
* \brief Executes all commands
|
||||||
*
|
*
|
||||||
@ -161,6 +179,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkCsCmd* m_head = nullptr;
|
DxvkCsCmd* m_head = nullptr;
|
||||||
DxvkCsCmd* m_tail = nullptr;
|
DxvkCsCmd* m_tail = nullptr;
|
||||||
|
|
||||||
|
DxvkCsChunkFlags m_flags;
|
||||||
|
|
||||||
alignas(64)
|
alignas(64)
|
||||||
char m_data[MaxBlockSize];
|
char m_data[MaxBlockSize];
|
||||||
@ -190,9 +210,10 @@ namespace dxvk {
|
|||||||
*
|
*
|
||||||
* Takes an existing chunk from the pool,
|
* Takes an existing chunk from the pool,
|
||||||
* or creates a new one if necessary.
|
* or creates a new one if necessary.
|
||||||
|
* \param [in] flags Chunk flags
|
||||||
* \returns Allocated chunk object
|
* \returns Allocated chunk object
|
||||||
*/
|
*/
|
||||||
DxvkCsChunk* allocChunk();
|
DxvkCsChunk* allocChunk(DxvkCsChunkFlags flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Releases a chunk
|
* \brief Releases a chunk
|
||||||
@ -288,8 +309,8 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Command stream thread
|
* \brief Command stream thread
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user