mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 22:24:15 +01:00
[dxvk] Recycle CS chunks
This commit is contained in:
parent
70b639784b
commit
7c3a9beb22
@ -266,10 +266,8 @@ namespace dxvk {
|
||||
|
||||
|
||||
void D3D11ImmediateContext::EmitCsChunk() {
|
||||
if (m_csChunk->commandCount() > 0) {
|
||||
m_csThread.dispatchChunk(std::move(m_csChunk));
|
||||
m_csChunk = new DxvkCsChunk();
|
||||
}
|
||||
if (m_csChunk->commandCount() > 0)
|
||||
m_csChunk = m_csThread.dispatchChunk(std::move(m_csChunk));
|
||||
}
|
||||
|
||||
}
|
@ -40,17 +40,37 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkCsThread::dispatchChunk(Rc<DxvkCsChunk>&& chunk) {
|
||||
Rc<DxvkCsChunk> DxvkCsThread::dispatchChunk(Rc<DxvkCsChunk>&& chunk) {
|
||||
Rc<DxvkCsChunk> nextChunk = nullptr;
|
||||
|
||||
{ std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_chunks.push(std::move(chunk));
|
||||
m_chunksQueued.push(std::move(chunk));
|
||||
m_chunksPending += 1;
|
||||
|
||||
m_condOnSync.wait(lock, [this] {
|
||||
return m_stopped.load() || (m_chunksPending < MaxChunksInFlight);
|
||||
});
|
||||
// If a large number of chunks are queued up, wait for
|
||||
// some of them to be processed in order to avoid memory
|
||||
// leaks, stuttering, input lag and similar issues.
|
||||
if (m_chunksPending >= MaxChunksInFlight) {
|
||||
m_condOnSync.wait(lock, [this] {
|
||||
return (m_chunksPending < MaxChunksInFlight / 2)
|
||||
|| (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;
|
||||
}
|
||||
|
||||
|
||||
@ -64,30 +84,31 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxvkCsThread::threadFunc() {
|
||||
Rc<DxvkCsChunk> chunk;
|
||||
|
||||
while (!m_stopped.load()) {
|
||||
Rc<DxvkCsChunk> chunk;
|
||||
|
||||
{ std::unique_lock<std::mutex> lock(m_mutex);
|
||||
if (chunk != nullptr) {
|
||||
m_chunksPending -= 1;
|
||||
m_chunksUnused.push(std::move(chunk));
|
||||
|
||||
m_condOnSync.notify_one();
|
||||
}
|
||||
|
||||
m_condOnAdd.wait(lock, [this] {
|
||||
return m_stopped.load() || (m_chunks.size() != 0);
|
||||
return m_stopped.load() || (m_chunksQueued.size() != 0);
|
||||
});
|
||||
|
||||
if (m_chunks.size() != 0) {
|
||||
chunk = std::move(m_chunks.front());
|
||||
m_chunks.pop();
|
||||
if (m_chunksQueued.size() != 0) {
|
||||
chunk = std::move(m_chunksQueued.front());
|
||||
m_chunksQueued.pop();
|
||||
} else {
|
||||
chunk = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk != nullptr) {
|
||||
if (chunk != nullptr)
|
||||
chunk->executeAll(m_context.ptr());
|
||||
|
||||
{ std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_chunksPending -= 1;
|
||||
}
|
||||
|
||||
m_condOnSync.notify_one();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ namespace dxvk {
|
||||
* Stores a list of commands.
|
||||
*/
|
||||
class DxvkCsChunk : public RcObject {
|
||||
constexpr static size_t MaxCommands = 64;
|
||||
constexpr static size_t MaxCommands = 1024;
|
||||
constexpr static size_t MaxBlockSize = 64 * MaxCommands;
|
||||
public:
|
||||
|
||||
@ -140,7 +140,7 @@ namespace dxvk {
|
||||
class DxvkCsThread {
|
||||
// Limit the number of chunks in the queue
|
||||
// to prevent memory leaks, stuttering etc.
|
||||
constexpr static uint32_t MaxChunksInFlight = 128;
|
||||
constexpr static uint32_t MaxChunksInFlight = 16;
|
||||
public:
|
||||
|
||||
DxvkCsThread(const Rc<DxvkContext>& context);
|
||||
@ -152,8 +152,9 @@ 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
|
||||
*/
|
||||
void dispatchChunk(Rc<DxvkCsChunk>&& chunk);
|
||||
Rc<DxvkCsChunk> dispatchChunk(Rc<DxvkCsChunk>&& chunk);
|
||||
|
||||
/**
|
||||
* \brief Synchronizes with the thread
|
||||
@ -173,7 +174,8 @@ namespace dxvk {
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_condOnAdd;
|
||||
std::condition_variable m_condOnSync;
|
||||
std::queue<Rc<DxvkCsChunk>> m_chunks;
|
||||
std::queue<Rc<DxvkCsChunk>> m_chunksQueued;
|
||||
std::queue<Rc<DxvkCsChunk>> m_chunksUnused;
|
||||
std::thread m_thread;
|
||||
|
||||
uint32_t m_chunksPending = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user