[dxvk] Estimate GPU idle time based on cleanup thread activity

We'll assume that GPU idle time == time spent waiting for new
command lists to be added to the queue of the cleanup thread.
This isn't entirely accurate, especially if CPU load is very
high, but should be good enough.
This commit is contained in:
Philip Rebohle 2019-07-18 22:52:20 +02:00
parent 02d917c680
commit 3d86ecd94d
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 23 additions and 3 deletions

View File

@ -137,9 +137,16 @@ namespace dxvk {
std::unique_lock<std::mutex> lock(m_mutex);
while (!m_stopped.load()) {
m_submitCond.wait(lock, [this] {
return m_stopped.load() || !m_finishQueue.empty();
});
if (m_finishQueue.empty()) {
auto t0 = std::chrono::high_resolution_clock::now();
m_submitCond.wait(lock, [this] {
return m_stopped.load() || !m_finishQueue.empty();
});
auto t1 = std::chrono::high_resolution_clock::now();
m_gpuIdle += std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count();
}
if (m_stopped.load())
return;

View File

@ -80,6 +80,18 @@ namespace dxvk {
uint32_t pendingSubmissions() const {
return m_pending.load();
}
/**
* \brief Retrieves estimated GPU idle time
*
* This is a monotonically increasing counter
* which can be evaluated periodically in order
* to calculate the GPU load.
* \returns Accumulated GPU idle time, in us
*/
uint64_t gpuIdleTicks() const {
return m_gpuIdle.load();
}
/**
* \brief Submits a command list asynchronously
@ -147,6 +159,7 @@ namespace dxvk {
std::atomic<bool> m_stopped = { false };
std::atomic<uint32_t> m_pending = { 0u };
std::atomic<uint64_t> m_gpuIdle = { 0ull };
std::mutex m_mutex;
std::mutex m_mutexQueue;