diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index d99309af..ce33c1d7 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -249,13 +249,10 @@ namespace dxvk { return; Com queryPtr = static_cast(pAsync); - - if (queryPtr->HasBeginEnabled()) { - uint32_t revision = queryPtr->Reset(); - EmitCs([revision, queryPtr] (DxvkContext* ctx) { - queryPtr->Begin(ctx, revision); - }); - } + + EmitCs([queryPtr] (DxvkContext* ctx) { + queryPtr->Begin(ctx); + }); } @@ -267,16 +264,9 @@ namespace dxvk { Com queryPtr = static_cast(pAsync); - if (queryPtr->HasBeginEnabled()) { - EmitCs([queryPtr] (DxvkContext* ctx) { - queryPtr->End(ctx); - }); - } else { - uint32_t revision = queryPtr->Reset(); - EmitCs([revision, queryPtr] (DxvkContext* ctx) { - queryPtr->Signal(ctx, revision); - }); - } + EmitCs([queryPtr] (DxvkContext* ctx) { + queryPtr->End(ctx); + }); } diff --git a/src/d3d11/d3d11_query.cpp b/src/d3d11/d3d11_query.cpp index 2837f131..e174d823 100644 --- a/src/d3d11/d3d11_query.cpp +++ b/src/d3d11/d3d11_query.cpp @@ -16,27 +16,27 @@ namespace dxvk { break; case D3D11_QUERY_OCCLUSION: - m_query = new DxvkQuery( + m_query = dxvkDevice->createGpuQuery( VK_QUERY_TYPE_OCCLUSION, - VK_QUERY_CONTROL_PRECISE_BIT); + VK_QUERY_CONTROL_PRECISE_BIT, 0); break; case D3D11_QUERY_OCCLUSION_PREDICATE: - m_query = new DxvkQuery( - VK_QUERY_TYPE_OCCLUSION, 0); + m_query = dxvkDevice->createGpuQuery( + VK_QUERY_TYPE_OCCLUSION, 0, 0); break; case D3D11_QUERY_TIMESTAMP: - m_query = new DxvkQuery( - VK_QUERY_TYPE_TIMESTAMP, 0); + m_query = dxvkDevice->createGpuQuery( + VK_QUERY_TYPE_TIMESTAMP, 0, 0); break; case D3D11_QUERY_TIMESTAMP_DISJOINT: break; case D3D11_QUERY_PIPELINE_STATISTICS: - m_query = new DxvkQuery( - VK_QUERY_TYPE_PIPELINE_STATISTICS, 0); + m_query = dxvkDevice->createGpuQuery( + VK_QUERY_TYPE_PIPELINE_STATISTICS, 0, 0); break; case D3D11_QUERY_SO_STATISTICS: @@ -46,25 +46,25 @@ namespace dxvk { // FIXME it is technically incorrect to map // SO_OVERFLOW_PREDICATE to the first stream, // but this is good enough for D3D10 behaviour - m_query = new DxvkQuery( + m_query = dxvkDevice->createGpuQuery( VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 0); break; case D3D11_QUERY_SO_STATISTICS_STREAM1: case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1: - m_query = new DxvkQuery( + m_query = dxvkDevice->createGpuQuery( VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 1); break; case D3D11_QUERY_SO_STATISTICS_STREAM2: case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2: - m_query = new DxvkQuery( + m_query = dxvkDevice->createGpuQuery( VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 2); break; case D3D11_QUERY_SO_STATISTICS_STREAM3: case D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3: - m_query = new DxvkQuery( + m_query = dxvkDevice->createGpuQuery( VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 0, 3); break; @@ -169,51 +169,34 @@ namespace dxvk { } - uint32_t D3D11Query::Reset() { - if (m_query != nullptr) - return m_query->reset(); - - return 0; - } - - - bool D3D11Query::HasBeginEnabled() const { - return m_desc.Query != D3D11_QUERY_EVENT - && m_desc.Query != D3D11_QUERY_TIMESTAMP; - } - - - void D3D11Query::Begin(DxvkContext* ctx, uint32_t revision) { - m_revision = revision; - - if (m_query != nullptr) { - DxvkQueryRevision rev = { m_query, revision }; - ctx->beginQuery(rev); + void D3D11Query::Begin(DxvkContext* ctx) { + switch (m_desc.Query) { + case D3D11_QUERY_EVENT: + case D3D11_QUERY_TIMESTAMP: + case D3D11_QUERY_TIMESTAMP_DISJOINT: + break; + + default: + ctx->beginQuery(m_query); } } void D3D11Query::End(DxvkContext* ctx) { - if (m_query != nullptr) { - DxvkQueryRevision rev = { m_query, m_revision }; - ctx->endQuery(rev); - } - } - - - void D3D11Query::Signal(DxvkContext* ctx, uint32_t revision) { switch (m_desc.Query) { - case D3D11_QUERY_EVENT: { + case D3D11_QUERY_EVENT: ctx->signalGpuEvent(m_event); - } break; + break; - case D3D11_QUERY_TIMESTAMP: { - DxvkQueryRevision rev = { m_query, revision }; - ctx->writeTimestamp(rev); - } break; + case D3D11_QUERY_TIMESTAMP: + ctx->writeTimestamp(m_query); + break; + + case D3D11_QUERY_TIMESTAMP_DISJOINT: + break; default: - break; + ctx->endQuery(m_query); } } @@ -229,10 +212,6 @@ namespace dxvk { bool signaled = status == DxvkGpuEventStatus::Signaled; - // FIXME remove once query refactor is done - if (m_event->isInUse()) - signaled = false; - if (pData != nullptr) *static_cast(pData) = signaled; @@ -241,12 +220,13 @@ namespace dxvk { DxvkQueryData queryData = {}; if (m_query != nullptr) { - DxvkQueryStatus status = m_query->getData(queryData); + DxvkGpuQueryStatus status = m_query->getData(queryData); - if (status == DxvkQueryStatus::Created) + if (status == DxvkGpuQueryStatus::Invalid + || status == DxvkGpuQueryStatus::Failed) return DXGI_ERROR_INVALID_CALL; - if (status != DxvkQueryStatus::Available) + if (status == DxvkGpuQueryStatus::Pending) return S_FALSE; } diff --git a/src/d3d11/d3d11_query.h b/src/d3d11/d3d11_query.h index 873a3b4b..dac80afb 100644 --- a/src/d3d11/d3d11_query.h +++ b/src/d3d11/d3d11_query.h @@ -1,7 +1,7 @@ #pragma once #include "../dxvk/dxvk_gpu_event.h" -#include "../dxvk/dxvk_query.h" +#include "../dxvk/dxvk_gpu_query.h" #include "../d3d10/d3d10_query.h" @@ -31,16 +31,10 @@ namespace dxvk { void STDMETHODCALLTYPE GetDesc( D3D11_QUERY_DESC *pDesc) final; - uint32_t Reset(); - - bool HasBeginEnabled() const; - - void Begin(DxvkContext* ctx, uint32_t revision); + void Begin(DxvkContext* ctx); void End(DxvkContext* ctx); - void Signal(DxvkContext* ctx, uint32_t revision); - HRESULT STDMETHODCALLTYPE GetData( void* pData, UINT GetDataFlags); @@ -54,7 +48,7 @@ namespace dxvk { D3D11Device* const m_device; D3D11_QUERY_DESC m_desc; - Rc m_query = nullptr; + Rc m_query = nullptr; Rc m_event = nullptr; uint32_t m_revision = 0; diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 856f0f87..f0848881 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -127,7 +127,6 @@ namespace dxvk { m_gpuQueryTracker.reset(); m_gpuEventTracker.reset(); m_eventTracker.reset(); - m_queryTracker.reset(); m_stagingAlloc.reset(); m_descriptorPoolTracker.reset(); m_resources.reset(); diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index d6a0012a..a2c6a057 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -11,7 +11,6 @@ #include "dxvk_lifetime.h" #include "dxvk_limits.h" #include "dxvk_pipelayout.h" -#include "dxvk_query_tracker.h" #include "dxvk_staging.h" #include "dxvk_stats.h" @@ -136,18 +135,6 @@ namespace dxvk { m_resources.trackResource(std::move(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(DxvkQueryRange&& queries) { - m_queryTracker.trackQueryRange(std::move(queries)); - } - /** * \brief Adds an event revision to track * @@ -198,17 +185,6 @@ namespace dxvk { m_eventTracker.signalEvents(); } - /** - * \brief Writes back query results - * - * Writes back query data to all queries tracked by the - * query range tracker. Call this after synchronizing - * with a fence for this command list. - */ - void writeQueryData() { - m_queryTracker.writeQueryData(); - } - /** * \brief Resets the command list * @@ -707,7 +683,6 @@ namespace dxvk { DxvkLifetimeTracker m_resources; DxvkDescriptorPoolTracker m_descriptorPoolTracker; DxvkStagingAlloc m_stagingAlloc; - DxvkQueryTracker m_queryTracker; DxvkEventTracker m_eventTracker; DxvkGpuEventTracker m_gpuEventTracker; DxvkGpuQueryTracker m_gpuQueryTracker; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 729201bb..ff656914 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -24,7 +24,6 @@ namespace dxvk { m_metaMipGen (metaMipGenObjects), m_metaPack (metaPackObjects), m_metaResolve (metaResolveObjects), - m_queries (device->vkd()), m_queryManager(gpuQueryPool) { } @@ -68,8 +67,6 @@ namespace dxvk { Rc DxvkContext::endRecording() { this->spillRenderPass(); - m_queries.trackQueryPools(m_cmd); - m_barriers.recordCommands(m_cmd); m_cmd->endRecording(); @@ -88,18 +85,6 @@ namespace dxvk { } - void DxvkContext::beginQuery(const DxvkQueryRevision& query) { - query.query->beginRecording(query.revision); - m_queries.enableQuery(m_cmd, query); - } - - - void DxvkContext::endQuery(const DxvkQueryRevision& query) { - m_queries.disableQuery(m_cmd, query); - query.query->endRecording(query.revision); - } - - void DxvkContext::beginQuery(const Rc& query) { m_queryManager.enableQuery(m_cmd, query); } @@ -1123,17 +1108,11 @@ namespace dxvk { if (this->validateComputeState()) { this->commitComputeInitBarriers(); - m_queries.beginQueries(m_cmd, - VK_QUERY_TYPE_PIPELINE_STATISTICS); - m_queryManager.beginQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); m_cmd->cmdDispatch(x, y, z); - m_queries.endQueries(m_cmd, - VK_QUERY_TYPE_PIPELINE_STATISTICS); - m_queryManager.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); @@ -1157,9 +1136,6 @@ namespace dxvk { if (this->validateComputeState()) { this->commitComputeInitBarriers(); - m_queries.beginQueries(m_cmd, - VK_QUERY_TYPE_PIPELINE_STATISTICS); - m_queryManager.beginQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); @@ -1167,9 +1143,6 @@ namespace dxvk { bufferSlice.handle, bufferSlice.offset); - m_queries.endQueries(m_cmd, - VK_QUERY_TYPE_PIPELINE_STATISTICS); - m_queryManager.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); @@ -1803,17 +1776,6 @@ namespace dxvk { } - void DxvkContext::writeTimestamp(const DxvkQueryRevision& query) { - DxvkQueryHandle handle = m_queries.allocQuery(m_cmd, query); - - m_cmd->cmdWriteTimestamp( - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - handle.queryPool, handle.queryId); - - query.query->endRecording(query.revision); - } - - void DxvkContext::writeTimestamp(const Rc& query) { m_queryManager.writeTimestamp(m_cmd, query); } @@ -2464,9 +2426,6 @@ namespace dxvk { m_state.om.renderPassOps); // Begin occlusion queries - m_queries.beginQueries(m_cmd, VK_QUERY_TYPE_OCCLUSION); - m_queries.beginQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); - m_queryManager.beginQueries(m_cmd, VK_QUERY_TYPE_OCCLUSION); m_queryManager.beginQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); } @@ -2482,9 +2441,6 @@ namespace dxvk { this->pauseTransformFeedback(); - m_queries.endQueries(m_cmd, VK_QUERY_TYPE_OCCLUSION); - m_queries.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); - m_queryManager.endQueries(m_cmd, VK_QUERY_TYPE_OCCLUSION); m_queryManager.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); @@ -2675,9 +2631,6 @@ namespace dxvk { m_cmd->cmdBeginTransformFeedback( 0, MaxNumXfbBuffers, ctrBuffers, ctrOffsets); - m_queries.beginQueries(m_cmd, - VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT); - m_queryManager.beginQueries(m_cmd, VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT); } @@ -2701,9 +2654,6 @@ namespace dxvk { m_cmd->trackResource(m_state.xfb.counters[i].buffer()); } - m_queries.endQueries(m_cmd, - VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT); - m_queryManager.endQueries(m_cmd, VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index f86b48b2..dae4a457 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -15,9 +15,6 @@ #include "dxvk_meta_resolve.h" #include "dxvk_pipecache.h" #include "dxvk_pipemanager.h" -#include "dxvk_query.h" -#include "dxvk_query_manager.h" -#include "dxvk_query_pool.h" #include "dxvk_util.h" namespace dxvk { @@ -81,9 +78,6 @@ namespace dxvk { * \brief Begins generating query data * \param [in] query The query to end */ - void beginQuery( - const DxvkQueryRevision& query); - void beginQuery( const Rc& query); @@ -91,9 +85,6 @@ namespace dxvk { * \brief Ends generating query data * \param [in] query The query to end */ - void endQuery( - const DxvkQueryRevision& query); - void endQuery( const Rc& query); @@ -792,9 +783,6 @@ namespace dxvk { * \brief Writes to a timestamp query * \param [in] query The timestamp query */ - void writeTimestamp( - const DxvkQueryRevision& query); - void writeTimestamp( const Rc& query); @@ -819,9 +807,8 @@ namespace dxvk { DxvkBarrierSet m_transitions; DxvkBarrierControlFlags m_barrierControl; - DxvkQueryManager m_queries; DxvkGpuQueryManager m_queryManager; - + VkPipeline m_gpActivePipeline = VK_NULL_HANDLE; VkPipeline m_cpActivePipeline = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 878c4933..08c8035f 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -14,7 +14,6 @@ #include "dxvk_pipecache.h" #include "dxvk_pipemanager.h" #include "dxvk_queue.h" -#include "dxvk_query_pool.h" #include "dxvk_recycler.h" #include "dxvk_renderpass.h" #include "dxvk_sampler.h" diff --git a/src/dxvk/dxvk_gpu_query.h b/src/dxvk/dxvk_gpu_query.h index 0f900e0b..2fd1a3e9 100644 --- a/src/dxvk/dxvk_gpu_query.h +++ b/src/dxvk/dxvk_gpu_query.h @@ -3,7 +3,6 @@ #include #include -#include "dxvk_query.h" #include "dxvk_resource.h" namespace dxvk { @@ -27,6 +26,72 @@ namespace dxvk { }; + /** + * \brief Occlusion query data + * + * Stores the number of samples + * that passes fragment tests. + */ + struct DxvkQueryOcclusionData { + uint64_t samplesPassed; + }; + + /** + * \brief Timestamp data + * + * Stores a GPU time stamp. + */ + struct DxvkQueryTimestampData { + uint64_t time; + }; + + /** + * \brief Pipeline statistics + * + * Stores the counters for + * pipeline statistics queries. + */ + struct DxvkQueryStatisticData { + uint64_t iaVertices; + uint64_t iaPrimitives; + uint64_t vsInvocations; + uint64_t gsInvocations; + uint64_t gsPrimitives; + uint64_t clipInvocations; + uint64_t clipPrimitives; + uint64_t fsInvocations; + uint64_t tcsPatches; + uint64_t tesInvocations; + uint64_t csInvocations; + }; + + /** + * \brief Transform feedback stream query + * + * Stores the number of primitives written to the + * buffer, as well as the number of primitives + * generated. The latter can be used to check for + * overflow. + */ + struct DxvkQueryXfbStreamData { + uint64_t primitivesWritten; + uint64_t primitivesNeeded; + }; + + /** + * \brief Query data + * + * A union that stores query data. Select an + * appropriate member based on the query type. + */ + union DxvkQueryData { + DxvkQueryOcclusionData occlusion; + DxvkQueryTimestampData timestamp; + DxvkQueryStatisticData statistic; + DxvkQueryXfbStreamData xfbStream; + }; + + /** * \brief Query handle * diff --git a/src/dxvk/dxvk_query.cpp b/src/dxvk/dxvk_query.cpp deleted file mode 100644 index efbecb84..00000000 --- a/src/dxvk/dxvk_query.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "dxvk_query.h" - -namespace dxvk { - - DxvkQuery::DxvkQuery( - VkQueryType type, - VkQueryControlFlags flags, - uint32_t index) - : m_type (type), - m_flags (flags), - m_index (index) { - - } - - - DxvkQuery::~DxvkQuery() { - - } - - - bool DxvkQuery::isIndexed() const { - return m_type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT; - } - - - uint32_t DxvkQuery::reset() { - std::unique_lock lock(m_mutex); - - m_status = DxvkQueryStatus::Reset; - m_data = DxvkQueryData { }; - - m_queryIndex = 0; - m_queryCount = 0; - - return ++m_revision; - } - - - DxvkQueryStatus DxvkQuery::getData(DxvkQueryData& data) { - std::unique_lock lock(m_mutex); - - if (m_status == DxvkQueryStatus::Available) - data = m_data; - - return m_status; - } - - - DxvkQueryHandle DxvkQuery::getHandle() { - return m_handle; - } - - - void DxvkQuery::beginRecording(uint32_t revision) { - std::unique_lock lock(m_mutex); - - if (m_revision == revision) - m_status = DxvkQueryStatus::Active; - } - - - void DxvkQuery::endRecording(uint32_t revision) { - std::unique_lock lock(m_mutex); - - if (m_revision == revision) { - m_status = m_queryIndex < m_queryCount - ? DxvkQueryStatus::Pending - : DxvkQueryStatus::Available; - m_handle = DxvkQueryHandle(); - } - } - - - void DxvkQuery::associateQuery(uint32_t revision, DxvkQueryHandle handle) { - std::unique_lock lock(m_mutex); - - if (m_revision == revision) - m_queryCount += 1; - - // Assign the handle either way as this - // will be used by the DXVK context. - m_handle = handle; - } - - - void DxvkQuery::updateData( - uint32_t revision, - const DxvkQueryData& data) { - std::unique_lock lock(m_mutex); - - if (m_revision == revision) { - switch (m_type) { - case VK_QUERY_TYPE_OCCLUSION: - m_data.occlusion.samplesPassed += data.occlusion.samplesPassed; - break; - - case VK_QUERY_TYPE_TIMESTAMP: - m_data.timestamp.time = data.timestamp.time; - break; - - case VK_QUERY_TYPE_PIPELINE_STATISTICS: - m_data.statistic.iaVertices += data.statistic.iaVertices; - m_data.statistic.iaPrimitives += data.statistic.iaPrimitives; - m_data.statistic.vsInvocations += data.statistic.vsInvocations; - m_data.statistic.gsInvocations += data.statistic.gsInvocations; - m_data.statistic.gsPrimitives += data.statistic.gsPrimitives; - m_data.statistic.clipInvocations += data.statistic.clipInvocations; - m_data.statistic.clipPrimitives += data.statistic.clipPrimitives; - m_data.statistic.fsInvocations += data.statistic.fsInvocations; - m_data.statistic.tcsPatches += data.statistic.tcsPatches; - m_data.statistic.tesInvocations += data.statistic.tesInvocations; - m_data.statistic.csInvocations += data.statistic.csInvocations; - break; - - case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: - m_data.xfbStream.primitivesWritten += data.xfbStream.primitivesWritten; - m_data.xfbStream.primitivesNeeded += data.xfbStream.primitivesNeeded; - break; - - default: - Logger::err(str::format("DxvkQuery: Unhandled query type: ", m_type)); - } - - if (++m_queryIndex == m_queryCount && m_status == DxvkQueryStatus::Pending) - m_status = DxvkQueryStatus::Available; - } - } - -} \ No newline at end of file diff --git a/src/dxvk/dxvk_query.h b/src/dxvk/dxvk_query.h deleted file mode 100644 index b5543747..00000000 --- a/src/dxvk/dxvk_query.h +++ /dev/null @@ -1,250 +0,0 @@ -#pragma once - -#include - -#include "dxvk_limits.h" - -namespace dxvk { - - /** - * \brief Query status - * - * Allows the application to query - * the current status of the query. - */ - enum class DxvkQueryStatus : uint32_t { - Created = 0, ///< Query was just created - Reset = 1, ///< Query is reset - Active = 2, ///< Query is being recorded - Pending = 3, ///< Query has been recorded - Available = 4, ///< Query results can be retrieved - }; - - /** - * \brief Occlusion query data - * - * Stores the number of samples - * that passes fragment tests. - */ - struct DxvkQueryOcclusionData { - uint64_t samplesPassed; - }; - - /** - * \brief Timestamp data - * - * Stores a GPU time stamp. - */ - struct DxvkQueryTimestampData { - uint64_t time; - }; - - /** - * \brief Pipeline statistics - * - * Stores the counters for - * pipeline statistics queries. - */ - struct DxvkQueryStatisticData { - uint64_t iaVertices; - uint64_t iaPrimitives; - uint64_t vsInvocations; - uint64_t gsInvocations; - uint64_t gsPrimitives; - uint64_t clipInvocations; - uint64_t clipPrimitives; - uint64_t fsInvocations; - uint64_t tcsPatches; - uint64_t tesInvocations; - uint64_t csInvocations; - }; - - /** - * \brief Transform feedback stream query - * - * Stores the number of primitives written to the - * buffer, as well as the number of primitives - * generated. The latter can be used to check for - * overflow. - */ - struct DxvkQueryXfbStreamData { - uint64_t primitivesWritten; - uint64_t primitivesNeeded; - }; - - /** - * \brief Query data - * - * A union that stores query data. Select an - * appropriate member based on the query type. - */ - union DxvkQueryData { - DxvkQueryOcclusionData occlusion; - DxvkQueryTimestampData timestamp; - DxvkQueryStatisticData statistic; - DxvkQueryXfbStreamData xfbStream; - }; - - /** - * \brief Query entry - * - * Stores the pool handle and the - * index of a single Vulkan query. - */ - struct DxvkQueryHandle { - VkQueryPool queryPool = VK_NULL_HANDLE; - uint32_t queryId = 0; - VkQueryControlFlags flags = 0; - uint32_t index = 0; - }; - - /** - * \brief Query object - * - * Represents a single virtual query. Since queries - * in Vulkan cannot be active across command buffer - * submissions, we need to - */ - class DxvkQuery : public RcObject { - - public: - - DxvkQuery( - VkQueryType type, - VkQueryControlFlags flags, - uint32_t index = ~0u); - ~DxvkQuery(); - - /** - * \brief Query type - * \returns Query type - */ - VkQueryType type() const { - return m_type; - } - - /** - * \brief Query control flags - * - * Flags that will be applied when - * calling \c vkCmdBeginQuery. - * \returns Query control flags - */ - VkQueryControlFlags flags() const { - return m_flags; - } - - /** - * \brief Query type index - * - * The query type index. Will be undefined if the - * query type is not indexed. Not to be confused - * with the query index within the query pool. - * \returns Query type index - */ - uint32_t index() const { - return m_index; - } - - /** - * \brief Checks whether the query type is indexed - * \returns \c true if the query type is indexed - */ - bool isIndexed() const; - - /** - * \brief Resets the query object - * - * Increments the revision number which will - * be used to determine when query data becomes - * available. All asynchronous query operations - * will take the revision number as an argument. - * \returns The new query revision number - */ - uint32_t reset(); - - /** - * \brief Retrieves query data - * - * \param [out] data Query data - * \returns Query status - */ - DxvkQueryStatus getData( - DxvkQueryData& data); - - /** - * \brief Gets current query handle - * \returns The current query handle - */ - DxvkQueryHandle getHandle(); - - /** - * \brief Begins recording the query - * - * Sets internal query state to 'active'. - * \param [in] revision Query version ID - */ - void beginRecording(uint32_t revision); - - /** - * \brief Ends recording the query - * - * Sets internal query state to 'pending'. - * \param [in] revision Query version ID - */ - void endRecording(uint32_t revision); - - /** - * \brief Increments internal query count - * - * The internal query count is used to determine - * when the query data is actually available. - * \param [in] revision Query version ID - * \param [in] handle The query handle - */ - void associateQuery( - uint32_t revision, - DxvkQueryHandle handle); - - /** - * \brief Updates query data - * - * Called by the command submission thread after - * the Vulkan queries have been evaluated. - * \param [in] revision Query version ID - * \param [in] data Query data - */ - void updateData( - uint32_t revision, - const DxvkQueryData& data); - - private: - - const VkQueryType m_type; - const VkQueryControlFlags m_flags; - const uint32_t m_index; - - sync::TicketLock m_mutex; - - DxvkQueryStatus m_status = DxvkQueryStatus::Created; - DxvkQueryData m_data = {}; - DxvkQueryHandle m_handle; - - uint32_t m_queryIndex = 0; - uint32_t m_queryCount = 0; - uint64_t m_revision = 0; - - }; - - /** - * \brief Query revision - * - * Stores the query object and the - * version ID for query operations. - */ - struct DxvkQueryRevision { - Rc query; - uint32_t revision; - }; - -} \ No newline at end of file diff --git a/src/dxvk/dxvk_query_manager.cpp b/src/dxvk/dxvk_query_manager.cpp deleted file mode 100644 index e459ef56..00000000 --- a/src/dxvk/dxvk_query_manager.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include "dxvk_query_manager.h" -#include "dxvk_query_pool.h" - -namespace dxvk { - - DxvkQueryManager::DxvkQueryManager(const Rc& vkd) - : m_vkd(vkd) { - - } - - - DxvkQueryManager::~DxvkQueryManager() { - - } - - - DxvkQueryHandle DxvkQueryManager::allocQuery( - const Rc& cmd, - const DxvkQueryRevision& query) { - const VkQueryType queryType = query.query->type(); - - DxvkQueryHandle queryHandle = DxvkQueryHandle(); - Rc& queryPool = this->getQueryPool(queryType); - - if (queryPool != nullptr) - queryHandle = queryPool->allocQuery(query); - - if (queryHandle.queryPool == VK_NULL_HANDLE) { - if (queryPool != nullptr) - this->trackQueryPool(cmd, queryPool); - - queryPool = new DxvkQueryPool(m_vkd, queryType, MaxNumQueryCountPerPool); - queryPool->reset(cmd); - - queryHandle = queryPool->allocQuery(query); - } - - return queryHandle; - } - - - void DxvkQueryManager::enableQuery( - const Rc& cmd, - const DxvkQueryRevision& query) { - m_activeQueries.push_back(query); - - if (m_activeTypes & getDxvkQueryTypeBit(query.query->type())) - this->beginVulkanQuery(cmd, query); - } - - - void DxvkQueryManager::disableQuery( - const Rc& cmd, - const DxvkQueryRevision& query) { - auto iter = m_activeQueries.begin(); - - while (iter != m_activeQueries.end()) { - if (iter->query == query.query - && iter->revision == query.revision) - break; - - iter++; - } - - if (iter != m_activeQueries.end()) { - if (m_activeTypes & getDxvkQueryTypeBit(iter->query->type())) - this->endVulkanQuery(cmd, query); - - m_activeQueries.erase(iter); - } - } - - - void DxvkQueryManager::beginQueries( - const Rc& cmd, - VkQueryType type) { - m_activeTypes |= getDxvkQueryTypeBit(type); - - for (const DxvkQueryRevision& query : m_activeQueries) { - if (type == query.query->type()) - this->beginVulkanQuery(cmd, query); - } - } - - - void DxvkQueryManager::endQueries( - const Rc& cmd, - VkQueryType type) { - m_activeTypes &= ~getDxvkQueryTypeBit(type); - - for (const DxvkQueryRevision& query : m_activeQueries) { - if (type == query.query->type()) - this->endVulkanQuery(cmd, query); - } - } - - - void DxvkQueryManager::trackQueryPools(const Rc& cmd) { - this->trackQueryPool(cmd, m_occlusion); - this->trackQueryPool(cmd, m_pipeStats); - this->trackQueryPool(cmd, m_timestamp); - this->trackQueryPool(cmd, m_xfbStream); - } - - - void DxvkQueryManager::trackQueryPool( - const Rc& cmd, - const Rc& pool) { - if (pool != nullptr) { - DxvkQueryRange range = pool->getActiveQueryRange(); - - if (range.queryCount > 0) - cmd->trackQueryRange(std::move(range)); - } - } - - - void DxvkQueryManager::beginVulkanQuery( - const Rc& cmd, - const DxvkQueryRevision& query) { - DxvkQueryHandle handle = this->allocQuery(cmd, query); - - if (query.query->isIndexed()) { - cmd->cmdBeginQueryIndexed( - handle.queryPool, - handle.queryId, - handle.flags, - handle.index); - } else { - cmd->cmdBeginQuery( - handle.queryPool, - handle.queryId, - handle.flags); - } - } - - - void DxvkQueryManager::endVulkanQuery( - const Rc& cmd, - const DxvkQueryRevision& query) { - DxvkQueryHandle handle = query.query->getHandle(); - - if (query.query->isIndexed()) { - cmd->cmdEndQueryIndexed( - handle.queryPool, - handle.queryId, - handle.index); - } else { - cmd->cmdEndQuery( - handle.queryPool, - handle.queryId); - } - } - - - Rc& DxvkQueryManager::getQueryPool(VkQueryType type) { - switch (type) { - case VK_QUERY_TYPE_OCCLUSION: - return m_occlusion; - - case VK_QUERY_TYPE_PIPELINE_STATISTICS: - return m_pipeStats; - - case VK_QUERY_TYPE_TIMESTAMP: - return m_timestamp; - - case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: - return m_xfbStream; - - default: - throw DxvkError("DXVK: Invalid query type"); - } - } - - - uint32_t DxvkQueryManager::getDxvkQueryTypeBit(VkQueryType type) { - switch (type) { - case VK_QUERY_TYPE_OCCLUSION: return 0x01; - case VK_QUERY_TYPE_PIPELINE_STATISTICS: return 0x02; - case VK_QUERY_TYPE_TIMESTAMP: return 0x04; - case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: return 0x08; - default: return 0; - } - } - -} \ No newline at end of file diff --git a/src/dxvk/dxvk_query_manager.h b/src/dxvk/dxvk_query_manager.h deleted file mode 100644 index fd38ffaa..00000000 --- a/src/dxvk/dxvk_query_manager.h +++ /dev/null @@ -1,128 +0,0 @@ -#pragma once - -#include - -#include "dxvk_cmdlist.h" -#include "dxvk_query.h" -#include "dxvk_query_pool.h" - -namespace dxvk { - - /** - * \brief Query manager - * - * Manages Vulkan query pools - * and the current query state. - */ - class DxvkQueryManager { - - public: - - DxvkQueryManager(const Rc& vkd); - ~DxvkQueryManager(); - - /** - * \brief Allocates a Vulkan query - * - * Creates a query pool of the correct type if - * necessary, and allocates one query from it. - * \param [in] cmd The context's command list - * \param [in] query The DXVK query revision - * \returns Allocated query handle - */ - DxvkQueryHandle allocQuery( - const Rc& cmd, - const DxvkQueryRevision& query); - - /** - * \brief Enables a query - * - * Starts tracking a query. Depending on the - * query type, unterlying Vulkan queries will - * begin and end on render pass boundaries. - * \param [in] cmd The context's command list - * \param [in] query The query to enable - */ - void enableQuery( - const Rc& cmd, - const DxvkQueryRevision& query); - - /** - * \brief Disables a query - * - * Ends the query if it is currently active, - * and stops tracking any further state changes. - * \param [in] cmd The context's command list - * \param [in] query The query to enable - */ - void disableQuery( - const Rc& cmd, - const DxvkQueryRevision& query); - - /** - * \brief Begins active queries - * - * Creates a Vulkan query for each enabled - * query of the given types and begins them. - * \param [in] cmd The context's command list - * \param [in] types Query types to begin - */ - void beginQueries( - const Rc& cmd, - VkQueryType type); - - /** - * \brief Ends active queries - * - * Ends active queries of the given types. - * \param [in] cmd The context's command list - * \param [in] types Query types to begin - */ - void endQueries( - const Rc& cmd, - VkQueryType type); - - /** - * \brief Tracks query pools - * - * Adds all current non-empty query pools to - * the query tracker of the given command list. - * \param [in] cmd The context's command list - */ - void trackQueryPools( - const Rc& cmd); - - private: - - const Rc m_vkd; - - uint32_t m_activeTypes = 0; - - Rc m_occlusion; - Rc m_pipeStats; - Rc m_timestamp; - Rc m_xfbStream; - - std::vector m_activeQueries; - - void trackQueryPool( - const Rc& cmd, - const Rc& pool); - - void beginVulkanQuery( - const Rc& cmd, - const DxvkQueryRevision& query); - - void endVulkanQuery( - const Rc& cmd, - const DxvkQueryRevision& query); - - Rc& getQueryPool( - VkQueryType type); - - static uint32_t getDxvkQueryTypeBit( - VkQueryType type); - - }; - -} \ No newline at end of file diff --git a/src/dxvk/dxvk_query_pool.cpp b/src/dxvk/dxvk_query_pool.cpp deleted file mode 100644 index 0fb17cb0..00000000 --- a/src/dxvk/dxvk_query_pool.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "dxvk_cmdlist.h" -#include "dxvk_query_pool.h" - -namespace dxvk { - - DxvkQueryPool::DxvkQueryPool( - const Rc& vkd, - 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; - info.flags = 0; - info.queryType = queryType; - info.queryCount = queryCount; - info.pipelineStatistics = 0; - - if (queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS) { - info.pipelineStatistics - = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT - | VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT - | VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT - | VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT - | VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT - | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT - | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT - | VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT - | VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT - | VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT - | VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT; - } - - if (m_vkd->vkCreateQueryPool(m_vkd->device(), &info, nullptr, &m_queryPool) != VK_SUCCESS) - Logger::err("DxvkQueryPool: Failed to create query pool"); - } - - - DxvkQueryPool::~DxvkQueryPool() { - m_vkd->vkDestroyQueryPool( - m_vkd->device(), m_queryPool, nullptr); - } - - - DxvkQueryHandle DxvkQueryPool::allocQuery(const DxvkQueryRevision& query) { - const uint32_t queryIndex = m_queryRangeOffset + m_queryRangeLength; - - if (queryIndex >= m_queryCount) - return DxvkQueryHandle(); - - DxvkQueryHandle result; - result.queryPool = m_queryPool; - result.queryId = queryIndex; - result.flags = query.query->flags(); - result.index = query.query->index(); - - query.query->associateQuery(query.revision, result); - m_queries.at(queryIndex) = query; - - m_queryRangeLength += 1; - return result; - } - - - VkResult DxvkQueryPool::getData( - uint32_t queryIndex, - uint32_t queryCount) { - std::array results; - - // We cannot use VK_QUERY_RESULT_WAIT_BIT here since that - // may stall the calling thread indefinitely. Instead, we - // just assume that all queries should be available after - // waiting for the fence that protects the command buffer. - const VkResult status = m_vkd->vkGetQueryPoolResults( - m_vkd->device(), m_queryPool, queryIndex, queryCount, - sizeof(DxvkQueryData) * queryCount, results.data(), - sizeof(DxvkQueryData), VK_QUERY_RESULT_64_BIT); - - if (status != VK_SUCCESS) { - Logger::warn(str::format( - "DxvkQueryPool: Failed to get query data for ", queryIndex, - ":", queryCount, " with: ", status)); - - // If retrieving query data failed, we need to fake query - // data. In case of occlusion queries, we should return a - // non-zero value for samples passed, so that games do not - // accidentally omit certain geometry because of this. - for (uint32_t i = 0; i < queryCount; i++) { - results[i] = DxvkQueryData(); - - if (m_queryType == VK_QUERY_TYPE_OCCLUSION) - results[i].occlusion.samplesPassed = 1; - } - } - - // Forward query data to the query objects - for (uint32_t i = 0; i < queryCount; i++) { - const DxvkQueryRevision& query = m_queries.at(queryIndex + i); - query.query->updateData(query.revision, results[i]); - } - - return VK_SUCCESS; - } - - - void DxvkQueryPool::reset(const Rc& cmd) { - cmd->cmdResetQueryPool(m_queryPool, 0, m_queryCount); - - m_queryRangeOffset = 0; - 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 deleted file mode 100644 index bfc68055..00000000 --- a/src/dxvk/dxvk_query_pool.h +++ /dev/null @@ -1,106 +0,0 @@ -#pragma once - -#include - -#include "dxvk_query.h" - -namespace dxvk { - - class DxvkCommandList; - class DxvkQueryPool; - - /** - * \brief Query range - * - * Stores an index of a query in a query pool, - * and the number of queries to track. - */ - struct DxvkQueryRange { - Rc queryPool; - - uint32_t queryIndex = 0; - uint32_t queryCount = 0; - }; - - /** - * \brief Query pool - * - * Manages a Vulkan query pool. This is used - * to allocate actual query objects for virtual - * query objects. - */ - class DxvkQueryPool : public RcObject { - - public: - - DxvkQueryPool( - const Rc& vkd, - VkQueryType queryType, - uint32_t queryCount); - - ~DxvkQueryPool(); - - /** - * \brief Query pool handle - * \returns Query pool handle - */ - VkQueryPool handle() const { - return m_queryPool; - } - - /** - * \brief Allocates a Vulkan query - * - * \param [in] revision Query revision - * \returns The query ID and pool handle - */ - DxvkQueryHandle allocQuery( - const DxvkQueryRevision& revision); - - /** - * \brief Writes back data for a range of queries - * - * \param [in] queryIndex First query in the range - * \param [in] queryCount Number of queries - * \returns Query result status - */ - VkResult getData( - 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); - - /** - * \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; - - uint32_t m_queryCount; - VkQueryType m_queryType; - VkQueryPool m_queryPool = VK_NULL_HANDLE; - - std::vector m_queries; - - uint32_t m_queryRangeOffset = 0; - uint32_t m_queryRangeLength = 0; - - }; - -} \ No newline at end of file diff --git a/src/dxvk/dxvk_query_tracker.cpp b/src/dxvk/dxvk_query_tracker.cpp deleted file mode 100644 index 6a46747e..00000000 --- a/src/dxvk/dxvk_query_tracker.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#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 deleted file mode 100644 index 5ac9d24c..00000000 --- a/src/dxvk/dxvk_query_tracker.h +++ /dev/null @@ -1,45 +0,0 @@ -#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 a0ee3f60..191db0da 100644 --- a/src/dxvk/dxvk_queue.cpp +++ b/src/dxvk/dxvk_queue.cpp @@ -58,7 +58,6 @@ namespace dxvk { VkResult status = cmdList->synchronize(); if (status == VK_SUCCESS) { - cmdList->writeQueryData(); cmdList->signalEvents(); cmdList->reset(); diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index d91f6873..23f773bc 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -73,10 +73,6 @@ dxvk_src = files([ 'dxvk_pipecache.cpp', 'dxvk_pipelayout.cpp', 'dxvk_pipemanager.cpp', - 'dxvk_query.cpp', - 'dxvk_query_pool.cpp', - 'dxvk_query_manager.cpp', - 'dxvk_query_tracker.cpp', 'dxvk_queue.cpp', 'dxvk_renderpass.cpp', 'dxvk_resource.cpp',