From 7ddd2500d1be6bed9a929b1effe0e2306c432891 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 18 Feb 2018 20:11:05 +0100 Subject: [PATCH] [dxvk] Added query tracker --- src/dxvk/dxvk_cmdlist.cpp | 1 + src/dxvk/dxvk_cmdlist.h | 21 +++++++++++---- src/dxvk/dxvk_context.cpp | 17 +++++++++++++ src/dxvk/dxvk_context.h | 3 +++ src/dxvk/dxvk_query_pool.cpp | 12 +++++++++ src/dxvk/dxvk_query_pool.h | 10 ++++++++ src/dxvk/dxvk_query_tracker.cpp | 24 ++++++++++++++++++ src/dxvk/dxvk_query_tracker.h | 45 +++++++++++++++++++++++++++++++++ src/dxvk/dxvk_queue.cpp | 2 ++ src/dxvk/meson.build | 1 + 10 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 src/dxvk/dxvk_query_tracker.cpp create mode 100644 src/dxvk/dxvk_query_tracker.h diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index e3585e20..f4fe755f 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -82,6 +82,7 @@ namespace dxvk { void DxvkCommandList::reset() { + m_queryTracker.reset(); m_stagingAlloc.reset(); m_descAlloc.reset(); m_resources.reset(); diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 8447a593..b449d72c 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -7,7 +7,7 @@ #include "dxvk_lifetime.h" #include "dxvk_limits.h" #include "dxvk_pipelayout.h" -#include "dxvk_query_pool.h" +#include "dxvk_query_tracker.h" #include "dxvk_staging.h" namespace dxvk { @@ -81,8 +81,19 @@ namespace dxvk { * finished executing on the GPU. * \param [in] queries The query range */ - void trackQueryRange(const DxvkQueryRange& queries) { - m_queryRanges.push_back(queries); + void trackQueryRange(DxvkQueryRange&& queries) { + m_queryTracker.trackQueryRange(std::move(queries)); + } + + /** + * \brief Writes back query results + * + * Uses the query range to write back query data + * after the command list has finished executing + * on the GPU. + */ + void writeQueryData() { + m_queryTracker.writeQueryData(); } /** @@ -95,6 +106,7 @@ namespace dxvk { */ void reset(); + VkDescriptorSet allocateDescriptorSet( VkDescriptorSetLayout descriptorLayout) { return m_descAlloc.alloc(descriptorLayout); @@ -473,8 +485,7 @@ namespace dxvk { DxvkLifetimeTracker m_resources; DxvkDescriptorAlloc m_descAlloc; DxvkStagingAlloc m_stagingAlloc; - - std::vector m_queryRanges; + DxvkQueryTracker m_queryTracker; }; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 243b27f6..b415ed01 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -58,6 +58,10 @@ namespace dxvk { this->renderPassEnd(); this->endActiveQueries(); + this->trackQueryPool(m_queryPools[VK_QUERY_TYPE_OCCLUSION]); + this->trackQueryPool(m_queryPools[VK_QUERY_TYPE_PIPELINE_STATISTICS]); + this->trackQueryPool(m_queryPools[VK_QUERY_TYPE_TIMESTAMP]); + m_cmd->endRecording(); return std::exchange(m_cmd, nullptr); } @@ -1634,6 +1638,9 @@ namespace dxvk { queryHandle = queryPool->allocQuery(query); if (queryHandle.queryPool == VK_NULL_HANDLE) { + if (queryPool != nullptr) + this->trackQueryPool(queryPool); + m_queryPools[queryType] = m_device->createQueryPool(queryType, MaxNumQueryCountPerPool); queryPool = m_queryPools[queryType]; @@ -1652,6 +1659,16 @@ namespace dxvk { } + void DxvkContext::trackQueryPool(const Rc& pool) { + if (pool != nullptr) { + DxvkQueryRange range = pool->getActiveQueryRange(); + + if (range.queryCount > 0) + m_cmd->trackQueryRange(std::move(range)); + } + } + + void DxvkContext::beginActiveQueries() { for (const DxvkQueryRevision& query : m_activeQueries) { DxvkQueryHandle handle = this->allocQuery(query); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 5ef47e90..0a4d0447 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -612,6 +612,9 @@ namespace dxvk { void resetQueryPool( const Rc& pool); + void trackQueryPool( + const Rc& pool); + void beginActiveQueries(); void endActiveQueries(); diff --git a/src/dxvk/dxvk_query_pool.cpp b/src/dxvk/dxvk_query_pool.cpp index 348af981..31826ee6 100644 --- a/src/dxvk/dxvk_query_pool.cpp +++ b/src/dxvk/dxvk_query_pool.cpp @@ -91,4 +91,16 @@ namespace dxvk { m_queryRangeLength = 0; } + + DxvkQueryRange DxvkQueryPool::getActiveQueryRange() { + DxvkQueryRange result; + result.queryPool = this; + result.queryIndex = m_queryRangeOffset; + result.queryCount = m_queryRangeLength; + + m_queryRangeOffset += m_queryRangeLength; + m_queryRangeLength = 0; + return result; + } + } \ No newline at end of file diff --git a/src/dxvk/dxvk_query_pool.h b/src/dxvk/dxvk_query_pool.h index 826f6bea..2c3110f7 100644 --- a/src/dxvk/dxvk_query_pool.h +++ b/src/dxvk/dxvk_query_pool.h @@ -75,6 +75,16 @@ namespace dxvk { void reset( const Rc& cmd); + /** + * \brief Retrieves active query range + * + * This will also move the beginning of the + * new active query range to the end of the + * current active query range. + * \returns Active query range + */ + DxvkQueryRange getActiveQueryRange(); + private: Rc m_vkd; diff --git a/src/dxvk/dxvk_query_tracker.cpp b/src/dxvk/dxvk_query_tracker.cpp new file mode 100644 index 00000000..6a46747e --- /dev/null +++ b/src/dxvk/dxvk_query_tracker.cpp @@ -0,0 +1,24 @@ +#include "dxvk_query_tracker.h" + +namespace dxvk { + + DxvkQueryTracker:: DxvkQueryTracker() { } + DxvkQueryTracker::~DxvkQueryTracker() { } + + + void DxvkQueryTracker::trackQueryRange(DxvkQueryRange&& queryRange) { + m_queries.push_back(std::move(queryRange)); + } + + + void DxvkQueryTracker::writeQueryData() { + for (const DxvkQueryRange& curr : m_queries) + curr.queryPool->getData(curr.queryIndex, curr.queryCount); + } + + + void DxvkQueryTracker::reset() { + m_queries.clear(); + } + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_query_tracker.h b/src/dxvk/dxvk_query_tracker.h new file mode 100644 index 00000000..5ac9d24c --- /dev/null +++ b/src/dxvk/dxvk_query_tracker.h @@ -0,0 +1,45 @@ +#pragma once + +#include "dxvk_query_pool.h" + +namespace dxvk { + + /** + * \brief Query tracker + */ + class DxvkQueryTracker { + + public: + + DxvkQueryTracker(); + ~DxvkQueryTracker(); + + /** + * \brief Adds a query range to track + * \param [in] queryRange The query range + */ + void trackQueryRange(DxvkQueryRange&& queryRange); + + /** + * \brief Fetches query data + * + * Retrieves query data from the query pools + * and writes it back to the query objects. + */ + void writeQueryData(); + + /** + * \brief Resets query tracker + * + * Releases all query ranges from the tracker. + * Call this after writing back the query data. + */ + void reset(); + + private: + + std::vector m_queries; + + }; + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_queue.cpp b/src/dxvk/dxvk_queue.cpp index 483f4f63..26a2fb95 100644 --- a/src/dxvk/dxvk_queue.cpp +++ b/src/dxvk/dxvk_queue.cpp @@ -56,6 +56,8 @@ namespace dxvk { if (entry.fence != nullptr) { entry.fence->wait(std::numeric_limits::max()); + + entry.cmdList->writeQueryData(); entry.cmdList->reset(); m_device->recycleCommandList(entry.cmdList); } diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 0ceb16cc..2e1317a4 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -31,6 +31,7 @@ dxvk_src = files([ 'dxvk_pipemanager.cpp', 'dxvk_query.cpp', 'dxvk_query_pool.cpp', + 'dxvk_query_tracker.cpp', 'dxvk_queue.cpp', 'dxvk_renderpass.cpp', 'dxvk_resource.cpp',