Don't save resources to be released later when the GPU is already done with them.

This commit is contained in:
Bryan Turkelson 2024-12-02 19:39:42 -05:00
Родитель e430795332
Коммит b992a0028d
3 изменённых файлов: 21 добавлений и 4 удалений

Просмотреть файл

@ -55,7 +55,8 @@ namespace Dml
// for example, an allocation from BucketizedBufferAllocator attempts to queue a reference
// to its underlying D3D resource when freed. Furthermore, these references are unnecessary
// since Close() already blocks for scheduled GPU work before clearing m_queuedReferences.
if (!m_closing)
// If the CommandQueue is releasing completed references, we don't need to queue the reference up again.
if (!m_closing && !m_releasing)
{
QueuedReference queuedReference = {GetLastFenceValue(), object};
@ -66,7 +67,13 @@ namespace Dml
++queuedReference.fenceValue;
}
m_queuedReferences.push_back(queuedReference);
// We don't need to queue references whose work has already completed on the GPU by the time the CPU queues
// the reference. Just let it go out of scope.
uint64_t completedValue = GetFence()->GetCompletedValue();
if (queuedReference.fenceValue > completedValue)
{
m_queuedReferences.push_back(queuedReference);
}
}
}
@ -84,10 +91,12 @@ namespace Dml
void CommandQueue::ReleaseCompletedReferences()
{
uint64_t completedValue = GetFence()->GetCompletedValue();
m_releasing = true;
while (!m_queuedReferences.empty() && m_queuedReferences.front().fenceValue <= completedValue)
{
m_queuedReferences.pop_front();
}
m_releasing = false;
}
} // namespace Dml

Просмотреть файл

@ -62,6 +62,7 @@ namespace Dml
ComPtr<ID3D12Fence> m_fence;
uint64_t m_lastFenceValue = 0;
bool m_closing = false;
bool m_releasing = false;
bool m_cpuSyncSpinningEnabled = false;
};

Просмотреть файл

@ -162,12 +162,19 @@ namespace Dml
{
assert(!m_closed);
if (!m_currentRecorder || !m_currentRecorder->HasUnsubmittedWork())
if (!m_currentRecorder)
{
// Nothing to flush
return;
}
if (!m_currentRecorder->HasUnsubmittedWork())
{
// Even if we have no queued work, we can still release resources that may no longer be needed.
ReleaseCompletedReferences();
return;
}
m_currentRecorder->CloseAndExecute();
ReleaseCompletedReferences();
@ -183,7 +190,7 @@ namespace Dml
assert(!m_closed);
// If something has been recorded into a command list but not submitted yet, it means that the *next* fence
// value is the one to signal completion.
bool waitForUnsubmittedWork = (m_currentRecorder != nullptr);
bool waitForUnsubmittedWork = ((m_currentRecorder != nullptr) && (m_currentRecorder->HasUnsubmittedWork()));
m_queue->QueueReference(object, waitForUnsubmittedWork);
}