From 9077aa2eb9da57af66a3c54afe0bbac989d8a75e Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 1 Oct 2025 08:09:33 +0000 Subject: [PATCH 1/8] [arm] Add "debugging" cpu accuracy option to replace CPU debug toggle The debug toggle and the CPU accuracy options are mutually exclusive, if debug toggle on => cpu accuracy is ignored, if debug toggle off => cpu accuracy is used. So just add it to cpu accuracy and avoid the extra hassle. Signed-off-by: lizzie --- src/common/settings.cpp | 6 +- src/common/settings.h | 3 - src/common/settings_enums.h | 2 +- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 77 ++++++++++----------- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 79 +++++++++++----------- src/qt_common/shared_translation.cpp | 1 + src/yuzu/configuration/configure_debug.cpp | 3 - src/yuzu/configuration/configure_debug.ui | 8 --- 8 files changed, 84 insertions(+), 95 deletions(-) diff --git a/src/common/settings.cpp b/src/common/settings.cpp index b41f4c75f5..e8fc910eb3 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -163,11 +163,11 @@ bool IsDMALevelSafe() { } bool IsFastmemEnabled() { - if (values.cpu_debug_mode) { - return static_cast(values.cpuopt_fastmem); + if (values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Debugging) { + return bool(values.cpuopt_fastmem); } if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe) { - return static_cast(values.cpuopt_unsafe_host_mmu); + return bool(values.cpuopt_unsafe_host_mmu); } #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) return false; diff --git a/src/common/settings.h b/src/common/settings.h index 891bde608c..3ed7deb626 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -275,9 +275,6 @@ struct Values { true, true, &use_custom_cpu_ticks}; - - SwitchableSetting cpu_debug_mode{linkage, false, "cpu_debug_mode", Category::CpuDebug}; - Setting cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug}; Setting cpuopt_block_linking{linkage, true, "cpuopt_block_linking", Category::CpuDebug}; Setting cpuopt_return_stack_buffer{linkage, true, "cpuopt_return_stack_buffer", diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 0e5a08d845..1b545ca038 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -136,7 +136,7 @@ ENUM(ShaderBackend, Glsl, Glasm, SpirV); ENUM(GpuAccuracy, Normal, High, Extreme); ENUM(DmaAccuracy, Default, Unsafe, Safe); ENUM(CpuBackend, Dynarmic, Nce); -ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid); +ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid, Debugging); ENUM(CpuClock, Boost, Fast) ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb); ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index d2035d0fe0..3c72ab2396 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -229,7 +229,8 @@ std::shared_ptr ArmDynarmic32::MakeJit(Common::PageTable* pa } // Safe optimizations - if (Settings::values.cpu_debug_mode) { + switch (Settings::values.cpu_accuracy.GetValue()) { + case Settings::CpuAccuracy::Debugging: if (!Settings::values.cpuopt_page_tables) { config.page_table = nullptr; } @@ -267,51 +268,51 @@ std::shared_ptr ArmDynarmic32::MakeJit(Common::PageTable* pa if (!Settings::values.cpuopt_ignore_memory_aborts) { config.check_halt_on_memory_access = true; } - } else { - // Unsafe optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) { - config.unsafe_optimizations = true; - if (!Settings::values.cpuopt_unsafe_host_mmu) { - config.fastmem_pointer = std::nullopt; - config.fastmem_exclusive_access = false; - } - if (Settings::values.cpuopt_unsafe_unfuse_fma) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; - } - if (Settings::values.cpuopt_unsafe_reduce_fp_error) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; - } - if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; - } - if (Settings::values.cpuopt_unsafe_inaccurate_nan) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; - } - if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; - } - } - - // Curated optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) { - config.unsafe_optimizations = true; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + break; + // Unsafe optimizations + case Settings::CpuAccuracy::Unsafe: + config.unsafe_optimizations = true; + if (!Settings::values.cpuopt_unsafe_host_mmu) { config.fastmem_pointer = std::nullopt; config.fastmem_exclusive_access = false; -#endif + } + if (Settings::values.cpuopt_unsafe_unfuse_fma) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + } + if (Settings::values.cpuopt_unsafe_reduce_fp_error) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; + } + if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; + } + if (Settings::values.cpuopt_unsafe_inaccurate_nan) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + } + if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; } - - // Paranoia mode for debugging optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) { - config.unsafe_optimizations = false; - config.optimizations = Dynarmic::no_optimizations; - } + break; + // Curated optimizations + case Settings::CpuAccuracy::Auto: + config.unsafe_optimizations = true; +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + config.fastmem_pointer = std::nullopt; + config.fastmem_exclusive_access = false; +#endif + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; + break; + // Paranoia mode for debugging optimizations + case Settings::CpuAccuracy::Paranoid: + config.unsafe_optimizations = false; + config.optimizations = Dynarmic::no_optimizations; + break; + case Settings::CpuAccuracy::Accurate: + default: + break; } - return std::make_unique(config); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 438b7b691c..707d51d2a2 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -287,8 +287,9 @@ std::shared_ptr ArmDynarmic64::MakeJit(Common::PageTable* pa config.code_cache_size = std::uint32_t(8_MiB); } - // Safe optimizations - if (Settings::values.cpu_debug_mode) { + switch (Settings::values.cpu_accuracy.GetValue()) { + // Debug mode + case Settings::CpuAccuracy::Debugging: if (!Settings::values.cpuopt_page_tables) { config.page_table = nullptr; } @@ -326,50 +327,50 @@ std::shared_ptr ArmDynarmic64::MakeJit(Common::PageTable* pa if (!Settings::values.cpuopt_ignore_memory_aborts) { config.check_halt_on_memory_access = true; } - } else { - // Unsafe optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) { - config.unsafe_optimizations = true; - if (!Settings::values.cpuopt_unsafe_host_mmu) { - config.fastmem_pointer = std::nullopt; - config.fastmem_exclusive_access = false; - } - if (Settings::values.cpuopt_unsafe_unfuse_fma) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; - } - if (Settings::values.cpuopt_unsafe_reduce_fp_error) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; - } - if (Settings::values.cpuopt_unsafe_inaccurate_nan) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; - } - if (Settings::values.cpuopt_unsafe_fastmem_check) { - config.fastmem_address_space_bits = 64; - } - if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; - } - } - - // Curated optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) { - config.unsafe_optimizations = true; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + break; + // Unsafe optimizations + case Settings::CpuAccuracy::Unsafe: + config.unsafe_optimizations = true; + if (!Settings::values.cpuopt_unsafe_host_mmu) { config.fastmem_pointer = std::nullopt; config.fastmem_exclusive_access = false; -#endif + } + if (Settings::values.cpuopt_unsafe_unfuse_fma) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + } + if (Settings::values.cpuopt_unsafe_reduce_fp_error) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; + } + if (Settings::values.cpuopt_unsafe_inaccurate_nan) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + } + if (Settings::values.cpuopt_unsafe_fastmem_check) { config.fastmem_address_space_bits = 64; + } + if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; } - - // Paranoia mode for debugging optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) { - config.unsafe_optimizations = false; - config.optimizations = Dynarmic::no_optimizations; - } + break; + // Safe optimisations + case Settings::CpuAccuracy::Auto: + config.unsafe_optimizations = true; +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + config.fastmem_pointer = std::nullopt; + config.fastmem_exclusive_access = false; +#endif + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + config.fastmem_address_space_bits = 64; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; + break; + // Paranoia mode for debugging optimizations + case Settings::CpuAccuracy::Paranoid: + config.unsafe_optimizations = false; + config.optimizations = Dynarmic::no_optimizations; + break; + case Settings::CpuAccuracy::Accurate: + default: + break; } - return std::make_shared(config); } diff --git a/src/qt_common/shared_translation.cpp b/src/qt_common/shared_translation.cpp index 8f5d929b74..b1f53d2142 100644 --- a/src/qt_common/shared_translation.cpp +++ b/src/qt_common/shared_translation.cpp @@ -516,6 +516,7 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) PAIR(CpuAccuracy, Accurate, tr("Accurate")), PAIR(CpuAccuracy, Unsafe, tr("Unsafe")), PAIR(CpuAccuracy, Paranoid, tr("Paranoid (disables most optimizations)")), + PAIR(CpuAccuracy, Debugging, tr("Debugging")), }}); translations->insert({Settings::EnumMetadata::Index(), { diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 18f629f639..287a3757b7 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -62,8 +62,6 @@ void ConfigureDebug::SetConfiguration() { ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug.GetValue()); ui->enable_shader_feedback->setEnabled(runtime_lock); ui->enable_shader_feedback->setChecked(Settings::values.renderer_shader_feedback.GetValue()); - ui->enable_cpu_debugging->setEnabled(runtime_lock); - ui->enable_cpu_debugging->setChecked(Settings::values.cpu_debug_mode.GetValue()); ui->enable_nsight_aftermath->setEnabled(runtime_lock); ui->enable_nsight_aftermath->setChecked(Settings::values.enable_nsight_aftermath.GetValue()); ui->dump_shaders->setEnabled(runtime_lock); @@ -107,7 +105,6 @@ void ConfigureDebug::ApplyConfiguration() { Settings::values.enable_renderdoc_hotkey = ui->enable_renderdoc_hotkey->isChecked(); Settings::values.disable_buffer_reorder = ui->disable_buffer_reorder->isChecked(); Settings::values.renderer_shader_feedback = ui->enable_shader_feedback->isChecked(); - Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked(); Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked(); Settings::values.dump_shaders = ui->dump_shaders->isChecked(); Settings::values.dump_macros = ui->dump_macros->isChecked(); diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index bd7125712c..1f302bf118 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui @@ -435,13 +435,6 @@ - - - - Enable CPU Debugging - - - @@ -582,7 +575,6 @@ fs_access_log reporting_services quest_flag - enable_cpu_debugging use_debug_asserts From 326865cba2641f693d8500506594c387259dfc11 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Thu, 2 Oct 2025 00:15:14 +0200 Subject: [PATCH 2/8] [host1x] Improve FFmpeg error handling (#2643) This improves the FFmpeg error handling. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2643 Co-authored-by: MaranBr Co-committed-by: MaranBr --- .../nvdrv/devices/nvhost_nvdec_common.cpp | 4 ++-- src/video_core/host1x/codecs/decoder.cpp | 4 ++++ src/video_core/host1x/ffmpeg/ffmpeg.cpp | 22 +++++++++---------- src/video_core/host1x/ffmpeg/ffmpeg.h | 2 +- src/video_core/host1x/vic.cpp | 5 +++++ 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index de4197c52d..f7d6c33f77 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -135,8 +135,8 @@ NvResult nvhost_nvdec_common::GetSyncpoint(IoctlGetSyncpoint& params) { } NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) { - LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); - params.value = 0; // Seems to be hard coded at 0 + LOG_DEBUG(Service_NVDRV, "called WAITBASE"); + params.value = 0; return NvResult::Success; } diff --git a/src/video_core/host1x/codecs/decoder.cpp b/src/video_core/host1x/codecs/decoder.cpp index cb17784b19..887eb28c8c 100755 --- a/src/video_core/host1x/codecs/decoder.cpp +++ b/src/video_core/host1x/codecs/decoder.cpp @@ -38,6 +38,10 @@ void Decoder::Decode() { // Receive output frames from decoder. auto frame = decode_api.ReceiveFrame(); + if (!frame) { + return; + } + if (IsInterlaced()) { auto [luma_top, luma_bottom, chroma_top, chroma_bottom] = GetInterlacedOffsets(); auto frame_copy = frame; diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.cpp b/src/video_core/host1x/ffmpeg/ffmpeg.cpp index 536a01fcc8..bbbbe615ce 100644 --- a/src/video_core/host1x/ffmpeg/ffmpeg.cpp +++ b/src/video_core/host1x/ffmpeg/ffmpeg.cpp @@ -233,7 +233,7 @@ bool DecoderContext::OpenContext(const Decoder& decoder) { } bool DecoderContext::SendPacket(const Packet& packet) { - if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0 && ret != AVERROR_EOF) { + if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) { LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret)); return false; } @@ -242,31 +242,31 @@ bool DecoderContext::SendPacket(const Packet& packet) { } std::shared_ptr DecoderContext::ReceiveFrame() { - auto ReceiveImpl = [&](AVFrame* frame) -> bool { - if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0 && ret != AVERROR_EOF) { + auto ReceiveImpl = [&](AVFrame* frame) -> int { + const int ret = avcodec_receive_frame(m_codec_context, frame); + if (ret < 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) { LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret)); - return false; } - return true; + return ret; }; std::shared_ptr intermediate_frame = std::make_shared(); - if (!ReceiveImpl(intermediate_frame->GetFrame())) { + if (ReceiveImpl(intermediate_frame->GetFrame()) < 0) { return {}; } - m_temp_frame = std::make_shared(); + m_final_frame = std::make_shared(); if (m_codec_context->hw_device_ctx) { - m_temp_frame->SetFormat(PreferredGpuFormat); - if (int ret = av_hwframe_transfer_data(m_temp_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) { + m_final_frame->SetFormat(PreferredGpuFormat); + if (const int ret = av_hwframe_transfer_data(m_final_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) { LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret)); return {}; } } else { - m_temp_frame = std::move(intermediate_frame); + m_final_frame = std::move(intermediate_frame); } - return std::move(m_temp_frame); + return std::move(m_final_frame); } void DecodeApi::Reset() { diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.h b/src/video_core/host1x/ffmpeg/ffmpeg.h index 0dd7c7cb04..d60a8ac4a7 100644 --- a/src/video_core/host1x/ffmpeg/ffmpeg.h +++ b/src/video_core/host1x/ffmpeg/ffmpeg.h @@ -194,7 +194,7 @@ public: private: const Decoder& m_decoder; AVCodecContext* m_codec_context{}; - std::shared_ptr m_temp_frame{}; + std::shared_ptr m_final_frame{}; bool m_decode_order{}; }; diff --git a/src/video_core/host1x/vic.cpp b/src/video_core/host1x/vic.cpp index 9c33370337..3dbbfa5552 100644 --- a/src/video_core/host1x/vic.cpp +++ b/src/video_core/host1x/vic.cpp @@ -146,6 +146,11 @@ void Vic::Execute() { } auto frame = frame_queue.GetFrame(nvdec_id, luma_offset); + + if (!frame) { + continue; + } + if (!frame.get()) { LOG_ERROR(HW_GPU, "Vic {} failed to get frame with offset {:#X}", id, luma_offset); continue; From 24e6c62109cd30e09dd72a4af58f132dd7c0d359 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 2 Oct 2025 00:25:41 +0200 Subject: [PATCH 3/8] [vk, ogl] invalidate pipeline caches from <=0.0.3 (#2637) Invalidates caches before next upcoming release, this will make transitions smoother especially for users whom do not know how to clear caches. The reasoning behind this is the recent changes to async shaders and other pipeline stuffs that may break compat Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2637 Reviewed-by: MaranBr Reviewed-by: Maufeat Co-authored-by: lizzie Co-committed-by: lizzie --- src/video_core/renderer_opengl/gl_shader_cache.cpp | 2 +- src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index c2ead26bd9..45f729698e 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -54,7 +54,7 @@ using VideoCommon::LoadPipelines; using VideoCommon::SerializePipeline; using Context = ShaderContext::Context; -constexpr u32 CACHE_VERSION = 10; +constexpr u32 CACHE_VERSION = 13; template auto MakeSpan(Container& container) { diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 2fd0b59b3a..9cdbe5611b 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -55,7 +55,7 @@ using VideoCommon::FileEnvironment; using VideoCommon::GenericEnvironment; using VideoCommon::GraphicsEnvironment; -constexpr u32 CACHE_VERSION = 12; +constexpr u32 CACHE_VERSION = 13; constexpr std::array VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'}; template From 1a5b3fb23934cfb9647120fc2a055bc116e67460 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Thu, 2 Oct 2025 01:30:05 +0200 Subject: [PATCH 4/8] [audio_core] Fix audio reverb effect (#2646) This fixes the audio reverb effect that was causing loud noise in some games and on some platforms. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2646 Co-authored-by: MaranBr Co-committed-by: MaranBr --- src/audio_core/renderer/behavior/info_updater.cpp | 12 ------------ src/audio_core/renderer/command/effect/reverb.cpp | 2 -- 2 files changed, 14 deletions(-) diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp index 48fe1f8975..20f6cda3a2 100644 --- a/src/audio_core/renderer/behavior/info_updater.cpp +++ b/src/audio_core/renderer/behavior/info_updater.cpp @@ -165,12 +165,6 @@ Result InfoUpdater::UpdateEffectsVersion1(EffectContext& effect_context, const b reinterpret_cast(output), effect_count}; for (u32 i = 0; i < effect_count; i++) { -#ifdef _WIN32 - // There's a bug in Windows where using this effect causes extreme noise. So let's skip it. - if (in_params[i].type == EffectInfoBase::Type::Reverb) { - continue; - } -#endif auto effect_info{&effect_context.GetInfo(i)}; if (effect_info->GetType() != in_params[i].type) { effect_info->ForceUnmapBuffers(pool_mapper); @@ -218,12 +212,6 @@ Result InfoUpdater::UpdateEffectsVersion2(EffectContext& effect_context, const b reinterpret_cast(output), effect_count}; for (u32 i = 0; i < effect_count; i++) { -#ifdef _WIN32 - // There's a bug in Windows where using this effect causes extreme noise. So let's skip it. - if (in_params[i].type == EffectInfoBase::Type::Reverb) { - continue; - } -#endif auto effect_info{&effect_context.GetInfo(i)}; if (effect_info->GetType() != in_params[i].type) { effect_info->ForceUnmapBuffers(pool_mapper); diff --git a/src/audio_core/renderer/command/effect/reverb.cpp b/src/audio_core/renderer/command/effect/reverb.cpp index 46b85b8945..87eab1adda 100644 --- a/src/audio_core/renderer/command/effect/reverb.cpp +++ b/src/audio_core/renderer/command/effect/reverb.cpp @@ -191,8 +191,6 @@ static void InitializeReverbEffect(const ReverbInfo::ParameterVersion2& params, const auto center_delay_time{(5 * delay).to_uint_floor()}; state.center_delay_line.Initialize(center_delay_time, 1.0f); - UpdateReverbEffectParameter(params, state); - for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) { std::ranges::fill(state.fdn_delay_lines[i].buffer, 0); std::ranges::fill(state.decay_delay_lines[i].buffer, 0); From 990a43a48c77816f0f9f5edad40ec905f05df62b Mon Sep 17 00:00:00 2001 From: Ribbit Date: Thu, 2 Oct 2025 20:00:34 +0200 Subject: [PATCH 5/8] [vk] Add missing flush per spec (#2624) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We copy pixels into a CPU-side staging buffer and then ask the GPU to read from it. On some systems those CPU writes aren’t automatically visible to the GPU unless explicitly flushed, so the GPU can sometimes read stale data. By calling buffer.Flush() immediately after writing, we force those CPU changes to become visible to the device, ensuring the GPU sees the latest frame. However, this is an emulator, so sometimes what spec says may not work cause reasons. Co-authored-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2624 Reviewed-by: Shinmegumi Reviewed-by: MaranBr Co-authored-by: Ribbit Co-committed-by: Ribbit --- src/video_core/renderer_vulkan/present/layer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video_core/renderer_vulkan/present/layer.cpp b/src/video_core/renderer_vulkan/present/layer.cpp index fa7c457573..5676dfe62a 100644 --- a/src/video_core/renderer_vulkan/present/layer.cpp +++ b/src/video_core/renderer_vulkan/present/layer.cpp @@ -280,6 +280,7 @@ void Layer::UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t i Tegra::Texture::UnswizzleTexture( mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size), bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0); + buffer.Flush(); // Ensure host writes are visible before the GPU copy. } const VkBufferImageCopy copy{ From 2d8cb2d4570b35985648079d2cfd69e96481ff2a Mon Sep 17 00:00:00 2001 From: MaranBr Date: Thu, 2 Oct 2025 22:48:52 +0200 Subject: [PATCH 6/8] [file_sys] Properly fix the installation of new updates (#2651) This removes the workaround and properly fix the installation of new updates. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2651 Co-authored-by: MaranBr Co-committed-by: MaranBr --- src/core/file_sys/content_archive.cpp | 4 --- src/core/file_sys/fssystem/fs_types.h | 3 ++ .../fssystem_nca_file_system_driver.cpp | 34 ++++++++++++++----- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index edd25644ac..4e3313f83c 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -38,9 +38,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca) reader = std::make_shared(); if (Result rc = reader->Initialize(file, GetCryptoConfiguration(), GetNcaCompressionConfiguration()); R_FAILED(rc)) { - if (rc != ResultInvalidNcaSignature) { - LOG_ERROR(Loader, "File reader errored out during header read: {:#x}", rc.GetInnerValue()); - } status = Loader::ResultStatus::ErrorBadNCAHeader; return; } @@ -85,7 +82,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca) for (s32 i = 0; i < fs_count; i++) { NcaFsHeaderReader header_reader; if (Result rc = fs.OpenStorage(&filesystems[i], &header_reader, i); R_FAILED(rc)) { - LOG_DEBUG(Loader, "File reader errored out during read of section {}: {:#x}", i, rc.GetInnerValue()); status = Loader::ResultStatus::ErrorBadNCAHeader; return; } diff --git a/src/core/file_sys/fssystem/fs_types.h b/src/core/file_sys/fssystem/fs_types.h index 43aeaf447b..f11b7f1dae 100644 --- a/src/core/file_sys/fssystem/fs_types.h +++ b/src/core/file_sys/fssystem/fs_types.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp index 25036b02c1..d496d58cec 100644 --- a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp +++ b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp @@ -1049,13 +1049,11 @@ Result NcaFileSystemDriver::CreatePatchMetaStorage( ASSERT(out_aes_ctr_ex_meta != nullptr); ASSERT(out_indirect_meta != nullptr); ASSERT(base_storage != nullptr); - //ASSERT(patch_info.HasAesCtrExTable()); - //ASSERT(patch_info.HasIndirectTable()); ASSERT(Common::IsAligned(patch_info.aes_ctr_ex_size, NcaHeader::XtsBlockSize)); // Validate patch info extents. - R_UNLESS(patch_info.indirect_size > 0, ResultInvalidNcaPatchInfoIndirectSize); - R_UNLESS(patch_info.aes_ctr_ex_size >= 0, ResultInvalidNcaPatchInfoAesCtrExSize); + R_UNLESS(patch_info.aes_ctr_ex_size >= 0 && patch_info.HasAesCtrExTable(), ResultInvalidNcaPatchInfoAesCtrExSize); + R_UNLESS(patch_info.indirect_size > 0 && patch_info.HasIndirectTable(), ResultInvalidNcaPatchInfoIndirectSize); R_UNLESS(patch_info.indirect_size + patch_info.indirect_offset <= patch_info.aes_ctr_ex_offset, ResultInvalidNcaPatchInfoAesCtrExOffset); R_UNLESS(patch_info.aes_ctr_ex_offset + patch_info.aes_ctr_ex_size <= @@ -1333,10 +1331,30 @@ Result NcaFileSystemDriver::CreateIntegrityVerificationStorageImpl( R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset, ResultRomNcaInvalidIntegrityLayerInfoOffset); } - storage_info[level_hash_info.max_layers - 1] - = std::make_shared(std::move(base_storage), - layer_info.size, - last_layer_info_offset); + + switch (level_hash_info.max_layers - 1) { + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::MasterStorage: + storage_info.SetMasterHashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer1Storage: + storage_info.SetLayer1HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer2Storage: + storage_info.SetLayer2HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer3Storage: + storage_info.SetLayer3HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer4Storage: + storage_info.SetLayer4HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer5Storage: + storage_info.SetLayer5HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::DataStorage: + storage_info.SetDataStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + } // Make the integrity romfs storage. auto integrity_storage = std::make_shared(); From de594c8792622caea4400c49df2cadac8f8b1143 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 2 Oct 2025 23:20:45 +0200 Subject: [PATCH 7/8] [dynarmic] add safe-opt to skip IR verification (#2613) Most programs are well behaved and don't cause internal IR issues. Hence, verification can be safely skipped. Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2613 Reviewed-by: MaranBr Co-authored-by: lizzie Co-committed-by: lizzie --- src/dynarmic/src/dynarmic/interface/optimization_flags.h | 5 +++++ src/dynarmic/src/dynarmic/ir/opt_passes.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/dynarmic/src/dynarmic/interface/optimization_flags.h b/src/dynarmic/src/dynarmic/interface/optimization_flags.h index 743d902767..9e58197b47 100644 --- a/src/dynarmic/src/dynarmic/interface/optimization_flags.h +++ b/src/dynarmic/src/dynarmic/interface/optimization_flags.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2020 MerryMage * SPDX-License-Identifier: 0BSD @@ -34,6 +37,8 @@ enum class OptimizationFlag : std::uint32_t { MiscIROpt = 0x00000020, /// Optimize for code speed rather than for code size (this serves well for tight loops) CodeSpeed = 0x00000040, + /// Disable verification passes + DisableVerification = 0x00000080, /// This is an UNSAFE optimization that reduces accuracy of fused multiply-add operations. /// This unfuses fused instructions to improve performance on host CPUs without FMA support. diff --git a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp index 844e29023c..e9175f0e6b 100644 --- a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp +++ b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp @@ -1491,9 +1491,9 @@ void Optimize(IR::Block& block, const A32::UserConfig& conf, const Optimization: Optimization::DeadCodeElimination(block); } Optimization::IdentityRemovalPass(block); - //if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { + if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { Optimization::VerificationPass(block); - //} + } } void Optimize(IR::Block& block, const A64::UserConfig& conf, const Optimization::PolyfillOptions& polyfill_options) { @@ -1511,9 +1511,9 @@ void Optimize(IR::Block& block, const A64::UserConfig& conf, const Optimization: if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) [[likely]] { Optimization::A64MergeInterpretBlocksPass(block, conf.callbacks); } - //if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { + if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { Optimization::VerificationPass(block); - //} + } } } // namespace Dynarmic::Optimization From fdcd3ef393538ad7c33b0aca9d86afae85817839 Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 1 Oct 2025 08:09:33 +0000 Subject: [PATCH 8/8] [arm] Add "debugging" cpu accuracy option to replace CPU debug toggle The debug toggle and the CPU accuracy options are mutually exclusive, if debug toggle on => cpu accuracy is ignored, if debug toggle off => cpu accuracy is used. So just add it to cpu accuracy and avoid the extra hassle. Signed-off-by: lizzie --- src/common/settings.cpp | 6 +- src/common/settings.h | 3 - src/common/settings_enums.h | 2 +- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 77 ++++++++++----------- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 79 +++++++++++----------- src/qt_common/shared_translation.cpp | 1 + src/yuzu/configuration/configure_debug.cpp | 3 - src/yuzu/configuration/configure_debug.ui | 8 --- 8 files changed, 84 insertions(+), 95 deletions(-) diff --git a/src/common/settings.cpp b/src/common/settings.cpp index b41f4c75f5..e8fc910eb3 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -163,11 +163,11 @@ bool IsDMALevelSafe() { } bool IsFastmemEnabled() { - if (values.cpu_debug_mode) { - return static_cast(values.cpuopt_fastmem); + if (values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Debugging) { + return bool(values.cpuopt_fastmem); } if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe) { - return static_cast(values.cpuopt_unsafe_host_mmu); + return bool(values.cpuopt_unsafe_host_mmu); } #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) return false; diff --git a/src/common/settings.h b/src/common/settings.h index 891bde608c..3ed7deb626 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -275,9 +275,6 @@ struct Values { true, true, &use_custom_cpu_ticks}; - - SwitchableSetting cpu_debug_mode{linkage, false, "cpu_debug_mode", Category::CpuDebug}; - Setting cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug}; Setting cpuopt_block_linking{linkage, true, "cpuopt_block_linking", Category::CpuDebug}; Setting cpuopt_return_stack_buffer{linkage, true, "cpuopt_return_stack_buffer", diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 0e5a08d845..1b545ca038 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -136,7 +136,7 @@ ENUM(ShaderBackend, Glsl, Glasm, SpirV); ENUM(GpuAccuracy, Normal, High, Extreme); ENUM(DmaAccuracy, Default, Unsafe, Safe); ENUM(CpuBackend, Dynarmic, Nce); -ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid); +ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid, Debugging); ENUM(CpuClock, Boost, Fast) ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb); ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index d2035d0fe0..3c72ab2396 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -229,7 +229,8 @@ std::shared_ptr ArmDynarmic32::MakeJit(Common::PageTable* pa } // Safe optimizations - if (Settings::values.cpu_debug_mode) { + switch (Settings::values.cpu_accuracy.GetValue()) { + case Settings::CpuAccuracy::Debugging: if (!Settings::values.cpuopt_page_tables) { config.page_table = nullptr; } @@ -267,51 +268,51 @@ std::shared_ptr ArmDynarmic32::MakeJit(Common::PageTable* pa if (!Settings::values.cpuopt_ignore_memory_aborts) { config.check_halt_on_memory_access = true; } - } else { - // Unsafe optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) { - config.unsafe_optimizations = true; - if (!Settings::values.cpuopt_unsafe_host_mmu) { - config.fastmem_pointer = std::nullopt; - config.fastmem_exclusive_access = false; - } - if (Settings::values.cpuopt_unsafe_unfuse_fma) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; - } - if (Settings::values.cpuopt_unsafe_reduce_fp_error) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; - } - if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; - } - if (Settings::values.cpuopt_unsafe_inaccurate_nan) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; - } - if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; - } - } - - // Curated optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) { - config.unsafe_optimizations = true; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + break; + // Unsafe optimizations + case Settings::CpuAccuracy::Unsafe: + config.unsafe_optimizations = true; + if (!Settings::values.cpuopt_unsafe_host_mmu) { config.fastmem_pointer = std::nullopt; config.fastmem_exclusive_access = false; -#endif + } + if (Settings::values.cpuopt_unsafe_unfuse_fma) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + } + if (Settings::values.cpuopt_unsafe_reduce_fp_error) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; + } + if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; + } + if (Settings::values.cpuopt_unsafe_inaccurate_nan) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + } + if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; } - - // Paranoia mode for debugging optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) { - config.unsafe_optimizations = false; - config.optimizations = Dynarmic::no_optimizations; - } + break; + // Curated optimizations + case Settings::CpuAccuracy::Auto: + config.unsafe_optimizations = true; +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + config.fastmem_pointer = std::nullopt; + config.fastmem_exclusive_access = false; +#endif + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; + break; + // Paranoia mode for debugging optimizations + case Settings::CpuAccuracy::Paranoid: + config.unsafe_optimizations = false; + config.optimizations = Dynarmic::no_optimizations; + break; + case Settings::CpuAccuracy::Accurate: + default: + break; } - return std::make_unique(config); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 438b7b691c..707d51d2a2 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -287,8 +287,9 @@ std::shared_ptr ArmDynarmic64::MakeJit(Common::PageTable* pa config.code_cache_size = std::uint32_t(8_MiB); } - // Safe optimizations - if (Settings::values.cpu_debug_mode) { + switch (Settings::values.cpu_accuracy.GetValue()) { + // Debug mode + case Settings::CpuAccuracy::Debugging: if (!Settings::values.cpuopt_page_tables) { config.page_table = nullptr; } @@ -326,50 +327,50 @@ std::shared_ptr ArmDynarmic64::MakeJit(Common::PageTable* pa if (!Settings::values.cpuopt_ignore_memory_aborts) { config.check_halt_on_memory_access = true; } - } else { - // Unsafe optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) { - config.unsafe_optimizations = true; - if (!Settings::values.cpuopt_unsafe_host_mmu) { - config.fastmem_pointer = std::nullopt; - config.fastmem_exclusive_access = false; - } - if (Settings::values.cpuopt_unsafe_unfuse_fma) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; - } - if (Settings::values.cpuopt_unsafe_reduce_fp_error) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; - } - if (Settings::values.cpuopt_unsafe_inaccurate_nan) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; - } - if (Settings::values.cpuopt_unsafe_fastmem_check) { - config.fastmem_address_space_bits = 64; - } - if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; - } - } - - // Curated optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) { - config.unsafe_optimizations = true; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + break; + // Unsafe optimizations + case Settings::CpuAccuracy::Unsafe: + config.unsafe_optimizations = true; + if (!Settings::values.cpuopt_unsafe_host_mmu) { config.fastmem_pointer = std::nullopt; config.fastmem_exclusive_access = false; -#endif + } + if (Settings::values.cpuopt_unsafe_unfuse_fma) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + } + if (Settings::values.cpuopt_unsafe_reduce_fp_error) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; + } + if (Settings::values.cpuopt_unsafe_inaccurate_nan) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + } + if (Settings::values.cpuopt_unsafe_fastmem_check) { config.fastmem_address_space_bits = 64; + } + if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; } - - // Paranoia mode for debugging optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) { - config.unsafe_optimizations = false; - config.optimizations = Dynarmic::no_optimizations; - } + break; + // Safe optimisations + case Settings::CpuAccuracy::Auto: + config.unsafe_optimizations = true; +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) + config.fastmem_pointer = std::nullopt; + config.fastmem_exclusive_access = false; +#endif + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + config.fastmem_address_space_bits = 64; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; + break; + // Paranoia mode for debugging optimizations + case Settings::CpuAccuracy::Paranoid: + config.unsafe_optimizations = false; + config.optimizations = Dynarmic::no_optimizations; + break; + case Settings::CpuAccuracy::Accurate: + default: + break; } - return std::make_shared(config); } diff --git a/src/qt_common/shared_translation.cpp b/src/qt_common/shared_translation.cpp index 8f5d929b74..b1f53d2142 100644 --- a/src/qt_common/shared_translation.cpp +++ b/src/qt_common/shared_translation.cpp @@ -516,6 +516,7 @@ std::unique_ptr ComboboxEnumeration(QObject* parent) PAIR(CpuAccuracy, Accurate, tr("Accurate")), PAIR(CpuAccuracy, Unsafe, tr("Unsafe")), PAIR(CpuAccuracy, Paranoid, tr("Paranoid (disables most optimizations)")), + PAIR(CpuAccuracy, Debugging, tr("Debugging")), }}); translations->insert({Settings::EnumMetadata::Index(), { diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 18f629f639..287a3757b7 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -62,8 +62,6 @@ void ConfigureDebug::SetConfiguration() { ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug.GetValue()); ui->enable_shader_feedback->setEnabled(runtime_lock); ui->enable_shader_feedback->setChecked(Settings::values.renderer_shader_feedback.GetValue()); - ui->enable_cpu_debugging->setEnabled(runtime_lock); - ui->enable_cpu_debugging->setChecked(Settings::values.cpu_debug_mode.GetValue()); ui->enable_nsight_aftermath->setEnabled(runtime_lock); ui->enable_nsight_aftermath->setChecked(Settings::values.enable_nsight_aftermath.GetValue()); ui->dump_shaders->setEnabled(runtime_lock); @@ -107,7 +105,6 @@ void ConfigureDebug::ApplyConfiguration() { Settings::values.enable_renderdoc_hotkey = ui->enable_renderdoc_hotkey->isChecked(); Settings::values.disable_buffer_reorder = ui->disable_buffer_reorder->isChecked(); Settings::values.renderer_shader_feedback = ui->enable_shader_feedback->isChecked(); - Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked(); Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked(); Settings::values.dump_shaders = ui->dump_shaders->isChecked(); Settings::values.dump_macros = ui->dump_macros->isChecked(); diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index bd7125712c..1f302bf118 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui @@ -435,13 +435,6 @@ - - - - Enable CPU Debugging - - - @@ -582,7 +575,6 @@ fs_access_log reporting_services quest_flag - enable_cpu_debugging use_debug_asserts