mirror of
https://git.citron-emu.org/citron/emulator
synced 2025-12-19 10:43:33 +00:00
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:
@@ -230,6 +230,10 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
|
|||||||
"unlocked."));
|
"unlocked."));
|
||||||
INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"),
|
INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"),
|
||||||
tr("Improves rendering of transparency effects in specific games."));
|
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)
|
// Renderer (Debug)
|
||||||
|
|
||||||
|
|||||||
@@ -469,6 +469,8 @@ struct Values {
|
|||||||
Category::RendererAdvanced};
|
Category::RendererAdvanced};
|
||||||
SwitchableSetting<bool> barrier_feedback_loops{linkage, true, "barrier_feedback_loops",
|
SwitchableSetting<bool> barrier_feedback_loops{linkage, true, "barrier_feedback_loops",
|
||||||
Category::RendererAdvanced};
|
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_debug{linkage, false, "debug", Category::RendererDebug};
|
||||||
Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback",
|
Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@@ -1290,6 +1291,9 @@ void QueryCacheRuntime::EndHostConditionalRendering() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QueryCacheRuntime::PauseHostConditionalRendering() {
|
void QueryCacheRuntime::PauseHostConditionalRendering() {
|
||||||
|
if (!Settings::values.use_conditional_rendering.GetValue()) [[unlikely]] {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!impl->hcr_is_set) {
|
if (!impl->hcr_is_set) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1301,6 +1305,9 @@ void QueryCacheRuntime::PauseHostConditionalRendering() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QueryCacheRuntime::ResumeHostConditionalRendering() {
|
void QueryCacheRuntime::ResumeHostConditionalRendering() {
|
||||||
|
if (!Settings::values.use_conditional_rendering.GetValue()) [[unlikely]] {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!impl->hcr_is_set) {
|
if (!impl->hcr_is_set) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1314,6 +1321,12 @@ void QueryCacheRuntime::ResumeHostConditionalRendering() {
|
|||||||
|
|
||||||
void QueryCacheRuntime::HostConditionalRenderingCompareValueImpl(VideoCommon::LookupData object,
|
void QueryCacheRuntime::HostConditionalRenderingCompareValueImpl(VideoCommon::LookupData object,
|
||||||
bool is_equal) {
|
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);
|
std::scoped_lock lk(impl->buffer_cache.mutex);
|
||||||
static constexpr auto sync_info = VideoCommon::ObtainBufferSynchronize::FullSynchronize;
|
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) {
|
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;
|
VkBuffer to_resolve;
|
||||||
u32 to_resolve_offset;
|
u32 to_resolve_offset;
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user