diff --git a/src/common/settings.h b/src/common/settings.h index 2a1c88c79e..1908d55a71 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -427,6 +427,16 @@ struct Values { Specialization::Default, true, true}; + SwitchableSetting dma_accuracy{linkage, + DmaAccuracy::Default, + DmaAccuracy::Normal, + DmaAccuracy::High, + DmaAccuracy::Extreme, + "dma_accuracy", + Category::RendererAdvanced, + Specialization::Default, + true, + true}; GpuAccuracy current_gpu_accuracy{GpuAccuracy::High}; SwitchableSetting max_anisotropy{linkage, #ifdef ANDROID diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index c2347f74d0..52b4a128f7 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -136,6 +136,8 @@ ENUM(ShaderBackend, Glsl, Glasm, SpirV); ENUM(GpuAccuracy, Normal, High, Extreme); +ENUM(DmaAccuracy, Default, Normal, High, Extreme); + ENUM(CpuBackend, Dynarmic, Nce); ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid); diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 8ea4cbd43a..fa8c438b6c 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -102,17 +102,29 @@ bool DmaPusher::Step() { ProcessCommands(headers); }; - if (Settings::IsGPULevelExtreme()) { + if (Settings::values.current_gpu_accuracy == DmaAccuracy::Extreme) { safe_process(); - } else if (Settings::IsGPULevelHigh()) { + } else if (Settings::values.current_gpu_accuracy == DmaAccuracy::High) { if (dma_state.method >= MacroRegistersStart) { unsafe_process(); } else { safe_process(); } - } else { + } else if (Settings::values.current_gpu_accuracy == DmaAccuracy::Normal) { unsafe_process(); - } + } else if (Settings::values.current_gpu_accuracy == DmaAccuracy::Default) { + if (Settings::IsGPULevelExtreme()) { + safe_process(); + } else if (Settings::IsGPULevelHigh()) { + if (dma_state.method >= MacroRegistersStart) { + unsafe_process(); + } else { + safe_process(); + } + } else { + unsafe_process(); + } + } if (dma_pushbuffer_subindex >= command_list.command_lists.size()) { // We've gone through the current list, remove it from the queue diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index c237015fed..7dcc270ba8 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -294,6 +294,10 @@ std::unique_ptr InitializeTranslations(QWidget* parent) "accuracy.\nExtreme should only be used for debugging.\nThis option can " "be changed while playing.\nSome games may require booting on high to render " "properly.")); + INSERT(Settings, + dma_accuracy, + tr("DMA Level:"), + tr("Adjusts the DMA precision level. Higher precision may fix some games, but it can also directly impact performance in some cases.\nIf unsure, leave it at Default.")); INSERT(Settings, use_asynchronous_shaders, tr("Use asynchronous shader building (Hack)"), @@ -522,6 +526,13 @@ std::unique_ptr ComboboxEnumeration(QWidget* parent) PAIR(GpuAccuracy, High, tr("High")), PAIR(GpuAccuracy, Extreme, tr("Extreme")), }}); + translations->insert({Settings::EnumMetadata::Index(), + { + PAIR(DmaAccuracy, Default, tr("Default")), + PAIR(DmaAccuracy, Normal, tr("Normal")), + PAIR(DmaAccuracy, High, tr("High")), + PAIR(DmaAccuracy, Extreme, tr("Extreme")), + }}); translations->insert( {Settings::EnumMetadata::Index(), { diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index 0502fe75e4..85de0ae72d 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h @@ -270,6 +270,7 @@ Q_DECLARE_METATYPE(UISettings::GameDir*); // These metatype declarations cannot be in common/settings.h because core is devoid of QT Q_DECLARE_METATYPE(Settings::CpuAccuracy); Q_DECLARE_METATYPE(Settings::GpuAccuracy); +Q_DECLARE_METATYPE(Settings::DmaAccuracy); Q_DECLARE_METATYPE(Settings::FullscreenMode); Q_DECLARE_METATYPE(Settings::NvdecEmulation); Q_DECLARE_METATYPE(Settings::ResolutionSetup);