[VK]Improve query reset before use so that now queries are reset outside render pass and are batched
Note to testers, please enable validation layers and see if there are any errors related to queries not being reset before every use, Thanks.
This commit is contained in:
parent
d19a7c3782
commit
94c9f828c5
5 changed files with 40 additions and 7 deletions
|
@ -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);
|
||||||
|
|
|
@ -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); });
|
||||||
|
|
|
@ -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) {
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue