#include "dxvk_hud_stats.h" namespace dxvk::hud { HudStats::HudStats(HudElements elements) : m_elements(filterElements(elements)) { } HudStats::~HudStats() { } void HudStats::update(const Rc& device) { if (m_elements.isClear()) return; // For some counters, we'll display the absolute value, // for others, the average counter increment per frame. DxvkStatCounters nextCounters = device->getStatCounters(); m_diffCounters = nextCounters.diff(m_prevCounters); m_prevCounters = nextCounters; } HudPos HudStats::render( const Rc& context, HudRenderer& renderer, HudPos position) { if (m_elements.test(HudElement::StatSubmissions)) position = this->printSubmissionStats(context, renderer, position); if (m_elements.test(HudElement::StatDrawCalls)) position = this->printDrawCallStats(context, renderer, position); if (m_elements.test(HudElement::StatPipelines)) position = this->printPipelineStats(context, renderer, position); if (m_elements.test(HudElement::StatMemory)) position = this->printMemoryStats(context, renderer, position); return position; } HudPos HudStats::printDrawCallStats( const Rc& context, HudRenderer& renderer, HudPos position) { const uint64_t frameCount = std::max(m_diffCounters.getCtr(DxvkStatCounter::QueuePresentCount), 1); const uint64_t gpCalls = m_diffCounters.getCtr(DxvkStatCounter::CmdDrawCalls) / frameCount; const uint64_t cpCalls = m_diffCounters.getCtr(DxvkStatCounter::CmdDispatchCalls) / frameCount; const uint64_t rpCalls = m_diffCounters.getCtr(DxvkStatCounter::CmdRenderPassCount) / frameCount; const std::string strDrawCalls = str::format("Draw calls: ", gpCalls); const std::string strDispatchCalls = str::format("Dispatch calls: ", cpCalls); const std::string strRenderPasses = str::format("Render passes: ", rpCalls); renderer.drawText(context, 16.0f, { position.x, position.y }, { 1.0f, 1.0f, 1.0f, 1.0f }, strDrawCalls); renderer.drawText(context, 16.0f, { position.x, position.y + 20.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, strDispatchCalls); renderer.drawText(context, 16.0f, { position.x, position.y + 40.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, strRenderPasses); return { position.x, position.y + 64 }; } HudPos HudStats::printSubmissionStats( const Rc& context, HudRenderer& renderer, HudPos position) { const uint64_t frameCount = std::max(m_diffCounters.getCtr(DxvkStatCounter::QueuePresentCount), 1); const uint64_t numSubmits = m_diffCounters.getCtr(DxvkStatCounter::QueueSubmitCount) / frameCount; const std::string strSubmissions = str::format("Queue submissions: ", numSubmits); renderer.drawText(context, 16.0f, { position.x, position.y }, { 1.0f, 1.0f, 1.0f, 1.0f }, strSubmissions); return { position.x, position.y + 24.0f }; } HudPos HudStats::printPipelineStats( const Rc& context, HudRenderer& renderer, HudPos position) { const uint64_t gpCount = m_prevCounters.getCtr(DxvkStatCounter::PipeCountGraphics); const uint64_t cpCount = m_prevCounters.getCtr(DxvkStatCounter::PipeCountCompute); const std::string strGpCount = str::format("Graphics pipelines: ", gpCount); const std::string strCpCount = str::format("Compute pipelines: ", cpCount); renderer.drawText(context, 16.0f, { position.x, position.y }, { 1.0f, 1.0f, 1.0f, 1.0f }, strGpCount); renderer.drawText(context, 16.0f, { position.x, position.y + 20.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, strCpCount); return { position.x, position.y + 44.0f }; } HudPos HudStats::printMemoryStats( const Rc& context, HudRenderer& renderer, HudPos position) { constexpr uint64_t mib = 1024 * 1024; const uint64_t memAllocated = m_prevCounters.getCtr(DxvkStatCounter::MemoryAllocated); const uint64_t memUsed = m_prevCounters.getCtr(DxvkStatCounter::MemoryUsed); const std::string strMemAllocated = str::format("Memory allocated: ", memAllocated / mib, " MB"); const std::string strMemUsed = str::format("Memory used: ", memUsed / mib, " MB"); renderer.drawText(context, 16.0f, { position.x, position.y }, { 1.0f, 1.0f, 1.0f, 1.0f }, strMemAllocated); renderer.drawText(context, 16.0f, { position.x, position.y + 20.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, strMemUsed); return { position.x, position.y + 44.0f }; } HudElements HudStats::filterElements(HudElements elements) { return elements & HudElements( HudElement::StatDrawCalls, HudElement::StatSubmissions, HudElement::StatPipelines, HudElement::StatMemory); } }