Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
f630a7f277 [VK]Improve query reset before use so that now queries are reset outside render pass and are batched
Some checks failed
eden-license / license-header (pull_request) Failing after 28s
Note to testers, please enable validation layers and see if there are any errors related to queries not being reset before every use, Thanks.
2025-08-14 22:00:09 +02:00
5 changed files with 40 additions and 7 deletions

View file

@ -27,7 +27,7 @@
#include "video_core/query_cache/query_cache_base.h" #include "video_core/query_cache/query_cache_base.h"
#include "video_core/query_cache/query_stream.h" #include "video_core/query_cache/query_stream.h"
#include "video_core/query_cache/types.h" #include "video_core/query_cache/types.h"
namespace Vulkan { class Scheduler; }
namespace VideoCommon { namespace VideoCommon {
using Maxwell = Tegra::Engines::Maxwell3D; using Maxwell = Tegra::Engines::Maxwell3D;
@ -222,6 +222,12 @@ void QueryCacheBase<Traits>::CounterReset(QueryType counter_type) {
streamer->ResetCounter(); streamer->ResetCounter();
} }
// Called at frame start to batch vkCmdResetQueryPool outside render passes.
template <typename Traits>
void QueryCacheBase<Traits>::FramePrologueResets(Vulkan::Scheduler& scheduler) {
impl->runtime.FramePrologueResets(scheduler);
}
template <typename Traits> template <typename Traits>
void QueryCacheBase<Traits>::BindToChannel(s32 id) { void QueryCacheBase<Traits>::BindToChannel(s32 id) {
VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo>::BindToChannel(id); VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo>::BindToChannel(id);

View file

@ -21,7 +21,9 @@
namespace VideoCore { namespace VideoCore {
class RasterizerInterface; class RasterizerInterface;
} }
namespace Vulkan {
class Scheduler;
}
namespace Tegra { namespace Tegra {
class GPU; class GPU;
} }
@ -53,7 +55,7 @@ public:
RuntimeType& runtime_); RuntimeType& runtime_);
~QueryCacheBase(); ~QueryCacheBase();
void FramePrologueResets(Vulkan::Scheduler& scheduler);
void InvalidateRegion(VAddr addr, std::size_t size) { void InvalidateRegion(VAddr addr, std::size_t size) {
IterateCache<true>(addr, size, IterateCache<true>(addr, size,
[this](QueryLocation location) { InvalidateQuery(location); }); [this](QueryLocation location) { InvalidateQuery(location); });

View file

@ -156,7 +156,7 @@ public:
ReserveHostQuery(); ReserveHostQuery();
// Ensure outside render pass /* Ensure outside render pass
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
// Reset query pool outside render pass // Reset query pool outside render pass
@ -167,7 +167,7 @@ public:
// Manually restart the render pass (required for vkCmdClearAttachments, etc.) // Manually restart the render pass (required for vkCmdClearAttachments, etc.)
scheduler.RequestRenderpass(texture_cache.GetFramebuffer()); scheduler.RequestRenderpass(texture_cache.GetFramebuffer());
*/
// Begin query inside the newly started render pass // Begin query inside the newly started render pass
scheduler.Record([query_pool = current_query_pool, scheduler.Record([query_pool = current_query_pool,
query_index = current_bank_slot](vk::CommandBuffer cmdbuf) { query_index = current_bank_slot](vk::CommandBuffer cmdbuf) {
@ -402,6 +402,13 @@ public:
} }
} }
VkQueryPool GetOrCreateCurrentPoolForPrologue() {
if (!current_bank || current_bank->IsClosed()) {
ReserveBank();
}
return current_query_pool;
}
private: private:
template <typename Func> template <typename Func>
void ApplyBankOp(VideoCommon::HostQueryBase* query, Func&& func) { void ApplyBankOp(VideoCommon::HostQueryBase* query, Func&& func) {
@ -1305,6 +1312,19 @@ void QueryCacheRuntime::ResumeHostConditionalRendering() {
impl->is_hcr_running = true; impl->is_hcr_running = true;
} }
void QueryCacheRuntime::FramePrologueResets(Scheduler& scheduler) {
// Reset the occlusion queries we plan to use this frame in one go.
// Ensure this is recorded OUTSIDE any render pass.
const VkQueryPool pool = impl->sample_streamer.GetOrCreateCurrentPoolForPrologue();
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([pool](vk::CommandBuffer cmdbuf) {
// Reset the whole bank so subsequent BeginQuery calls don't need per-slot resets.
cmdbuf.ResetQueryPool(pool,
/*first*/ 0,
/*count*/ SamplesQueryBank::BANK_SIZE);
});
}
void QueryCacheRuntime::HostConditionalRenderingCompareValueImpl(VideoCommon::LookupData object, void QueryCacheRuntime::HostConditionalRenderingCompareValueImpl(VideoCommon::LookupData object,
bool is_equal) { bool is_equal) {
{ {

View file

@ -20,7 +20,7 @@ namespace Vulkan {
class Device; class Device;
class Scheduler; class Scheduler;
class StagingBufferPool; class StagingBufferPool;
class Scheduler;
struct QueryCacheRuntimeImpl; struct QueryCacheRuntimeImpl;
class QueryCacheRuntime { class QueryCacheRuntime {
@ -33,7 +33,7 @@ public:
ComputePassDescriptorQueue& compute_pass_descriptor_queue, ComputePassDescriptorQueue& compute_pass_descriptor_queue,
DescriptorPool& descriptor_pool, TextureCache& texture_cache_); DescriptorPool& descriptor_pool, TextureCache& texture_cache_);
~QueryCacheRuntime(); ~QueryCacheRuntime();
void FramePrologueResets(Scheduler& scheduler);
template <typename SyncValuesType> template <typename SyncValuesType>
void SyncValues(std::span<SyncValuesType> values, VkBuffer base_src_buffer = nullptr); void SyncValues(std::span<SyncValuesType> values, VkBuffer base_src_buffer = nullptr);

View file

@ -257,6 +257,11 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se
void Scheduler::AllocateNewContext() { void Scheduler::AllocateNewContext() {
// Enable counters once again. These are disabled when a command buffer is finished. // Enable counters once again. These are disabled when a command buffer is finished.
// Record per frame query resets outside any render pass, before the first draw.
if (query_cache) {
query_cache->FramePrologueResets(*this);
}
} }
void Scheduler::InvalidateState() { void Scheduler::InvalidateState() {