From 3fc9466a07b053dbd37fbad564367416c5801791 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 12 May 2018 19:46:08 +0200 Subject: [PATCH] [dxvk] Fix query scopes Occlusion queries must begin and end in the same render pass. Fixes a rendering issue in Shadow Warrior 2 on AMD drivers. --- src/dxvk/dxvk_context.cpp | 46 ++++++++++++++++++--------------------- src/dxvk/dxvk_context.h | 3 --- src/dxvk/dxvk_query.cpp | 9 +++----- 3 files changed, 24 insertions(+), 34 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 25f040f0..bb966228 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -40,16 +40,11 @@ namespace dxvk { DxvkContextFlag::CpDirtyPipeline, DxvkContextFlag::CpDirtyPipelineState, DxvkContextFlag::CpDirtyResources); - - // Restart queries that were active during - // the last command buffer submission. - this->beginActiveQueries(); } Rc DxvkContext::endRecording() { this->spillRenderPass(); - this->endActiveQueries(); this->trackQueryPool(m_queryPools[VK_QUERY_TYPE_OCCLUSION]); this->trackQueryPool(m_queryPools[VK_QUERY_TYPE_PIPELINE_STATISTICS]); @@ -61,24 +56,29 @@ namespace dxvk { void DxvkContext::beginQuery(const DxvkQueryRevision& query) { - DxvkQueryHandle handle = this->allocQuery(query); - - m_cmd->cmdBeginQuery( - handle.queryPool, - handle.queryId, - handle.flags); - query.query->beginRecording(query.revision); + + if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) { + DxvkQueryHandle handle = this->allocQuery(query); + + m_cmd->cmdBeginQuery( + handle.queryPool, + handle.queryId, + handle.flags); + } + this->insertActiveQuery(query); } void DxvkContext::endQuery(const DxvkQueryRevision& query) { - DxvkQueryHandle handle = query.query->getHandle(); - - m_cmd->cmdEndQuery( - handle.queryPool, - handle.queryId); + if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) { + DxvkQueryHandle handle = query.query->getHandle(); + + m_cmd->cmdEndQuery( + handle.queryPool, + handle.queryId); + } query.query->endRecording(query.revision); this->eraseActiveQuery(query); @@ -1559,6 +1559,8 @@ namespace dxvk { this->resetRenderPassOps( m_state.om.renderTargets, m_state.om.renderPassOps); + + this->beginActiveQueries(); } } @@ -1569,6 +1571,7 @@ namespace dxvk { if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) { m_flags.clr(DxvkContextFlag::GpRenderPassBound); + this->endActiveQueries(); this->renderPassUnbindFramebuffer(); } } @@ -2096,7 +2099,7 @@ namespace dxvk { m_queryPools[queryType] = m_device->createQueryPool(queryType, MaxNumQueryCountPerPool); queryPool = m_queryPools[queryType]; - this->resetQueryPool(queryPool); + queryPool->reset(m_cmd); queryHandle = queryPool->allocQuery(query); } @@ -2104,13 +2107,6 @@ namespace dxvk { } - void DxvkContext::resetQueryPool(const Rc& pool) { - this->spillRenderPass(); - - pool->reset(m_cmd); - } - - void DxvkContext::trackQueryPool(const Rc& pool) { if (pool != nullptr) { DxvkQueryRange range = pool->getActiveQueryRange(); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index c8665326..fc74bfe2 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -692,9 +692,6 @@ namespace dxvk { DxvkQueryHandle allocQuery( const DxvkQueryRevision& query); - void resetQueryPool( - const Rc& pool); - void trackQueryPool( const Rc& pool); diff --git a/src/dxvk/dxvk_query.cpp b/src/dxvk/dxvk_query.cpp index 520b3928..0b054913 100644 --- a/src/dxvk/dxvk_query.cpp +++ b/src/dxvk/dxvk_query.cpp @@ -55,12 +55,9 @@ namespace dxvk { std::unique_lock lock(m_mutex); if (m_revision == revision) { - if (m_queryIndex < m_queryCount) { - m_status = DxvkQueryStatus::Pending; - } else { - m_status = DxvkQueryStatus::Available; - } - + m_status = m_queryIndex < m_queryCount + ? DxvkQueryStatus::Pending + : DxvkQueryStatus::Available; m_handle = DxvkQueryHandle(); } }