From 8aa861022179b991b50aa2a58f74106426dda074 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 3 Apr 2018 11:56:12 +0200 Subject: [PATCH] [dxvk] Implement basic stat counters for draw calls, queue ops --- src/dxvk/dxvk_cmdlist.cpp | 1 + src/dxvk/dxvk_cmdlist.h | 25 +++++++++++++++++++++++++ src/dxvk/dxvk_context.cpp | 13 +++++++++++++ src/dxvk/dxvk_device.cpp | 27 ++++++++++++++++++++++++--- src/dxvk/dxvk_device.h | 13 +++++++++++++ 5 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 30f0471b..914f7c89 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -107,6 +107,7 @@ namespace dxvk { void DxvkCommandList::reset() { + m_statCounters.reset(); m_bufferTracker.reset(); m_eventTracker.reset(); m_queryTracker.reset(); diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index d711be5e..f214e3e5 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -11,6 +11,7 @@ #include "dxvk_pipelayout.h" #include "dxvk_query_tracker.h" #include "dxvk_staging.h" +#include "dxvk_stats.h" #include "dxvk_sync.h" namespace dxvk { @@ -56,6 +57,28 @@ namespace dxvk { */ VkResult synchronize(); + /** + * \brief Stat counters + * + * Retrieves some info about per-command list + * statistics, such as the number of draw calls + * or the number of pipelines compiled. + * \returns Read-only reference to stat counters + */ + const DxvkStatCounters& statCounters() const { + return m_statCounters; + } + + /** + * \brief Increments a stat counter value + * + * \param [in] ctr The counter to increment + * \param [in] val The value to add + */ + void addStatCtr(DxvkStatCounter ctr, uint32_t val) { + m_statCounters.addCtr(ctr, val); + } + /** * \brief Begins recording * @@ -69,6 +92,7 @@ namespace dxvk { * * Ends command buffer recording, making * the command list ready for submission. + * \param [in] stats Stat counters */ void endRecording(); @@ -536,6 +560,7 @@ namespace dxvk { DxvkQueryTracker m_queryTracker; DxvkEventTracker m_eventTracker; DxvkBufferTracker m_bufferTracker; + DxvkStatCounters m_statCounters; }; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 99598fca..c4e101e1 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -667,6 +667,8 @@ namespace dxvk { this->commitComputeBarriers(); } + + m_cmd->addStatCtr(DxvkStatCounter::CmdDispatchCalls, 1); } @@ -683,6 +685,8 @@ namespace dxvk { this->commitComputeBarriers(); } + + m_cmd->addStatCtr(DxvkStatCounter::CmdDispatchCalls, 1); } @@ -698,6 +702,8 @@ namespace dxvk { vertexCount, instanceCount, firstVertex, firstInstance); } + + m_cmd->addStatCtr(DxvkStatCounter::CmdDrawCalls, 1); } @@ -715,6 +721,8 @@ namespace dxvk { physicalSlice.offset(), count, stride); } + + m_cmd->addStatCtr(DxvkStatCounter::CmdDrawCalls, 1); } @@ -732,6 +740,8 @@ namespace dxvk { firstIndex, vertexOffset, firstInstance); } + + m_cmd->addStatCtr(DxvkStatCounter::CmdDrawCalls, 1); } @@ -749,6 +759,8 @@ namespace dxvk { physicalSlice.offset(), count, stride); } + + m_cmd->addStatCtr(DxvkStatCounter::CmdDrawCalls, 1); } @@ -1363,6 +1375,7 @@ namespace dxvk { m_cmd->cmdBeginRenderPass(&info, VK_SUBPASS_CONTENTS_INLINE); m_cmd->trackResource(framebuffer); + m_cmd->addStatCtr(DxvkStatCounter::CmdRenderPassCount, 1); } diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 2dddf000..5dc8627a 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -178,6 +178,18 @@ namespace dxvk { } + DxvkStatCounters DxvkDevice::getStatCounters() { + // TODO Add memory info + DxvkStatCounters result; + + { std::lock_guard lock(m_statLock); + result.merge(m_statCounters); + } + + return result; + } + + void DxvkDevice::initResources() { m_unboundResources.clearResources(this); } @@ -185,8 +197,13 @@ namespace dxvk { VkResult DxvkDevice::presentSwapImage( const VkPresentInfoKHR& presentInfo) { - std::lock_guard lock(m_submissionLock); - return m_vkd->vkQueuePresentKHR(m_presentQueue, &presentInfo); + { // Queue submissions are not thread safe + std::lock_guard queueLock(m_submissionLock); + std::lock_guard statLock(m_statLock); + + m_statCounters.addCtr(DxvkStatCounter::QueuePresentCount, 1); + return m_vkd->vkQueuePresentKHR(m_presentQueue, &presentInfo); + } } @@ -210,7 +227,11 @@ namespace dxvk { VkResult status; { // Queue submissions are not thread safe - std::lock_guard lock(m_submissionLock); + std::lock_guard queueLock(m_submissionLock); + std::lock_guard statLock(m_statLock); + + m_statCounters.merge(commandList->statCounters()); + m_statCounters.addCtr(DxvkStatCounter::QueueSubmitCount, 1); status = commandList->submit( m_graphicsQueue, waitSemaphore, wakeSemaphore); diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 600a783d..6de8d169 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -18,6 +18,7 @@ #include "dxvk_renderpass.h" #include "dxvk_sampler.h" #include "dxvk_shader.h" +#include "dxvk_stats.h" #include "dxvk_swapchain.h" #include "dxvk_sync.h" #include "dxvk_unbound.h" @@ -257,6 +258,15 @@ namespace dxvk { const Rc& surface, const DxvkSwapchainProperties& properties); + /** + * \brief Retrieves stat counters + * + * Can be used by the HUD to display some + * internal information, such as memory + * usage, draw calls, etc. + */ + DxvkStatCounters getStatCounters(); + /** * \brief Initializes dummy resources * @@ -315,6 +325,9 @@ namespace dxvk { DxvkUnboundResources m_unboundResources; DxvkOptions m_options; + sync::Spinlock m_statLock; + DxvkStatCounters m_statCounters; + std::mutex m_submissionLock; VkQueue m_graphicsQueue = VK_NULL_HANDLE; VkQueue m_presentQueue = VK_NULL_HANDLE;