renderer_vulkan: Add conditional rendering control setting

Adds user option to disable Vulkan conditional rendering, which can fix
flickering objects in some games caused by rapidly toggled draw calls.

Changes:
- Add use_conditional_rendering setting (default: enabled)
- Guard conditional rendering functions with setting check using [[unlikely]]
- Early exit in Pause/Resume and Compare functions when disabled

Disabling this in Graphics (Advanced) fixes flickering at cost of performance.

Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
Zephyron
2025-10-17 16:47:57 +10:00
parent dd49615a48
commit 99073c8e19
3 changed files with 25 additions and 0 deletions

View File

@@ -230,6 +230,10 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
"unlocked."));
INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"),
tr("Improves rendering of transparency effects in specific games."));
INSERT(Settings, use_conditional_rendering, tr("Use conditional rendering"),
tr("Enables conditional rendering based on query results.\n"
"Disabling this can fix flickering objects in some games but may impact performance.\n"
"Try disabling if you see objects appearing and disappearing rapidly."));
// Renderer (Debug)

View File

@@ -469,6 +469,8 @@ struct Values {
Category::RendererAdvanced};
SwitchableSetting<bool> barrier_feedback_loops{linkage, true, "barrier_feedback_loops",
Category::RendererAdvanced};
SwitchableSetting<bool> use_conditional_rendering{linkage, true, "use_conditional_rendering",
Category::RendererAdvanced};
Setting<bool> renderer_debug{linkage, false, "debug", Category::RendererDebug};
Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback",

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <cstddef>
@@ -1290,6 +1291,9 @@ void QueryCacheRuntime::EndHostConditionalRendering() {
}
void QueryCacheRuntime::PauseHostConditionalRendering() {
if (!Settings::values.use_conditional_rendering.GetValue()) [[unlikely]] {
return;
}
if (!impl->hcr_is_set) {
return;
}
@@ -1301,6 +1305,9 @@ void QueryCacheRuntime::PauseHostConditionalRendering() {
}
void QueryCacheRuntime::ResumeHostConditionalRendering() {
if (!Settings::values.use_conditional_rendering.GetValue()) [[unlikely]] {
return;
}
if (!impl->hcr_is_set) {
return;
}
@@ -1314,6 +1321,12 @@ void QueryCacheRuntime::ResumeHostConditionalRendering() {
void QueryCacheRuntime::HostConditionalRenderingCompareValueImpl(VideoCommon::LookupData object,
bool is_equal) {
// Early exit if conditional rendering is disabled by user
if (!Settings::values.use_conditional_rendering.GetValue()) [[unlikely]] {
impl->hcr_is_set = false;
return;
}
{
std::scoped_lock lk(impl->buffer_cache.mutex);
static constexpr auto sync_info = VideoCommon::ObtainBufferSynchronize::FullSynchronize;
@@ -1340,6 +1353,12 @@ void QueryCacheRuntime::HostConditionalRenderingCompareValueImpl(VideoCommon::Lo
}
void QueryCacheRuntime::HostConditionalRenderingCompareBCImpl(DAddr address, bool is_equal) {
// Early exit if conditional rendering is disabled by user
if (!Settings::values.use_conditional_rendering.GetValue()) [[unlikely]] {
impl->hcr_is_set = false;
return;
}
VkBuffer to_resolve;
u32 to_resolve_offset;
{