From dd237d866d8ac18b6ecd2c934c8450d90a0181e4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 15 Feb 2018 13:25:18 +0100 Subject: [PATCH] [dxvk] Make query pools more usable as query allocators --- src/dxvk/dxvk_cmdlist.h | 17 ++++++++++++++ src/dxvk/dxvk_context.cpp | 17 ++++++++++---- src/dxvk/dxvk_context.h | 11 +++++++++ src/dxvk/dxvk_device.cpp | 5 +++-- src/dxvk/dxvk_device.h | 3 ++- src/dxvk/dxvk_query.h | 8 +++++++ src/dxvk/dxvk_query_pool.cpp | 33 +++++++++++++++++++++------ src/dxvk/dxvk_query_pool.h | 43 +++++++++++++++++++++++++++--------- src/dxvk/meson.build | 1 + 9 files changed, 113 insertions(+), 25 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index cb1068bf..8447a593 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -7,6 +7,7 @@ #include "dxvk_lifetime.h" #include "dxvk_limits.h" #include "dxvk_pipelayout.h" +#include "dxvk_query_pool.h" #include "dxvk_staging.h" namespace dxvk { @@ -72,6 +73,18 @@ namespace dxvk { m_resources.trackResource(rc); } + /** + * \brief Adds a query range to track + * + * Query data will be retrieved and written back to + * the query objects after the command buffer has + * finished executing on the GPU. + * \param [in] queries The query range + */ + void trackQueryRange(const DxvkQueryRange& queries) { + m_queryRanges.push_back(queries); + } + /** * \brief Resets the command list * @@ -436,12 +449,14 @@ namespace dxvk { DxvkStagingBufferSlice stagedAlloc( VkDeviceSize size); + void stagedBufferCopy( VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const DxvkStagingBufferSlice& dataSlice); + void stagedBufferImageCopy( VkImage dstImage, VkImageLayout dstImageLayout, @@ -459,6 +474,8 @@ namespace dxvk { DxvkDescriptorAlloc m_descAlloc; DxvkStagingAlloc m_stagingAlloc; + std::vector m_queryRanges; + }; } \ No newline at end of file diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index a5d95c78..a8eca942 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1197,6 +1197,17 @@ namespace dxvk { } + void DxvkContext::writeTimestamp(const DxvkQueryRevision& query) { + DxvkQueryHandle handle = this->allocateQuery(query); + + m_cmd->cmdWriteTimestamp( + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + handle.queryPool, handle.queryId); + + query.query->endRecording(query.revision); + } + + void DxvkContext::renderPassBegin() { if (!m_flags.test(DxvkContextFlag::GpRenderPassBound) && (m_state.om.framebuffer != nullptr)) { @@ -1615,16 +1626,14 @@ namespace dxvk { DxvkQueryHandle DxvkContext::allocateQuery(const DxvkQueryRevision& query) { // TODO implement - return DxvkQueryHandle { }; + return DxvkQueryHandle(); } void DxvkContext::resetQueryPool(const Rc& pool) { this->renderPassEnd(); - m_cmd->cmdResetQueryPool( - pool->handle(), 0, - pool->queryCount()); + pool->reset(m_cmd); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index c0143b0c..755d1041 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -542,6 +542,13 @@ namespace dxvk { uint32_t attachment, const DxvkBlendMode& blendMode); + /** + * \brief Writes to a timestamp query + * \param [in] query The timestamp query + */ + void writeTimestamp( + const DxvkQueryRevision& query); + private: const Rc m_device; @@ -551,6 +558,10 @@ namespace dxvk { DxvkContextState m_state; DxvkBarrierSet m_barriers; + Rc m_occlusionQueries; + Rc m_statisticQueries; + Rc m_timestampQueries; + VkPipeline m_gpActivePipeline = VK_NULL_HANDLE; VkPipeline m_cpActivePipeline = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index a678b9f3..263938f8 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -146,8 +146,9 @@ namespace dxvk { Rc DxvkDevice::createQueryPool( - VkQueryType queryType) { - return new DxvkQueryPool(m_vkd, queryType); + VkQueryType queryType, + uint32_t queryCount) { + return new DxvkQueryPool(m_vkd, queryType, queryCount); } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 0a56e92d..f052f734 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -212,7 +212,8 @@ namespace dxvk { * \param [in] queryType Query type */ Rc createQueryPool( - VkQueryType queryType); + VkQueryType queryType, + uint32_t queryCount); /** * \brief Creates a sampler object diff --git a/src/dxvk/dxvk_query.h b/src/dxvk/dxvk_query.h index 1cba8a59..118df046 100644 --- a/src/dxvk/dxvk_query.h +++ b/src/dxvk/dxvk_query.h @@ -96,6 +96,14 @@ namespace dxvk { DxvkQuery(VkQueryType type); ~DxvkQuery(); + /** + * \brief Query type + * \returns Query type + */ + VkQueryType type() const { + return m_type; + } + /** * \brief Resets the query object * diff --git a/src/dxvk/dxvk_query_pool.cpp b/src/dxvk/dxvk_query_pool.cpp index 7321b9e9..348af981 100644 --- a/src/dxvk/dxvk_query_pool.cpp +++ b/src/dxvk/dxvk_query_pool.cpp @@ -1,11 +1,15 @@ +#include "dxvk_cmdlist.h" #include "dxvk_query_pool.h" namespace dxvk { DxvkQueryPool::DxvkQueryPool( const Rc& vkd, - VkQueryType queryType) - : m_vkd(vkd), m_queryType(queryType) { + VkQueryType queryType, + uint32_t queryCount) + : m_vkd(vkd), m_queryCount(queryCount), m_queryType(queryType) { + m_queries.resize(queryCount); + VkQueryPoolCreateInfo info; info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; info.pNext = nullptr; @@ -41,12 +45,19 @@ namespace dxvk { DxvkQueryHandle DxvkQueryPool::allocQuery(const DxvkQueryRevision& query) { - const DxvkQueryHandle result = { m_queryPool, m_queryId }; + const uint32_t queryIndex = m_queryRangeOffset + m_queryRangeLength; - query.query->associateQuery(query.revision, result); - m_queries.at(m_queryId) = query; - m_queryId += 1; - return result; + if (queryIndex < m_queryCount) { + const DxvkQueryHandle result = { m_queryPool, queryIndex }; + + query.query->associateQuery(query.revision, result); + m_queries.at(queryIndex) = query; + + m_queryRangeLength += 1; + return result; + } else { + return DxvkQueryHandle { VK_NULL_HANDLE, 0 }; + } } @@ -72,4 +83,12 @@ namespace dxvk { return VK_SUCCESS; } + + void DxvkQueryPool::reset(const Rc& cmd) { + cmd->cmdResetQueryPool(m_queryPool, 0, m_queryCount); + + m_queryRangeOffset = 0; + m_queryRangeLength = 0; + } + } \ No newline at end of file diff --git a/src/dxvk/dxvk_query_pool.h b/src/dxvk/dxvk_query_pool.h index a839e470..826f6bea 100644 --- a/src/dxvk/dxvk_query_pool.h +++ b/src/dxvk/dxvk_query_pool.h @@ -4,6 +4,21 @@ namespace dxvk { + class DxvkCommandList; + class DxvkQueryPool; + + /** + * \brief Query range + * + * + */ + struct DxvkQueryRange { + Rc queryPool; + + uint32_t queryIndex = 0; + uint32_t queryCount = 0; + }; + /** * \brief Query pool * @@ -17,7 +32,8 @@ namespace dxvk { DxvkQueryPool( const Rc& vkd, - VkQueryType queryType); + VkQueryType queryType, + uint32_t queryCount); ~DxvkQueryPool(); @@ -29,14 +45,6 @@ namespace dxvk { return m_queryPool; } - /** - * \brief Query count - * \returns Query count - */ - uint32_t queryCount() const { - return MaxNumQueryCountPerPool; - } - /** * \brief Allocates a Vulkan query * @@ -57,15 +65,28 @@ namespace dxvk { uint32_t queryIndex, uint32_t queryCount); + /** + * \brief Resets query pool + * + * Resets the Vulkan query pool itself, as + * well as the the internal query allocator. + * \param [in] cmd Command list + */ + void reset( + const Rc& cmd); + private: Rc m_vkd; + uint32_t m_queryCount; VkQueryType m_queryType; VkQueryPool m_queryPool = VK_NULL_HANDLE; - std::array m_queries; - uint32_t m_queryId = 0; + std::vector m_queries; + + uint32_t m_queryRangeOffset = 0; + uint32_t m_queryRangeLength = 0; }; diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 824d4565..0ceb16cc 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -16,6 +16,7 @@ dxvk_src = files([ 'dxvk_descriptor.cpp', 'dxvk_device.cpp', 'dxvk_extensions.cpp', + 'dxvk_event.cpp', 'dxvk_format.cpp', 'dxvk_framebuffer.cpp', 'dxvk_graphics.cpp',