summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/command_generator.cpp9
-rw-r--r--src/common/settings.cpp4
-rw-r--r--src/common/settings.h23
-rw-r--r--src/core/CMakeLists.txt72
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp18
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp18
-rw-r--r--src/core/core.cpp4
-rw-r--r--src/core/file_sys/content_archive.cpp1
-rw-r--r--src/core/frontend/applets/software_keyboard.h2
-rw-r--r--src/core/frontend/applets/web_browser.h2
-rw-r--r--src/core/hardware_interrupt_manager.cpp2
-rw-r--r--src/core/hle/service/acc/acc.cpp2
-rw-r--r--src/core/hle/service/acc/acc.h2
-rw-r--r--src/core/hle/service/am/am.cpp10
-rw-r--r--src/core/hle/service/am/applets/applet_controller.cpp (renamed from src/core/hle/service/am/applets/controller.cpp)2
-rw-r--r--src/core/hle/service/am/applets/applet_controller.h (renamed from src/core/hle/service/am/applets/controller.h)0
-rw-r--r--src/core/hle/service/am/applets/applet_error.cpp (renamed from src/core/hle/service/am/applets/error.cpp)2
-rw-r--r--src/core/hle/service/am/applets/applet_error.h (renamed from src/core/hle/service/am/applets/error.h)0
-rw-r--r--src/core/hle/service/am/applets/applet_general_backend.cpp (renamed from src/core/hle/service/am/applets/general_backend.cpp)2
-rw-r--r--src/core/hle/service/am/applets/applet_general_backend.h (renamed from src/core/hle/service/am/applets/general_backend.h)0
-rw-r--r--src/core/hle/service/am/applets/applet_profile_select.cpp (renamed from src/core/hle/service/am/applets/profile_select.cpp)2
-rw-r--r--src/core/hle/service/am/applets/applet_profile_select.h (renamed from src/core/hle/service/am/applets/profile_select.h)0
-rw-r--r--src/core/hle/service/am/applets/applet_software_keyboard.cpp (renamed from src/core/hle/service/am/applets/software_keyboard.cpp)2
-rw-r--r--src/core/hle/service/am/applets/applet_software_keyboard.h (renamed from src/core/hle/service/am/applets/software_keyboard.h)2
-rw-r--r--src/core/hle/service/am/applets/applet_software_keyboard_types.h (renamed from src/core/hle/service/am/applets/software_keyboard_types.h)0
-rw-r--r--src/core/hle/service/am/applets/applet_web_browser.cpp (renamed from src/core/hle/service/am/applets/web_browser.cpp)15
-rw-r--r--src/core/hle/service/am/applets/applet_web_browser.h (renamed from src/core/hle/service/am/applets/web_browser.h)2
-rw-r--r--src/core/hle/service/am/applets/applet_web_browser_types.h (renamed from src/core/hle/service/am/applets/web_types.h)0
-rw-r--r--src/core/hle/service/am/applets/applets.cpp12
-rw-r--r--src/core/hle/service/apm/apm.cpp2
-rw-r--r--src/core/hle/service/apm/apm_controller.cpp (renamed from src/core/hle/service/apm/controller.cpp)2
-rw-r--r--src/core/hle/service/apm/apm_controller.h (renamed from src/core/hle/service/apm/controller.h)0
-rw-r--r--src/core/hle/service/apm/apm_interface.cpp (renamed from src/core/hle/service/apm/interface.cpp)4
-rw-r--r--src/core/hle/service/apm/apm_interface.h (renamed from src/core/hle/service/apm/interface.h)0
-rw-r--r--src/core/hle/service/bcat/backend/boxcat.cpp3
-rw-r--r--src/core/hle/service/bcat/bcat.h2
-rw-r--r--src/core/hle/service/bcat/bcat_module.cpp (renamed from src/core/hle/service/bcat/module.cpp)2
-rw-r--r--src/core/hle/service/bcat/bcat_module.h (renamed from src/core/hle/service/bcat/module.h)0
-rw-r--r--src/core/hle/service/friend/friend.cpp2
-rw-r--r--src/core/hle/service/friend/friend_interface.cpp (renamed from src/core/hle/service/friend/interface.cpp)2
-rw-r--r--src/core/hle/service/friend/friend_interface.h (renamed from src/core/hle/service/friend/interface.h)0
-rw-r--r--src/core/hle/service/glue/arp.cpp2
-rw-r--r--src/core/hle/service/glue/glue_manager.cpp (renamed from src/core/hle/service/glue/manager.cpp)2
-rw-r--r--src/core/hle/service/glue/glue_manager.h (renamed from src/core/hle/service/glue/manager.h)0
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp5
-rw-r--r--src/core/hle/service/mii/mii.cpp2
-rw-r--r--src/core/hle/service/mii/mii_manager.cpp (renamed from src/core/hle/service/mii/manager.cpp)2
-rw-r--r--src/core/hle/service/mii/mii_manager.h (renamed from src/core/hle/service/mii/manager.h)0
-rw-r--r--src/core/hle/service/mii/raw_data.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp85
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp2
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.cpp (renamed from src/core/hle/service/nvdrv/interface.cpp)2
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.h (renamed from src/core/hle/service/nvdrv/interface.h)0
-rw-r--r--src/core/hle/service/pctl/pctl.h2
-rw-r--r--src/core/hle/service/pctl/pctl_module.cpp (renamed from src/core/hle/service/pctl/module.cpp)2
-rw-r--r--src/core/hle/service/pctl/pctl_module.h (renamed from src/core/hle/service/pctl/module.h)0
-rw-r--r--src/core/hle/service/service.cpp6
-rw-r--r--src/core/hle/service/sm/sm.cpp2
-rw-r--r--src/core/hle/service/sm/sm_controller.cpp (renamed from src/core/hle/service/sm/controller.cpp)2
-rw-r--r--src/core/hle/service/sm/sm_controller.h (renamed from src/core/hle/service/sm/controller.h)0
-rw-r--r--src/core/hle/service/spl/csrng.h2
-rw-r--r--src/core/hle/service/spl/spl.h2
-rw-r--r--src/core/hle/service/spl/spl_module.cpp (renamed from src/core/hle/service/spl/module.cpp)2
-rw-r--r--src/core/hle/service/spl/spl_module.h (renamed from src/core/hle/service/spl/module.h)0
-rw-r--r--src/core/hle/service/time/time.cpp2
-rw-r--r--src/core/hle/service/time/time_interface.cpp (renamed from src/core/hle/service/time/interface.cpp)2
-rw-r--r--src/core/hle/service/time/time_interface.h (renamed from src/core/hle/service/time/interface.h)0
-rw-r--r--src/input_common/main.cpp4
-rw-r--r--src/input_common/mouse/mouse_poller.cpp2
-rw-r--r--src/input_common/sdl/sdl_impl.h8
-rw-r--r--src/tests/video_core/buffer_base.cpp2
-rw-r--r--src/video_core/buffer_cache/buffer_base.h19
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h292
-rw-r--r--src/video_core/command_classes/vic.cpp21
-rw-r--r--src/video_core/dma_pusher.cpp10
-rw-r--r--src/video_core/engines/maxwell_dma.cpp36
-rw-r--r--src/video_core/engines/maxwell_dma.h17
-rw-r--r--src/video_core/fence_manager.h7
-rw-r--r--src/video_core/gpu.cpp5
-rw-r--r--src/video_core/rasterizer_interface.h8
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp21
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h14
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp8
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pass.cpp33
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp27
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h14
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp6
-rw-r--r--src/video_core/texture_cache/texture_cache.h6
-rw-r--r--src/video_core/texture_cache/types.h4
-rw-r--r--src/video_core/texture_cache/util.cpp86
-rw-r--r--src/web_service/web_backend.cpp10
-rw-r--r--src/yuzu/CMakeLists.txt28
-rw-r--r--src/yuzu/applets/qt_controller.cpp (renamed from src/yuzu/applets/controller.cpp)4
-rw-r--r--src/yuzu/applets/qt_controller.h (renamed from src/yuzu/applets/controller.h)0
-rw-r--r--src/yuzu/applets/qt_controller.ui (renamed from src/yuzu/applets/controller.ui)0
-rw-r--r--src/yuzu/applets/qt_error.cpp (renamed from src/yuzu/applets/error.cpp)2
-rw-r--r--src/yuzu/applets/qt_error.h (renamed from src/yuzu/applets/error.h)0
-rw-r--r--src/yuzu/applets/qt_profile_select.cpp (renamed from src/yuzu/applets/profile_select.cpp)2
-rw-r--r--src/yuzu/applets/qt_profile_select.h (renamed from src/yuzu/applets/profile_select.h)0
-rw-r--r--src/yuzu/applets/qt_software_keyboard.cpp (renamed from src/yuzu/applets/software_keyboard.cpp)4
-rw-r--r--src/yuzu/applets/qt_software_keyboard.h (renamed from src/yuzu/applets/software_keyboard.h)0
-rw-r--r--src/yuzu/applets/qt_software_keyboard.ui (renamed from src/yuzu/applets/software_keyboard.ui)0
-rw-r--r--src/yuzu/applets/qt_web_browser.cpp (renamed from src/yuzu/applets/web_browser.cpp)4
-rw-r--r--src/yuzu/applets/qt_web_browser.h (renamed from src/yuzu/applets/web_browser.h)0
-rw-r--r--src/yuzu/applets/qt_web_browser_scripts.h (renamed from src/yuzu/applets/web_browser_scripts.h)0
-rw-r--r--src/yuzu/bootmanager.cpp9
-rw-r--r--src/yuzu/configuration/config.cpp48
-rw-r--r--src/yuzu/configuration/configure.ui50
-rw-r--r--src/yuzu/configuration/configure_audio.cpp13
-rw-r--r--src/yuzu/configuration/configure_cpu.cpp18
-rw-r--r--src/yuzu/configuration/configure_cpu.h1
-rw-r--r--src/yuzu/configuration/configure_cpu.ui14
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.h1
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.ui94
-rw-r--r--src/yuzu/configuration/configure_debug.cpp3
-rw-r--r--src/yuzu/configuration/configure_debug.ui63
-rw-r--r--src/yuzu/configuration/configure_debug_tab.cpp38
-rw-r--r--src/yuzu/configuration/configure_debug_tab.h32
-rw-r--r--src/yuzu/configuration/configure_debug_tab.ui52
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp6
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp18
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.cpp6
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.h1
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.ui18
-rw-r--r--src/yuzu/configuration/configure_input_advanced.ui15
-rw-r--r--src/yuzu/main.cpp26
-rw-r--r--src/yuzu_cmd/CMakeLists.txt5
-rw-r--r--src/yuzu_cmd/config.cpp30
-rw-r--r--src/yuzu_cmd/default_ini.h146
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp8
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp8
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp28
133 files changed, 1138 insertions, 679 deletions
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp
index b99d0fc91..45b2eef52 100644
--- a/src/audio_core/command_generator.cpp
+++ b/src/audio_core/command_generator.cpp
@@ -42,6 +42,15 @@ void ApplyMix(std::span<s32> output, std::span<const s32> input, s32 gain, s32 s
42 42
43s32 ApplyMixRamp(std::span<s32> output, std::span<const s32> input, float gain, float delta, 43s32 ApplyMixRamp(std::span<s32> output, std::span<const s32> input, float gain, float delta,
44 s32 sample_count) { 44 s32 sample_count) {
45 // XC2 passes in NaN mix volumes, causing further issues as we handle everything as s32 rather
46 // than float, so the NaN propogation is lost. As the samples get further modified for
47 // volume etc, they can get out of NaN range, so a later heuristic for catching this is
48 // more difficult. Handle it here by setting these samples to silence.
49 if (std::isnan(gain)) {
50 gain = 0.0f;
51 delta = 0.0f;
52 }
53
45 s32 x = 0; 54 s32 x = 0;
46 for (s32 i = 0; i < sample_count; i++) { 55 for (s32 i = 0; i < sample_count; i++) {
47 x = static_cast<s32>(static_cast<float>(input[i]) * gain); 56 x = static_cast<s32>(static_cast<float>(input[i]) * gain);
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 0061e29cc..bf5514386 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -93,7 +93,7 @@ bool IsGPULevelHigh() {
93} 93}
94 94
95bool IsFastmemEnabled() { 95bool IsFastmemEnabled() {
96 if (values.cpu_accuracy.GetValue() == CPUAccuracy::DebugMode) { 96 if (values.cpu_debug_mode) {
97 return static_cast<bool>(values.cpuopt_fastmem); 97 return static_cast<bool>(values.cpuopt_fastmem);
98 } 98 }
99 return true; 99 return true;
@@ -103,7 +103,7 @@ float Volume() {
103 if (values.audio_muted) { 103 if (values.audio_muted) {
104 return 0.0f; 104 return 0.0f;
105 } 105 }
106 return values.volume.GetValue(); 106 return values.volume.GetValue() / 100.0f;
107} 107}
108 108
109void RestoreGlobalState(bool is_powered_on) { 109void RestoreGlobalState(bool is_powered_on) {
diff --git a/src/common/settings.h b/src/common/settings.h
index bf83186f5..ce1bc647d 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -31,9 +31,9 @@ enum class GPUAccuracy : u32 {
31}; 31};
32 32
33enum class CPUAccuracy : u32 { 33enum class CPUAccuracy : u32 {
34 Accurate = 0, 34 Auto = 0,
35 Unsafe = 1, 35 Accurate = 1,
36 DebugMode = 2, 36 Unsafe = 2,
37}; 37};
38 38
39/** The BasicSetting class is a simple resource manager. It defines a label and default value 39/** The BasicSetting class is a simple resource manager. It defines a label and default value
@@ -278,13 +278,16 @@ struct Values {
278 BasicSetting<std::string> sink_id{"auto", "output_engine"}; 278 BasicSetting<std::string> sink_id{"auto", "output_engine"};
279 BasicSetting<bool> audio_muted{false, "audio_muted"}; 279 BasicSetting<bool> audio_muted{false, "audio_muted"};
280 Setting<bool> enable_audio_stretching{true, "enable_audio_stretching"}; 280 Setting<bool> enable_audio_stretching{true, "enable_audio_stretching"};
281 Setting<float> volume{1.0f, "volume"}; 281 Setting<u8> volume{100, "volume"};
282 282
283 // Core 283 // Core
284 Setting<bool> use_multi_core{true, "use_multi_core"}; 284 Setting<bool> use_multi_core{true, "use_multi_core"};
285 285
286 // Cpu 286 // Cpu
287 Setting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Accurate, "cpu_accuracy"}; 287 Setting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, "cpu_accuracy"};
288 // TODO: remove cpu_accuracy_first_time, migration setting added 8 July 2021
289 BasicSetting<bool> cpu_accuracy_first_time{true, "cpu_accuracy_first_time"};
290 BasicSetting<bool> cpu_debug_mode{false, "cpu_debug_mode"};
288 291
289 BasicSetting<bool> cpuopt_page_tables{true, "cpuopt_page_tables"}; 292 BasicSetting<bool> cpuopt_page_tables{true, "cpuopt_page_tables"};
290 BasicSetting<bool> cpuopt_block_linking{true, "cpuopt_block_linking"}; 293 BasicSetting<bool> cpuopt_block_linking{true, "cpuopt_block_linking"};
@@ -327,15 +330,15 @@ struct Values {
327 Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"}; 330 Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"};
328 Setting<bool> accelerate_astc{true, "accelerate_astc"}; 331 Setting<bool> accelerate_astc{true, "accelerate_astc"};
329 Setting<bool> use_vsync{true, "use_vsync"}; 332 Setting<bool> use_vsync{true, "use_vsync"};
330 Setting<bool> disable_fps_limit{false, "disable_fps_limit"}; 333 BasicSetting<bool> disable_fps_limit{false, "disable_fps_limit"};
331 Setting<bool> use_assembly_shaders{false, "use_assembly_shaders"}; 334 Setting<bool> use_assembly_shaders{false, "use_assembly_shaders"};
332 Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"}; 335 Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
333 Setting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"}; 336 Setting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"};
334 Setting<bool> use_caches_gc{false, "use_caches_gc"}; 337 Setting<bool> use_caches_gc{false, "use_caches_gc"};
335 338
336 Setting<float> bg_red{0.0f, "bg_red"}; 339 Setting<u8> bg_red{0, "bg_red"};
337 Setting<float> bg_green{0.0f, "bg_green"}; 340 Setting<u8> bg_green{0, "bg_green"};
338 Setting<float> bg_blue{0.0f, "bg_blue"}; 341 Setting<u8> bg_blue{0, "bg_blue"};
339 342
340 // System 343 // System
341 Setting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"}; 344 Setting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"};
@@ -365,7 +368,7 @@ struct Values {
365 "udp_input_servers"}; 368 "udp_input_servers"};
366 369
367 BasicSetting<bool> mouse_panning{false, "mouse_panning"}; 370 BasicSetting<bool> mouse_panning{false, "mouse_panning"};
368 BasicSetting<float> mouse_panning_sensitivity{1.0f, "mouse_panning_sensitivity"}; 371 BasicSetting<u8> mouse_panning_sensitivity{10, "mouse_panning_sensitivity"};
369 BasicSetting<bool> mouse_enabled{false, "mouse_enabled"}; 372 BasicSetting<bool> mouse_enabled{false, "mouse_enabled"};
370 std::string mouse_device; 373 std::string mouse_device;
371 MouseButtonsRaw mouse_buttons; 374 MouseButtonsRaw mouse_buttons;
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index b2b0dbe05..c7b899131 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -272,22 +272,22 @@ add_library(core STATIC
272 hle/service/am/applet_ae.h 272 hle/service/am/applet_ae.h
273 hle/service/am/applet_oe.cpp 273 hle/service/am/applet_oe.cpp
274 hle/service/am/applet_oe.h 274 hle/service/am/applet_oe.h
275 hle/service/am/applets/applet_controller.cpp
276 hle/service/am/applets/applet_controller.h
277 hle/service/am/applets/applet_error.cpp
278 hle/service/am/applets/applet_error.h
279 hle/service/am/applets/applet_general_backend.cpp
280 hle/service/am/applets/applet_general_backend.h
281 hle/service/am/applets/applet_profile_select.cpp
282 hle/service/am/applets/applet_profile_select.h
283 hle/service/am/applets/applet_software_keyboard.cpp
284 hle/service/am/applets/applet_software_keyboard.h
285 hle/service/am/applets/applet_software_keyboard_types.h
286 hle/service/am/applets/applet_web_browser.cpp
287 hle/service/am/applets/applet_web_browser.h
288 hle/service/am/applets/applet_web_browser_types.h
275 hle/service/am/applets/applets.cpp 289 hle/service/am/applets/applets.cpp
276 hle/service/am/applets/applets.h 290 hle/service/am/applets/applets.h
277 hle/service/am/applets/controller.cpp
278 hle/service/am/applets/controller.h
279 hle/service/am/applets/error.cpp
280 hle/service/am/applets/error.h
281 hle/service/am/applets/general_backend.cpp
282 hle/service/am/applets/general_backend.h
283 hle/service/am/applets/profile_select.cpp
284 hle/service/am/applets/profile_select.h
285 hle/service/am/applets/software_keyboard.cpp
286 hle/service/am/applets/software_keyboard.h
287 hle/service/am/applets/software_keyboard_types.h
288 hle/service/am/applets/web_browser.cpp
289 hle/service/am/applets/web_browser.h
290 hle/service/am/applets/web_types.h
291 hle/service/am/idle.cpp 291 hle/service/am/idle.cpp
292 hle/service/am/idle.h 292 hle/service/am/idle.h
293 hle/service/am/omm.cpp 293 hle/service/am/omm.cpp
@@ -300,10 +300,10 @@ add_library(core STATIC
300 hle/service/aoc/aoc_u.h 300 hle/service/aoc/aoc_u.h
301 hle/service/apm/apm.cpp 301 hle/service/apm/apm.cpp
302 hle/service/apm/apm.h 302 hle/service/apm/apm.h
303 hle/service/apm/controller.cpp 303 hle/service/apm/apm_controller.cpp
304 hle/service/apm/controller.h 304 hle/service/apm/apm_controller.h
305 hle/service/apm/interface.cpp 305 hle/service/apm/apm_interface.cpp
306 hle/service/apm/interface.h 306 hle/service/apm/apm_interface.h
307 hle/service/audio/audctl.cpp 307 hle/service/audio/audctl.cpp
308 hle/service/audio/audctl.h 308 hle/service/audio/audctl.h
309 hle/service/audio/auddbg.cpp 309 hle/service/audio/auddbg.cpp
@@ -335,8 +335,8 @@ add_library(core STATIC
335 hle/service/bcat/backend/backend.h 335 hle/service/bcat/backend/backend.h
336 hle/service/bcat/bcat.cpp 336 hle/service/bcat/bcat.cpp
337 hle/service/bcat/bcat.h 337 hle/service/bcat/bcat.h
338 hle/service/bcat/module.cpp 338 hle/service/bcat/bcat_module.cpp
339 hle/service/bcat/module.h 339 hle/service/bcat/bcat_module.h
340 hle/service/bpc/bpc.cpp 340 hle/service/bpc/bpc.cpp
341 hle/service/bpc/bpc.h 341 hle/service/bpc/bpc.h
342 hle/service/btdrv/btdrv.cpp 342 hle/service/btdrv/btdrv.cpp
@@ -382,8 +382,8 @@ add_library(core STATIC
382 hle/service/friend/errors.h 382 hle/service/friend/errors.h
383 hle/service/friend/friend.cpp 383 hle/service/friend/friend.cpp
384 hle/service/friend/friend.h 384 hle/service/friend/friend.h
385 hle/service/friend/interface.cpp 385 hle/service/friend/friend_interface.cpp
386 hle/service/friend/interface.h 386 hle/service/friend/friend_interface.h
387 hle/service/glue/arp.cpp 387 hle/service/glue/arp.cpp
388 hle/service/glue/arp.h 388 hle/service/glue/arp.h
389 hle/service/glue/bgtc.cpp 389 hle/service/glue/bgtc.cpp
@@ -393,8 +393,8 @@ add_library(core STATIC
393 hle/service/glue/errors.h 393 hle/service/glue/errors.h
394 hle/service/glue/glue.cpp 394 hle/service/glue/glue.cpp
395 hle/service/glue/glue.h 395 hle/service/glue/glue.h
396 hle/service/glue/manager.cpp 396 hle/service/glue/glue_manager.cpp
397 hle/service/glue/manager.h 397 hle/service/glue/glue_manager.h
398 hle/service/grc/grc.cpp 398 hle/service/grc/grc.cpp
399 hle/service/grc/grc.h 399 hle/service/grc/grc.h
400 hle/service/hid/hid.cpp 400 hle/service/hid/hid.cpp
@@ -435,10 +435,10 @@ add_library(core STATIC
435 hle/service/lm/lm.h 435 hle/service/lm/lm.h
436 hle/service/mig/mig.cpp 436 hle/service/mig/mig.cpp
437 hle/service/mig/mig.h 437 hle/service/mig/mig.h
438 hle/service/mii/manager.cpp
439 hle/service/mii/manager.h
440 hle/service/mii/mii.cpp 438 hle/service/mii/mii.cpp
441 hle/service/mii/mii.h 439 hle/service/mii/mii.h
440 hle/service/mii/mii_manager.cpp
441 hle/service/mii/mii_manager.h
442 hle/service/mii/raw_data.cpp 442 hle/service/mii/raw_data.cpp
443 hle/service/mii/raw_data.h 443 hle/service/mii/raw_data.h
444 hle/service/mii/types.h 444 hle/service/mii/types.h
@@ -486,11 +486,11 @@ add_library(core STATIC
486 hle/service/nvdrv/devices/nvhost_vic.h 486 hle/service/nvdrv/devices/nvhost_vic.h
487 hle/service/nvdrv/devices/nvmap.cpp 487 hle/service/nvdrv/devices/nvmap.cpp
488 hle/service/nvdrv/devices/nvmap.h 488 hle/service/nvdrv/devices/nvmap.h
489 hle/service/nvdrv/interface.cpp
490 hle/service/nvdrv/interface.h
491 hle/service/nvdrv/nvdata.h 489 hle/service/nvdrv/nvdata.h
492 hle/service/nvdrv/nvdrv.cpp 490 hle/service/nvdrv/nvdrv.cpp
493 hle/service/nvdrv/nvdrv.h 491 hle/service/nvdrv/nvdrv.h
492 hle/service/nvdrv/nvdrv_interface.cpp
493 hle/service/nvdrv/nvdrv_interface.h
494 hle/service/nvdrv/nvmemp.cpp 494 hle/service/nvdrv/nvmemp.cpp
495 hle/service/nvdrv/nvmemp.h 495 hle/service/nvdrv/nvmemp.h
496 hle/service/nvdrv/syncpoint_manager.cpp 496 hle/service/nvdrv/syncpoint_manager.cpp
@@ -503,10 +503,10 @@ add_library(core STATIC
503 hle/service/olsc/olsc.h 503 hle/service/olsc/olsc.h
504 hle/service/pcie/pcie.cpp 504 hle/service/pcie/pcie.cpp
505 hle/service/pcie/pcie.h 505 hle/service/pcie/pcie.h
506 hle/service/pctl/module.cpp
507 hle/service/pctl/module.h
508 hle/service/pctl/pctl.cpp 506 hle/service/pctl/pctl.cpp
509 hle/service/pctl/pctl.h 507 hle/service/pctl/pctl.h
508 hle/service/pctl/pctl_module.cpp
509 hle/service/pctl/pctl_module.h
510 hle/service/pcv/pcv.cpp 510 hle/service/pcv/pcv.cpp
511 hle/service/pcv/pcv.h 511 hle/service/pcv/pcv.h
512 hle/service/pm/pm.cpp 512 hle/service/pm/pm.cpp
@@ -529,10 +529,10 @@ add_library(core STATIC
529 hle/service/set/set_sys.h 529 hle/service/set/set_sys.h
530 hle/service/set/settings.cpp 530 hle/service/set/settings.cpp
531 hle/service/set/settings.h 531 hle/service/set/settings.h
532 hle/service/sm/controller.cpp
533 hle/service/sm/controller.h
534 hle/service/sm/sm.cpp 532 hle/service/sm/sm.cpp
535 hle/service/sm/sm.h 533 hle/service/sm/sm.h
534 hle/service/sm/sm_controller.cpp
535 hle/service/sm/sm_controller.h
536 hle/service/sockets/bsd.cpp 536 hle/service/sockets/bsd.cpp
537 hle/service/sockets/bsd.h 537 hle/service/sockets/bsd.h
538 hle/service/sockets/ethc.cpp 538 hle/service/sockets/ethc.cpp
@@ -547,10 +547,10 @@ add_library(core STATIC
547 hle/service/sockets/sockets_translate.h 547 hle/service/sockets/sockets_translate.h
548 hle/service/spl/csrng.cpp 548 hle/service/spl/csrng.cpp
549 hle/service/spl/csrng.h 549 hle/service/spl/csrng.h
550 hle/service/spl/module.cpp
551 hle/service/spl/module.h
552 hle/service/spl/spl.cpp 550 hle/service/spl/spl.cpp
553 hle/service/spl/spl.h 551 hle/service/spl/spl.h
552 hle/service/spl/spl_module.cpp
553 hle/service/spl/spl_module.h
554 hle/service/spl/spl_results.h 554 hle/service/spl/spl_results.h
555 hle/service/spl/spl_types.h 555 hle/service/spl/spl_types.h
556 hle/service/ssl/ssl.cpp 556 hle/service/ssl/ssl.cpp
@@ -559,8 +559,6 @@ add_library(core STATIC
559 hle/service/time/ephemeral_network_system_clock_context_writer.h 559 hle/service/time/ephemeral_network_system_clock_context_writer.h
560 hle/service/time/ephemeral_network_system_clock_core.h 560 hle/service/time/ephemeral_network_system_clock_core.h
561 hle/service/time/errors.h 561 hle/service/time/errors.h
562 hle/service/time/interface.cpp
563 hle/service/time/interface.h
564 hle/service/time/local_system_clock_context_writer.h 562 hle/service/time/local_system_clock_context_writer.h
565 hle/service/time/network_system_clock_context_writer.h 563 hle/service/time/network_system_clock_context_writer.h
566 hle/service/time/standard_local_system_clock_core.h 564 hle/service/time/standard_local_system_clock_core.h
@@ -578,6 +576,8 @@ add_library(core STATIC
578 hle/service/time/tick_based_steady_clock_core.h 576 hle/service/time/tick_based_steady_clock_core.h
579 hle/service/time/time.cpp 577 hle/service/time/time.cpp
580 hle/service/time/time.h 578 hle/service/time/time.h
579 hle/service/time/time_interface.cpp
580 hle/service/time/time_interface.h
581 hle/service/time/time_manager.cpp 581 hle/service/time/time_manager.cpp
582 hle/service/time/time_manager.h 582 hle/service/time/time_manager.h
583 hle/service/time/time_sharedmemory.cpp 583 hle/service/time/time_sharedmemory.cpp
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 77a44f862..b0d89c539 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -150,7 +150,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
150 config.far_code_offset = 400_MiB; 150 config.far_code_offset = 400_MiB;
151 151
152 // Safe optimizations 152 // Safe optimizations
153 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) { 153 if (Settings::values.cpu_debug_mode) {
154 if (!Settings::values.cpuopt_page_tables) { 154 if (!Settings::values.cpuopt_page_tables) {
155 config.page_table = nullptr; 155 config.page_table = nullptr;
156 } 156 }
@@ -183,20 +183,28 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
183 // Unsafe optimizations 183 // Unsafe optimizations
184 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { 184 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
185 config.unsafe_optimizations = true; 185 config.unsafe_optimizations = true;
186 if (Settings::values.cpuopt_unsafe_unfuse_fma.GetValue()) { 186 if (Settings::values.cpuopt_unsafe_unfuse_fma) {
187 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; 187 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
188 } 188 }
189 if (Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue()) { 189 if (Settings::values.cpuopt_unsafe_reduce_fp_error) {
190 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; 190 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
191 } 191 }
192 if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr.GetValue()) { 192 if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr) {
193 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; 193 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
194 } 194 }
195 if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) { 195 if (Settings::values.cpuopt_unsafe_inaccurate_nan) {
196 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; 196 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
197 } 197 }
198 } 198 }
199 199
200 // Curated optimizations
201 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Auto) {
202 config.unsafe_optimizations = true;
203 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
204 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
205 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
206 }
207
200 return std::make_unique<Dynarmic::A32::Jit>(config); 208 return std::make_unique<Dynarmic::A32::Jit>(config);
201} 209}
202 210
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 75332e348..bf27ffe71 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -190,7 +190,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
190 config.far_code_offset = 400_MiB; 190 config.far_code_offset = 400_MiB;
191 191
192 // Safe optimizations 192 // Safe optimizations
193 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) { 193 if (Settings::values.cpu_debug_mode) {
194 if (!Settings::values.cpuopt_page_tables) { 194 if (!Settings::values.cpuopt_page_tables) {
195 config.page_table = nullptr; 195 config.page_table = nullptr;
196 } 196 }
@@ -223,20 +223,28 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
223 // Unsafe optimizations 223 // Unsafe optimizations
224 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { 224 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
225 config.unsafe_optimizations = true; 225 config.unsafe_optimizations = true;
226 if (Settings::values.cpuopt_unsafe_unfuse_fma.GetValue()) { 226 if (Settings::values.cpuopt_unsafe_unfuse_fma) {
227 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; 227 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
228 } 228 }
229 if (Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue()) { 229 if (Settings::values.cpuopt_unsafe_reduce_fp_error) {
230 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; 230 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
231 } 231 }
232 if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) { 232 if (Settings::values.cpuopt_unsafe_inaccurate_nan) {
233 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; 233 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
234 } 234 }
235 if (Settings::values.cpuopt_unsafe_fastmem_check.GetValue()) { 235 if (Settings::values.cpuopt_unsafe_fastmem_check) {
236 config.fastmem_address_space_bits = 64; 236 config.fastmem_address_space_bits = 64;
237 } 237 }
238 } 238 }
239 239
240 // Curated optimizations
241 if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Auto) {
242 config.unsafe_optimizations = true;
243 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
244 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
245 config.fastmem_address_space_bits = 64;
246 }
247
240 return std::make_shared<Dynarmic::A64::Jit>(config); 248 return std::make_shared<Dynarmic::A64::Jit>(config);
241} 249}
242 250
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 891f1cb49..406320ed6 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -35,9 +35,9 @@
35#include "core/hle/kernel/kernel.h" 35#include "core/hle/kernel/kernel.h"
36#include "core/hle/kernel/physical_core.h" 36#include "core/hle/kernel/physical_core.h"
37#include "core/hle/service/am/applets/applets.h" 37#include "core/hle/service/am/applets/applets.h"
38#include "core/hle/service/apm/controller.h" 38#include "core/hle/service/apm/apm_controller.h"
39#include "core/hle/service/filesystem/filesystem.h" 39#include "core/hle/service/filesystem/filesystem.h"
40#include "core/hle/service/glue/manager.h" 40#include "core/hle/service/glue/glue_manager.h"
41#include "core/hle/service/hid/hid.h" 41#include "core/hle/service/hid/hid.h"
42#include "core/hle/service/service.h" 42#include "core/hle/service/service.h"
43#include "core/hle/service/sm/sm.h" 43#include "core/hle/service/sm/sm.h"
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp
index 24eff210f..7019a7a68 100644
--- a/src/core/file_sys/content_archive.cpp
+++ b/src/core/file_sys/content_archive.cpp
@@ -5,7 +5,6 @@
5#include <algorithm> 5#include <algorithm>
6#include <cstring> 6#include <cstring>
7#include <optional> 7#include <optional>
8#include <ranges>
9#include <utility> 8#include <utility>
10 9
11#include "common/logging/log.h" 10#include "common/logging/log.h"
diff --git a/src/core/frontend/applets/software_keyboard.h b/src/core/frontend/applets/software_keyboard.h
index 506eb35bb..228a548d4 100644
--- a/src/core/frontend/applets/software_keyboard.h
+++ b/src/core/frontend/applets/software_keyboard.h
@@ -9,7 +9,7 @@
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11 11
12#include "core/hle/service/am/applets/software_keyboard_types.h" 12#include "core/hle/service/am/applets/applet_software_keyboard_types.h"
13 13
14namespace Core::Frontend { 14namespace Core::Frontend {
15 15
diff --git a/src/core/frontend/applets/web_browser.h b/src/core/frontend/applets/web_browser.h
index d7bd44c27..915dde677 100644
--- a/src/core/frontend/applets/web_browser.h
+++ b/src/core/frontend/applets/web_browser.h
@@ -7,7 +7,7 @@
7#include <functional> 7#include <functional>
8#include <string_view> 8#include <string_view>
9 9
10#include "core/hle/service/am/applets/web_types.h" 10#include "core/hle/service/am/applets/applet_web_browser_types.h"
11 11
12namespace Core::Frontend { 12namespace Core::Frontend {
13 13
diff --git a/src/core/hardware_interrupt_manager.cpp b/src/core/hardware_interrupt_manager.cpp
index 645f26e91..290db505e 100644
--- a/src/core/hardware_interrupt_manager.cpp
+++ b/src/core/hardware_interrupt_manager.cpp
@@ -5,7 +5,7 @@
5#include "core/core.h" 5#include "core/core.h"
6#include "core/core_timing.h" 6#include "core/core_timing.h"
7#include "core/hardware_interrupt_manager.h" 7#include "core/hardware_interrupt_manager.h"
8#include "core/hle/service/nvdrv/interface.h" 8#include "core/hle/service/nvdrv/nvdrv_interface.h"
9#include "core/hle/service/sm/sm.h" 9#include "core/hle/service/sm/sm.h"
10 10
11namespace Core::Hardware { 11namespace Core::Hardware {
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index d1c1fb71d..2e969f2a8 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -26,7 +26,7 @@
26#include "core/hle/service/acc/errors.h" 26#include "core/hle/service/acc/errors.h"
27#include "core/hle/service/acc/profile_manager.h" 27#include "core/hle/service/acc/profile_manager.h"
28#include "core/hle/service/glue/arp.h" 28#include "core/hle/service/glue/arp.h"
29#include "core/hle/service/glue/manager.h" 29#include "core/hle/service/glue/glue_manager.h"
30#include "core/hle/service/sm/sm.h" 30#include "core/hle/service/sm/sm.h"
31#include "core/loader/loader.h" 31#include "core/loader/loader.h"
32 32
diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h
index 0e3ad8ec6..a83a480cd 100644
--- a/src/core/hle/service/acc/acc.h
+++ b/src/core/hle/service/acc/acc.h
@@ -5,7 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include "common/uuid.h" 7#include "common/uuid.h"
8#include "core/hle/service/glue/manager.h" 8#include "core/hle/service/glue/glue_manager.h"
9#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
10 10
11namespace Service::Account { 11namespace Service::Account {
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 23ebc1138..a538f82e3 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -24,16 +24,16 @@
24#include "core/hle/service/am/am.h" 24#include "core/hle/service/am/am.h"
25#include "core/hle/service/am/applet_ae.h" 25#include "core/hle/service/am/applet_ae.h"
26#include "core/hle/service/am/applet_oe.h" 26#include "core/hle/service/am/applet_oe.h"
27#include "core/hle/service/am/applets/applet_profile_select.h"
28#include "core/hle/service/am/applets/applet_software_keyboard.h"
29#include "core/hle/service/am/applets/applet_web_browser.h"
27#include "core/hle/service/am/applets/applets.h" 30#include "core/hle/service/am/applets/applets.h"
28#include "core/hle/service/am/applets/profile_select.h"
29#include "core/hle/service/am/applets/software_keyboard.h"
30#include "core/hle/service/am/applets/web_browser.h"
31#include "core/hle/service/am/idle.h" 31#include "core/hle/service/am/idle.h"
32#include "core/hle/service/am/omm.h" 32#include "core/hle/service/am/omm.h"
33#include "core/hle/service/am/spsm.h" 33#include "core/hle/service/am/spsm.h"
34#include "core/hle/service/am/tcap.h" 34#include "core/hle/service/am/tcap.h"
35#include "core/hle/service/apm/controller.h" 35#include "core/hle/service/apm/apm_controller.h"
36#include "core/hle/service/apm/interface.h" 36#include "core/hle/service/apm/apm_interface.h"
37#include "core/hle/service/bcat/backend/backend.h" 37#include "core/hle/service/bcat/backend/backend.h"
38#include "core/hle/service/filesystem/filesystem.h" 38#include "core/hle/service/filesystem/filesystem.h"
39#include "core/hle/service/ns/ns.h" 39#include "core/hle/service/ns/ns.h"
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp
index 218c8d1e4..12682effe 100644
--- a/src/core/hle/service/am/applets/controller.cpp
+++ b/src/core/hle/service/am/applets/applet_controller.cpp
@@ -12,7 +12,7 @@
12#include "core/frontend/applets/controller.h" 12#include "core/frontend/applets/controller.h"
13#include "core/hle/result.h" 13#include "core/hle/result.h"
14#include "core/hle/service/am/am.h" 14#include "core/hle/service/am/am.h"
15#include "core/hle/service/am/applets/controller.h" 15#include "core/hle/service/am/applets/applet_controller.h"
16#include "core/hle/service/hid/controllers/npad.h" 16#include "core/hle/service/hid/controllers/npad.h"
17 17
18namespace Service::AM::Applets { 18namespace Service::AM::Applets {
diff --git a/src/core/hle/service/am/applets/controller.h b/src/core/hle/service/am/applets/applet_controller.h
index 20617e91f..20617e91f 100644
--- a/src/core/hle/service/am/applets/controller.h
+++ b/src/core/hle/service/am/applets/applet_controller.h
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/applet_error.cpp
index c724e5d5b..ef6854d62 100644
--- a/src/core/hle/service/am/applets/error.cpp
+++ b/src/core/hle/service/am/applets/applet_error.cpp
@@ -11,7 +11,7 @@
11#include "core/frontend/applets/error.h" 11#include "core/frontend/applets/error.h"
12#include "core/hle/kernel/k_process.h" 12#include "core/hle/kernel/k_process.h"
13#include "core/hle/service/am/am.h" 13#include "core/hle/service/am/am.h"
14#include "core/hle/service/am/applets/error.h" 14#include "core/hle/service/am/applets/applet_error.h"
15#include "core/reporter.h" 15#include "core/reporter.h"
16 16
17namespace Service::AM::Applets { 17namespace Service::AM::Applets {
diff --git a/src/core/hle/service/am/applets/error.h b/src/core/hle/service/am/applets/applet_error.h
index 8aa9046a5..8aa9046a5 100644
--- a/src/core/hle/service/am/applets/error.h
+++ b/src/core/hle/service/am/applets/applet_error.h
diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp
index 9fcb9f95b..0f413f9a0 100644
--- a/src/core/hle/service/am/applets/general_backend.cpp
+++ b/src/core/hle/service/am/applets/applet_general_backend.cpp
@@ -12,7 +12,7 @@
12#include "core/hle/kernel/k_process.h" 12#include "core/hle/kernel/k_process.h"
13#include "core/hle/result.h" 13#include "core/hle/result.h"
14#include "core/hle/service/am/am.h" 14#include "core/hle/service/am/am.h"
15#include "core/hle/service/am/applets/general_backend.h" 15#include "core/hle/service/am/applets/applet_general_backend.h"
16#include "core/reporter.h" 16#include "core/reporter.h"
17 17
18namespace Service::AM::Applets { 18namespace Service::AM::Applets {
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/applet_general_backend.h
index 7496ded88..7496ded88 100644
--- a/src/core/hle/service/am/applets/general_backend.h
+++ b/src/core/hle/service/am/applets/applet_general_backend.h
diff --git a/src/core/hle/service/am/applets/profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp
index 37048be26..bdc21778e 100644
--- a/src/core/hle/service/am/applets/profile_select.cpp
+++ b/src/core/hle/service/am/applets/applet_profile_select.cpp
@@ -9,7 +9,7 @@
9#include "core/core.h" 9#include "core/core.h"
10#include "core/frontend/applets/profile_select.h" 10#include "core/frontend/applets/profile_select.h"
11#include "core/hle/service/am/am.h" 11#include "core/hle/service/am/am.h"
12#include "core/hle/service/am/applets/profile_select.h" 12#include "core/hle/service/am/applets/applet_profile_select.h"
13 13
14namespace Service::AM::Applets { 14namespace Service::AM::Applets {
15 15
diff --git a/src/core/hle/service/am/applets/profile_select.h b/src/core/hle/service/am/applets/applet_profile_select.h
index 8fb76e6c4..8fb76e6c4 100644
--- a/src/core/hle/service/am/applets/profile_select.h
+++ b/src/core/hle/service/am/applets/applet_profile_select.h
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/applet_software_keyboard.cpp
index 00dfe1675..7cae90609 100644
--- a/src/core/hle/service/am/applets/software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/applet_software_keyboard.cpp
@@ -6,7 +6,7 @@
6#include "core/core.h" 6#include "core/core.h"
7#include "core/frontend/applets/software_keyboard.h" 7#include "core/frontend/applets/software_keyboard.h"
8#include "core/hle/service/am/am.h" 8#include "core/hle/service/am/am.h"
9#include "core/hle/service/am/applets/software_keyboard.h" 9#include "core/hle/service/am/applets/applet_software_keyboard.h"
10 10
11namespace Service::AM::Applets { 11namespace Service::AM::Applets {
12 12
diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/applet_software_keyboard.h
index e3fc733d0..9aef1bf11 100644
--- a/src/core/hle/service/am/applets/software_keyboard.h
+++ b/src/core/hle/service/am/applets/applet_software_keyboard.h
@@ -7,8 +7,8 @@
7#include "common/common_funcs.h" 7#include "common/common_funcs.h"
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/result.h" 9#include "core/hle/result.h"
10#include "core/hle/service/am/applets/applet_software_keyboard_types.h"
10#include "core/hle/service/am/applets/applets.h" 11#include "core/hle/service/am/applets/applets.h"
11#include "core/hle/service/am/applets/software_keyboard_types.h"
12 12
13namespace Core { 13namespace Core {
14class System; 14class System;
diff --git a/src/core/hle/service/am/applets/software_keyboard_types.h b/src/core/hle/service/am/applets/applet_software_keyboard_types.h
index 21aa8e800..21aa8e800 100644
--- a/src/core/hle/service/am/applets/software_keyboard_types.h
+++ b/src/core/hle/service/am/applets/applet_software_keyboard_types.h
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp
index 3b28e829b..35f194961 100644
--- a/src/core/hle/service/am/applets/web_browser.cpp
+++ b/src/core/hle/service/am/applets/applet_web_browser.cpp
@@ -21,7 +21,7 @@
21#include "core/hle/kernel/k_process.h" 21#include "core/hle/kernel/k_process.h"
22#include "core/hle/result.h" 22#include "core/hle/result.h"
23#include "core/hle/service/am/am.h" 23#include "core/hle/service/am/am.h"
24#include "core/hle/service/am/applets/web_browser.h" 24#include "core/hle/service/am/applets/applet_web_browser.h"
25#include "core/hle/service/filesystem/filesystem.h" 25#include "core/hle/service/filesystem/filesystem.h"
26#include "core/hle/service/ns/pl_u.h" 26#include "core/hle/service/ns/pl_u.h"
27 27
@@ -58,6 +58,16 @@ std::string GetMainURL(const std::string& url) {
58 return url.substr(0, index); 58 return url.substr(0, index);
59} 59}
60 60
61std::string ResolveURL(const std::string& url) {
62 const auto index = url.find_first_of('%');
63
64 if (index == std::string::npos) {
65 return url;
66 }
67
68 return url.substr(0, index) + "lp1" + url.substr(index + 1);
69}
70
61WebArgInputTLVMap ReadWebArgs(const std::vector<u8>& web_arg, WebArgHeader& web_arg_header) { 71WebArgInputTLVMap ReadWebArgs(const std::vector<u8>& web_arg, WebArgHeader& web_arg_header) {
62 std::memcpy(&web_arg_header, web_arg.data(), sizeof(WebArgHeader)); 72 std::memcpy(&web_arg_header, web_arg.data(), sizeof(WebArgHeader));
63 73
@@ -407,6 +417,9 @@ void WebBrowser::InitializeShare() {}
407 417
408void WebBrowser::InitializeWeb() { 418void WebBrowser::InitializeWeb() {
409 external_url = ParseStringValue(GetInputTLVData(WebArgInputTLVType::InitialURL).value()); 419 external_url = ParseStringValue(GetInputTLVData(WebArgInputTLVType::InitialURL).value());
420
421 // Resolve Nintendo CDN URLs.
422 external_url = ResolveURL(external_url);
410} 423}
411 424
412void WebBrowser::InitializeWifi() {} 425void WebBrowser::InitializeWifi() {}
diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/applet_web_browser.h
index 9f81214b6..4f9e81b79 100644
--- a/src/core/hle/service/am/applets/web_browser.h
+++ b/src/core/hle/service/am/applets/applet_web_browser.h
@@ -11,8 +11,8 @@
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/file_sys/vfs_types.h" 12#include "core/file_sys/vfs_types.h"
13#include "core/hle/result.h" 13#include "core/hle/result.h"
14#include "core/hle/service/am/applets/applet_web_browser_types.h"
14#include "core/hle/service/am/applets/applets.h" 15#include "core/hle/service/am/applets/applets.h"
15#include "core/hle/service/am/applets/web_types.h"
16 16
17namespace Core { 17namespace Core {
18class System; 18class System;
diff --git a/src/core/hle/service/am/applets/web_types.h b/src/core/hle/service/am/applets/applet_web_browser_types.h
index 419c2bf79..419c2bf79 100644
--- a/src/core/hle/service/am/applets/web_types.h
+++ b/src/core/hle/service/am/applets/applet_web_browser_types.h
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index ae995df6b..2b7685d42 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -17,13 +17,13 @@
17#include "core/hle/service/am/am.h" 17#include "core/hle/service/am/am.h"
18#include "core/hle/service/am/applet_ae.h" 18#include "core/hle/service/am/applet_ae.h"
19#include "core/hle/service/am/applet_oe.h" 19#include "core/hle/service/am/applet_oe.h"
20#include "core/hle/service/am/applets/applet_controller.h"
21#include "core/hle/service/am/applets/applet_error.h"
22#include "core/hle/service/am/applets/applet_general_backend.h"
23#include "core/hle/service/am/applets/applet_profile_select.h"
24#include "core/hle/service/am/applets/applet_software_keyboard.h"
25#include "core/hle/service/am/applets/applet_web_browser.h"
20#include "core/hle/service/am/applets/applets.h" 26#include "core/hle/service/am/applets/applets.h"
21#include "core/hle/service/am/applets/controller.h"
22#include "core/hle/service/am/applets/error.h"
23#include "core/hle/service/am/applets/general_backend.h"
24#include "core/hle/service/am/applets/profile_select.h"
25#include "core/hle/service/am/applets/software_keyboard.h"
26#include "core/hle/service/am/applets/web_browser.h"
27#include "core/hle/service/sm/sm.h" 27#include "core/hle/service/sm/sm.h"
28 28
29namespace Service::AM::Applets { 29namespace Service::AM::Applets {
diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp
index 97d6619dd..f5ebfe8d6 100644
--- a/src/core/hle/service/apm/apm.cpp
+++ b/src/core/hle/service/apm/apm.cpp
@@ -5,7 +5,7 @@
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/ipc_helpers.h" 6#include "core/hle/ipc_helpers.h"
7#include "core/hle/service/apm/apm.h" 7#include "core/hle/service/apm/apm.h"
8#include "core/hle/service/apm/interface.h" 8#include "core/hle/service/apm/apm_interface.h"
9 9
10namespace Service::APM { 10namespace Service::APM {
11 11
diff --git a/src/core/hle/service/apm/controller.cpp b/src/core/hle/service/apm/apm_controller.cpp
index 8bfa7c0e4..98839fe97 100644
--- a/src/core/hle/service/apm/controller.cpp
+++ b/src/core/hle/service/apm/apm_controller.cpp
@@ -9,7 +9,7 @@
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "common/settings.h" 10#include "common/settings.h"
11#include "core/core_timing.h" 11#include "core/core_timing.h"
12#include "core/hle/service/apm/controller.h" 12#include "core/hle/service/apm/apm_controller.h"
13 13
14namespace Service::APM { 14namespace Service::APM {
15 15
diff --git a/src/core/hle/service/apm/controller.h b/src/core/hle/service/apm/apm_controller.h
index 8d48e0104..8d48e0104 100644
--- a/src/core/hle/service/apm/controller.h
+++ b/src/core/hle/service/apm/apm_controller.h
diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/apm_interface.cpp
index d69ddd135..e58bad083 100644
--- a/src/core/hle/service/apm/interface.cpp
+++ b/src/core/hle/service/apm/apm_interface.cpp
@@ -5,8 +5,8 @@
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "core/hle/ipc_helpers.h" 6#include "core/hle/ipc_helpers.h"
7#include "core/hle/service/apm/apm.h" 7#include "core/hle/service/apm/apm.h"
8#include "core/hle/service/apm/controller.h" 8#include "core/hle/service/apm/apm_controller.h"
9#include "core/hle/service/apm/interface.h" 9#include "core/hle/service/apm/apm_interface.h"
10 10
11namespace Service::APM { 11namespace Service::APM {
12 12
diff --git a/src/core/hle/service/apm/interface.h b/src/core/hle/service/apm/apm_interface.h
index 063ad5308..063ad5308 100644
--- a/src/core/hle/service/apm/interface.h
+++ b/src/core/hle/service/apm/apm_interface.h
diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp
index dc15cf58b..7ca7f2aac 100644
--- a/src/core/hle/service/bcat/backend/boxcat.cpp
+++ b/src/core/hle/service/bcat/backend/boxcat.cpp
@@ -7,6 +7,9 @@
7#ifdef __GNUC__ 7#ifdef __GNUC__
8#pragma GCC diagnostic push 8#pragma GCC diagnostic push
9#pragma GCC diagnostic ignored "-Wshadow" 9#pragma GCC diagnostic ignored "-Wshadow"
10#ifndef __clang__
11#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
12#endif
10#endif 13#endif
11#include <httplib.h> 14#include <httplib.h>
12#include <mbedtls/sha256.h> 15#include <mbedtls/sha256.h>
diff --git a/src/core/hle/service/bcat/bcat.h b/src/core/hle/service/bcat/bcat.h
index d72798980..1eba477da 100644
--- a/src/core/hle/service/bcat/bcat.h
+++ b/src/core/hle/service/bcat/bcat.h
@@ -4,7 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/service/bcat/module.h" 7#include "core/hle/service/bcat/bcat_module.h"
8 8
9namespace Core { 9namespace Core {
10class System; 10class System;
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/bcat_module.cpp
index f85444da8..72294eb2e 100644
--- a/src/core/hle/service/bcat/module.cpp
+++ b/src/core/hle/service/bcat/bcat_module.cpp
@@ -17,7 +17,7 @@
17#include "core/hle/kernel/k_writable_event.h" 17#include "core/hle/kernel/k_writable_event.h"
18#include "core/hle/service/bcat/backend/backend.h" 18#include "core/hle/service/bcat/backend/backend.h"
19#include "core/hle/service/bcat/bcat.h" 19#include "core/hle/service/bcat/bcat.h"
20#include "core/hle/service/bcat/module.h" 20#include "core/hle/service/bcat/bcat_module.h"
21#include "core/hle/service/filesystem/filesystem.h" 21#include "core/hle/service/filesystem/filesystem.h"
22 22
23namespace Service::BCAT { 23namespace Service::BCAT {
diff --git a/src/core/hle/service/bcat/module.h b/src/core/hle/service/bcat/bcat_module.h
index 738731c06..738731c06 100644
--- a/src/core/hle/service/bcat/module.h
+++ b/src/core/hle/service/bcat/bcat_module.h
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index c5f88bce7..a3c939c0c 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -12,7 +12,7 @@
12#include "core/hle/kernel/k_writable_event.h" 12#include "core/hle/kernel/k_writable_event.h"
13#include "core/hle/service/friend/errors.h" 13#include "core/hle/service/friend/errors.h"
14#include "core/hle/service/friend/friend.h" 14#include "core/hle/service/friend/friend.h"
15#include "core/hle/service/friend/interface.h" 15#include "core/hle/service/friend/friend_interface.h"
16 16
17namespace Service::Friend { 17namespace Service::Friend {
18 18
diff --git a/src/core/hle/service/friend/interface.cpp b/src/core/hle/service/friend/friend_interface.cpp
index 7368ccec2..9b18b2a32 100644
--- a/src/core/hle/service/friend/interface.cpp
+++ b/src/core/hle/service/friend/friend_interface.cpp
@@ -2,7 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/service/friend/interface.h" 5#include "core/hle/service/friend/friend_interface.h"
6 6
7namespace Service::Friend { 7namespace Service::Friend {
8 8
diff --git a/src/core/hle/service/friend/interface.h b/src/core/hle/service/friend/friend_interface.h
index 43d914b32..43d914b32 100644
--- a/src/core/hle/service/friend/interface.h
+++ b/src/core/hle/service/friend/friend_interface.h
diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp
index ca25df67e..5a3b54cc1 100644
--- a/src/core/hle/service/glue/arp.cpp
+++ b/src/core/hle/service/glue/arp.cpp
@@ -13,7 +13,7 @@
13#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
14#include "core/hle/service/glue/arp.h" 14#include "core/hle/service/glue/arp.h"
15#include "core/hle/service/glue/errors.h" 15#include "core/hle/service/glue/errors.h"
16#include "core/hle/service/glue/manager.h" 16#include "core/hle/service/glue/glue_manager.h"
17#include "core/hle/service/service.h" 17#include "core/hle/service/service.h"
18 18
19namespace Service::Glue { 19namespace Service::Glue {
diff --git a/src/core/hle/service/glue/manager.cpp b/src/core/hle/service/glue/glue_manager.cpp
index 9b1754cf8..aa9d48c0c 100644
--- a/src/core/hle/service/glue/manager.cpp
+++ b/src/core/hle/service/glue/glue_manager.cpp
@@ -3,7 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/service/glue/errors.h" 5#include "core/hle/service/glue/errors.h"
6#include "core/hle/service/glue/manager.h" 6#include "core/hle/service/glue/glue_manager.h"
7 7
8namespace Service::Glue { 8namespace Service::Glue {
9 9
diff --git a/src/core/hle/service/glue/manager.h b/src/core/hle/service/glue/glue_manager.h
index a7f5ce3ee..a7f5ce3ee 100644
--- a/src/core/hle/service/glue/manager.h
+++ b/src/core/hle/service/glue/glue_manager.h
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 1eb02aee2..6ce1360e3 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -941,6 +941,11 @@ void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_de
941 941
942void Controller_NPad::InitializeVibrationDeviceAtIndex(std::size_t npad_index, 942void Controller_NPad::InitializeVibrationDeviceAtIndex(std::size_t npad_index,
943 std::size_t device_index) { 943 std::size_t device_index) {
944 if (!Settings::values.vibration_enabled.GetValue()) {
945 vibration_devices_mounted[npad_index][device_index] = false;
946 return;
947 }
948
944 if (vibrations[npad_index][device_index]) { 949 if (vibrations[npad_index][device_index]) {
945 vibration_devices_mounted[npad_index][device_index] = 950 vibration_devices_mounted[npad_index][device_index] =
946 vibrations[npad_index][device_index]->GetStatus() == 1; 951 vibrations[npad_index][device_index]->GetStatus() == 1;
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp
index bbd81a88a..9d863486a 100644
--- a/src/core/hle/service/mii/mii.cpp
+++ b/src/core/hle/service/mii/mii.cpp
@@ -7,8 +7,8 @@
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/hle_ipc.h" 9#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/service/mii/manager.h"
11#include "core/hle/service/mii/mii.h" 10#include "core/hle/service/mii/mii.h"
11#include "core/hle/service/mii/mii_manager.h"
12#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
13#include "core/hle/service/sm/sm.h" 13#include "core/hle/service/sm/sm.h"
14 14
diff --git a/src/core/hle/service/mii/manager.cpp b/src/core/hle/service/mii/mii_manager.cpp
index 869d2763f..4fef2aea4 100644
--- a/src/core/hle/service/mii/manager.cpp
+++ b/src/core/hle/service/mii/mii_manager.cpp
@@ -10,7 +10,7 @@
10#include "common/string_util.h" 10#include "common/string_util.h"
11 11
12#include "core/hle/service/acc/profile_manager.h" 12#include "core/hle/service/acc/profile_manager.h"
13#include "core/hle/service/mii/manager.h" 13#include "core/hle/service/mii/mii_manager.h"
14#include "core/hle/service/mii/raw_data.h" 14#include "core/hle/service/mii/raw_data.h"
15#include "core/hle/service/mii/types.h" 15#include "core/hle/service/mii/types.h"
16 16
diff --git a/src/core/hle/service/mii/manager.h b/src/core/hle/service/mii/mii_manager.h
index 8e048fc56..8e048fc56 100644
--- a/src/core/hle/service/mii/manager.h
+++ b/src/core/hle/service/mii/mii_manager.h
diff --git a/src/core/hle/service/mii/raw_data.h b/src/core/hle/service/mii/raw_data.h
index 0e35d69d2..a0d2b9d3a 100644
--- a/src/core/hle/service/mii/raw_data.h
+++ b/src/core/hle/service/mii/raw_data.h
@@ -7,7 +7,7 @@
7#include <array> 7#include <array>
8 8
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/hle/service/mii/manager.h" 10#include "core/hle/service/mii/mii_manager.h"
11 11
12namespace Service::Mii::RawData { 12namespace Service::Mii::RawData {
13 13
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 98e6296f1..1403a39d0 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -19,26 +19,29 @@
19namespace Service::Nvidia::Devices { 19namespace Service::Nvidia::Devices {
20 20
21namespace { 21namespace {
22// Splice vectors will copy count amount of type T from the input vector into the dst vector. 22// Copies count amount of type T from the input vector into the dst vector.
23// Returns the number of bytes written into dst.
23template <typename T> 24template <typename T>
24std::size_t SpliceVectors(const std::vector<u8>& input, std::vector<T>& dst, std::size_t count, 25std::size_t SliceVectors(const std::vector<u8>& input, std::vector<T>& dst, std::size_t count,
25 std::size_t offset) { 26 std::size_t offset) {
26 if (!dst.empty()) { 27 if (dst.empty()) {
27 std::memcpy(dst.data(), input.data() + offset, count * sizeof(T)); 28 return 0;
28 } 29 }
29 return 0; 30 const size_t bytes_copied = count * sizeof(T);
31 std::memcpy(dst.data(), input.data() + offset, bytes_copied);
32 return bytes_copied;
30} 33}
31 34
32// Write vectors will write data to the output buffer 35// Writes the data in src to an offset into the dst vector. The offset is specified in bytes
36// Returns the number of bytes written into dst.
33template <typename T> 37template <typename T>
34std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::size_t offset) { 38std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::size_t offset) {
35 if (src.empty()) { 39 if (src.empty()) {
36 return 0; 40 return 0;
37 } else {
38 std::memcpy(dst.data() + offset, src.data(), src.size() * sizeof(T));
39 offset += src.size() * sizeof(T);
40 return offset;
41 } 41 }
42 const size_t bytes_copied = src.size() * sizeof(T);
43 std::memcpy(dst.data() + offset, src.data(), bytes_copied);
44 return bytes_copied;
42} 45}
43} // Anonymous namespace 46} // Anonymous namespace
44 47
@@ -62,7 +65,6 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
62 LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); 65 LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count);
63 66
64 // Instantiate param buffers 67 // Instantiate param buffers
65 std::size_t offset = sizeof(IoctlSubmit);
66 std::vector<CommandBuffer> command_buffers(params.cmd_buffer_count); 68 std::vector<CommandBuffer> command_buffers(params.cmd_buffer_count);
67 std::vector<Reloc> relocs(params.relocation_count); 69 std::vector<Reloc> relocs(params.relocation_count);
68 std::vector<u32> reloc_shifts(params.relocation_count); 70 std::vector<u32> reloc_shifts(params.relocation_count);
@@ -70,13 +72,14 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
70 std::vector<SyncptIncr> wait_checks(params.syncpoint_count); 72 std::vector<SyncptIncr> wait_checks(params.syncpoint_count);
71 std::vector<Fence> fences(params.fence_count); 73 std::vector<Fence> fences(params.fence_count);
72 74
73 // Splice input into their respective buffers 75 // Slice input into their respective buffers
74 offset = SpliceVectors(input, command_buffers, params.cmd_buffer_count, offset); 76 std::size_t offset = sizeof(IoctlSubmit);
75 offset = SpliceVectors(input, relocs, params.relocation_count, offset); 77 offset += SliceVectors(input, command_buffers, params.cmd_buffer_count, offset);
76 offset = SpliceVectors(input, reloc_shifts, params.relocation_count, offset); 78 offset += SliceVectors(input, relocs, params.relocation_count, offset);
77 offset = SpliceVectors(input, syncpt_increments, params.syncpoint_count, offset); 79 offset += SliceVectors(input, reloc_shifts, params.relocation_count, offset);
78 offset = SpliceVectors(input, wait_checks, params.syncpoint_count, offset); 80 offset += SliceVectors(input, syncpt_increments, params.syncpoint_count, offset);
79 offset = SpliceVectors(input, fences, params.fence_count, offset); 81 offset += SliceVectors(input, wait_checks, params.syncpoint_count, offset);
82 offset += SliceVectors(input, fences, params.fence_count, offset);
80 83
81 auto& gpu = system.GPU(); 84 auto& gpu = system.GPU();
82 if (gpu.UseNvdec()) { 85 if (gpu.UseNvdec()) {
@@ -88,35 +91,27 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
88 } 91 }
89 } 92 }
90 for (const auto& cmd_buffer : command_buffers) { 93 for (const auto& cmd_buffer : command_buffers) {
91 auto object = nvmap_dev->GetObject(cmd_buffer.memory_id); 94 const auto object = nvmap_dev->GetObject(cmd_buffer.memory_id);
92 ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); 95 ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;);
93 const auto map = FindBufferMap(object->dma_map_addr);
94 if (!map) {
95 LOG_ERROR(Service_NVDRV, "Tried to submit an invalid offset 0x{:X} dma 0x{:X}",
96 object->addr, object->dma_map_addr);
97 return NvResult::Success;
98 }
99 Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); 96 Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count);
100 gpu.MemoryManager().ReadBlock(map->StartAddr() + cmd_buffer.offset, cmdlist.data(), 97 system.Memory().ReadBlock(object->addr + cmd_buffer.offset, cmdlist.data(),
101 cmdlist.size() * sizeof(u32)); 98 cmdlist.size() * sizeof(u32));
102 gpu.PushCommandBuffer(cmdlist); 99 gpu.PushCommandBuffer(cmdlist);
103 } 100 }
104 if (gpu.UseNvdec()) { 101 if (gpu.UseNvdec()) {
105
106 fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1); 102 fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1);
107
108 Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}}; 103 Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}};
109 gpu.PushCommandBuffer(cmdlist); 104 gpu.PushCommandBuffer(cmdlist);
110 } 105 }
111 std::memcpy(output.data(), &params, sizeof(IoctlSubmit)); 106 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
112 // Some games expect command_buffers to be written back 107 // Some games expect command_buffers to be written back
113 offset = sizeof(IoctlSubmit); 108 offset = sizeof(IoctlSubmit);
114 offset = WriteVectors(output, command_buffers, offset); 109 offset += WriteVectors(output, command_buffers, offset);
115 offset = WriteVectors(output, relocs, offset); 110 offset += WriteVectors(output, relocs, offset);
116 offset = WriteVectors(output, reloc_shifts, offset); 111 offset += WriteVectors(output, reloc_shifts, offset);
117 offset = WriteVectors(output, syncpt_increments, offset); 112 offset += WriteVectors(output, syncpt_increments, offset);
118 offset = WriteVectors(output, wait_checks, offset); 113 offset += WriteVectors(output, wait_checks, offset);
119 offset = WriteVectors(output, fences, offset); 114 offset += WriteVectors(output, fences, offset);
120 115
121 return NvResult::Success; 116 return NvResult::Success;
122} 117}
@@ -148,14 +143,14 @@ NvResult nvhost_nvdec_common::MapBuffer(const std::vector<u8>& input, std::vecto
148 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer)); 143 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
149 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); 144 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
150 145
151 SpliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer)); 146 SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer));
152 147
153 auto& gpu = system.GPU(); 148 auto& gpu = system.GPU();
154 149
155 for (auto& cmf_buff : cmd_buffer_handles) { 150 for (auto& cmd_buffer : cmd_buffer_handles) {
156 auto object{nvmap_dev->GetObject(cmf_buff.map_handle)}; 151 auto object{nvmap_dev->GetObject(cmd_buffer.map_handle)};
157 if (!object) { 152 if (!object) {
158 LOG_ERROR(Service_NVDRV, "invalid cmd_buffer nvmap_handle={:X}", cmf_buff.map_handle); 153 LOG_ERROR(Service_NVDRV, "invalid cmd_buffer nvmap_handle={:X}", cmd_buffer.map_handle);
159 std::memcpy(output.data(), &params, output.size()); 154 std::memcpy(output.data(), &params, output.size());
160 return NvResult::InvalidState; 155 return NvResult::InvalidState;
161 } 156 }
@@ -170,7 +165,7 @@ NvResult nvhost_nvdec_common::MapBuffer(const std::vector<u8>& input, std::vecto
170 if (!object->dma_map_addr) { 165 if (!object->dma_map_addr) {
171 LOG_ERROR(Service_NVDRV, "failed to map size={}", object->size); 166 LOG_ERROR(Service_NVDRV, "failed to map size={}", object->size);
172 } else { 167 } else {
173 cmf_buff.map_address = object->dma_map_addr; 168 cmd_buffer.map_address = object->dma_map_addr;
174 AddBufferMap(object->dma_map_addr, object->size, object->addr, 169 AddBufferMap(object->dma_map_addr, object->size, object->addr,
175 object->status == nvmap::Object::Status::Allocated); 170 object->status == nvmap::Object::Status::Allocated);
176 } 171 }
@@ -186,14 +181,14 @@ NvResult nvhost_nvdec_common::UnmapBuffer(const std::vector<u8>& input, std::vec
186 IoctlMapBuffer params{}; 181 IoctlMapBuffer params{};
187 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer)); 182 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
188 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); 183 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
189 SpliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer)); 184 SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer));
190 185
191 auto& gpu = system.GPU(); 186 auto& gpu = system.GPU();
192 187
193 for (auto& cmf_buff : cmd_buffer_handles) { 188 for (auto& cmd_buffer : cmd_buffer_handles) {
194 const auto object{nvmap_dev->GetObject(cmf_buff.map_handle)}; 189 const auto object{nvmap_dev->GetObject(cmd_buffer.map_handle)};
195 if (!object) { 190 if (!object) {
196 LOG_ERROR(Service_NVDRV, "invalid cmd_buffer nvmap_handle={:X}", cmf_buff.map_handle); 191 LOG_ERROR(Service_NVDRV, "invalid cmd_buffer nvmap_handle={:X}", cmd_buffer.map_handle);
197 std::memcpy(output.data(), &params, output.size()); 192 std::memcpy(output.data(), &params, output.size());
198 return NvResult::InvalidState; 193 return NvResult::InvalidState;
199 } 194 }
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 74796dce1..03992af5e 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -20,8 +20,8 @@
20#include "core/hle/service/nvdrv/devices/nvhost_nvjpg.h" 20#include "core/hle/service/nvdrv/devices/nvhost_nvjpg.h"
21#include "core/hle/service/nvdrv/devices/nvhost_vic.h" 21#include "core/hle/service/nvdrv/devices/nvhost_vic.h"
22#include "core/hle/service/nvdrv/devices/nvmap.h" 22#include "core/hle/service/nvdrv/devices/nvmap.h"
23#include "core/hle/service/nvdrv/interface.h"
24#include "core/hle/service/nvdrv/nvdrv.h" 23#include "core/hle/service/nvdrv/nvdrv.h"
24#include "core/hle/service/nvdrv/nvdrv_interface.h"
25#include "core/hle/service/nvdrv/nvmemp.h" 25#include "core/hle/service/nvdrv/nvmemp.h"
26#include "core/hle/service/nvdrv/syncpoint_manager.h" 26#include "core/hle/service/nvdrv/syncpoint_manager.h"
27#include "core/hle/service/nvflinger/nvflinger.h" 27#include "core/hle/service/nvflinger/nvflinger.h"
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
index e4d495000..d61fb73dc 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
@@ -10,9 +10,9 @@
10#include "core/hle/kernel/k_thread.h" 10#include "core/hle/kernel/k_thread.h"
11#include "core/hle/kernel/k_writable_event.h" 11#include "core/hle/kernel/k_writable_event.h"
12#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/kernel.h"
13#include "core/hle/service/nvdrv/interface.h"
14#include "core/hle/service/nvdrv/nvdata.h" 13#include "core/hle/service/nvdrv/nvdata.h"
15#include "core/hle/service/nvdrv/nvdrv.h" 14#include "core/hle/service/nvdrv/nvdrv.h"
15#include "core/hle/service/nvdrv/nvdrv_interface.h"
16 16
17namespace Service::Nvidia { 17namespace Service::Nvidia {
18 18
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h
index 0e764c53f..0e764c53f 100644
--- a/src/core/hle/service/nvdrv/interface.h
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.h
diff --git a/src/core/hle/service/pctl/pctl.h b/src/core/hle/service/pctl/pctl.h
index ea3b97823..1d28900b2 100644
--- a/src/core/hle/service/pctl/pctl.h
+++ b/src/core/hle/service/pctl/pctl.h
@@ -4,7 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/service/pctl/module.h" 7#include "core/hle/service/pctl/pctl_module.h"
8 8
9namespace Core { 9namespace Core {
10class System; 10class System;
diff --git a/src/core/hle/service/pctl/module.cpp b/src/core/hle/service/pctl/pctl_module.cpp
index 1e31d05a6..6949fcf3b 100644
--- a/src/core/hle/service/pctl/module.cpp
+++ b/src/core/hle/service/pctl/pctl_module.cpp
@@ -8,8 +8,8 @@
8#include "core/file_sys/patch_manager.h" 8#include "core/file_sys/patch_manager.h"
9#include "core/hle/ipc_helpers.h" 9#include "core/hle/ipc_helpers.h"
10#include "core/hle/kernel/k_process.h" 10#include "core/hle/kernel/k_process.h"
11#include "core/hle/service/pctl/module.h"
12#include "core/hle/service/pctl/pctl.h" 11#include "core/hle/service/pctl/pctl.h"
12#include "core/hle/service/pctl/pctl_module.h"
13 13
14namespace Service::PCTL { 14namespace Service::PCTL {
15 15
diff --git a/src/core/hle/service/pctl/module.h b/src/core/hle/service/pctl/pctl_module.h
index f25c5c557..f25c5c557 100644
--- a/src/core/hle/service/pctl/module.h
+++ b/src/core/hle/service/pctl/pctl_module.h
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 663b83cd3..e6fba88b2 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -21,7 +21,7 @@
21#include "core/hle/service/aoc/aoc_u.h" 21#include "core/hle/service/aoc/aoc_u.h"
22#include "core/hle/service/apm/apm.h" 22#include "core/hle/service/apm/apm.h"
23#include "core/hle/service/audio/audio.h" 23#include "core/hle/service/audio/audio.h"
24#include "core/hle/service/bcat/module.h" 24#include "core/hle/service/bcat/bcat_module.h"
25#include "core/hle/service/bpc/bpc.h" 25#include "core/hle/service/bpc/bpc.h"
26#include "core/hle/service/btdrv/btdrv.h" 26#include "core/hle/service/btdrv/btdrv.h"
27#include "core/hle/service/btm/btm.h" 27#include "core/hle/service/btm/btm.h"
@@ -54,7 +54,7 @@
54#include "core/hle/service/nvflinger/nvflinger.h" 54#include "core/hle/service/nvflinger/nvflinger.h"
55#include "core/hle/service/olsc/olsc.h" 55#include "core/hle/service/olsc/olsc.h"
56#include "core/hle/service/pcie/pcie.h" 56#include "core/hle/service/pcie/pcie.h"
57#include "core/hle/service/pctl/module.h" 57#include "core/hle/service/pctl/pctl_module.h"
58#include "core/hle/service/pcv/pcv.h" 58#include "core/hle/service/pcv/pcv.h"
59#include "core/hle/service/pm/pm.h" 59#include "core/hle/service/pm/pm.h"
60#include "core/hle/service/prepo/prepo.h" 60#include "core/hle/service/prepo/prepo.h"
@@ -64,7 +64,7 @@
64#include "core/hle/service/set/settings.h" 64#include "core/hle/service/set/settings.h"
65#include "core/hle/service/sm/sm.h" 65#include "core/hle/service/sm/sm.h"
66#include "core/hle/service/sockets/sockets.h" 66#include "core/hle/service/sockets/sockets.h"
67#include "core/hle/service/spl/module.h" 67#include "core/hle/service/spl/spl_module.h"
68#include "core/hle/service/ssl/ssl.h" 68#include "core/hle/service/ssl/ssl.h"
69#include "core/hle/service/time/time.h" 69#include "core/hle/service/time/time.h"
70#include "core/hle/service/usb/usb.h" 70#include "core/hle/service/usb/usb.h"
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index c7828c3bd..15034abed 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -14,8 +14,8 @@
14#include "core/hle/kernel/k_server_session.h" 14#include "core/hle/kernel/k_server_session.h"
15#include "core/hle/kernel/k_session.h" 15#include "core/hle/kernel/k_session.h"
16#include "core/hle/result.h" 16#include "core/hle/result.h"
17#include "core/hle/service/sm/controller.h"
18#include "core/hle/service/sm/sm.h" 17#include "core/hle/service/sm/sm.h"
18#include "core/hle/service/sm/sm_controller.h"
19 19
20namespace Service::SM { 20namespace Service::SM {
21 21
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/sm_controller.cpp
index 8b9418e0f..b5fbc4569 100644
--- a/src/core/hle/service/sm/controller.cpp
+++ b/src/core/hle/service/sm/sm_controller.cpp
@@ -13,7 +13,7 @@
13#include "core/hle/kernel/k_server_port.h" 13#include "core/hle/kernel/k_server_port.h"
14#include "core/hle/kernel/k_server_session.h" 14#include "core/hle/kernel/k_server_session.h"
15#include "core/hle/kernel/k_session.h" 15#include "core/hle/kernel/k_session.h"
16#include "core/hle/service/sm/controller.h" 16#include "core/hle/service/sm/sm_controller.h"
17 17
18namespace Service::SM { 18namespace Service::SM {
19 19
diff --git a/src/core/hle/service/sm/controller.h b/src/core/hle/service/sm/sm_controller.h
index 7494f898d..7494f898d 100644
--- a/src/core/hle/service/sm/controller.h
+++ b/src/core/hle/service/sm/sm_controller.h
diff --git a/src/core/hle/service/spl/csrng.h b/src/core/hle/service/spl/csrng.h
index 5c0bd2199..0d03cc6cb 100644
--- a/src/core/hle/service/spl/csrng.h
+++ b/src/core/hle/service/spl/csrng.h
@@ -4,7 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/service/spl/module.h" 7#include "core/hle/service/spl/spl_module.h"
8 8
9namespace Core { 9namespace Core {
10class System; 10class System;
diff --git a/src/core/hle/service/spl/spl.h b/src/core/hle/service/spl/spl.h
index 9b35012ed..5599c0c01 100644
--- a/src/core/hle/service/spl/spl.h
+++ b/src/core/hle/service/spl/spl.h
@@ -4,7 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "core/hle/service/spl/module.h" 7#include "core/hle/service/spl/spl_module.h"
8 8
9namespace Core { 9namespace Core {
10class System; 10class System;
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/spl_module.cpp
index ebb179aa8..918633af5 100644
--- a/src/core/hle/service/spl/module.cpp
+++ b/src/core/hle/service/spl/spl_module.cpp
@@ -13,8 +13,8 @@
13#include "core/hle/api_version.h" 13#include "core/hle/api_version.h"
14#include "core/hle/ipc_helpers.h" 14#include "core/hle/ipc_helpers.h"
15#include "core/hle/service/spl/csrng.h" 15#include "core/hle/service/spl/csrng.h"
16#include "core/hle/service/spl/module.h"
17#include "core/hle/service/spl/spl.h" 16#include "core/hle/service/spl/spl.h"
17#include "core/hle/service/spl/spl_module.h"
18 18
19namespace Service::SPL { 19namespace Service::SPL {
20 20
diff --git a/src/core/hle/service/spl/module.h b/src/core/hle/service/spl/spl_module.h
index 61630df80..61630df80 100644
--- a/src/core/hle/service/spl/module.h
+++ b/src/core/hle/service/spl/spl_module.h
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index d6f710eba..8fdd5076f 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -11,8 +11,8 @@
11#include "core/hle/kernel/k_client_port.h" 11#include "core/hle/kernel/k_client_port.h"
12#include "core/hle/kernel/k_scheduler.h" 12#include "core/hle/kernel/k_scheduler.h"
13#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
14#include "core/hle/service/time/interface.h"
15#include "core/hle/service/time/time.h" 14#include "core/hle/service/time/time.h"
15#include "core/hle/service/time/time_interface.h"
16#include "core/hle/service/time/time_sharedmemory.h" 16#include "core/hle/service/time/time_sharedmemory.h"
17#include "core/hle/service/time/time_zone_service.h" 17#include "core/hle/service/time/time_zone_service.h"
18 18
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/time_interface.cpp
index 53a204796..bb7b6b5c1 100644
--- a/src/core/hle/service/time/interface.cpp
+++ b/src/core/hle/service/time/time_interface.cpp
@@ -2,7 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/service/time/interface.h" 5#include "core/hle/service/time/time_interface.h"
6 6
7namespace Service::Time { 7namespace Service::Time {
8 8
diff --git a/src/core/hle/service/time/interface.h b/src/core/hle/service/time/time_interface.h
index c41766f1a..c41766f1a 100644
--- a/src/core/hle/service/time/interface.h
+++ b/src/core/hle/service/time/time_interface.h
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index 7399c3648..8de3d4520 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -294,8 +294,8 @@ void InputSubsystem::ReloadInputDevices() {
294 impl->udp->ReloadSockets(); 294 impl->udp->ReloadSockets();
295} 295}
296 296
297std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers( 297std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers([
298 Polling::DeviceType type) const { 298 [maybe_unused]] Polling::DeviceType type) const {
299#ifdef HAVE_SDL2 299#ifdef HAVE_SDL2
300 return impl->sdl->GetPollers(type); 300 return impl->sdl->GetPollers(type);
301#else 301#else
diff --git a/src/input_common/mouse/mouse_poller.cpp b/src/input_common/mouse/mouse_poller.cpp
index 45b3d7340..efcdd85d2 100644
--- a/src/input_common/mouse/mouse_poller.cpp
+++ b/src/input_common/mouse/mouse_poller.cpp
@@ -84,7 +84,7 @@ public:
84 std::lock_guard lock{mutex}; 84 std::lock_guard lock{mutex};
85 const auto axis_value = 85 const auto axis_value =
86 static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis)); 86 static_cast<float>(mouse_input->GetMouseState(button).axis.at(axis));
87 const float sensitivity = Settings::values.mouse_panning_sensitivity.GetValue(); 87 const float sensitivity = Settings::values.mouse_panning_sensitivity.GetValue() * 0.10f;
88 return axis_value * sensitivity / (100.0f * range); 88 return axis_value * sensitivity / (100.0f * range);
89 } 89 }
90 90
diff --git a/src/input_common/sdl/sdl_impl.h b/src/input_common/sdl/sdl_impl.h
index b77afcbd8..7a9ad6346 100644
--- a/src/input_common/sdl/sdl_impl.h
+++ b/src/input_common/sdl/sdl_impl.h
@@ -10,15 +10,7 @@
10#include <thread> 10#include <thread>
11#include <unordered_map> 11#include <unordered_map>
12 12
13// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
14#ifdef __GNUC__
15#pragma GCC diagnostic push
16#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
17#endif
18#include <SDL.h> 13#include <SDL.h>
19#ifdef __GNUC__
20#pragma GCC diagnostic pop
21#endif
22 14
23#include "common/common_types.h" 15#include "common/common_types.h"
24#include "common/threadsafe_queue.h" 16#include "common/threadsafe_queue.h"
diff --git a/src/tests/video_core/buffer_base.cpp b/src/tests/video_core/buffer_base.cpp
index edced69bb..9f5a54de4 100644
--- a/src/tests/video_core/buffer_base.cpp
+++ b/src/tests/video_core/buffer_base.cpp
@@ -536,7 +536,7 @@ TEST_CASE("BufferBase: Cached write downloads") {
536 REQUIRE(rasterizer.Count() == 63); 536 REQUIRE(rasterizer.Count() == 63);
537 buffer.MarkRegionAsGpuModified(c + PAGE, PAGE); 537 buffer.MarkRegionAsGpuModified(c + PAGE, PAGE);
538 int num = 0; 538 int num = 0;
539 buffer.ForEachDownloadRange(c, WORD, [&](u64 offset, u64 size) { ++num; }); 539 buffer.ForEachDownloadRangeAndClear(c, WORD, [&](u64 offset, u64 size) { ++num; });
540 buffer.ForEachUploadRange(c, WORD, [&](u64 offset, u64 size) { ++num; }); 540 buffer.ForEachUploadRange(c, WORD, [&](u64 offset, u64 size) { ++num; });
541 REQUIRE(num == 0); 541 REQUIRE(num == 0);
542 REQUIRE(!buffer.IsRegionCpuModified(c + PAGE, PAGE)); 542 REQUIRE(!buffer.IsRegionCpuModified(c + PAGE, PAGE));
diff --git a/src/video_core/buffer_cache/buffer_base.h b/src/video_core/buffer_cache/buffer_base.h
index b121d36a3..c3318095c 100644
--- a/src/video_core/buffer_cache/buffer_base.h
+++ b/src/video_core/buffer_cache/buffer_base.h
@@ -226,19 +226,24 @@ public:
226 /// Call 'func' for each CPU modified range and unmark those pages as CPU modified 226 /// Call 'func' for each CPU modified range and unmark those pages as CPU modified
227 template <typename Func> 227 template <typename Func>
228 void ForEachUploadRange(VAddr query_cpu_range, u64 size, Func&& func) { 228 void ForEachUploadRange(VAddr query_cpu_range, u64 size, Func&& func) {
229 ForEachModifiedRange<Type::CPU>(query_cpu_range, size, func); 229 ForEachModifiedRange<Type::CPU>(query_cpu_range, size, true, func);
230 } 230 }
231 231
232 /// Call 'func' for each GPU modified range and unmark those pages as GPU modified 232 /// Call 'func' for each GPU modified range and unmark those pages as GPU modified
233 template <typename Func> 233 template <typename Func>
234 void ForEachDownloadRange(VAddr query_cpu_range, u64 size, Func&& func) { 234 void ForEachDownloadRange(VAddr query_cpu_range, u64 size, bool clear, Func&& func) {
235 ForEachModifiedRange<Type::GPU>(query_cpu_range, size, func); 235 ForEachModifiedRange<Type::GPU>(query_cpu_range, size, clear, func);
236 }
237
238 template <typename Func>
239 void ForEachDownloadRangeAndClear(VAddr query_cpu_range, u64 size, Func&& func) {
240 ForEachModifiedRange<Type::GPU>(query_cpu_range, size, true, func);
236 } 241 }
237 242
238 /// Call 'func' for each GPU modified range and unmark those pages as GPU modified 243 /// Call 'func' for each GPU modified range and unmark those pages as GPU modified
239 template <typename Func> 244 template <typename Func>
240 void ForEachDownloadRange(Func&& func) { 245 void ForEachDownloadRange(Func&& func) {
241 ForEachModifiedRange<Type::GPU>(cpu_addr, SizeBytes(), func); 246 ForEachModifiedRange<Type::GPU>(cpu_addr, SizeBytes(), true, func);
242 } 247 }
243 248
244 /// Mark buffer as picked 249 /// Mark buffer as picked
@@ -415,7 +420,7 @@ private:
415 * @param func Function to call for each turned off region 420 * @param func Function to call for each turned off region
416 */ 421 */
417 template <Type type, typename Func> 422 template <Type type, typename Func>
418 void ForEachModifiedRange(VAddr query_cpu_range, s64 size, Func&& func) { 423 void ForEachModifiedRange(VAddr query_cpu_range, s64 size, bool clear, Func&& func) {
419 static_assert(type != Type::Untracked); 424 static_assert(type != Type::Untracked);
420 425
421 const s64 difference = query_cpu_range - cpu_addr; 426 const s64 difference = query_cpu_range - cpu_addr;
@@ -467,7 +472,9 @@ private:
467 bits = (bits << left_offset) >> left_offset; 472 bits = (bits << left_offset) >> left_offset;
468 473
469 const u64 current_word = state_words[word_index] & bits; 474 const u64 current_word = state_words[word_index] & bits;
470 state_words[word_index] &= ~bits; 475 if (clear) {
476 state_words[word_index] &= ~bits;
477 }
471 478
472 if constexpr (type == Type::CPU) { 479 if constexpr (type == Type::CPU) {
473 const u64 current_bits = untracked_words[word_index] & bits; 480 const u64 current_bits = untracked_words[word_index] & bits;
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index cad7f902d..2871682f6 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -15,6 +15,7 @@
15#include <vector> 15#include <vector>
16 16
17#include <boost/container/small_vector.hpp> 17#include <boost/container/small_vector.hpp>
18#include <boost/icl/interval_set.hpp>
18 19
19#include "common/common_types.h" 20#include "common/common_types.h"
20#include "common/div_ceil.h" 21#include "common/div_ceil.h"
@@ -77,6 +78,9 @@ class BufferCache {
77 using Runtime = typename P::Runtime; 78 using Runtime = typename P::Runtime;
78 using Buffer = typename P::Buffer; 79 using Buffer = typename P::Buffer;
79 80
81 using IntervalSet = boost::icl::interval_set<VAddr>;
82 using IntervalType = typename IntervalSet::interval_type;
83
80 struct Empty {}; 84 struct Empty {};
81 85
82 struct OverlapResult { 86 struct OverlapResult {
@@ -148,18 +152,26 @@ public:
148 /// Return true when there are uncommitted buffers to be downloaded 152 /// Return true when there are uncommitted buffers to be downloaded
149 [[nodiscard]] bool HasUncommittedFlushes() const noexcept; 153 [[nodiscard]] bool HasUncommittedFlushes() const noexcept;
150 154
155 void AccumulateFlushes();
156
151 /// Return true when the caller should wait for async downloads 157 /// Return true when the caller should wait for async downloads
152 [[nodiscard]] bool ShouldWaitAsyncFlushes() const noexcept; 158 [[nodiscard]] bool ShouldWaitAsyncFlushes() const noexcept;
153 159
154 /// Commit asynchronous downloads 160 /// Commit asynchronous downloads
155 void CommitAsyncFlushes(); 161 void CommitAsyncFlushes();
162 void CommitAsyncFlushesHigh();
156 163
157 /// Pop asynchronous downloads 164 /// Pop asynchronous downloads
158 void PopAsyncFlushes(); 165 void PopAsyncFlushes();
159 166
167 [[nodiscard]] bool DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount);
168
160 /// Return true when a CPU region is modified from the GPU 169 /// Return true when a CPU region is modified from the GPU
161 [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); 170 [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size);
162 171
172 /// Return true when a CPU region is modified from the CPU
173 [[nodiscard]] bool IsRegionCpuModified(VAddr addr, size_t size);
174
163 std::mutex mutex; 175 std::mutex mutex;
164 176
165private: 177private:
@@ -190,6 +202,36 @@ private:
190 } 202 }
191 } 203 }
192 204
205 template <typename Func>
206 void ForEachWrittenRange(VAddr cpu_addr, u64 size, Func&& func) {
207 const VAddr start_address = cpu_addr;
208 const VAddr end_address = start_address + size;
209 const VAddr search_base =
210 static_cast<VAddr>(std::min<s64>(0LL, static_cast<s64>(start_address - size)));
211 const IntervalType search_interval{search_base, search_base + 1};
212 auto it = common_ranges.lower_bound(search_interval);
213 if (it == common_ranges.end()) {
214 it = common_ranges.begin();
215 }
216 for (; it != common_ranges.end(); it++) {
217 VAddr inter_addr_end = it->upper();
218 VAddr inter_addr = it->lower();
219 if (inter_addr >= end_address) {
220 break;
221 }
222 if (inter_addr_end <= start_address) {
223 continue;
224 }
225 if (inter_addr_end > end_address) {
226 inter_addr_end = end_address;
227 }
228 if (inter_addr < start_address) {
229 inter_addr = start_address;
230 }
231 func(inter_addr, inter_addr_end);
232 }
233 }
234
193 static bool IsRangeGranular(VAddr cpu_addr, size_t size) { 235 static bool IsRangeGranular(VAddr cpu_addr, size_t size) {
194 return (cpu_addr & ~Core::Memory::PAGE_MASK) == 236 return (cpu_addr & ~Core::Memory::PAGE_MASK) ==
195 ((cpu_addr + size) & ~Core::Memory::PAGE_MASK); 237 ((cpu_addr + size) & ~Core::Memory::PAGE_MASK);
@@ -272,8 +314,6 @@ private:
272 314
273 void DeleteBuffer(BufferId buffer_id); 315 void DeleteBuffer(BufferId buffer_id);
274 316
275 void ReplaceBufferDownloads(BufferId old_buffer_id, BufferId new_buffer_id);
276
277 void NotifyBufferDeletion(); 317 void NotifyBufferDeletion();
278 318
279 [[nodiscard]] Binding StorageBufferBinding(GPUVAddr ssbo_addr) const; 319 [[nodiscard]] Binding StorageBufferBinding(GPUVAddr ssbo_addr) const;
@@ -327,9 +367,9 @@ private:
327 367
328 std::vector<BufferId> cached_write_buffer_ids; 368 std::vector<BufferId> cached_write_buffer_ids;
329 369
330 // TODO: This data structure is not optimal and it should be reworked 370 IntervalSet uncommitted_ranges;
331 std::vector<BufferId> uncommitted_downloads; 371 IntervalSet common_ranges;
332 std::deque<std::vector<BufferId>> committed_downloads; 372 std::deque<IntervalSet> committed_ranges;
333 373
334 size_t immediate_buffer_capacity = 0; 374 size_t immediate_buffer_capacity = 0;
335 std::unique_ptr<u8[]> immediate_buffer_alloc; 375 std::unique_ptr<u8[]> immediate_buffer_alloc;
@@ -352,6 +392,7 @@ BufferCache<P>::BufferCache(VideoCore::RasterizerInterface& rasterizer_,
352 // Ensure the first slot is used for the null buffer 392 // Ensure the first slot is used for the null buffer
353 void(slot_buffers.insert(runtime, NullBufferParams{})); 393 void(slot_buffers.insert(runtime, NullBufferParams{}));
354 deletion_iterator = slot_buffers.end(); 394 deletion_iterator = slot_buffers.end();
395 common_ranges.clear();
355} 396}
356 397
357template <class P> 398template <class P>
@@ -422,6 +463,68 @@ void BufferCache<P>::DownloadMemory(VAddr cpu_addr, u64 size) {
422} 463}
423 464
424template <class P> 465template <class P>
466bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) {
467 const std::optional<VAddr> cpu_src_address = gpu_memory.GpuToCpuAddress(src_address);
468 const std::optional<VAddr> cpu_dest_address = gpu_memory.GpuToCpuAddress(dest_address);
469 if (!cpu_src_address || !cpu_dest_address) {
470 return false;
471 }
472 const bool source_dirty = IsRegionGpuModified(*cpu_src_address, amount);
473 const bool dest_dirty = IsRegionGpuModified(*cpu_dest_address, amount);
474 if (!source_dirty && !dest_dirty) {
475 return false;
476 }
477
478 const IntervalType subtract_interval{*cpu_dest_address, *cpu_dest_address + amount};
479 uncommitted_ranges.subtract(subtract_interval);
480 for (auto& interval_set : committed_ranges) {
481 interval_set.subtract(subtract_interval);
482 }
483
484 BufferId buffer_a;
485 BufferId buffer_b;
486 do {
487 has_deleted_buffers = false;
488 buffer_a = FindBuffer(*cpu_src_address, static_cast<u32>(amount));
489 buffer_b = FindBuffer(*cpu_dest_address, static_cast<u32>(amount));
490 } while (has_deleted_buffers);
491 auto& src_buffer = slot_buffers[buffer_a];
492 auto& dest_buffer = slot_buffers[buffer_b];
493 SynchronizeBuffer(src_buffer, *cpu_src_address, static_cast<u32>(amount));
494 SynchronizeBuffer(dest_buffer, *cpu_dest_address, static_cast<u32>(amount));
495 std::array copies{BufferCopy{
496 .src_offset = src_buffer.Offset(*cpu_src_address),
497 .dst_offset = dest_buffer.Offset(*cpu_dest_address),
498 .size = amount,
499 }};
500
501 boost::container::small_vector<IntervalType, 4> tmp_intervals;
502 auto mirror = [&](VAddr base_address, VAddr base_address_end) {
503 const u64 size = base_address_end - base_address;
504 const VAddr diff = base_address - *cpu_src_address;
505 const VAddr new_base_address = *cpu_dest_address + diff;
506 const IntervalType add_interval{new_base_address, new_base_address + size};
507 uncommitted_ranges.add(add_interval);
508 tmp_intervals.push_back(add_interval);
509 };
510 ForEachWrittenRange(*cpu_src_address, amount, mirror);
511 // This subtraction in this order is important for overlapping copies.
512 common_ranges.subtract(subtract_interval);
513 for (const IntervalType add_interval : tmp_intervals) {
514 common_ranges.add(add_interval);
515 }
516
517 runtime.CopyBuffer(dest_buffer, src_buffer, copies);
518 if (source_dirty) {
519 dest_buffer.MarkRegionAsGpuModified(*cpu_dest_address, amount);
520 }
521 std::vector<u8> tmp_buffer(amount);
522 cpu_memory.ReadBlockUnsafe(*cpu_src_address, tmp_buffer.data(), amount);
523 cpu_memory.WriteBlockUnsafe(*cpu_dest_address, tmp_buffer.data(), amount);
524 return true;
525}
526
527template <class P>
425void BufferCache<P>::BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, 528void BufferCache<P>::BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr,
426 u32 size) { 529 u32 size) {
427 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); 530 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
@@ -547,29 +650,30 @@ void BufferCache<P>::FlushCachedWrites() {
547 650
548template <class P> 651template <class P>
549bool BufferCache<P>::HasUncommittedFlushes() const noexcept { 652bool BufferCache<P>::HasUncommittedFlushes() const noexcept {
550 return !uncommitted_downloads.empty(); 653 return !uncommitted_ranges.empty() || !committed_ranges.empty();
551} 654}
552 655
553template <class P> 656template <class P>
554bool BufferCache<P>::ShouldWaitAsyncFlushes() const noexcept { 657void BufferCache<P>::AccumulateFlushes() {
555 return !committed_downloads.empty() && !committed_downloads.front().empty(); 658 if (Settings::values.gpu_accuracy.GetValue() != Settings::GPUAccuracy::High) {
659 uncommitted_ranges.clear();
660 return;
661 }
662 if (uncommitted_ranges.empty()) {
663 return;
664 }
665 committed_ranges.emplace_back(std::move(uncommitted_ranges));
556} 666}
557 667
558template <class P> 668template <class P>
559void BufferCache<P>::CommitAsyncFlushes() { 669bool BufferCache<P>::ShouldWaitAsyncFlushes() const noexcept {
560 // This is intentionally passing the value by copy 670 return false;
561 committed_downloads.push_front(uncommitted_downloads);
562 uncommitted_downloads.clear();
563} 671}
564 672
565template <class P> 673template <class P>
566void BufferCache<P>::PopAsyncFlushes() { 674void BufferCache<P>::CommitAsyncFlushesHigh() {
567 if (committed_downloads.empty()) { 675 AccumulateFlushes();
568 return; 676 if (committed_ranges.empty()) {
569 }
570 auto scope_exit_pop_download = detail::ScopeExit([this] { committed_downloads.pop_back(); });
571 const std::span<const BufferId> download_ids = committed_downloads.back();
572 if (download_ids.empty()) {
573 return; 677 return;
574 } 678 }
575 MICROPROFILE_SCOPE(GPU_DownloadMemory); 679 MICROPROFILE_SCOPE(GPU_DownloadMemory);
@@ -577,20 +681,43 @@ void BufferCache<P>::PopAsyncFlushes() {
577 boost::container::small_vector<std::pair<BufferCopy, BufferId>, 1> downloads; 681 boost::container::small_vector<std::pair<BufferCopy, BufferId>, 1> downloads;
578 u64 total_size_bytes = 0; 682 u64 total_size_bytes = 0;
579 u64 largest_copy = 0; 683 u64 largest_copy = 0;
580 for (const BufferId buffer_id : download_ids) { 684 for (const IntervalSet& intervals : committed_ranges) {
581 slot_buffers[buffer_id].ForEachDownloadRange([&](u64 range_offset, u64 range_size) { 685 for (auto& interval : intervals) {
582 downloads.push_back({ 686 const std::size_t size = interval.upper() - interval.lower();
583 BufferCopy{ 687 const VAddr cpu_addr = interval.lower();
584 .src_offset = range_offset, 688 ForEachBufferInRange(cpu_addr, size, [&](BufferId buffer_id, Buffer& buffer) {
585 .dst_offset = total_size_bytes, 689 boost::container::small_vector<BufferCopy, 1> copies;
586 .size = range_size, 690 buffer.ForEachDownloadRangeAndClear(
587 }, 691 cpu_addr, size, [&](u64 range_offset, u64 range_size) {
588 buffer_id, 692 const VAddr buffer_addr = buffer.CpuAddr();
693 const auto add_download = [&](VAddr start, VAddr end) {
694 const u64 new_offset = start - buffer_addr;
695 const u64 new_size = end - start;
696 downloads.push_back({
697 BufferCopy{
698 .src_offset = new_offset,
699 .dst_offset = total_size_bytes,
700 .size = new_size,
701 },
702 buffer_id,
703 });
704 // Align up to avoid cache conflicts
705 constexpr u64 align = 256ULL;
706 constexpr u64 mask = ~(align - 1ULL);
707 total_size_bytes += (new_size + align - 1) & mask;
708 largest_copy = std::max(largest_copy, new_size);
709 };
710
711 const VAddr start_address = buffer_addr + range_offset;
712 const VAddr end_address = start_address + range_size;
713 ForEachWrittenRange(start_address, range_size, add_download);
714 const IntervalType subtract_interval{start_address, end_address};
715 common_ranges.subtract(subtract_interval);
716 });
589 }); 717 });
590 total_size_bytes += range_size; 718 }
591 largest_copy = std::max(largest_copy, range_size);
592 });
593 } 719 }
720 committed_ranges.clear();
594 if (downloads.empty()) { 721 if (downloads.empty()) {
595 return; 722 return;
596 } 723 }
@@ -623,6 +750,19 @@ void BufferCache<P>::PopAsyncFlushes() {
623} 750}
624 751
625template <class P> 752template <class P>
753void BufferCache<P>::CommitAsyncFlushes() {
754 if (Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::High) {
755 CommitAsyncFlushesHigh();
756 } else {
757 uncommitted_ranges.clear();
758 committed_ranges.clear();
759 }
760}
761
762template <class P>
763void BufferCache<P>::PopAsyncFlushes() {}
764
765template <class P>
626bool BufferCache<P>::IsRegionGpuModified(VAddr addr, size_t size) { 766bool BufferCache<P>::IsRegionGpuModified(VAddr addr, size_t size) {
627 const u64 page_end = Common::DivCeil(addr + size, PAGE_SIZE); 767 const u64 page_end = Common::DivCeil(addr + size, PAGE_SIZE);
628 for (u64 page = addr >> PAGE_BITS; page < page_end;) { 768 for (u64 page = addr >> PAGE_BITS; page < page_end;) {
@@ -642,6 +782,25 @@ bool BufferCache<P>::IsRegionGpuModified(VAddr addr, size_t size) {
642} 782}
643 783
644template <class P> 784template <class P>
785bool BufferCache<P>::IsRegionCpuModified(VAddr addr, size_t size) {
786 const u64 page_end = Common::DivCeil(addr + size, PAGE_SIZE);
787 for (u64 page = addr >> PAGE_BITS; page < page_end;) {
788 const BufferId image_id = page_table[page];
789 if (!image_id) {
790 ++page;
791 continue;
792 }
793 Buffer& buffer = slot_buffers[image_id];
794 if (buffer.IsRegionCpuModified(addr, size)) {
795 return true;
796 }
797 const VAddr end_addr = buffer.CpuAddr() + buffer.SizeBytes();
798 page = Common::DivCeil(end_addr, PAGE_SIZE);
799 }
800 return false;
801}
802
803template <class P>
645void BufferCache<P>::BindHostIndexBuffer() { 804void BufferCache<P>::BindHostIndexBuffer() {
646 Buffer& buffer = slot_buffers[index_buffer.buffer_id]; 805 Buffer& buffer = slot_buffers[index_buffer.buffer_id];
647 TouchBuffer(buffer); 806 TouchBuffer(buffer);
@@ -649,7 +808,9 @@ void BufferCache<P>::BindHostIndexBuffer() {
649 const u32 size = index_buffer.size; 808 const u32 size = index_buffer.size;
650 SynchronizeBuffer(buffer, index_buffer.cpu_addr, size); 809 SynchronizeBuffer(buffer, index_buffer.cpu_addr, size);
651 if constexpr (HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) { 810 if constexpr (HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) {
652 runtime.BindIndexBuffer(buffer, offset, size); 811 const u32 new_offset = offset + maxwell3d.regs.index_array.first *
812 maxwell3d.regs.index_array.FormatSizeInBytes();
813 runtime.BindIndexBuffer(buffer, new_offset, size);
653 } else { 814 } else {
654 runtime.BindIndexBuffer(maxwell3d.regs.draw.topology, maxwell3d.regs.index_array.format, 815 runtime.BindIndexBuffer(maxwell3d.regs.draw.topology, maxwell3d.regs.index_array.format,
655 maxwell3d.regs.index_array.first, maxwell3d.regs.index_array.count, 816 maxwell3d.regs.index_array.first, maxwell3d.regs.index_array.count,
@@ -863,7 +1024,7 @@ void BufferCache<P>::UpdateIndexBuffer() {
863 const GPUVAddr gpu_addr_end = index_array.EndAddress(); 1024 const GPUVAddr gpu_addr_end = index_array.EndAddress();
864 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr_begin); 1025 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr_begin);
865 const u32 address_size = static_cast<u32>(gpu_addr_end - gpu_addr_begin); 1026 const u32 address_size = static_cast<u32>(gpu_addr_end - gpu_addr_begin);
866 const u32 draw_size = index_array.count * index_array.FormatSizeInBytes(); 1027 const u32 draw_size = (index_array.count + index_array.first) * index_array.FormatSizeInBytes();
867 const u32 size = std::min(address_size, draw_size); 1028 const u32 size = std::min(address_size, draw_size);
868 if (size == 0 || !cpu_addr) { 1029 if (size == 0 || !cpu_addr) {
869 index_buffer = NULL_BINDING; 1030 index_buffer = NULL_BINDING;
@@ -1010,16 +1171,16 @@ void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 s
1010 Buffer& buffer = slot_buffers[buffer_id]; 1171 Buffer& buffer = slot_buffers[buffer_id];
1011 buffer.MarkRegionAsGpuModified(cpu_addr, size); 1172 buffer.MarkRegionAsGpuModified(cpu_addr, size);
1012 1173
1013 const bool is_accuracy_high = Settings::IsGPULevelHigh(); 1174 const IntervalType base_interval{cpu_addr, cpu_addr + size};
1175 common_ranges.add(base_interval);
1176
1177 const bool is_accuracy_high =
1178 Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::High;
1014 const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue(); 1179 const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue();
1015 if (!is_accuracy_high || !is_async) { 1180 if (!is_async && !is_accuracy_high) {
1016 return;
1017 }
1018 if (std::ranges::find(uncommitted_downloads, buffer_id) != uncommitted_downloads.end()) {
1019 // Already inserted
1020 return; 1181 return;
1021 } 1182 }
1022 uncommitted_downloads.push_back(buffer_id); 1183 uncommitted_ranges.add(base_interval);
1023} 1184}
1024 1185
1025template <class P> 1186template <class P>
@@ -1103,7 +1264,6 @@ void BufferCache<P>::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id,
1103 if (!copies.empty()) { 1264 if (!copies.empty()) {
1104 runtime.CopyBuffer(slot_buffers[new_buffer_id], overlap, copies); 1265 runtime.CopyBuffer(slot_buffers[new_buffer_id], overlap, copies);
1105 } 1266 }
1106 ReplaceBufferDownloads(overlap_id, new_buffer_id);
1107 DeleteBuffer(overlap_id); 1267 DeleteBuffer(overlap_id);
1108} 1268}
1109 1269
@@ -1244,14 +1404,28 @@ void BufferCache<P>::DownloadBufferMemory(Buffer& buffer, VAddr cpu_addr, u64 si
1244 boost::container::small_vector<BufferCopy, 1> copies; 1404 boost::container::small_vector<BufferCopy, 1> copies;
1245 u64 total_size_bytes = 0; 1405 u64 total_size_bytes = 0;
1246 u64 largest_copy = 0; 1406 u64 largest_copy = 0;
1247 buffer.ForEachDownloadRange(cpu_addr, size, [&](u64 range_offset, u64 range_size) { 1407 buffer.ForEachDownloadRangeAndClear(cpu_addr, size, [&](u64 range_offset, u64 range_size) {
1248 copies.push_back(BufferCopy{ 1408 const VAddr buffer_addr = buffer.CpuAddr();
1249 .src_offset = range_offset, 1409 const auto add_download = [&](VAddr start, VAddr end) {
1250 .dst_offset = total_size_bytes, 1410 const u64 new_offset = start - buffer_addr;
1251 .size = range_size, 1411 const u64 new_size = end - start;
1252 }); 1412 copies.push_back(BufferCopy{
1253 total_size_bytes += range_size; 1413 .src_offset = new_offset,
1254 largest_copy = std::max(largest_copy, range_size); 1414 .dst_offset = total_size_bytes,
1415 .size = new_size,
1416 });
1417 // Align up to avoid cache conflicts
1418 constexpr u64 align = 256ULL;
1419 constexpr u64 mask = ~(align - 1ULL);
1420 total_size_bytes += (new_size + align - 1) & mask;
1421 largest_copy = std::max(largest_copy, new_size);
1422 };
1423
1424 const VAddr start_address = buffer_addr + range_offset;
1425 const VAddr end_address = start_address + range_size;
1426 ForEachWrittenRange(start_address, range_size, add_download);
1427 const IntervalType subtract_interval{start_address, end_address};
1428 common_ranges.subtract(subtract_interval);
1255 }); 1429 });
1256 if (total_size_bytes == 0) { 1430 if (total_size_bytes == 0) {
1257 return; 1431 return;
@@ -1316,18 +1490,6 @@ void BufferCache<P>::DeleteBuffer(BufferId buffer_id) {
1316} 1490}
1317 1491
1318template <class P> 1492template <class P>
1319void BufferCache<P>::ReplaceBufferDownloads(BufferId old_buffer_id, BufferId new_buffer_id) {
1320 const auto replace = [old_buffer_id, new_buffer_id](std::vector<BufferId>& buffers) {
1321 std::ranges::replace(buffers, old_buffer_id, new_buffer_id);
1322 if (auto it = std::ranges::find(buffers, new_buffer_id); it != buffers.end()) {
1323 buffers.erase(std::remove(it + 1, buffers.end(), new_buffer_id), buffers.end());
1324 }
1325 };
1326 replace(uncommitted_downloads);
1327 std::ranges::for_each(committed_downloads, replace);
1328}
1329
1330template <class P>
1331void BufferCache<P>::NotifyBufferDeletion() { 1493void BufferCache<P>::NotifyBufferDeletion() {
1332 if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { 1494 if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
1333 dirty_uniform_buffers.fill(~u32{0}); 1495 dirty_uniform_buffers.fill(~u32{0});
@@ -1349,15 +1511,9 @@ typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr s
1349 if (!cpu_addr || size == 0) { 1511 if (!cpu_addr || size == 0) {
1350 return NULL_BINDING; 1512 return NULL_BINDING;
1351 } 1513 }
1352 // HACK(Rodrigo): This is the number of bytes bound in host beyond the guest API's range.
1353 // It exists due to some games like Astral Chain operate out of bounds.
1354 // Binding the whole map range would be technically correct, but games have large maps that make
1355 // this approach unaffordable for now.
1356 static constexpr u32 arbitrary_extra_bytes = 0xc000;
1357 const u32 bytes_to_map_end = static_cast<u32>(gpu_memory.BytesToMapEnd(gpu_addr));
1358 const Binding binding{ 1514 const Binding binding{
1359 .cpu_addr = *cpu_addr, 1515 .cpu_addr = *cpu_addr,
1360 .size = std::min(size + arbitrary_extra_bytes, bytes_to_map_end), 1516 .size = size,
1361 .buffer_id = BufferId{}, 1517 .buffer_id = BufferId{},
1362 }; 1518 };
1363 return binding; 1519 return binding;
diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp
index ff3db0aee..ffb7c82a1 100644
--- a/src/video_core/command_classes/vic.cpp
+++ b/src/video_core/command_classes/vic.cpp
@@ -129,28 +129,27 @@ void Vic::Execute() {
129 129
130 const std::size_t surface_width = config.surface_width_minus1 + 1; 130 const std::size_t surface_width = config.surface_width_minus1 + 1;
131 const std::size_t surface_height = config.surface_height_minus1 + 1; 131 const std::size_t surface_height = config.surface_height_minus1 + 1;
132 const std::size_t half_width = surface_width / 2; 132 const auto frame_width = std::min(surface_width, static_cast<size_t>(frame->width));
133 const std::size_t half_height = config.surface_height_minus1 / 2; 133 const auto frame_height = std::min(surface_height, static_cast<size_t>(frame->height));
134 const std::size_t half_width = frame_width / 2;
135 const std::size_t half_height = frame_height / 2;
134 const std::size_t aligned_width = (surface_width + 0xff) & ~0xff; 136 const std::size_t aligned_width = (surface_width + 0xff) & ~0xff;
135 137
136 const auto* luma_ptr = frame->data[0]; 138 const auto* luma_ptr = frame->data[0];
137 const auto* chroma_b_ptr = frame->data[1]; 139 const auto* chroma_b_ptr = frame->data[1];
138 const auto* chroma_r_ptr = frame->data[2]; 140 const auto* chroma_r_ptr = frame->data[2];
139 const auto stride = frame->linesize[0]; 141 const auto stride = static_cast<size_t>(frame->linesize[0]);
140 const auto half_stride = frame->linesize[1]; 142 const auto half_stride = static_cast<size_t>(frame->linesize[1]);
141 143
142 luma_buffer.resize(aligned_width * surface_height); 144 luma_buffer.resize(aligned_width * surface_height);
143 chroma_buffer.resize(aligned_width * half_height); 145 chroma_buffer.resize(aligned_width * surface_height / 2);
144 146
145 // Populate luma buffer 147 // Populate luma buffer
146 for (std::size_t y = 0; y < surface_height - 1; ++y) { 148 for (std::size_t y = 0; y < frame_height; ++y) {
147 const std::size_t src = y * stride; 149 const std::size_t src = y * stride;
148 const std::size_t dst = y * aligned_width; 150 const std::size_t dst = y * aligned_width;
149 151 for (std::size_t x = 0; x < frame_width; ++x) {
150 const std::size_t size = surface_width; 152 luma_buffer[dst + x] = luma_ptr[src + x];
151
152 for (std::size_t offset = 0; offset < size; ++offset) {
153 luma_buffer[dst + offset] = luma_ptr[src + offset];
154 } 153 }
155 } 154 }
156 gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), 155 gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(),
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp
index 8b33c04ab..8d28bd884 100644
--- a/src/video_core/dma_pusher.cpp
+++ b/src/video_core/dma_pusher.cpp
@@ -4,6 +4,7 @@
4 4
5#include "common/cityhash.h" 5#include "common/cityhash.h"
6#include "common/microprofile.h" 6#include "common/microprofile.h"
7#include "common/settings.h"
7#include "core/core.h" 8#include "core/core.h"
8#include "core/memory.h" 9#include "core/memory.h"
9#include "video_core/dma_pusher.h" 10#include "video_core/dma_pusher.h"
@@ -76,8 +77,13 @@ bool DmaPusher::Step() {
76 77
77 // Push buffer non-empty, read a word 78 // Push buffer non-empty, read a word
78 command_headers.resize(command_list_header.size); 79 command_headers.resize(command_list_header.size);
79 gpu.MemoryManager().ReadBlockUnsafe(dma_get, command_headers.data(), 80 if (Settings::IsGPULevelHigh()) {
80 command_list_header.size * sizeof(u32)); 81 gpu.MemoryManager().ReadBlock(dma_get, command_headers.data(),
82 command_list_header.size * sizeof(u32));
83 } else {
84 gpu.MemoryManager().ReadBlockUnsafe(dma_get, command_headers.data(),
85 command_list_header.size * sizeof(u32));
86 }
81 } 87 }
82 for (std::size_t index = 0; index < command_headers.size();) { 88 for (std::size_t index = 0; index < command_headers.size();) {
83 const CommandHeader& command_header = command_headers[index]; 89 const CommandHeader& command_header = command_headers[index];
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index 2ee980bab..24481952b 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -21,6 +21,10 @@ MaxwellDMA::MaxwellDMA(Core::System& system_, MemoryManager& memory_manager_)
21 21
22MaxwellDMA::~MaxwellDMA() = default; 22MaxwellDMA::~MaxwellDMA() = default;
23 23
24void MaxwellDMA::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) {
25 rasterizer = rasterizer_;
26}
27
24void MaxwellDMA::CallMethod(u32 method, u32 method_argument, bool is_last_call) { 28void MaxwellDMA::CallMethod(u32 method, u32 method_argument, bool is_last_call) {
25 ASSERT_MSG(method < NUM_REGS, "Invalid MaxwellDMA register"); 29 ASSERT_MSG(method < NUM_REGS, "Invalid MaxwellDMA register");
26 30
@@ -44,7 +48,6 @@ void MaxwellDMA::Launch() {
44 48
45 // TODO(Subv): Perform more research and implement all features of this engine. 49 // TODO(Subv): Perform more research and implement all features of this engine.
46 const LaunchDMA& launch = regs.launch_dma; 50 const LaunchDMA& launch = regs.launch_dma;
47 ASSERT(launch.remap_enable == 0);
48 ASSERT(launch.semaphore_type == LaunchDMA::SemaphoreType::NONE); 51 ASSERT(launch.semaphore_type == LaunchDMA::SemaphoreType::NONE);
49 ASSERT(launch.interrupt_type == LaunchDMA::InterruptType::NONE); 52 ASSERT(launch.interrupt_type == LaunchDMA::InterruptType::NONE);
50 ASSERT(launch.data_transfer_type == LaunchDMA::DataTransferType::NON_PIPELINED); 53 ASSERT(launch.data_transfer_type == LaunchDMA::DataTransferType::NON_PIPELINED);
@@ -77,11 +80,29 @@ void MaxwellDMA::CopyPitchToPitch() {
77 // When `multi_line_enable` bit is disabled the copy is performed as if we were copying a 1D 80 // When `multi_line_enable` bit is disabled the copy is performed as if we were copying a 1D
78 // buffer of length `line_length_in`. 81 // buffer of length `line_length_in`.
79 // Otherwise we copy a 2D image of dimensions (line_length_in, line_count). 82 // Otherwise we copy a 2D image of dimensions (line_length_in, line_count).
83 auto& accelerate = rasterizer->AccessAccelerateDMA();
80 if (!regs.launch_dma.multi_line_enable) { 84 if (!regs.launch_dma.multi_line_enable) {
81 memory_manager.CopyBlock(regs.offset_out, regs.offset_in, regs.line_length_in); 85 const bool is_buffer_clear = regs.launch_dma.remap_enable != 0 &&
86 regs.remap_const.dst_x == RemapConst::Swizzle::CONST_A;
87 // TODO: allow multisized components.
88 if (is_buffer_clear) {
89 ASSERT(regs.remap_const.component_size_minus_one == 3);
90 std::vector<u32> tmp_buffer(regs.line_length_in, regs.remap_consta_value);
91 memory_manager.WriteBlock(regs.offset_out, reinterpret_cast<u8*>(tmp_buffer.data()),
92 regs.line_length_in * sizeof(u32));
93 return;
94 }
95 UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0);
96 if (!accelerate.BufferCopy(regs.offset_in, regs.offset_out, regs.line_length_in)) {
97 std::vector<u8> tmp_buffer(regs.line_length_in);
98 memory_manager.ReadBlockUnsafe(regs.offset_in, tmp_buffer.data(), regs.line_length_in);
99 memory_manager.WriteBlock(regs.offset_out, tmp_buffer.data(), regs.line_length_in);
100 }
82 return; 101 return;
83 } 102 }
84 103
104 UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0);
105
85 // Perform a line-by-line copy. 106 // Perform a line-by-line copy.
86 // We're going to take a subrect of size (line_length_in, line_count) from the source rectangle. 107 // We're going to take a subrect of size (line_length_in, line_count) from the source rectangle.
87 // There is no need to manually flush/invalidate the regions because CopyBlock does that for us. 108 // There is no need to manually flush/invalidate the regions because CopyBlock does that for us.
@@ -105,6 +126,7 @@ void MaxwellDMA::CopyBlockLinearToPitch() {
105 } 126 }
106 127
107 // Deswizzle the input and copy it over. 128 // Deswizzle the input and copy it over.
129 UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0);
108 const u32 bytes_per_pixel = regs.pitch_out / regs.line_length_in; 130 const u32 bytes_per_pixel = regs.pitch_out / regs.line_length_in;
109 const Parameters& src_params = regs.src_params; 131 const Parameters& src_params = regs.src_params;
110 const u32 width = src_params.width; 132 const u32 width = src_params.width;
@@ -134,6 +156,7 @@ void MaxwellDMA::CopyBlockLinearToPitch() {
134 156
135void MaxwellDMA::CopyPitchToBlockLinear() { 157void MaxwellDMA::CopyPitchToBlockLinear() {
136 UNIMPLEMENTED_IF_MSG(regs.dst_params.block_size.width != 0, "Block width is not one"); 158 UNIMPLEMENTED_IF_MSG(regs.dst_params.block_size.width != 0, "Block width is not one");
159 UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0);
137 160
138 const auto& dst_params = regs.dst_params; 161 const auto& dst_params = regs.dst_params;
139 const u32 bytes_per_pixel = regs.pitch_in / regs.line_length_in; 162 const u32 bytes_per_pixel = regs.pitch_in / regs.line_length_in;
@@ -156,13 +179,8 @@ void MaxwellDMA::CopyPitchToBlockLinear() {
156 write_buffer.resize(dst_size); 179 write_buffer.resize(dst_size);
157 } 180 }
158 181
159 if (Settings::IsGPULevelExtreme()) { 182 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size);
160 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size); 183 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size);
161 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size);
162 } else {
163 memory_manager.ReadBlockUnsafe(regs.offset_in, read_buffer.data(), src_size);
164 memory_manager.ReadBlockUnsafe(regs.offset_out, write_buffer.data(), dst_size);
165 }
166 184
167 // If the input is linear and the output is tiled, swizzle the input and copy it over. 185 // If the input is linear and the output is tiled, swizzle the input and copy it over.
168 if (regs.dst_params.block_size.depth > 0) { 186 if (regs.dst_params.block_size.depth > 0) {
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h
index c77f02a22..4ed0d0996 100644
--- a/src/video_core/engines/maxwell_dma.h
+++ b/src/video_core/engines/maxwell_dma.h
@@ -21,8 +21,18 @@ namespace Tegra {
21class MemoryManager; 21class MemoryManager;
22} 22}
23 23
24namespace VideoCore {
25class RasterizerInterface;
26}
27
24namespace Tegra::Engines { 28namespace Tegra::Engines {
25 29
30class AccelerateDMAInterface {
31public:
32 /// Write the value to the register identified by method.
33 virtual bool BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) = 0;
34};
35
26/** 36/**
27 * This engine is known as gk104_copy. Documentation can be found in: 37 * This engine is known as gk104_copy. Documentation can be found in:
28 * https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/dma-copy/clb0b5.h 38 * https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/dma-copy/clb0b5.h
@@ -187,6 +197,8 @@ public:
187 }; 197 };
188 static_assert(sizeof(RemapConst) == 12); 198 static_assert(sizeof(RemapConst) == 12);
189 199
200 void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
201
190 explicit MaxwellDMA(Core::System& system_, MemoryManager& memory_manager_); 202 explicit MaxwellDMA(Core::System& system_, MemoryManager& memory_manager_);
191 ~MaxwellDMA() override; 203 ~MaxwellDMA() override;
192 204
@@ -213,6 +225,7 @@ private:
213 Core::System& system; 225 Core::System& system;
214 226
215 MemoryManager& memory_manager; 227 MemoryManager& memory_manager;
228 VideoCore::RasterizerInterface* rasterizer;
216 229
217 std::vector<u8> read_buffer; 230 std::vector<u8> read_buffer;
218 std::vector<u8> write_buffer; 231 std::vector<u8> write_buffer;
@@ -240,7 +253,9 @@ private:
240 u32 pitch_out; 253 u32 pitch_out;
241 u32 line_length_in; 254 u32 line_length_in;
242 u32 line_count; 255 u32 line_count;
243 u32 reserved06[0xb8]; 256 u32 reserved06[0xb6];
257 u32 remap_consta_value;
258 u32 remap_constb_value;
244 RemapConst remap_const; 259 RemapConst remap_const;
245 Parameters dst_params; 260 Parameters dst_params;
246 u32 reserved07[0x1]; 261 u32 reserved07[0x1];
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h
index f055b61e9..34dc6c596 100644
--- a/src/video_core/fence_manager.h
+++ b/src/video_core/fence_manager.h
@@ -8,6 +8,7 @@
8#include <queue> 8#include <queue>
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/settings.h"
11#include "core/core.h" 12#include "core/core.h"
12#include "video_core/delayed_destruction_ring.h" 13#include "video_core/delayed_destruction_ring.h"
13#include "video_core/gpu.h" 14#include "video_core/gpu.h"
@@ -53,6 +54,12 @@ public:
53 delayed_destruction_ring.Tick(); 54 delayed_destruction_ring.Tick();
54 } 55 }
55 56
57 // Unlike other fences, this one doesn't
58 void SignalOrdering() {
59 std::scoped_lock lock{buffer_cache.mutex};
60 buffer_cache.AccumulateFlushes();
61 }
62
56 void SignalSemaphore(GPUVAddr addr, u32 value) { 63 void SignalSemaphore(GPUVAddr addr, u32 value) {
57 TryReleasePendingFences(); 64 TryReleasePendingFences();
58 const bool should_flush = ShouldFlush(); 65 const bool should_flush = ShouldFlush();
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 35cc561be..ff024f530 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -50,6 +50,7 @@ void GPU::BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer_) {
50 maxwell_3d->BindRasterizer(rasterizer); 50 maxwell_3d->BindRasterizer(rasterizer);
51 fermi_2d->BindRasterizer(rasterizer); 51 fermi_2d->BindRasterizer(rasterizer);
52 kepler_compute->BindRasterizer(rasterizer); 52 kepler_compute->BindRasterizer(rasterizer);
53 maxwell_dma->BindRasterizer(rasterizer);
53} 54}
54 55
55Engines::Maxwell3D& GPU::Maxwell3D() { 56Engines::Maxwell3D& GPU::Maxwell3D() {
@@ -268,11 +269,13 @@ void GPU::CallPullerMethod(const MethodCall& method_call) {
268 case BufferMethods::SemaphoreAddressHigh: 269 case BufferMethods::SemaphoreAddressHigh:
269 case BufferMethods::SemaphoreAddressLow: 270 case BufferMethods::SemaphoreAddressLow:
270 case BufferMethods::SemaphoreSequence: 271 case BufferMethods::SemaphoreSequence:
271 case BufferMethods::RefCnt:
272 case BufferMethods::UnkCacheFlush: 272 case BufferMethods::UnkCacheFlush:
273 case BufferMethods::WrcacheFlush: 273 case BufferMethods::WrcacheFlush:
274 case BufferMethods::FenceValue: 274 case BufferMethods::FenceValue:
275 break; 275 break;
276 case BufferMethods::RefCnt:
277 rasterizer->SignalReference();
278 break;
276 case BufferMethods::FenceAction: 279 case BufferMethods::FenceAction:
277 ProcessFenceActionMethod(); 280 ProcessFenceActionMethod();
278 break; 281 break;
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 0cec4225b..58014c1c3 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -15,7 +15,10 @@
15 15
16namespace Tegra { 16namespace Tegra {
17class MemoryManager; 17class MemoryManager;
18namespace Engines {
19class AccelerateDMAInterface;
18} 20}
21} // namespace Tegra
19 22
20namespace VideoCore { 23namespace VideoCore {
21 24
@@ -63,6 +66,9 @@ public:
63 /// Signal a GPU based syncpoint as a fence 66 /// Signal a GPU based syncpoint as a fence
64 virtual void SignalSyncPoint(u32 value) = 0; 67 virtual void SignalSyncPoint(u32 value) = 0;
65 68
69 /// Signal a GPU based reference as point
70 virtual void SignalReference() = 0;
71
66 /// Release all pending fences. 72 /// Release all pending fences.
67 virtual void ReleaseFences() = 0; 73 virtual void ReleaseFences() = 0;
68 74
@@ -116,6 +122,8 @@ public:
116 return false; 122 return false;
117 } 123 }
118 124
125 [[nodiscard]] virtual Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() = 0;
126
119 /// Attempt to use a faster method to display the framebuffer to screen 127 /// Attempt to use a faster method to display the framebuffer to screen
120 [[nodiscard]] virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config, 128 [[nodiscard]] virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config,
121 VAddr framebuffer_addr, u32 pixel_stride) { 129 VAddr framebuffer_addr, u32 pixel_stride) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 07ad0e205..82c84127a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -171,7 +171,7 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra
171 buffer_cache_runtime(device), 171 buffer_cache_runtime(device),
172 buffer_cache(*this, maxwell3d, kepler_compute, gpu_memory, cpu_memory_, buffer_cache_runtime), 172 buffer_cache(*this, maxwell3d, kepler_compute, gpu_memory, cpu_memory_, buffer_cache_runtime),
173 shader_cache(*this, emu_window_, gpu, maxwell3d, kepler_compute, gpu_memory, device), 173 shader_cache(*this, emu_window_, gpu, maxwell3d, kepler_compute, gpu_memory, device),
174 query_cache(*this, maxwell3d, gpu_memory), 174 query_cache(*this, maxwell3d, gpu_memory), accelerate_dma(buffer_cache),
175 fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache), 175 fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache),
176 async_shaders(emu_window_) { 176 async_shaders(emu_window_) {
177 if (device.UseAsynchronousShaders()) { 177 if (device.UseAsynchronousShaders()) {
@@ -634,6 +634,13 @@ void RasterizerOpenGL::SignalSyncPoint(u32 value) {
634 fence_manager.SignalSyncPoint(value); 634 fence_manager.SignalSyncPoint(value);
635} 635}
636 636
637void RasterizerOpenGL::SignalReference() {
638 if (!gpu.IsAsync()) {
639 return;
640 }
641 fence_manager.SignalOrdering();
642}
643
637void RasterizerOpenGL::ReleaseFences() { 644void RasterizerOpenGL::ReleaseFences() {
638 if (!gpu.IsAsync()) { 645 if (!gpu.IsAsync()) {
639 return; 646 return;
@@ -650,6 +657,7 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
650 657
651void RasterizerOpenGL::WaitForIdle() { 658void RasterizerOpenGL::WaitForIdle() {
652 glMemoryBarrier(GL_ALL_BARRIER_BITS); 659 glMemoryBarrier(GL_ALL_BARRIER_BITS);
660 SignalReference();
653} 661}
654 662
655void RasterizerOpenGL::FragmentBarrier() { 663void RasterizerOpenGL::FragmentBarrier() {
@@ -693,6 +701,10 @@ bool RasterizerOpenGL::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surf
693 return true; 701 return true;
694} 702}
695 703
704Tegra::Engines::AccelerateDMAInterface& RasterizerOpenGL::AccessAccelerateDMA() {
705 return accelerate_dma;
706}
707
696bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, 708bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
697 VAddr framebuffer_addr, u32 pixel_stride) { 709 VAddr framebuffer_addr, u32 pixel_stride) {
698 if (framebuffer_addr == 0) { 710 if (framebuffer_addr == 0) {
@@ -1388,4 +1400,11 @@ void RasterizerOpenGL::EndTransformFeedback() {
1388 glEndTransformFeedback(); 1400 glEndTransformFeedback();
1389} 1401}
1390 1402
1403AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {}
1404
1405bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) {
1406 std::scoped_lock lock{buffer_cache.mutex};
1407 return buffer_cache.DMACopy(src_address, dest_address, amount);
1408}
1409
1391} // namespace OpenGL 1410} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 482efed7a..ccee9ba33 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -19,6 +19,7 @@
19#include "common/common_types.h" 19#include "common/common_types.h"
20#include "video_core/engines/const_buffer_info.h" 20#include "video_core/engines/const_buffer_info.h"
21#include "video_core/engines/maxwell_3d.h" 21#include "video_core/engines/maxwell_3d.h"
22#include "video_core/engines/maxwell_dma.h"
22#include "video_core/rasterizer_accelerated.h" 23#include "video_core/rasterizer_accelerated.h"
23#include "video_core/rasterizer_interface.h" 24#include "video_core/rasterizer_interface.h"
24#include "video_core/renderer_opengl/gl_buffer_cache.h" 25#include "video_core/renderer_opengl/gl_buffer_cache.h"
@@ -58,6 +59,16 @@ struct BindlessSSBO {
58}; 59};
59static_assert(sizeof(BindlessSSBO) * CHAR_BIT == 128); 60static_assert(sizeof(BindlessSSBO) * CHAR_BIT == 128);
60 61
62class AccelerateDMA : public Tegra::Engines::AccelerateDMAInterface {
63public:
64 explicit AccelerateDMA(BufferCache& buffer_cache);
65
66 bool BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) override;
67
68private:
69 BufferCache& buffer_cache;
70};
71
61class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { 72class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
62public: 73public:
63 explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, 74 explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
@@ -83,6 +94,7 @@ public:
83 void ModifyGPUMemory(GPUVAddr addr, u64 size) override; 94 void ModifyGPUMemory(GPUVAddr addr, u64 size) override;
84 void SignalSemaphore(GPUVAddr addr, u32 value) override; 95 void SignalSemaphore(GPUVAddr addr, u32 value) override;
85 void SignalSyncPoint(u32 value) override; 96 void SignalSyncPoint(u32 value) override;
97 void SignalReference() override;
86 void ReleaseFences() override; 98 void ReleaseFences() override;
87 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 99 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
88 void WaitForIdle() override; 100 void WaitForIdle() override;
@@ -93,6 +105,7 @@ public:
93 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surface& src, 105 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surface& src,
94 const Tegra::Engines::Fermi2D::Surface& dst, 106 const Tegra::Engines::Fermi2D::Surface& dst,
95 const Tegra::Engines::Fermi2D::Config& copy_config) override; 107 const Tegra::Engines::Fermi2D::Config& copy_config) override;
108 Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override;
96 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 109 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
97 u32 pixel_stride) override; 110 u32 pixel_stride) override;
98 void LoadDiskResources(u64 title_id, std::stop_token stop_loading, 111 void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
@@ -233,6 +246,7 @@ private:
233 BufferCache buffer_cache; 246 BufferCache buffer_cache;
234 ShaderCacheOpenGL shader_cache; 247 ShaderCacheOpenGL shader_cache;
235 QueryCache query_cache; 248 QueryCache query_cache;
249 AccelerateDMA accelerate_dma;
236 FenceManagerOpenGL fence_manager; 250 FenceManagerOpenGL fence_manager;
237 251
238 VideoCommon::Shader::AsyncShaders async_shaders; 252 VideoCommon::Shader::AsyncShaders async_shaders;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index a718bff7a..c12929de6 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -229,9 +229,6 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color
229} 229}
230 230
231void RendererOpenGL::InitOpenGLObjects() { 231void RendererOpenGL::InitOpenGLObjects() {
232 glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(),
233 Settings::values.bg_blue.GetValue(), 0.0f);
234
235 // Create shader programs 232 // Create shader programs
236 OGLShader vertex_shader; 233 OGLShader vertex_shader;
237 vertex_shader.Create(HostShaders::OPENGL_PRESENT_VERT, GL_VERTEX_SHADER); 234 vertex_shader.Create(HostShaders::OPENGL_PRESENT_VERT, GL_VERTEX_SHADER);
@@ -337,8 +334,9 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
337void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { 334void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
338 if (renderer_settings.set_background_color) { 335 if (renderer_settings.set_background_color) {
339 // Update background color before drawing 336 // Update background color before drawing
340 glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(), 337 glClearColor(Settings::values.bg_red.GetValue() / 255.0f,
341 Settings::values.bg_blue.GetValue(), 0.0f); 338 Settings::values.bg_green.GetValue() / 255.0f,
339 Settings::values.bg_blue.GetValue() / 255.0f, 1.0f);
342 } 340 }
343 341
344 // Set projection matrix 342 // Set projection matrix
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index a1a32aabe..363134129 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -225,8 +225,11 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, bool
225 descriptor_set = descriptor_sets[image_index], buffer = *buffer, 225 descriptor_set = descriptor_sets[image_index], buffer = *buffer,
226 size = swapchain.GetSize(), pipeline = *pipeline, 226 size = swapchain.GetSize(), pipeline = *pipeline,
227 layout = *pipeline_layout](vk::CommandBuffer cmdbuf) { 227 layout = *pipeline_layout](vk::CommandBuffer cmdbuf) {
228 const f32 bg_red = Settings::values.bg_red.GetValue() / 255.0f;
229 const f32 bg_green = Settings::values.bg_green.GetValue() / 255.0f;
230 const f32 bg_blue = Settings::values.bg_blue.GetValue() / 255.0f;
228 const VkClearValue clear_color{ 231 const VkClearValue clear_color{
229 .color = {.float32 = {0.0f, 0.0f, 0.0f, 0.0f}}, 232 .color = {.float32 = {bg_red, bg_green, bg_blue, 1.0f}},
230 }; 233 };
231 const VkRenderPassBeginInfo renderpass_bi{ 234 const VkRenderPassBeginInfo renderpass_bi{
232 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 235 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
index 205cd3b05..4181d83ee 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
@@ -374,20 +374,20 @@ void ASTCDecoderPass::MakeDataBuffer() {
374 374
375 scheduler.Record([src = staging_ref.buffer, offset = staging_ref.offset, dst = *data_buffer, 375 scheduler.Record([src = staging_ref.buffer, offset = staging_ref.offset, dst = *data_buffer,
376 TOTAL_BUFFER_SIZE](vk::CommandBuffer cmdbuf) { 376 TOTAL_BUFFER_SIZE](vk::CommandBuffer cmdbuf) {
377 cmdbuf.CopyBuffer(src, dst, 377 static constexpr VkMemoryBarrier write_barrier{
378 VkBufferCopy{ 378 .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
379 .srcOffset = offset, 379 .pNext = nullptr,
380 .dstOffset = 0, 380 .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
381 .size = TOTAL_BUFFER_SIZE, 381 .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
382 }); 382 };
383 cmdbuf.PipelineBarrier( 383 const VkBufferCopy copy{
384 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 384 .srcOffset = offset,
385 VkMemoryBarrier{ 385 .dstOffset = 0,
386 .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, 386 .size = TOTAL_BUFFER_SIZE,
387 .pNext = nullptr, 387 };
388 .srcAccessMask = 0, 388 cmdbuf.CopyBuffer(src, dst, copy);
389 .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, 389 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
390 }); 390 0, write_barrier);
391 }); 391 });
392} 392}
393 393
@@ -411,7 +411,7 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map,
411 const VkImageMemoryBarrier image_barrier{ 411 const VkImageMemoryBarrier image_barrier{
412 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 412 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
413 .pNext = nullptr, 413 .pNext = nullptr,
414 .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, 414 .srcAccessMask = is_initialized ? VK_ACCESS_SHADER_WRITE_BIT : VkAccessFlags{},
415 .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, 415 .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
416 .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, 416 .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED,
417 .newLayout = VK_IMAGE_LAYOUT_GENERAL, 417 .newLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -426,7 +426,8 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map,
426 .layerCount = VK_REMAINING_ARRAY_LAYERS, 426 .layerCount = VK_REMAINING_ARRAY_LAYERS,
427 }, 427 },
428 }; 428 };
429 cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT : 0, 429 cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
430 : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
430 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); 431 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier);
431 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); 432 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline);
432 }); 433 });
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index bd4d649cc..a8ffbe6ba 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -251,7 +251,7 @@ RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra
251 buffer_cache(*this, maxwell3d, kepler_compute, gpu_memory, cpu_memory_, buffer_cache_runtime), 251 buffer_cache(*this, maxwell3d, kepler_compute, gpu_memory, cpu_memory_, buffer_cache_runtime),
252 pipeline_cache(*this, gpu, maxwell3d, kepler_compute, gpu_memory, device, scheduler, 252 pipeline_cache(*this, gpu, maxwell3d, kepler_compute, gpu_memory, device, scheduler,
253 descriptor_pool, update_descriptor_queue), 253 descriptor_pool, update_descriptor_queue),
254 query_cache{*this, maxwell3d, gpu_memory, device, scheduler}, 254 query_cache{*this, maxwell3d, gpu_memory, device, scheduler}, accelerate_dma{buffer_cache},
255 fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache, device, scheduler), 255 fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache, device, scheduler),
256 wfi_event(device.GetLogical().CreateEvent()), async_shaders(emu_window_) { 256 wfi_event(device.GetLogical().CreateEvent()), async_shaders(emu_window_) {
257 scheduler.SetQueryCache(query_cache); 257 scheduler.SetQueryCache(query_cache);
@@ -357,11 +357,13 @@ void RasterizerVulkan::Clear() {
357 .height = std::min(clear_rect.rect.extent.height, render_area.height), 357 .height = std::min(clear_rect.rect.extent.height, render_area.height),
358 }; 358 };
359 359
360 if (use_color) { 360 const u32 color_attachment = regs.clear_buffers.RT;
361 const auto attachment_aspect_mask = framebuffer->ImageRanges()[color_attachment].aspectMask;
362 const bool is_color_rt = (attachment_aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != 0;
363 if (use_color && is_color_rt) {
361 VkClearValue clear_value; 364 VkClearValue clear_value;
362 std::memcpy(clear_value.color.float32, regs.clear_color, sizeof(regs.clear_color)); 365 std::memcpy(clear_value.color.float32, regs.clear_color, sizeof(regs.clear_color));
363 366
364 const u32 color_attachment = regs.clear_buffers.RT;
365 scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) { 367 scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) {
366 const VkClearAttachment attachment{ 368 const VkClearAttachment attachment{
367 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 369 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
@@ -580,6 +582,13 @@ void RasterizerVulkan::SignalSyncPoint(u32 value) {
580 fence_manager.SignalSyncPoint(value); 582 fence_manager.SignalSyncPoint(value);
581} 583}
582 584
585void RasterizerVulkan::SignalReference() {
586 if (!gpu.IsAsync()) {
587 return;
588 }
589 fence_manager.SignalOrdering();
590}
591
583void RasterizerVulkan::ReleaseFences() { 592void RasterizerVulkan::ReleaseFences() {
584 if (!gpu.IsAsync()) { 593 if (!gpu.IsAsync()) {
585 return; 594 return;
@@ -612,6 +621,7 @@ void RasterizerVulkan::WaitForIdle() {
612 cmdbuf.SetEvent(event, flags); 621 cmdbuf.SetEvent(event, flags);
613 cmdbuf.WaitEvents(event, flags, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, {}, {}, {}); 622 cmdbuf.WaitEvents(event, flags, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, {}, {}, {});
614 }); 623 });
624 SignalReference();
615} 625}
616 626
617void RasterizerVulkan::FragmentBarrier() { 627void RasterizerVulkan::FragmentBarrier() {
@@ -652,6 +662,10 @@ bool RasterizerVulkan::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surf
652 return true; 662 return true;
653} 663}
654 664
665Tegra::Engines::AccelerateDMAInterface& RasterizerVulkan::AccessAccelerateDMA() {
666 return accelerate_dma;
667}
668
655bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config, 669bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config,
656 VAddr framebuffer_addr, u32 pixel_stride) { 670 VAddr framebuffer_addr, u32 pixel_stride) {
657 if (!framebuffer_addr) { 671 if (!framebuffer_addr) {
@@ -690,6 +704,13 @@ void RasterizerVulkan::FlushWork() {
690 draw_counter = 0; 704 draw_counter = 0;
691} 705}
692 706
707AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {}
708
709bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) {
710 std::scoped_lock lock{buffer_cache.mutex};
711 return buffer_cache.DMACopy(src_address, dest_address, amount);
712}
713
693void RasterizerVulkan::SetupShaderDescriptors( 714void RasterizerVulkan::SetupShaderDescriptors(
694 const std::array<Shader*, Maxwell::MaxShaderProgram>& shaders, bool is_indexed) { 715 const std::array<Shader*, Maxwell::MaxShaderProgram>& shaders, bool is_indexed) {
695 image_view_indices.clear(); 716 image_view_indices.clear();
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 41459c5c5..3a78de258 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -13,6 +13,7 @@
13#include <boost/container/static_vector.hpp> 13#include <boost/container/static_vector.hpp>
14 14
15#include "common/common_types.h" 15#include "common/common_types.h"
16#include "video_core/engines/maxwell_dma.h"
16#include "video_core/rasterizer_accelerated.h" 17#include "video_core/rasterizer_accelerated.h"
17#include "video_core/rasterizer_interface.h" 18#include "video_core/rasterizer_interface.h"
18#include "video_core/renderer_vulkan/blit_image.h" 19#include "video_core/renderer_vulkan/blit_image.h"
@@ -49,6 +50,16 @@ struct VKScreenInfo;
49 50
50class StateTracker; 51class StateTracker;
51 52
53class AccelerateDMA : public Tegra::Engines::AccelerateDMAInterface {
54public:
55 explicit AccelerateDMA(BufferCache& buffer_cache);
56
57 bool BufferCopy(GPUVAddr start_address, GPUVAddr end_address, u64 amount) override;
58
59private:
60 BufferCache& buffer_cache;
61};
62
52class RasterizerVulkan final : public VideoCore::RasterizerAccelerated { 63class RasterizerVulkan final : public VideoCore::RasterizerAccelerated {
53public: 64public:
54 explicit RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, 65 explicit RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
@@ -75,6 +86,7 @@ public:
75 void ModifyGPUMemory(GPUVAddr addr, u64 size) override; 86 void ModifyGPUMemory(GPUVAddr addr, u64 size) override;
76 void SignalSemaphore(GPUVAddr addr, u32 value) override; 87 void SignalSemaphore(GPUVAddr addr, u32 value) override;
77 void SignalSyncPoint(u32 value) override; 88 void SignalSyncPoint(u32 value) override;
89 void SignalReference() override;
78 void ReleaseFences() override; 90 void ReleaseFences() override;
79 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 91 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
80 void WaitForIdle() override; 92 void WaitForIdle() override;
@@ -85,6 +97,7 @@ public:
85 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surface& src, 97 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surface& src,
86 const Tegra::Engines::Fermi2D::Surface& dst, 98 const Tegra::Engines::Fermi2D::Surface& dst,
87 const Tegra::Engines::Fermi2D::Config& copy_config) override; 99 const Tegra::Engines::Fermi2D::Config& copy_config) override;
100 Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override;
88 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 101 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
89 u32 pixel_stride) override; 102 u32 pixel_stride) override;
90 103
@@ -185,6 +198,7 @@ private:
185 BufferCache buffer_cache; 198 BufferCache buffer_cache;
186 VKPipelineCache pipeline_cache; 199 VKPipelineCache pipeline_cache;
187 VKQueryCache query_cache; 200 VKQueryCache query_cache;
201 AccelerateDMA accelerate_dma;
188 VKFenceManager fence_manager; 202 VKFenceManager fence_manager;
189 203
190 vk::Event wfi_event; 204 vk::Event wfi_event;
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index a2ab4d1ee..fd01c902c 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -608,7 +608,10 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
608 const VkImageAspectFlags aspect_mask = ImageAspectMask(src.format); 608 const VkImageAspectFlags aspect_mask = ImageAspectMask(src.format);
609 const bool is_dst_msaa = dst.Samples() != VK_SAMPLE_COUNT_1_BIT; 609 const bool is_dst_msaa = dst.Samples() != VK_SAMPLE_COUNT_1_BIT;
610 const bool is_src_msaa = src.Samples() != VK_SAMPLE_COUNT_1_BIT; 610 const bool is_src_msaa = src.Samples() != VK_SAMPLE_COUNT_1_BIT;
611 ASSERT(aspect_mask == ImageAspectMask(dst.format)); 611 if (aspect_mask != ImageAspectMask(dst.format)) {
612 UNIMPLEMENTED_MSG("Incompatible blit from format {} to {}", src.format, dst.format);
613 return;
614 }
612 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT && !is_src_msaa && !is_dst_msaa) { 615 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT && !is_src_msaa && !is_dst_msaa) {
613 blit_image_helper.BlitColor(dst_framebuffer, src, dst_region, src_region, filter, 616 blit_image_helper.BlitColor(dst_framebuffer, src, dst_region, src_region, filter,
614 operation); 617 operation);
@@ -911,6 +914,7 @@ void Image::UploadMemory(const StagingBufferRef& map,
911 914
912void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { 915void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) {
913 std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); 916 std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask);
917 scheduler->RequestOutsideRenderPassOperationContext();
914 scheduler->Record([buffer = map.buffer, image = *image, aspect_mask = aspect_mask, 918 scheduler->Record([buffer = map.buffer, image = *image, aspect_mask = aspect_mask,
915 vk_copies](vk::CommandBuffer cmdbuf) { 919 vk_copies](vk::CommandBuffer cmdbuf) {
916 const VkImageMemoryBarrier read_barrier{ 920 const VkImageMemoryBarrier read_barrier{
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 01de2d498..85ce06d56 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -599,6 +599,12 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
599 using namespace VideoCommon::Dirty; 599 using namespace VideoCommon::Dirty;
600 auto& flags = maxwell3d.dirty.flags; 600 auto& flags = maxwell3d.dirty.flags;
601 if (!flags[Dirty::RenderTargets]) { 601 if (!flags[Dirty::RenderTargets]) {
602 for (size_t index = 0; index < NUM_RT; ++index) {
603 ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
604 PrepareImageView(color_buffer_id, true, is_clear && IsFullClear(color_buffer_id));
605 }
606 const ImageViewId depth_buffer_id = render_targets.depth_buffer_id;
607 PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
602 return; 608 return;
603 } 609 }
604 flags[Dirty::RenderTargets] = false; 610 flags[Dirty::RenderTargets] = false;
diff --git a/src/video_core/texture_cache/types.h b/src/video_core/texture_cache/types.h
index 9fbdc1ac6..47a11cb2f 100644
--- a/src/video_core/texture_cache/types.h
+++ b/src/video_core/texture_cache/types.h
@@ -133,8 +133,8 @@ struct BufferImageCopy {
133}; 133};
134 134
135struct BufferCopy { 135struct BufferCopy {
136 size_t src_offset; 136 u64 src_offset;
137 size_t dst_offset; 137 u64 dst_offset;
138 size_t size; 138 size_t size;
139}; 139};
140 140
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index c872517b8..59cf2f561 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -169,23 +169,6 @@ template <u32 GOB_EXTENT>
169 return Common::DivCeil(AdjustMipSize(size, level), block_size); 169 return Common::DivCeil(AdjustMipSize(size, level), block_size);
170} 170}
171 171
172[[nodiscard]] constexpr std::pair<int, int> Samples(int num_samples) {
173 switch (num_samples) {
174 case 1:
175 return {1, 1};
176 case 2:
177 return {2, 1};
178 case 4:
179 return {2, 2};
180 case 8:
181 return {4, 2};
182 case 16:
183 return {4, 4};
184 }
185 UNREACHABLE_MSG("Invalid number of samples={}", num_samples);
186 return {1, 1};
187}
188
189[[nodiscard]] constexpr Extent2D DefaultBlockSize(PixelFormat format) { 172[[nodiscard]] constexpr Extent2D DefaultBlockSize(PixelFormat format) {
190 return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; 173 return {DefaultBlockWidth(format), DefaultBlockHeight(format)};
191} 174}
@@ -283,14 +266,13 @@ template <u32 GOB_EXTENT>
283} 266}
284 267
285[[nodiscard]] constexpr LevelInfo MakeLevelInfo(PixelFormat format, Extent3D size, Extent3D block, 268[[nodiscard]] constexpr LevelInfo MakeLevelInfo(PixelFormat format, Extent3D size, Extent3D block,
286 u32 num_samples, u32 tile_width_spacing) { 269 u32 tile_width_spacing) {
287 const auto [samples_x, samples_y] = Samples(num_samples);
288 const u32 bytes_per_block = BytesPerBlock(format); 270 const u32 bytes_per_block = BytesPerBlock(format);
289 return { 271 return {
290 .size = 272 .size =
291 { 273 {
292 .width = size.width * samples_x, 274 .width = size.width,
293 .height = size.height * samples_y, 275 .height = size.height,
294 .depth = size.depth, 276 .depth = size.depth,
295 }, 277 },
296 .block = block, 278 .block = block,
@@ -301,14 +283,12 @@ template <u32 GOB_EXTENT>
301} 283}
302 284
303[[nodiscard]] constexpr LevelInfo MakeLevelInfo(const ImageInfo& info) { 285[[nodiscard]] constexpr LevelInfo MakeLevelInfo(const ImageInfo& info) {
304 return MakeLevelInfo(info.format, info.size, info.block, info.num_samples, 286 return MakeLevelInfo(info.format, info.size, info.block, info.tile_width_spacing);
305 info.tile_width_spacing);
306} 287}
307 288
308[[nodiscard]] constexpr u32 CalculateLevelOffset(PixelFormat format, Extent3D size, Extent3D block, 289[[nodiscard]] constexpr u32 CalculateLevelOffset(PixelFormat format, Extent3D size, Extent3D block,
309 u32 num_samples, u32 tile_width_spacing, 290 u32 tile_width_spacing, u32 level) {
310 u32 level) { 291 const LevelInfo info = MakeLevelInfo(format, size, block, tile_width_spacing);
311 const LevelInfo info = MakeLevelInfo(format, size, block, num_samples, tile_width_spacing);
312 u32 offset = 0; 292 u32 offset = 0;
313 for (u32 current_level = 0; current_level < level; ++current_level) { 293 for (u32 current_level = 0; current_level < level; ++current_level) {
314 offset += CalculateLevelSize(info, current_level); 294 offset += CalculateLevelSize(info, current_level);
@@ -645,8 +625,8 @@ u32 CalculateLayerStride(const ImageInfo& info) noexcept {
645 625
646u32 CalculateLayerSize(const ImageInfo& info) noexcept { 626u32 CalculateLayerSize(const ImageInfo& info) noexcept {
647 ASSERT(info.type != ImageType::Linear); 627 ASSERT(info.type != ImageType::Linear);
648 return CalculateLevelOffset(info.format, info.size, info.block, info.num_samples, 628 return CalculateLevelOffset(info.format, info.size, info.block, info.tile_width_spacing,
649 info.tile_width_spacing, info.resources.levels); 629 info.resources.levels);
650} 630}
651 631
652LevelArray CalculateMipLevelOffsets(const ImageInfo& info) noexcept { 632LevelArray CalculateMipLevelOffsets(const ImageInfo& info) noexcept {
@@ -1195,37 +1175,37 @@ static_assert(CalculateLevelSize(LevelInfo{{1920, 1080, 1}, {0, 2, 0}, {1, 1}, 2
1195 0x7f8000); 1175 0x7f8000);
1196static_assert(CalculateLevelSize(LevelInfo{{32, 32, 1}, {0, 0, 4}, {1, 1}, 4, 0}, 0) == 0x4000); 1176static_assert(CalculateLevelSize(LevelInfo{{32, 32, 1}, {0, 0, 4}, {1, 1}, 4, 0}, 0) == 0x4000);
1197 1177
1198static_assert(CalculateLevelOffset(PixelFormat::R8_SINT, {1920, 1080, 1}, {0, 2, 0}, 1, 0, 7) == 1178static_assert(CalculateLevelOffset(PixelFormat::R8_SINT, {1920, 1080, 1}, {0, 2, 0}, 0, 7) ==
1199 0x2afc00); 1179 0x2afc00);
1200static_assert(CalculateLevelOffset(PixelFormat::ASTC_2D_12X12_UNORM, {8192, 4096, 1}, {0, 2, 0}, 1, 1180static_assert(CalculateLevelOffset(PixelFormat::ASTC_2D_12X12_UNORM, {8192, 4096, 1}, {0, 2, 0}, 0,
1201 0, 12) == 0x50d200); 1181 12) == 0x50d200);
1202 1182
1203static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1183static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 0) ==
1204 0) == 0); 1184 0);
1205static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1185static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 1) ==
1206 1) == 0x400000); 1186 0x400000);
1207static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1187static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 2) ==
1208 2) == 0x500000); 1188 0x500000);
1209static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1189static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 3) ==
1210 3) == 0x540000); 1190 0x540000);
1211static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1191static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 4) ==
1212 4) == 0x550000); 1192 0x550000);
1213static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1193static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 5) ==
1214 5) == 0x554000); 1194 0x554000);
1215static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1195static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 6) ==
1216 6) == 0x555000); 1196 0x555000);
1217static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1197static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 7) ==
1218 7) == 0x555400); 1198 0x555400);
1219static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1199static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 8) ==
1220 8) == 0x555600); 1200 0x555600);
1221static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 1, 0, 1201static_assert(CalculateLevelOffset(PixelFormat::A8B8G8R8_UNORM, {1024, 1024, 1}, {0, 4, 0}, 0, 9) ==
1222 9) == 0x555800); 1202 0x555800);
1223 1203
1224constexpr u32 ValidateLayerSize(PixelFormat format, u32 width, u32 height, u32 block_height, 1204constexpr u32 ValidateLayerSize(PixelFormat format, u32 width, u32 height, u32 block_height,
1225 u32 tile_width_spacing, u32 level) { 1205 u32 tile_width_spacing, u32 level) {
1226 const Extent3D size{width, height, 1}; 1206 const Extent3D size{width, height, 1};
1227 const Extent3D block{0, block_height, 0}; 1207 const Extent3D block{0, block_height, 0};
1228 const u32 offset = CalculateLevelOffset(format, size, block, 1, tile_width_spacing, level); 1208 const u32 offset = CalculateLevelOffset(format, size, block, tile_width_spacing, level);
1229 return AlignLayerSize(offset, size, block, DefaultBlockHeight(format), tile_width_spacing); 1209 return AlignLayerSize(offset, size, block, DefaultBlockHeight(format), tile_width_spacing);
1230} 1210}
1231 1211
diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp
index e04f7dfc6..b1e02c57a 100644
--- a/src/web_service/web_backend.cpp
+++ b/src/web_service/web_backend.cpp
@@ -8,7 +8,17 @@
8#include <string> 8#include <string>
9 9
10#include <fmt/format.h> 10#include <fmt/format.h>
11
12#ifdef __GNUC__
13#pragma GCC diagnostic push
14#ifndef __clang__
15#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
16#endif
17#endif
11#include <httplib.h> 18#include <httplib.h>
19#ifdef __GNUC__
20#pragma GCC diagnostic pop
21#endif
12 22
13#include "common/logging/log.h" 23#include "common/logging/log.h"
14#include "web_service/web_backend.h" 24#include "web_service/web_backend.h"
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 634fe66a5..cb4bdcc7e 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -15,18 +15,19 @@ add_executable(yuzu
15 about_dialog.cpp 15 about_dialog.cpp
16 about_dialog.h 16 about_dialog.h
17 aboutdialog.ui 17 aboutdialog.ui
18 applets/controller.cpp 18 applets/qt_controller.cpp
19 applets/controller.h 19 applets/qt_controller.h
20 applets/controller.ui 20 applets/qt_controller.ui
21 applets/error.cpp 21 applets/qt_error.cpp
22 applets/error.h 22 applets/qt_error.h
23 applets/profile_select.cpp 23 applets/qt_profile_select.cpp
24 applets/profile_select.h 24 applets/qt_profile_select.h
25 applets/software_keyboard.cpp 25 applets/qt_software_keyboard.cpp
26 applets/software_keyboard.h 26 applets/qt_software_keyboard.h
27 applets/software_keyboard.ui 27 applets/qt_software_keyboard.ui
28 applets/web_browser.cpp 28 applets/qt_web_browser.cpp
29 applets/web_browser.h 29 applets/qt_web_browser.h
30 applets/qt_web_browser_scripts.h
30 bootmanager.cpp 31 bootmanager.cpp
31 bootmanager.h 32 bootmanager.h
32 compatdb.ui 33 compatdb.ui
@@ -52,6 +53,9 @@ add_executable(yuzu
52 configuration/configure_debug_controller.cpp 53 configuration/configure_debug_controller.cpp
53 configuration/configure_debug_controller.h 54 configuration/configure_debug_controller.h
54 configuration/configure_debug_controller.ui 55 configuration/configure_debug_controller.ui
56 configuration/configure_debug_tab.cpp
57 configuration/configure_debug_tab.h
58 configuration/configure_debug_tab.ui
55 configuration/configure_dialog.cpp 59 configuration/configure_dialog.cpp
56 configuration/configure_dialog.h 60 configuration/configure_dialog.h
57 configuration/configure_filesystem.cpp 61 configuration/configure_filesystem.cpp
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/qt_controller.cpp
index 836d90fda..97106d2cc 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -12,8 +12,8 @@
12#include "core/hle/service/hid/controllers/npad.h" 12#include "core/hle/service/hid/controllers/npad.h"
13#include "core/hle/service/hid/hid.h" 13#include "core/hle/service/hid/hid.h"
14#include "core/hle/service/sm/sm.h" 14#include "core/hle/service/sm/sm.h"
15#include "ui_controller.h" 15#include "ui_qt_controller.h"
16#include "yuzu/applets/controller.h" 16#include "yuzu/applets/qt_controller.h"
17#include "yuzu/configuration/configure_input.h" 17#include "yuzu/configuration/configure_input.h"
18#include "yuzu/configuration/configure_input_profile_dialog.h" 18#include "yuzu/configuration/configure_input_profile_dialog.h"
19#include "yuzu/configuration/configure_motion_touch.h" 19#include "yuzu/configuration/configure_motion_touch.h"
diff --git a/src/yuzu/applets/controller.h b/src/yuzu/applets/qt_controller.h
index 9b57aea1a..9b57aea1a 100644
--- a/src/yuzu/applets/controller.h
+++ b/src/yuzu/applets/qt_controller.h
diff --git a/src/yuzu/applets/controller.ui b/src/yuzu/applets/qt_controller.ui
index c8cb6bcf3..c8cb6bcf3 100644
--- a/src/yuzu/applets/controller.ui
+++ b/src/yuzu/applets/qt_controller.ui
diff --git a/src/yuzu/applets/error.cpp b/src/yuzu/applets/qt_error.cpp
index 085688cd4..45cf64603 100644
--- a/src/yuzu/applets/error.cpp
+++ b/src/yuzu/applets/qt_error.cpp
@@ -4,7 +4,7 @@
4 4
5#include <QDateTime> 5#include <QDateTime>
6#include "core/hle/lock.h" 6#include "core/hle/lock.h"
7#include "yuzu/applets/error.h" 7#include "yuzu/applets/qt_error.h"
8#include "yuzu/main.h" 8#include "yuzu/main.h"
9 9
10QtErrorDisplay::QtErrorDisplay(GMainWindow& parent) { 10QtErrorDisplay::QtErrorDisplay(GMainWindow& parent) {
diff --git a/src/yuzu/applets/error.h b/src/yuzu/applets/qt_error.h
index 8bd895a32..8bd895a32 100644
--- a/src/yuzu/applets/error.h
+++ b/src/yuzu/applets/qt_error.h
diff --git a/src/yuzu/applets/profile_select.cpp b/src/yuzu/applets/qt_profile_select.cpp
index 62fd1141c..a56638e21 100644
--- a/src/yuzu/applets/profile_select.cpp
+++ b/src/yuzu/applets/qt_profile_select.cpp
@@ -14,7 +14,7 @@
14#include "common/string_util.h" 14#include "common/string_util.h"
15#include "core/constants.h" 15#include "core/constants.h"
16#include "core/hle/lock.h" 16#include "core/hle/lock.h"
17#include "yuzu/applets/profile_select.h" 17#include "yuzu/applets/qt_profile_select.h"
18#include "yuzu/main.h" 18#include "yuzu/main.h"
19 19
20namespace { 20namespace {
diff --git a/src/yuzu/applets/profile_select.h b/src/yuzu/applets/qt_profile_select.h
index 4e9037488..4e9037488 100644
--- a/src/yuzu/applets/profile_select.h
+++ b/src/yuzu/applets/qt_profile_select.h
diff --git a/src/yuzu/applets/software_keyboard.cpp b/src/yuzu/applets/qt_software_keyboard.cpp
index aa453a79f..848801cec 100644
--- a/src/yuzu/applets/software_keyboard.cpp
+++ b/src/yuzu/applets/qt_software_keyboard.cpp
@@ -11,8 +11,8 @@
11#include "common/string_util.h" 11#include "common/string_util.h"
12#include "core/core.h" 12#include "core/core.h"
13#include "core/frontend/input_interpreter.h" 13#include "core/frontend/input_interpreter.h"
14#include "ui_software_keyboard.h" 14#include "ui_qt_software_keyboard.h"
15#include "yuzu/applets/software_keyboard.h" 15#include "yuzu/applets/qt_software_keyboard.h"
16#include "yuzu/main.h" 16#include "yuzu/main.h"
17#include "yuzu/util/overlay_dialog.h" 17#include "yuzu/util/overlay_dialog.h"
18 18
diff --git a/src/yuzu/applets/software_keyboard.h b/src/yuzu/applets/qt_software_keyboard.h
index 1a03c098c..1a03c098c 100644
--- a/src/yuzu/applets/software_keyboard.h
+++ b/src/yuzu/applets/qt_software_keyboard.h
diff --git a/src/yuzu/applets/software_keyboard.ui b/src/yuzu/applets/qt_software_keyboard.ui
index b0a1fcde9..b0a1fcde9 100644
--- a/src/yuzu/applets/software_keyboard.ui
+++ b/src/yuzu/applets/qt_software_keyboard.ui
diff --git a/src/yuzu/applets/web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp
index 34d3feb55..b112dd7b0 100644
--- a/src/yuzu/applets/web_browser.cpp
+++ b/src/yuzu/applets/qt_web_browser.cpp
@@ -17,8 +17,8 @@
17#include "core/frontend/input_interpreter.h" 17#include "core/frontend/input_interpreter.h"
18#include "input_common/keyboard.h" 18#include "input_common/keyboard.h"
19#include "input_common/main.h" 19#include "input_common/main.h"
20#include "yuzu/applets/web_browser.h" 20#include "yuzu/applets/qt_web_browser.h"
21#include "yuzu/applets/web_browser_scripts.h" 21#include "yuzu/applets/qt_web_browser_scripts.h"
22#include "yuzu/main.h" 22#include "yuzu/main.h"
23#include "yuzu/util/url_request_interceptor.h" 23#include "yuzu/util/url_request_interceptor.h"
24 24
diff --git a/src/yuzu/applets/web_browser.h b/src/yuzu/applets/qt_web_browser.h
index 7ad07409f..7ad07409f 100644
--- a/src/yuzu/applets/web_browser.h
+++ b/src/yuzu/applets/qt_web_browser.h
diff --git a/src/yuzu/applets/web_browser_scripts.h b/src/yuzu/applets/qt_web_browser_scripts.h
index 992837a85..992837a85 100644
--- a/src/yuzu/applets/web_browser_scripts.h
+++ b/src/yuzu/applets/qt_web_browser_scripts.h
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 7524e3c40..bfae73b60 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -411,8 +411,9 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
411 if (event->source() == Qt::MouseEventSynthesizedBySystem) { 411 if (event->source() == Qt::MouseEventSynthesizedBySystem) {
412 return; 412 return;
413 } 413 }
414 414 // Qt sometimes returns the parent coordinates. To avoid this we read the global mouse
415 auto pos = event->pos(); 415 // coordinates and map them to the current render area
416 const auto pos = mapFromGlobal(QCursor::pos());
416 const auto [x, y] = ScaleTouch(pos); 417 const auto [x, y] = ScaleTouch(pos);
417 const auto button = QtButtonToMouseButton(event->button()); 418 const auto button = QtButtonToMouseButton(event->button());
418 input_subsystem->GetMouse()->PressButton(x, y, button); 419 input_subsystem->GetMouse()->PressButton(x, y, button);
@@ -429,7 +430,9 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
429 if (event->source() == Qt::MouseEventSynthesizedBySystem) { 430 if (event->source() == Qt::MouseEventSynthesizedBySystem) {
430 return; 431 return;
431 } 432 }
432 auto pos = event->pos(); 433 // Qt sometimes returns the parent coordinates. To avoid this we read the global mouse
434 // coordinates and map them to the current render area
435 const auto pos = mapFromGlobal(QCursor::pos());
433 const auto [x, y] = ScaleTouch(pos); 436 const auto [x, y] = ScaleTouch(pos);
434 const int center_x = width() / 2; 437 const int center_x = width() / 2;
435 const int center_y = height() / 2; 438 const int center_y = height() / 2;
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 1a0f75373..a5e032959 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -311,16 +311,6 @@ void Config::WriteBasicSetting(const Settings::BasicSetting<std::string>& settin
311 qt_config->setValue(name, QString::fromStdString(value)); 311 qt_config->setValue(name, QString::fromStdString(value));
312} 312}
313 313
314// Explicit float definition: use a double as Qt doesn't write legible floats to config files
315template <>
316void Config::WriteBasicSetting(const Settings::BasicSetting<float>& setting) {
317 const QString name = QString::fromStdString(setting.GetLabel());
318 const double value = setting.GetValue();
319 qt_config->setValue(name + QStringLiteral("/default"),
320 setting.GetValue() == setting.GetDefault());
321 qt_config->setValue(name, value);
322}
323
324template <typename Type> 314template <typename Type>
325void Config::WriteBasicSetting(const Settings::BasicSetting<Type>& setting) { 315void Config::WriteBasicSetting(const Settings::BasicSetting<Type>& setting) {
326 const QString name = QString::fromStdString(setting.GetLabel()); 316 const QString name = QString::fromStdString(setting.GetLabel());
@@ -329,21 +319,6 @@ void Config::WriteBasicSetting(const Settings::BasicSetting<Type>& setting) {
329 qt_config->setValue(name, value); 319 qt_config->setValue(name, value);
330} 320}
331 321
332// Explicit float definition: use a double as Qt doesn't write legible floats to config files
333template <>
334void Config::WriteGlobalSetting(const Settings::Setting<float>& setting) {
335 const QString name = QString::fromStdString(setting.GetLabel());
336 const double value = setting.GetValue(global);
337 if (!global) {
338 qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal());
339 }
340 if (global || !setting.UsingGlobal()) {
341 qt_config->setValue(name + QStringLiteral("/default"),
342 setting.GetValue(global) == setting.GetDefault());
343 qt_config->setValue(name, value);
344 }
345}
346
347template <typename Type> 322template <typename Type>
348void Config::WriteGlobalSetting(const Settings::Setting<Type>& setting) { 323void Config::WriteGlobalSetting(const Settings::Setting<Type>& setting) {
349 const QString name = QString::fromStdString(setting.GetLabel()); 324 const QString name = QString::fromStdString(setting.GetLabel());
@@ -793,7 +768,13 @@ void Config::ReadPathValues() {
793void Config::ReadCpuValues() { 768void Config::ReadCpuValues() {
794 qt_config->beginGroup(QStringLiteral("Cpu")); 769 qt_config->beginGroup(QStringLiteral("Cpu"));
795 770
796 ReadGlobalSetting(Settings::values.cpu_accuracy); 771 ReadBasicSetting(Settings::values.cpu_accuracy_first_time);
772 if (Settings::values.cpu_accuracy_first_time) {
773 Settings::values.cpu_accuracy.SetValue(Settings::values.cpu_accuracy.GetDefault());
774 Settings::values.cpu_accuracy_first_time.SetValue(false);
775 } else {
776 ReadGlobalSetting(Settings::values.cpu_accuracy);
777 }
797 778
798 ReadGlobalSetting(Settings::values.cpuopt_unsafe_unfuse_fma); 779 ReadGlobalSetting(Settings::values.cpuopt_unsafe_unfuse_fma);
799 ReadGlobalSetting(Settings::values.cpuopt_unsafe_reduce_fp_error); 780 ReadGlobalSetting(Settings::values.cpuopt_unsafe_reduce_fp_error);
@@ -802,6 +783,7 @@ void Config::ReadCpuValues() {
802 ReadGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check); 783 ReadGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check);
803 784
804 if (global) { 785 if (global) {
786 ReadBasicSetting(Settings::values.cpu_debug_mode);
805 ReadBasicSetting(Settings::values.cpuopt_page_tables); 787 ReadBasicSetting(Settings::values.cpuopt_page_tables);
806 ReadBasicSetting(Settings::values.cpuopt_block_linking); 788 ReadBasicSetting(Settings::values.cpuopt_block_linking);
807 ReadBasicSetting(Settings::values.cpuopt_return_stack_buffer); 789 ReadBasicSetting(Settings::values.cpuopt_return_stack_buffer);
@@ -820,7 +802,6 @@ void Config::ReadRendererValues() {
820 qt_config->beginGroup(QStringLiteral("Renderer")); 802 qt_config->beginGroup(QStringLiteral("Renderer"));
821 803
822 ReadGlobalSetting(Settings::values.renderer_backend); 804 ReadGlobalSetting(Settings::values.renderer_backend);
823 ReadBasicSetting(Settings::values.renderer_debug);
824 ReadGlobalSetting(Settings::values.vulkan_device); 805 ReadGlobalSetting(Settings::values.vulkan_device);
825 ReadGlobalSetting(Settings::values.fullscreen_mode); 806 ReadGlobalSetting(Settings::values.fullscreen_mode);
826 ReadGlobalSetting(Settings::values.aspect_ratio); 807 ReadGlobalSetting(Settings::values.aspect_ratio);
@@ -833,7 +814,6 @@ void Config::ReadRendererValues() {
833 ReadGlobalSetting(Settings::values.use_nvdec_emulation); 814 ReadGlobalSetting(Settings::values.use_nvdec_emulation);
834 ReadGlobalSetting(Settings::values.accelerate_astc); 815 ReadGlobalSetting(Settings::values.accelerate_astc);
835 ReadGlobalSetting(Settings::values.use_vsync); 816 ReadGlobalSetting(Settings::values.use_vsync);
836 ReadGlobalSetting(Settings::values.disable_fps_limit);
837 ReadGlobalSetting(Settings::values.use_assembly_shaders); 817 ReadGlobalSetting(Settings::values.use_assembly_shaders);
838 ReadGlobalSetting(Settings::values.use_asynchronous_shaders); 818 ReadGlobalSetting(Settings::values.use_asynchronous_shaders);
839 ReadGlobalSetting(Settings::values.use_fast_gpu_time); 819 ReadGlobalSetting(Settings::values.use_fast_gpu_time);
@@ -842,6 +822,10 @@ void Config::ReadRendererValues() {
842 ReadGlobalSetting(Settings::values.bg_green); 822 ReadGlobalSetting(Settings::values.bg_green);
843 ReadGlobalSetting(Settings::values.bg_blue); 823 ReadGlobalSetting(Settings::values.bg_blue);
844 824
825 if (global) {
826 ReadBasicSetting(Settings::values.renderer_debug);
827 }
828
845 qt_config->endGroup(); 829 qt_config->endGroup();
846} 830}
847 831
@@ -1309,6 +1293,7 @@ void Config::SavePathValues() {
1309void Config::SaveCpuValues() { 1293void Config::SaveCpuValues() {
1310 qt_config->beginGroup(QStringLiteral("Cpu")); 1294 qt_config->beginGroup(QStringLiteral("Cpu"));
1311 1295
1296 WriteBasicSetting(Settings::values.cpu_accuracy_first_time);
1312 WriteSetting(QStringLiteral("cpu_accuracy"), 1297 WriteSetting(QStringLiteral("cpu_accuracy"),
1313 static_cast<u32>(Settings::values.cpu_accuracy.GetValue(global)), 1298 static_cast<u32>(Settings::values.cpu_accuracy.GetValue(global)),
1314 static_cast<u32>(Settings::values.cpu_accuracy.GetDefault()), 1299 static_cast<u32>(Settings::values.cpu_accuracy.GetDefault()),
@@ -1321,6 +1306,7 @@ void Config::SaveCpuValues() {
1321 WriteGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check); 1306 WriteGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check);
1322 1307
1323 if (global) { 1308 if (global) {
1309 WriteBasicSetting(Settings::values.cpu_debug_mode);
1324 WriteBasicSetting(Settings::values.cpuopt_page_tables); 1310 WriteBasicSetting(Settings::values.cpuopt_page_tables);
1325 WriteBasicSetting(Settings::values.cpuopt_block_linking); 1311 WriteBasicSetting(Settings::values.cpuopt_block_linking);
1326 WriteBasicSetting(Settings::values.cpuopt_return_stack_buffer); 1312 WriteBasicSetting(Settings::values.cpuopt_return_stack_buffer);
@@ -1342,7 +1328,6 @@ void Config::SaveRendererValues() {
1342 static_cast<u32>(Settings::values.renderer_backend.GetValue(global)), 1328 static_cast<u32>(Settings::values.renderer_backend.GetValue(global)),
1343 static_cast<u32>(Settings::values.renderer_backend.GetDefault()), 1329 static_cast<u32>(Settings::values.renderer_backend.GetDefault()),
1344 Settings::values.renderer_backend.UsingGlobal()); 1330 Settings::values.renderer_backend.UsingGlobal());
1345 WriteBasicSetting(Settings::values.renderer_debug);
1346 WriteGlobalSetting(Settings::values.vulkan_device); 1331 WriteGlobalSetting(Settings::values.vulkan_device);
1347 WriteGlobalSetting(Settings::values.fullscreen_mode); 1332 WriteGlobalSetting(Settings::values.fullscreen_mode);
1348 WriteGlobalSetting(Settings::values.aspect_ratio); 1333 WriteGlobalSetting(Settings::values.aspect_ratio);
@@ -1358,7 +1343,6 @@ void Config::SaveRendererValues() {
1358 WriteGlobalSetting(Settings::values.use_nvdec_emulation); 1343 WriteGlobalSetting(Settings::values.use_nvdec_emulation);
1359 WriteGlobalSetting(Settings::values.accelerate_astc); 1344 WriteGlobalSetting(Settings::values.accelerate_astc);
1360 WriteGlobalSetting(Settings::values.use_vsync); 1345 WriteGlobalSetting(Settings::values.use_vsync);
1361 WriteGlobalSetting(Settings::values.disable_fps_limit);
1362 WriteGlobalSetting(Settings::values.use_assembly_shaders); 1346 WriteGlobalSetting(Settings::values.use_assembly_shaders);
1363 WriteGlobalSetting(Settings::values.use_asynchronous_shaders); 1347 WriteGlobalSetting(Settings::values.use_asynchronous_shaders);
1364 WriteGlobalSetting(Settings::values.use_fast_gpu_time); 1348 WriteGlobalSetting(Settings::values.use_fast_gpu_time);
@@ -1367,6 +1351,10 @@ void Config::SaveRendererValues() {
1367 WriteGlobalSetting(Settings::values.bg_green); 1351 WriteGlobalSetting(Settings::values.bg_green);
1368 WriteGlobalSetting(Settings::values.bg_blue); 1352 WriteGlobalSetting(Settings::values.bg_blue);
1369 1353
1354 if (global) {
1355 WriteBasicSetting(Settings::values.renderer_debug);
1356 }
1357
1370 qt_config->endGroup(); 1358 qt_config->endGroup();
1371} 1359}
1372 1360
diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui
index f92c3aff3..fca9aed5f 100644
--- a/src/yuzu/configuration/configure.ui
+++ b/src/yuzu/configuration/configure.ui
@@ -41,7 +41,7 @@
41 <item> 41 <item>
42 <widget class="QTabWidget" name="tabWidget"> 42 <widget class="QTabWidget" name="tabWidget">
43 <property name="currentIndex"> 43 <property name="currentIndex">
44 <number>0</number> 44 <number>11</number>
45 </property> 45 </property>
46 <widget class="ConfigureGeneral" name="generalTab"> 46 <widget class="ConfigureGeneral" name="generalTab">
47 <property name="accessibleName"> 47 <property name="accessibleName">
@@ -107,14 +107,6 @@
107 <string>CPU</string> 107 <string>CPU</string>
108 </attribute> 108 </attribute>
109 </widget> 109 </widget>
110 <widget class="ConfigureCpuDebug" name="cpuDebugTab">
111 <property name="accessibleName">
112 <string>Debug</string>
113 </property>
114 <attribute name="title">
115 <string>Debug</string>
116 </attribute>
117 </widget>
118 <widget class="ConfigureGraphics" name="graphicsTab"> 110 <widget class="ConfigureGraphics" name="graphicsTab">
119 <property name="accessibleName"> 111 <property name="accessibleName">
120 <string>Graphics</string> 112 <string>Graphics</string>
@@ -139,7 +131,7 @@
139 <string>Audio</string> 131 <string>Audio</string>
140 </attribute> 132 </attribute>
141 </widget> 133 </widget>
142 <widget class="ConfigureDebug" name="debugTab"> 134 <widget class="ConfigureDebugTab" name="debugTab">
143 <property name="accessibleName"> 135 <property name="accessibleName">
144 <string>Debug</string> 136 <string>Debug</string>
145 </property> 137 </property>
@@ -208,24 +200,12 @@
208 <container>1</container> 200 <container>1</container>
209 </customwidget> 201 </customwidget>
210 <customwidget> 202 <customwidget>
211 <class>ConfigureDebug</class>
212 <extends>QWidget</extends>
213 <header>configuration/configure_debug.h</header>
214 <container>1</container>
215 </customwidget>
216 <customwidget>
217 <class>ConfigureCpu</class> 203 <class>ConfigureCpu</class>
218 <extends>QWidget</extends> 204 <extends>QWidget</extends>
219 <header>configuration/configure_cpu.h</header> 205 <header>configuration/configure_cpu.h</header>
220 <container>1</container> 206 <container>1</container>
221 </customwidget> 207 </customwidget>
222 <customwidget> 208 <customwidget>
223 <class>ConfigureCpuDebug</class>
224 <extends>QWidget</extends>
225 <header>configuration/configure_cpu_debug.h</header>
226 <container>1</container>
227 </customwidget>
228 <customwidget>
229 <class>ConfigureGraphics</class> 209 <class>ConfigureGraphics</class>
230 <extends>QWidget</extends> 210 <extends>QWidget</extends>
231 <header>configuration/configure_graphics.h</header> 211 <header>configuration/configure_graphics.h</header>
@@ -267,6 +247,12 @@
267 <header>configuration/configure_service.h</header> 247 <header>configuration/configure_service.h</header>
268 <container>1</container> 248 <container>1</container>
269 </customwidget> 249 </customwidget>
250 <customwidget>
251 <class>ConfigureDebugTab</class>
252 <extends>QWidget</extends>
253 <header>configuration/configure_debug_tab.h</header>
254 <container>1</container>
255 </customwidget>
270 </customwidgets> 256 </customwidgets>
271 <resources/> 257 <resources/>
272 <connections> 258 <connections>
@@ -275,12 +261,32 @@
275 <signal>accepted()</signal> 261 <signal>accepted()</signal>
276 <receiver>ConfigureDialog</receiver> 262 <receiver>ConfigureDialog</receiver>
277 <slot>accept()</slot> 263 <slot>accept()</slot>
264 <hints>
265 <hint type="sourcelabel">
266 <x>20</x>
267 <y>20</y>
268 </hint>
269 <hint type="destinationlabel">
270 <x>20</x>
271 <y>20</y>
272 </hint>
273 </hints>
278 </connection> 274 </connection>
279 <connection> 275 <connection>
280 <sender>buttonBox</sender> 276 <sender>buttonBox</sender>
281 <signal>rejected()</signal> 277 <signal>rejected()</signal>
282 <receiver>ConfigureDialog</receiver> 278 <receiver>ConfigureDialog</receiver>
283 <slot>reject()</slot> 279 <slot>reject()</slot>
280 <hints>
281 <hint type="sourcelabel">
282 <x>20</x>
283 <y>20</y>
284 </hint>
285 <hint type="destinationlabel">
286 <x>20</x>
287 <y>20</y>
288 </hint>
289 </hints>
284 </connection> 290 </connection>
285 </connections> 291 </connections>
286</ui> 292</ui>
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
index 5aba1a3b2..1d84bf4ed 100644
--- a/src/yuzu/configuration/configure_audio.cpp
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -47,7 +47,8 @@ void ConfigureAudio::SetConfiguration() {
47 47
48 SetAudioDeviceFromDeviceID(); 48 SetAudioDeviceFromDeviceID();
49 49
50 ui->volume_slider->setValue(Settings::values.volume.GetValue() * ui->volume_slider->maximum()); 50 const auto volume_value = static_cast<int>(Settings::values.volume.GetValue());
51 ui->volume_slider->setValue(volume_value);
51 52
52 ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching.GetValue()); 53 ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching.GetValue());
53 54
@@ -112,18 +113,16 @@ void ConfigureAudio::ApplyConfiguration() {
112 113
113 // Guard if during game and set to game-specific value 114 // Guard if during game and set to game-specific value
114 if (Settings::values.volume.UsingGlobal()) { 115 if (Settings::values.volume.UsingGlobal()) {
115 Settings::values.volume.SetValue( 116 const auto volume = static_cast<u8>(ui->volume_slider->value());
116 static_cast<float>(ui->volume_slider->sliderPosition()) / 117 Settings::values.volume.SetValue(volume);
117 ui->volume_slider->maximum());
118 } 118 }
119 } else { 119 } else {
120 if (ui->volume_combo_box->currentIndex() == 0) { 120 if (ui->volume_combo_box->currentIndex() == 0) {
121 Settings::values.volume.SetGlobal(true); 121 Settings::values.volume.SetGlobal(true);
122 } else { 122 } else {
123 Settings::values.volume.SetGlobal(false); 123 Settings::values.volume.SetGlobal(false);
124 Settings::values.volume.SetValue( 124 const auto volume = static_cast<u8>(ui->volume_slider->value());
125 static_cast<float>(ui->volume_slider->sliderPosition()) / 125 Settings::values.volume.SetValue(volume);
126 ui->volume_slider->maximum());
127 } 126 }
128 } 127 }
129} 128}
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index 13db2ba98..8d7171487 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -20,8 +20,6 @@ ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::Config
20 20
21 SetConfiguration(); 21 SetConfiguration();
22 22
23 connect(ui->accuracy, qOverload<int>(&QComboBox::activated), this,
24 &ConfigureCpu::AccuracyUpdated);
25 connect(ui->accuracy, qOverload<int>(&QComboBox::currentIndexChanged), this, 23 connect(ui->accuracy, qOverload<int>(&QComboBox::currentIndexChanged), this,
26 &ConfigureCpu::UpdateGroup); 24 &ConfigureCpu::UpdateGroup);
27} 25}
@@ -58,20 +56,6 @@ void ConfigureCpu::SetConfiguration() {
58 UpdateGroup(ui->accuracy->currentIndex()); 56 UpdateGroup(ui->accuracy->currentIndex());
59} 57}
60 58
61void ConfigureCpu::AccuracyUpdated(int index) {
62 if (Settings::IsConfiguringGlobal() &&
63 static_cast<Settings::CPUAccuracy>(index) == Settings::CPUAccuracy::DebugMode) {
64 const auto result = QMessageBox::warning(this, tr("Setting CPU to Debug Mode"),
65 tr("CPU Debug Mode is only intended for developer "
66 "use. Are you sure you want to enable this?"),
67 QMessageBox::Yes | QMessageBox::No);
68 if (result == QMessageBox::No) {
69 ui->accuracy->setCurrentIndex(static_cast<int>(Settings::CPUAccuracy::Accurate));
70 UpdateGroup(static_cast<int>(Settings::CPUAccuracy::Accurate));
71 }
72 }
73}
74
75void ConfigureCpu::UpdateGroup(int index) { 59void ConfigureCpu::UpdateGroup(int index) {
76 if (!Settings::IsConfiguringGlobal()) { 60 if (!Settings::IsConfiguringGlobal()) {
77 index -= ConfigurationShared::USE_GLOBAL_OFFSET; 61 index -= ConfigurationShared::USE_GLOBAL_OFFSET;
@@ -134,8 +118,6 @@ void ConfigureCpu::SetupPerGameUI() {
134 ConfigurationShared::SetColoredComboBox( 118 ConfigurationShared::SetColoredComboBox(
135 ui->accuracy, ui->widget_accuracy, 119 ui->accuracy, ui->widget_accuracy,
136 static_cast<u32>(Settings::values.cpu_accuracy.GetValue(true))); 120 static_cast<u32>(Settings::values.cpu_accuracy.GetValue(true)));
137 ui->accuracy->removeItem(static_cast<u32>(Settings::CPUAccuracy::DebugMode) +
138 ConfigurationShared::USE_GLOBAL_OFFSET);
139 121
140 ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_unfuse_fma, 122 ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_unfuse_fma,
141 Settings::values.cpuopt_unsafe_unfuse_fma, 123 Settings::values.cpuopt_unsafe_unfuse_fma,
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
index b2b5f1671..154931482 100644
--- a/src/yuzu/configuration/configure_cpu.h
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -29,7 +29,6 @@ private:
29 void changeEvent(QEvent* event) override; 29 void changeEvent(QEvent* event) override;
30 void RetranslateUI(); 30 void RetranslateUI();
31 31
32 void AccuracyUpdated(int index);
33 void UpdateGroup(int index); 32 void UpdateGroup(int index);
34 33
35 void SetConfiguration(); 34 void SetConfiguration();
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
index 0e296d4e5..5b9457faf 100644
--- a/src/yuzu/configuration/configure_cpu.ui
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -6,8 +6,8 @@
6 <rect> 6 <rect>
7 <x>0</x> 7 <x>0</x>
8 <y>0</y> 8 <y>0</y>
9 <width>400</width> 9 <width>448</width>
10 <height>321</height> 10 <height>433</height>
11 </rect> 11 </rect>
12 </property> 12 </property>
13 <property name="windowTitle"> 13 <property name="windowTitle">
@@ -17,7 +17,7 @@
17 <item> 17 <item>
18 <layout class="QVBoxLayout"> 18 <layout class="QVBoxLayout">
19 <item> 19 <item>
20 <widget class="QGroupBox"> 20 <widget class="QGroupBox" name="groupBox">
21 <property name="title"> 21 <property name="title">
22 <string>General</string> 22 <string>General</string>
23 </property> 23 </property>
@@ -36,17 +36,17 @@
36 <widget class="QComboBox" name="accuracy"> 36 <widget class="QComboBox" name="accuracy">
37 <item> 37 <item>
38 <property name="text"> 38 <property name="text">
39 <string>Accurate</string> 39 <string>Auto</string>
40 </property> 40 </property>
41 </item> 41 </item>
42 <item> 42 <item>
43 <property name="text"> 43 <property name="text">
44 <string>Unsafe</string> 44 <string>Accurate</string>
45 </property> 45 </property>
46 </item> 46 </item>
47 <item> 47 <item>
48 <property name="text"> 48 <property name="text">
49 <string>Enable Debug Mode</string> 49 <string>Unsafe</string>
50 </property> 50 </property>
51 </item> 51 </item>
52 </widget> 52 </widget>
@@ -57,7 +57,7 @@
57 <item> 57 <item>
58 <widget class="QLabel" name="label_recommended_accuracy"> 58 <widget class="QLabel" name="label_recommended_accuracy">
59 <property name="text"> 59 <property name="text">
60 <string>We recommend setting accuracy to &quot;Accurate&quot;.</string> 60 <string>We recommend setting accuracy to &quot;Auto&quot;.</string>
61 </property> 61 </property>
62 <property name="wordWrap"> 62 <property name="wordWrap">
63 <bool>false</bool> 63 <bool>false</bool>
diff --git a/src/yuzu/configuration/configure_cpu_debug.h b/src/yuzu/configuration/configure_cpu_debug.h
index 10de55099..1b0d8050c 100644
--- a/src/yuzu/configuration/configure_cpu_debug.h
+++ b/src/yuzu/configuration/configure_cpu_debug.h
@@ -6,7 +6,6 @@
6 6
7#include <memory> 7#include <memory>
8#include <QWidget> 8#include <QWidget>
9#include "common/settings.h"
10 9
11namespace Ui { 10namespace Ui {
12class ConfigureCpuDebug; 11class ConfigureCpuDebug;
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui
index c43f89a5a..abf469b55 100644
--- a/src/yuzu/configuration/configure_cpu_debug.ui
+++ b/src/yuzu/configuration/configure_cpu_debug.ui
@@ -6,8 +6,8 @@
6 <rect> 6 <rect>
7 <x>0</x> 7 <x>0</x>
8 <y>0</y> 8 <y>0</y>
9 <width>400</width> 9 <width>592</width>
10 <height>321</height> 10 <height>503</height>
11 </rect> 11 </rect>
12 </property> 12 </property>
13 <property name="windowTitle"> 13 <property name="windowTitle">
@@ -17,140 +17,132 @@
17 <item> 17 <item>
18 <layout class="QVBoxLayout"> 18 <layout class="QVBoxLayout">
19 <item> 19 <item>
20 <widget class="QGroupBox"> 20 <widget class="QGroupBox" name="groupBox">
21 <property name="title"> 21 <property name="title">
22 <string>Toggle CPU Optimizations</string> 22 <string>Toggle CPU Optimizations</string>
23 </property> 23 </property>
24 <layout class="QVBoxLayout"> 24 <layout class="QVBoxLayout">
25 <item> 25 <item>
26 <widget class="QLabel"> 26 <widget class="QLabel" name="label">
27 <property name="wordWrap">
28 <bool>1</bool>
29 </property>
30 <property name="text"> 27 <property name="text">
31 <string> 28 <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;For debugging only.&lt;/span&gt;&lt;br/&gt;If you're not sure what these do, keep all of these enabled. &lt;br/&gt;These settings, when disabled, only take effect when CPU Debugging is enabled. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
32 &lt;div&gt; 29 </property>
33 &lt;b&gt;For debugging only.&lt;/b&gt; 30 <property name="wordWrap">
34 &lt;br&gt; 31 <bool>false</bool>
35 If you're not sure what these do, keep all of these enabled.
36 &lt;br&gt;
37 These settings, when disabled, only take effect when CPU Accuracy is "Debug Mode".
38 &lt;/div&gt;
39 </string>
40 </property> 32 </property>
41 </widget> 33 </widget>
42 </item> 34 </item>
43 <item> 35 <item>
44 <widget class="QCheckBox" name="cpuopt_page_tables"> 36 <widget class="QCheckBox" name="cpuopt_page_tables">
45 <property name="text">
46 <string>Enable inline page tables</string>
47 </property>
48 <property name="toolTip"> 37 <property name="toolTip">
49 <string> 38 <string>
50 &lt;div style="white-space: nowrap"&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt; 39 &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
51 &lt;div style="white-space: nowrap"&gt;Enabling it inlines accesses to PageTable::pointers into emitted code.&lt;/div&gt; 40 &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it inlines accesses to PageTable::pointers into emitted code.&lt;/div&gt;
52 &lt;div style="white-space: nowrap"&gt;Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.&lt;/div&gt; 41 &lt;div style=&quot;white-space: nowrap&quot;&gt;Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.&lt;/div&gt;
53 </string> 42 </string>
54 </property> 43 </property>
44 <property name="text">
45 <string>Enable inline page tables</string>
46 </property>
55 </widget> 47 </widget>
56 </item> 48 </item>
57 <item> 49 <item>
58 <widget class="QCheckBox" name="cpuopt_block_linking"> 50 <widget class="QCheckBox" name="cpuopt_block_linking">
59 <property name="text">
60 <string>Enable block linking</string>
61 </property>
62 <property name="toolTip"> 51 <property name="toolTip">
63 <string> 52 <string>
64 &lt;div&gt;This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.&lt;/div&gt; 53 &lt;div&gt;This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.&lt;/div&gt;
65 </string> 54 </string>
66 </property> 55 </property>
56 <property name="text">
57 <string>Enable block linking</string>
58 </property>
67 </widget> 59 </widget>
68 </item> 60 </item>
69 <item> 61 <item>
70 <widget class="QCheckBox" name="cpuopt_return_stack_buffer"> 62 <widget class="QCheckBox" name="cpuopt_return_stack_buffer">
71 <property name="text">
72 <string>Enable return stack buffer</string>
73 </property>
74 <property name="toolTip"> 63 <property name="toolTip">
75 <string> 64 <string>
76 &lt;div&gt;This optimization avoids dispatcher lookups by keeping track potential return addresses of BL instructions. This approximates what happens with a return stack buffer on a real CPU.&lt;/div&gt; 65 &lt;div&gt;This optimization avoids dispatcher lookups by keeping track potential return addresses of BL instructions. This approximates what happens with a return stack buffer on a real CPU.&lt;/div&gt;
77 </string> 66 </string>
78 </property> 67 </property>
68 <property name="text">
69 <string>Enable return stack buffer</string>
70 </property>
79 </widget> 71 </widget>
80 </item> 72 </item>
81 <item> 73 <item>
82 <widget class="QCheckBox" name="cpuopt_fast_dispatcher"> 74 <widget class="QCheckBox" name="cpuopt_fast_dispatcher">
83 <property name="text">
84 <string>Enable fast dispatcher</string>
85 </property>
86 <property name="toolTip"> 75 <property name="toolTip">
87 <string> 76 <string>
88 &lt;div&gt;Enable a two-tiered dispatch system. A faster dispatcher written in assembly has a small MRU cache of jump destinations is used first. If that fails, dispatch falls back to the slower C++ dispatcher.&lt;/div&gt; 77 &lt;div&gt;Enable a two-tiered dispatch system. A faster dispatcher written in assembly has a small MRU cache of jump destinations is used first. If that fails, dispatch falls back to the slower C++ dispatcher.&lt;/div&gt;
89 </string> 78 </string>
90 </property> 79 </property>
80 <property name="text">
81 <string>Enable fast dispatcher</string>
82 </property>
91 </widget> 83 </widget>
92 </item> 84 </item>
93 <item> 85 <item>
94 <widget class="QCheckBox" name="cpuopt_context_elimination"> 86 <widget class="QCheckBox" name="cpuopt_context_elimination">
95 <property name="text">
96 <string>Enable context elimination</string>
97 </property>
98 <property name="toolTip"> 87 <property name="toolTip">
99 <string> 88 <string>
100 &lt;div&gt;Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.&lt;/div&gt; 89 &lt;div&gt;Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.&lt;/div&gt;
101 </string> 90 </string>
102 </property> 91 </property>
92 <property name="text">
93 <string>Enable context elimination</string>
94 </property>
103 </widget> 95 </widget>
104 </item> 96 </item>
105 <item> 97 <item>
106 <widget class="QCheckBox" name="cpuopt_const_prop"> 98 <widget class="QCheckBox" name="cpuopt_const_prop">
107 <property name="text">
108 <string>Enable constant propagation</string>
109 </property>
110 <property name="toolTip"> 99 <property name="toolTip">
111 <string> 100 <string>
112 &lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt; 101 &lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt;
113 </string> 102 </string>
114 </property> 103 </property>
104 <property name="text">
105 <string>Enable constant propagation</string>
106 </property>
115 </widget> 107 </widget>
116 </item> 108 </item>
117 <item> 109 <item>
118 <widget class="QCheckBox" name="cpuopt_misc_ir"> 110 <widget class="QCheckBox" name="cpuopt_misc_ir">
119 <property name="text">
120 <string>Enable miscellaneous optimizations</string>
121 </property>
122 <property name="toolTip"> 111 <property name="toolTip">
123 <string> 112 <string>
124 &lt;div&gt;Enables miscellaneous IR optimizations.&lt;/div&gt; 113 &lt;div&gt;Enables miscellaneous IR optimizations.&lt;/div&gt;
125 </string> 114 </string>
126 </property> 115 </property>
116 <property name="text">
117 <string>Enable miscellaneous optimizations</string>
118 </property>
127 </widget> 119 </widget>
128 </item> 120 </item>
129 <item> 121 <item>
130 <widget class="QCheckBox" name="cpuopt_reduce_misalign_checks"> 122 <widget class="QCheckBox" name="cpuopt_reduce_misalign_checks">
131 <property name="text">
132 <string>Enable misalignment check reduction</string>
133 </property>
134 <property name="toolTip"> 123 <property name="toolTip">
135 <string> 124 <string>
136 &lt;div style="white-space: nowrap"&gt;When enabled, a misalignment is only triggered when an access crosses a page boundary.&lt;/div&gt; 125 &lt;div style=&quot;white-space: nowrap&quot;&gt;When enabled, a misalignment is only triggered when an access crosses a page boundary.&lt;/div&gt;
137 &lt;div style="white-space: nowrap"&gt;When disabled, a misalignment is triggered on all misaligned accesses.&lt;/div&gt; 126 &lt;div style=&quot;white-space: nowrap&quot;&gt;When disabled, a misalignment is triggered on all misaligned accesses.&lt;/div&gt;
138 </string> 127 </string>
139 </property> 128 </property>
129 <property name="text">
130 <string>Enable misalignment check reduction</string>
131 </property>
140 </widget> 132 </widget>
141 </item> 133 </item>
142 <item> 134 <item>
143 <widget class="QCheckBox" name="cpuopt_fastmem"> 135 <widget class="QCheckBox" name="cpuopt_fastmem">
144 <property name="text">
145 <string>Enable Host MMU Emulation</string>
146 </property>
147 <property name="toolTip"> 136 <property name="toolTip">
148 <string> 137 <string>
149 &lt;div style="white-space: nowrap"&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt; 138 &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
150 &lt;div style="white-space: nowrap"&gt;Enabling it causes guest memory reads/writes to be done directly into memory and make use of Host's MMU.&lt;/div&gt; 139 &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it causes guest memory reads/writes to be done directly into memory and make use of Host's MMU.&lt;/div&gt;
151 &lt;div style="white-space: nowrap"&gt;Disabling this forces all memory accesses to use Software MMU Emulation.&lt;/div&gt; 140 &lt;div style=&quot;white-space: nowrap&quot;&gt;Disabling this forces all memory accesses to use Software MMU Emulation.&lt;/div&gt;
152 </string> 141 </string>
153 </property> 142 </property>
143 <property name="text">
144 <string>Enable Host MMU Emulation</string>
145 </property>
154 </widget> 146 </widget>
155 </item> 147 </item>
156 </layout> 148 </layout>
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index cbe45a305..8fceb3878 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -43,6 +43,8 @@ void ConfigureDebug::SetConfiguration() {
43 ui->use_auto_stub->setChecked(Settings::values.use_auto_stub.GetValue()); 43 ui->use_auto_stub->setChecked(Settings::values.use_auto_stub.GetValue());
44 ui->enable_graphics_debugging->setEnabled(runtime_lock); 44 ui->enable_graphics_debugging->setEnabled(runtime_lock);
45 ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug.GetValue()); 45 ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug.GetValue());
46 ui->enable_cpu_debugging->setEnabled(runtime_lock);
47 ui->enable_cpu_debugging->setChecked(Settings::values.cpu_debug_mode.GetValue());
46 ui->disable_macro_jit->setEnabled(runtime_lock); 48 ui->disable_macro_jit->setEnabled(runtime_lock);
47 ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit.GetValue()); 49 ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit.GetValue());
48 ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue()); 50 ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue());
@@ -58,6 +60,7 @@ void ConfigureDebug::ApplyConfiguration() {
58 Settings::values.use_debug_asserts = ui->use_debug_asserts->isChecked(); 60 Settings::values.use_debug_asserts = ui->use_debug_asserts->isChecked();
59 Settings::values.use_auto_stub = ui->use_auto_stub->isChecked(); 61 Settings::values.use_auto_stub = ui->use_auto_stub->isChecked();
60 Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked(); 62 Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked();
63 Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked();
61 Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); 64 Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
62 Settings::values.extended_logging = ui->extended_logging->isChecked(); 65 Settings::values.extended_logging = ui->extended_logging->isChecked();
63 Debugger::ToggleConsole(); 66 Debugger::ToggleConsole();
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index c8087542f..1260ad6f0 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -7,7 +7,7 @@
7 <x>0</x> 7 <x>0</x>
8 <y>0</y> 8 <y>0</y>
9 <width>400</width> 9 <width>400</width>
10 <height>486</height> 10 <height>777</height>
11 </rect> 11 </rect>
12 </property> 12 </property>
13 <property name="windowTitle"> 13 <property name="windowTitle">
@@ -192,34 +192,41 @@
192 </property> 192 </property>
193 </widget> 193 </widget>
194 </item> 194 </item>
195 <item>
196 <widget class="QCheckBox" name="use_debug_asserts">
197 <property name="text">
198 <string>Enable Debug Asserts</string>
199 </property>
200 </widget>
201 </item>
202 <item>
203 <widget class="QCheckBox" name="use_auto_stub">
204 <property name="text">
205 <string>Enable Auto-Stub</string>
206 </property>
207 </widget>
208 </item>
209 <item> 195 <item>
210 <widget class="QLabel" name="label_5"> 196 <widget class="QCheckBox" name="enable_cpu_debugging">
211 <property name="font"> 197 <property name="text">
212 <font> 198 <string>Enable CPU Debugging</string>
213 <italic>true</italic> 199 </property>
214 </font> 200 </widget>
215 </property> 201 </item>
216 <property name="text"> 202 <item>
217 <string>This will be reset automatically when yuzu closes.</string> 203 <widget class="QCheckBox" name="use_debug_asserts">
218 </property> 204 <property name="text">
219 <property name="indent"> 205 <string>Enable Debug Asserts</string>
220 <number>20</number> 206 </property>
221 </property> 207 </widget>
222 </widget> 208 </item>
209 <item>
210 <widget class="QCheckBox" name="use_auto_stub">
211 <property name="text">
212 <string>Enable Auto-Stub</string>
213 </property>
214 </widget>
215 </item>
216 <item>
217 <widget class="QLabel" name="label_5">
218 <property name="font">
219 <font>
220 <italic>true</italic>
221 </font>
222 </property>
223 <property name="text">
224 <string>This will be reset automatically when yuzu closes.</string>
225 </property>
226 <property name="indent">
227 <number>20</number>
228 </property>
229 </widget>
223 </item> 230 </item>
224 </layout> 231 </layout>
225 </widget> 232 </widget>
diff --git a/src/yuzu/configuration/configure_debug_tab.cpp b/src/yuzu/configuration/configure_debug_tab.cpp
new file mode 100644
index 000000000..67d369249
--- /dev/null
+++ b/src/yuzu/configuration/configure_debug_tab.cpp
@@ -0,0 +1,38 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "ui_configure_debug_tab.h"
6#include "yuzu/configuration/configure_debug_tab.h"
7
8ConfigureDebugTab::ConfigureDebugTab(QWidget* parent)
9 : QWidget(parent), ui(new Ui::ConfigureDebugTab) {
10 ui->setupUi(this);
11
12 SetConfiguration();
13}
14
15ConfigureDebugTab::~ConfigureDebugTab() = default;
16
17void ConfigureDebugTab::ApplyConfiguration() {
18 ui->debugTab->ApplyConfiguration();
19 ui->cpuDebugTab->ApplyConfiguration();
20}
21
22void ConfigureDebugTab::SetCurrentIndex(int index) {
23 ui->tabWidget->setCurrentIndex(index);
24}
25
26void ConfigureDebugTab::changeEvent(QEvent* event) {
27 if (event->type() == QEvent::LanguageChange) {
28 RetranslateUI();
29 }
30
31 QWidget::changeEvent(event);
32}
33
34void ConfigureDebugTab::RetranslateUI() {
35 ui->retranslateUi(this);
36}
37
38void ConfigureDebugTab::SetConfiguration() {}
diff --git a/src/yuzu/configuration/configure_debug_tab.h b/src/yuzu/configuration/configure_debug_tab.h
new file mode 100644
index 000000000..0a96d43d0
--- /dev/null
+++ b/src/yuzu/configuration/configure_debug_tab.h
@@ -0,0 +1,32 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <QWidget>
9
10namespace Ui {
11class ConfigureDebugTab;
12}
13
14class ConfigureDebugTab : public QWidget {
15 Q_OBJECT
16
17public:
18 explicit ConfigureDebugTab(QWidget* parent = nullptr);
19 ~ConfigureDebugTab() override;
20
21 void ApplyConfiguration();
22
23 void SetCurrentIndex(int index);
24
25private:
26 void changeEvent(QEvent* event) override;
27 void RetranslateUI();
28
29 void SetConfiguration();
30
31 std::unique_ptr<Ui::ConfigureDebugTab> ui;
32};
diff --git a/src/yuzu/configuration/configure_debug_tab.ui b/src/yuzu/configuration/configure_debug_tab.ui
new file mode 100644
index 000000000..7dc6dd704
--- /dev/null
+++ b/src/yuzu/configuration/configure_debug_tab.ui
@@ -0,0 +1,52 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConfigureDebugTab</class>
4 <widget class="QWidget" name="ConfigureDebugTab">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>320</width>
10 <height>240</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Form</string>
15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout">
17 <item>
18 <widget class="QTabWidget" name="tabWidget">
19 <property name="currentIndex">
20 <number>1</number>
21 </property>
22 <widget class="ConfigureDebug" name="debugTab">
23 <attribute name="title">
24 <string>General</string>
25 </attribute>
26 </widget>
27 <widget class="ConfigureCpuDebug" name="cpuDebugTab">
28 <attribute name="title">
29 <string>CPU</string>
30 </attribute>
31 </widget>
32 </widget>
33 </item>
34 </layout>
35 </widget>
36 <customwidgets>
37 <customwidget>
38 <class>ConfigureDebug</class>
39 <extends>QWidget</extends>
40 <header>configuration/configure_debug.h</header>
41 <container>1</container>
42 </customwidget>
43 <customwidget>
44 <class>ConfigureCpuDebug</class>
45 <extends>QWidget</extends>
46 <header>configuration/configure_cpu_debug.h</header>
47 <container>1</container>
48 </customwidget>
49 </customwidgets>
50 <resources/>
51 <connections/>
52</ui>
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 371bc01b1..bc009b6b3 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -8,6 +8,7 @@
8#include <QListWidgetItem> 8#include <QListWidgetItem>
9#include <QPushButton> 9#include <QPushButton>
10#include <QSignalBlocker> 10#include <QSignalBlocker>
11#include <QTabWidget>
11#include "common/settings.h" 12#include "common/settings.h"
12#include "core/core.h" 13#include "core/core.h"
13#include "ui_configure.h" 14#include "ui_configure.h"
@@ -32,6 +33,8 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry,
32 SetConfiguration(); 33 SetConfiguration();
33 PopulateSelectionList(); 34 PopulateSelectionList();
34 35
36 connect(ui->tabWidget, &QTabWidget::currentChanged, this,
37 [this]() { ui->debugTab->SetCurrentIndex(0); });
35 connect(ui->uiTab, &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged); 38 connect(ui->uiTab, &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged);
36 connect(ui->selectorList, &QListWidget::itemSelectionChanged, this, 39 connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
37 &ConfigureDialog::UpdateVisibleTabs); 40 &ConfigureDialog::UpdateVisibleTabs);
@@ -59,7 +62,6 @@ void ConfigureDialog::ApplyConfiguration() {
59 ui->inputTab->ApplyConfiguration(); 62 ui->inputTab->ApplyConfiguration();
60 ui->hotkeysTab->ApplyConfiguration(registry); 63 ui->hotkeysTab->ApplyConfiguration(registry);
61 ui->cpuTab->ApplyConfiguration(); 64 ui->cpuTab->ApplyConfiguration();
62 ui->cpuDebugTab->ApplyConfiguration();
63 ui->graphicsTab->ApplyConfiguration(); 65 ui->graphicsTab->ApplyConfiguration();
64 ui->graphicsAdvancedTab->ApplyConfiguration(); 66 ui->graphicsAdvancedTab->ApplyConfiguration();
65 ui->audioTab->ApplyConfiguration(); 67 ui->audioTab->ApplyConfiguration();
@@ -102,7 +104,7 @@ void ConfigureDialog::PopulateSelectionList() {
102 const std::array<std::pair<QString, QList<QWidget*>>, 6> items{ 104 const std::array<std::pair<QString, QList<QWidget*>>, 6> items{
103 {{tr("General"), {ui->generalTab, ui->hotkeysTab, ui->uiTab, ui->webTab, ui->debugTab}}, 105 {{tr("General"), {ui->generalTab, ui->hotkeysTab, ui->uiTab, ui->webTab, ui->debugTab}},
104 {tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}}, 106 {tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}},
105 {tr("CPU"), {ui->cpuTab, ui->cpuDebugTab}}, 107 {tr("CPU"), {ui->cpuTab}},
106 {tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}}, 108 {tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}},
107 {tr("Audio"), {ui->audioTab}}, 109 {tr("Audio"), {ui->audioTab}},
108 {tr("Controls"), ui->inputTab->GetSubTabs()}}, 110 {tr("Controls"), ui->inputTab->GetSubTabs()}},
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 41a69d9b8..4d5b4c0e6 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -101,9 +101,9 @@ void ConfigureGraphics::SetConfiguration() {
101 ConfigurationShared::SetHighlight(ui->bg_layout, !Settings::values.bg_red.UsingGlobal()); 101 ConfigurationShared::SetHighlight(ui->bg_layout, !Settings::values.bg_red.UsingGlobal());
102 } 102 }
103 103
104 UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red.GetValue(), 104 UpdateBackgroundColorButton(QColor::fromRgb(Settings::values.bg_red.GetValue(),
105 Settings::values.bg_green.GetValue(), 105 Settings::values.bg_green.GetValue(),
106 Settings::values.bg_blue.GetValue())); 106 Settings::values.bg_blue.GetValue()));
107 UpdateDeviceComboBox(); 107 UpdateDeviceComboBox();
108} 108}
109 109
@@ -132,9 +132,9 @@ void ConfigureGraphics::ApplyConfiguration() {
132 Settings::values.vulkan_device.SetValue(vulkan_device); 132 Settings::values.vulkan_device.SetValue(vulkan_device);
133 } 133 }
134 if (Settings::values.bg_red.UsingGlobal()) { 134 if (Settings::values.bg_red.UsingGlobal()) {
135 Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF())); 135 Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
136 Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF())); 136 Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
137 Settings::values.bg_blue.SetValue(static_cast<float>(bg_color.blueF())); 137 Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
138 } 138 }
139 } else { 139 } else {
140 if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { 140 if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
@@ -159,9 +159,9 @@ void ConfigureGraphics::ApplyConfiguration() {
159 Settings::values.bg_red.SetGlobal(false); 159 Settings::values.bg_red.SetGlobal(false);
160 Settings::values.bg_green.SetGlobal(false); 160 Settings::values.bg_green.SetGlobal(false);
161 Settings::values.bg_blue.SetGlobal(false); 161 Settings::values.bg_blue.SetGlobal(false);
162 Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF())); 162 Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
163 Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF())); 163 Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
164 Settings::values.bg_blue.SetValue(static_cast<float>(bg_color.blueF())); 164 Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
165 } 165 }
166 } 166 }
167} 167}
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index 8d13c9857..a9e611125 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -28,7 +28,6 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
28 ui->anisotropic_filtering_combobox->setEnabled(runtime_lock); 28 ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
29 29
30 ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue()); 30 ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
31 ui->disable_fps_limit->setChecked(Settings::values.disable_fps_limit.GetValue());
32 ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue()); 31 ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue());
33 ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue()); 32 ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
34 ui->use_caches_gc->setChecked(Settings::values.use_caches_gc.GetValue()); 33 ui->use_caches_gc->setChecked(Settings::values.use_caches_gc.GetValue());
@@ -59,8 +58,6 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
59 ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, 58 ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
60 ui->anisotropic_filtering_combobox); 59 ui->anisotropic_filtering_combobox);
61 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync); 60 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync);
62 ConfigurationShared::ApplyPerGameSetting(&Settings::values.disable_fps_limit,
63 ui->disable_fps_limit, disable_fps_limit);
64 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders, 61 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders,
65 ui->use_assembly_shaders, use_assembly_shaders); 62 ui->use_assembly_shaders, use_assembly_shaders);
66 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders, 63 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
@@ -103,7 +100,6 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
103 if (Settings::IsConfiguringGlobal()) { 100 if (Settings::IsConfiguringGlobal()) {
104 ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal()); 101 ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal());
105 ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal()); 102 ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal());
106 ui->disable_fps_limit->setEnabled(Settings::values.disable_fps_limit.UsingGlobal());
107 ui->use_assembly_shaders->setEnabled(Settings::values.use_assembly_shaders.UsingGlobal()); 103 ui->use_assembly_shaders->setEnabled(Settings::values.use_assembly_shaders.UsingGlobal());
108 ui->use_asynchronous_shaders->setEnabled( 104 ui->use_asynchronous_shaders->setEnabled(
109 Settings::values.use_asynchronous_shaders.UsingGlobal()); 105 Settings::values.use_asynchronous_shaders.UsingGlobal());
@@ -116,8 +112,6 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
116 } 112 }
117 113
118 ConfigurationShared::SetColoredTristate(ui->use_vsync, Settings::values.use_vsync, use_vsync); 114 ConfigurationShared::SetColoredTristate(ui->use_vsync, Settings::values.use_vsync, use_vsync);
119 ConfigurationShared::SetColoredTristate(ui->disable_fps_limit,
120 Settings::values.disable_fps_limit, disable_fps_limit);
121 ConfigurationShared::SetColoredTristate( 115 ConfigurationShared::SetColoredTristate(
122 ui->use_assembly_shaders, Settings::values.use_assembly_shaders, use_assembly_shaders); 116 ui->use_assembly_shaders, Settings::values.use_assembly_shaders, use_assembly_shaders);
123 ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders, 117 ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders,
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h
index 6ac5f20ec..9148aacf2 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.h
+++ b/src/yuzu/configuration/configure_graphics_advanced.h
@@ -35,7 +35,6 @@ private:
35 std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui; 35 std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
36 36
37 ConfigurationShared::CheckState use_vsync; 37 ConfigurationShared::CheckState use_vsync;
38 ConfigurationShared::CheckState disable_fps_limit;
39 ConfigurationShared::CheckState use_assembly_shaders; 38 ConfigurationShared::CheckState use_assembly_shaders;
40 ConfigurationShared::CheckState use_asynchronous_shaders; 39 ConfigurationShared::CheckState use_asynchronous_shaders;
41 ConfigurationShared::CheckState use_fast_gpu_time; 40 ConfigurationShared::CheckState use_fast_gpu_time;
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui
index 18c43629e..ad0840355 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.ui
+++ b/src/yuzu/configuration/configure_graphics_advanced.ui
@@ -77,24 +77,6 @@
77 </widget> 77 </widget>
78 </item> 78 </item>
79 <item> 79 <item>
80 <widget class="QCheckBox" name="disable_fps_limit">
81 <property name="enabled">
82 <bool>true</bool>
83 </property>
84 <property name="toolTip">
85 <string>
86 &lt;html&gt;&lt;head/&gt;&lt;body&gt;
87 &lt;p&gt;Presents guest frames as they become available, disabling the FPS limit in most titles.&lt;/p&gt;
88 &lt;p&gt;NOTE: Will cause instabilities.&lt;/p&gt;
89 &lt;/body&gt;&lt;/html&gt;
90 </string>
91 </property>
92 <property name="text">
93 <string>Disable framerate limit (experimental)</string>
94 </property>
95 </widget>
96 </item>
97 <item>
98 <widget class="QCheckBox" name="use_assembly_shaders"> 80 <widget class="QCheckBox" name="use_assembly_shaders">
99 <property name="toolTip"> 81 <property name="toolTip">
100 <string>Enabling this reduces shader stutter. Enables OpenGL assembly shaders on supported Nvidia devices (NV_gpu_program5 is required). This feature is experimental.</string> 82 <string>Enabling this reduces shader stutter. Enables OpenGL assembly shaders on supported Nvidia devices (NV_gpu_program5 is required). This feature is experimental.</string>
diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui
index 173130d8d..d3ef5bd06 100644
--- a/src/yuzu/configuration/configure_input_advanced.ui
+++ b/src/yuzu/configuration/configure_input_advanced.ui
@@ -2573,27 +2573,24 @@
2573 </widget> 2573 </widget>
2574 </item> 2574 </item>
2575 <item row="2" column="2"> 2575 <item row="2" column="2">
2576 <widget class="QDoubleSpinBox" name="mouse_panning_sensitivity"> 2576 <widget class="QSpinBox" name="mouse_panning_sensitivity">
2577 <property name="toolTip"> 2577 <property name="toolTip">
2578 <string>Mouse sensitivity</string> 2578 <string>Mouse sensitivity</string>
2579 </property> 2579 </property>
2580 <property name="alignment"> 2580 <property name="alignment">
2581 <set>Qt::AlignCenter</set> 2581 <set>Qt::AlignCenter</set>
2582 </property> 2582 </property>
2583 <property name="decimals"> 2583 <property name="suffix">
2584 <number>2</number> 2584 <string>%</string>
2585 </property> 2585 </property>
2586 <property name="minimum"> 2586 <property name="minimum">
2587 <double>0.100000000000000</double> 2587 <number>1</number>
2588 </property> 2588 </property>
2589 <property name="maximum"> 2589 <property name="maximum">
2590 <double>16.000000000000000</double> 2590 <number>100</number>
2591 </property>
2592 <property name="singleStep">
2593 <double>0.010000000000000</double>
2594 </property> 2591 </property>
2595 <property name="value"> 2592 <property name="value">
2596 <double>1.000000000000000</double> 2593 <number>100</number>
2597 </property> 2594 </property>
2598 </widget> 2595 </widget>
2599 </item> 2596 </item>
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 5ed3b90b8..b7fd33ae7 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -11,11 +11,11 @@
11#endif 11#endif
12 12
13// VFS includes must be before glad as they will conflict with Windows file api, which uses defines. 13// VFS includes must be before glad as they will conflict with Windows file api, which uses defines.
14#include "applets/controller.h" 14#include "applets/qt_controller.h"
15#include "applets/error.h" 15#include "applets/qt_error.h"
16#include "applets/profile_select.h" 16#include "applets/qt_profile_select.h"
17#include "applets/software_keyboard.h" 17#include "applets/qt_software_keyboard.h"
18#include "applets/web_browser.h" 18#include "applets/qt_web_browser.h"
19#include "common/nvidia_flags.h" 19#include "common/nvidia_flags.h"
20#include "configuration/configure_input.h" 20#include "configuration/configure_input.h"
21#include "configuration/configure_per_game.h" 21#include "configuration/configure_per_game.h"
@@ -1355,6 +1355,9 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S
1355 1355
1356 ConfigureVibration::SetAllVibrationDevices(); 1356 ConfigureVibration::SetAllVibrationDevices();
1357 1357
1358 // Disable fps limit toggle when booting a new title
1359 Settings::values.disable_fps_limit.SetValue(false);
1360
1358 // Save configurations 1361 // Save configurations
1359 UpdateUISettings(); 1362 UpdateUISettings();
1360 game_list->SaveInterfaceLayout(); 1363 game_list->SaveInterfaceLayout();
@@ -1428,8 +1431,10 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S
1428 std::filesystem::path{filename.toStdU16String()}.filename()); 1431 std::filesystem::path{filename.toStdU16String()}.filename());
1429 } 1432 }
1430 const bool is_64bit = system.Kernel().CurrentProcess()->Is64BitProcess(); 1433 const bool is_64bit = system.Kernel().CurrentProcess()->Is64BitProcess();
1431 const auto instruction_set_suffix = is_64bit ? " (64-bit)" : " (32-bit)"; 1434 const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)");
1432 title_name += instruction_set_suffix; 1435 title_name = tr("%1 %2", "%1 is the title name. %2 indicates if the title is 64-bit or 32-bit")
1436 .arg(QString::fromStdString(title_name), instruction_set_suffix)
1437 .toStdString();
1433 LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version); 1438 LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version);
1434 const auto gpu_vendor = system.GPU().Renderer().GetDeviceVendor(); 1439 const auto gpu_vendor = system.GPU().Renderer().GetDeviceVendor();
1435 UpdateWindowTitle(title_name, title_version, gpu_vendor); 1440 UpdateWindowTitle(title_name, title_version, gpu_vendor);
@@ -2913,7 +2918,12 @@ void GMainWindow::UpdateStatusBar() {
2913 } else { 2918 } else {
2914 emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); 2919 emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
2915 } 2920 }
2916 game_fps_label->setText(tr("Game: %1 FPS").arg(results.average_game_fps, 0, 'f', 0)); 2921 if (Settings::values.disable_fps_limit) {
2922 game_fps_label->setText(
2923 tr("Game: %1 FPS (Limit off)").arg(results.average_game_fps, 0, 'f', 0));
2924 } else {
2925 game_fps_label->setText(tr("Game: %1 FPS").arg(results.average_game_fps, 0, 'f', 0));
2926 }
2917 emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2)); 2927 emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));
2918 2928
2919 emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue()); 2929 emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue());
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index 4bf25727b..e55a19649 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -38,6 +38,11 @@ target_include_directories(yuzu-cmd PRIVATE ${RESOURCES_DIR})
38 38
39target_include_directories(yuzu-cmd PRIVATE ../../externals/Vulkan-Headers/include) 39target_include_directories(yuzu-cmd PRIVATE ../../externals/Vulkan-Headers/include)
40 40
41if (YUZU_USE_EXTERNAL_SDL2)
42 target_compile_definitions(yuzu-cmd PRIVATE -DYUZU_USE_EXTERNAL_SDL2)
43 target_include_directories(yuzu-cmd PRIVATE ${PROJECT_BINARY_DIR}/externals/SDL/include)
44endif()
45
41if(UNIX AND NOT APPLE) 46if(UNIX AND NOT APPLE)
42 install(TARGETS yuzu-cmd RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") 47 install(TARGETS yuzu-cmd RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
43endif() 48endif()
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 325584a1a..b18056baf 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -242,17 +242,15 @@ static const std::array<int, 8> keyboard_mods{
242}; 242};
243 243
244template <> 244template <>
245void Config::ReadSetting(const std::string& group, Settings::BasicSetting<float>& setting) {
246 setting = sdl2_config->GetReal(group, setting.GetLabel(), setting.GetDefault());
247}
248template <>
249void Config::ReadSetting(const std::string& group, Settings::BasicSetting<std::string>& setting) { 245void Config::ReadSetting(const std::string& group, Settings::BasicSetting<std::string>& setting) {
250 setting = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault()); 246 setting = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault());
251} 247}
248
252template <> 249template <>
253void Config::ReadSetting(const std::string& group, Settings::BasicSetting<bool>& setting) { 250void Config::ReadSetting(const std::string& group, Settings::BasicSetting<bool>& setting) {
254 setting = sdl2_config->GetBoolean(group, setting.GetLabel(), setting.GetDefault()); 251 setting = sdl2_config->GetBoolean(group, setting.GetLabel(), setting.GetDefault());
255} 252}
253
256template <typename Type> 254template <typename Type>
257void Config::ReadSetting(const std::string& group, Settings::BasicSetting<Type>& setting) { 255void Config::ReadSetting(const std::string& group, Settings::BasicSetting<Type>& setting) {
258 setting = static_cast<Type>(sdl2_config->GetInteger(group, setting.GetLabel(), 256 setting = static_cast<Type>(sdl2_config->GetInteger(group, setting.GetLabel(),
@@ -294,6 +292,8 @@ void Config::ReadValues() {
294 292
295 ReadSetting("ControlsGeneral", Settings::values.motion_device); 293 ReadSetting("ControlsGeneral", Settings::values.motion_device);
296 294
295 ReadSetting("ControlsGeneral", Settings::values.touch_device);
296
297 ReadSetting("ControlsGeneral", Settings::values.keyboard_enabled); 297 ReadSetting("ControlsGeneral", Settings::values.keyboard_enabled);
298 298
299 ReadSetting("ControlsGeneral", Settings::values.debug_pad_enabled); 299 ReadSetting("ControlsGeneral", Settings::values.debug_pad_enabled);
@@ -416,11 +416,31 @@ void Config::ReadValues() {
416 } 416 }
417 417
418 ReadSetting("System", Settings::values.language_index); 418 ReadSetting("System", Settings::values.language_index);
419 ReadSetting("System", Settings::values.region_index);
419 ReadSetting("System", Settings::values.time_zone_index); 420 ReadSetting("System", Settings::values.time_zone_index);
421 ReadSetting("System", Settings::values.sound_index);
420 422
421 // Core 423 // Core
422 ReadSetting("Core", Settings::values.use_multi_core); 424 ReadSetting("Core", Settings::values.use_multi_core);
423 425
426 // Cpu
427 ReadSetting("Cpu", Settings::values.cpu_accuracy);
428 ReadSetting("Cpu", Settings::values.cpu_debug_mode);
429 ReadSetting("Cpu", Settings::values.cpuopt_page_tables);
430 ReadSetting("Cpu", Settings::values.cpuopt_block_linking);
431 ReadSetting("Cpu", Settings::values.cpuopt_return_stack_buffer);
432 ReadSetting("Cpu", Settings::values.cpuopt_fast_dispatcher);
433 ReadSetting("Cpu", Settings::values.cpuopt_context_elimination);
434 ReadSetting("Cpu", Settings::values.cpuopt_const_prop);
435 ReadSetting("Cpu", Settings::values.cpuopt_misc_ir);
436 ReadSetting("Cpu", Settings::values.cpuopt_reduce_misalign_checks);
437 ReadSetting("Cpu", Settings::values.cpuopt_fastmem);
438 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma);
439 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error);
440 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
441 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_inaccurate_nan);
442 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_fastmem_check);
443
424 // Renderer 444 // Renderer
425 ReadSetting("Renderer", Settings::values.renderer_backend); 445 ReadSetting("Renderer", Settings::values.renderer_backend);
426 ReadSetting("Renderer", Settings::values.renderer_debug); 446 ReadSetting("Renderer", Settings::values.renderer_debug);
@@ -440,6 +460,7 @@ void Config::ReadValues() {
440 ReadSetting("Renderer", Settings::values.use_nvdec_emulation); 460 ReadSetting("Renderer", Settings::values.use_nvdec_emulation);
441 ReadSetting("Renderer", Settings::values.accelerate_astc); 461 ReadSetting("Renderer", Settings::values.accelerate_astc);
442 ReadSetting("Renderer", Settings::values.use_fast_gpu_time); 462 ReadSetting("Renderer", Settings::values.use_fast_gpu_time);
463 ReadSetting("Renderer", Settings::values.use_caches_gc);
443 464
444 ReadSetting("Renderer", Settings::values.bg_red); 465 ReadSetting("Renderer", Settings::values.bg_red);
445 ReadSetting("Renderer", Settings::values.bg_green); 466 ReadSetting("Renderer", Settings::values.bg_green);
@@ -460,7 +481,6 @@ void Config::ReadValues() {
460 // Debugging 481 // Debugging
461 Settings::values.record_frame_times = 482 Settings::values.record_frame_times =
462 sdl2_config->GetBoolean("Debugging", "record_frame_times", false); 483 sdl2_config->GetBoolean("Debugging", "record_frame_times", false);
463 ReadSetting("Debugging", Settings::values.program_args);
464 ReadSetting("Debugging", Settings::values.dump_exefs); 484 ReadSetting("Debugging", Settings::values.dump_exefs);
465 ReadSetting("Debugging", Settings::values.dump_nso); 485 ReadSetting("Debugging", Settings::values.dump_nso);
466 ReadSetting("Debugging", Settings::values.enable_fs_access_log); 486 ReadSetting("Debugging", Settings::values.enable_fs_access_log);
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index cc9850aad..b362f10b4 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -65,6 +65,13 @@ button_screenshot=
65lstick= 65lstick=
66rstick= 66rstick=
67 67
68# To use the debug_pad, prepend `debug_pad_` before each button setting above.
69# i.e. debug_pad_button_a=
70
71# Enable debug pad inputs to the guest
72# 0 (default): Disabled, 1: Enabled
73debug_pad_enabled =
74
68# Whether to enable or disable vibration 75# Whether to enable or disable vibration
69# 0: Disabled, 1 (default): Enabled 76# 0: Disabled, 1 (default): Enabled
70vibration_enabled= 77vibration_enabled=
@@ -73,6 +80,10 @@ vibration_enabled=
73# 0 (default): Disabled, 1: Enabled 80# 0 (default): Disabled, 1: Enabled
74enable_accurate_vibrations= 81enable_accurate_vibrations=
75 82
83# Enables controller motion inputs
84# 0: Disabled, 1 (default): Enabled
85motion_enabled =
86
76# for motion input, the following devices are available: 87# for motion input, the following devices are available:
77# - "motion_emu" (default) for emulating motion input from mouse input. Required parameters: 88# - "motion_emu" (default) for emulating motion input from mouse input. Required parameters:
78# - "update_period": update period in milliseconds (default to 100) 89# - "update_period": update period in milliseconds (default to 100)
@@ -98,19 +109,30 @@ use_touch_from_button=
98#touch_from_button_maps_0_bind_1=bar 109#touch_from_button_maps_0_bind_1=bar
99# etc. 110# etc.
100 111
101# Most desktop operating systems do not expose a way to poll the motion state of the controllers 112# List of Cemuhook UDP servers, delimited by ','.
102# so as a way around it, cemuhook created a udp client/server protocol to broadcast the data directly 113# Default: 127.0.0.1:26760
103# from a controller device to the client program. Citra has a client that can connect and read 114# Example: 127.0.0.1:26760,123.4.5.67:26761
104# from any cemuhook compatible motion program. 115udp_input_servers =
105 116
106# IPv4 address of the udp input server (Default "127.0.0.1") 117# Enable controlling an axis via a mouse input.
107udp_input_address=127.0.0.1 118# 0 (default): Off, 1: On
119mouse_panning =
120
121# Set mouse sensitivity.
122# Default: 1.0
123mouse_panning_sensitivity =
124
125# Emulate an analog control stick from keyboard inputs.
126# 0 (default): Disabled, 1: Enabled
127emulate_analog_keyboard =
108 128
109# Port of the udp input server. (Default 26760) 129# Enable mouse inputs to the guest
110udp_input_port= 130# 0 (default): Disabled, 1: Enabled
131mouse_enabled =
111 132
112# The pad to request data on. Should be between 0 (Pad 1) and 3 (Pad 4). (Default 0) 133# Enable keyboard inputs to the guest
113udp_pad_index= 134# 0 (default): Disabled, 1: Enabled
135keyboard_enabled =
114 136
115[Core] 137[Core]
116# Whether to use multi-core for CPU emulation 138# Whether to use multi-core for CPU emulation
@@ -118,6 +140,17 @@ udp_pad_index=
118use_multi_core= 140use_multi_core=
119 141
120[Cpu] 142[Cpu]
143# Adjusts various optimizations.
144# Auto-select mode enables choice unsafe optimizations.
145# Accurate enables only safe optimizations.
146# Unsafe allows any unsafe optimizations.
147# 0 (default): Auto-select, 1: Accurate, 2: Enable unsafe optimizations
148cpu_accuracy =
149
150# Allow disabling safe optimizations.
151# 0 (default): Disabled, 1: Enabled
152cpu_debug_mode =
153
121# Enable inline page tables optimization (faster guest memory access) 154# Enable inline page tables optimization (faster guest memory access)
122# 0: Disabled, 1 (default): Enabled 155# 0: Disabled, 1 (default): Enabled
123cpuopt_page_tables = 156cpuopt_page_tables =
@@ -154,6 +187,31 @@ cpuopt_reduce_misalign_checks =
154# 0: Disabled, 1 (default): Enabled 187# 0: Disabled, 1 (default): Enabled
155cpuopt_fastmem = 188cpuopt_fastmem =
156 189
190# Enable unfuse FMA (improve performance on CPUs without FMA)
191# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
192# 0: Disabled, 1 (default): Enabled
193cpuopt_unsafe_unfuse_fma =
194
195# Enable faster FRSQRTE and FRECPE
196# Only enabled if cpu_accuracy is set to Unsafe.
197# 0: Disabled, 1 (default): Enabled
198cpuopt_unsafe_reduce_fp_error =
199
200# Enable faster ASIMD instructions (32 bits only)
201# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
202# 0: Disabled, 1 (default): Enabled
203cpuopt_unsafe_ignore_standard_fpcr =
204
205# Enable inaccurate NaN handling
206# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
207# 0: Disabled, 1 (default): Enabled
208cpuopt_unsafe_inaccurate_nan =
209
210# Disable address space checks (64 bits only)
211# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
212# 0: Disabled, 1 (default): Enabled
213cpuopt_unsafe_fastmem_check =
214
157[Renderer] 215[Renderer]
158# Which backend API to use. 216# Which backend API to use.
159# 0 (default): OpenGL, 1: Vulkan 217# 0 (default): OpenGL, 1: Vulkan
@@ -166,14 +224,6 @@ debug =
166# Which Vulkan physical device to use (defaults to 0) 224# Which Vulkan physical device to use (defaults to 0)
167vulkan_device = 225vulkan_device =
168 226
169# Whether to use software or hardware rendering.
170# 0: Software, 1 (default): Hardware
171use_hw_renderer =
172
173# Whether to use the Just-In-Time (JIT) compiler for shader emulation
174# 0: Interpreter (slow), 1 (default): JIT (fast)
175use_shader_jit =
176
177# Aspect ratio 227# Aspect ratio
178# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Stretch to Window 228# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Stretch to Window
179aspect_ratio = 229aspect_ratio =
@@ -211,57 +261,31 @@ use_frame_limit =
211frame_limit = 261frame_limit =
212 262
213# Whether to use disk based shader cache 263# Whether to use disk based shader cache
214# 0 (default): Off, 1 : On 264# 0: Off, 1 (default): On
215use_disk_shader_cache = 265use_disk_shader_cache =
216 266
217# Which gpu accuracy level to use 267# Which gpu accuracy level to use
218# 0 (Normal), 1 (High), 2 (Extreme) 268# 0: Normal, 1 (default): High, 2: Extreme (Very slow)
219gpu_accuracy = 269gpu_accuracy =
220 270
221# Whether to use asynchronous GPU emulation 271# Whether to use asynchronous GPU emulation
222# 0 : Off (slow), 1 (default): On (fast) 272# 0 : Off (slow), 1 (default): On (fast)
223use_asynchronous_gpu_emulation = 273use_asynchronous_gpu_emulation =
224 274
225# Forces VSync on the display thread. Usually doesn't impact performance, but on some drivers it can 275# Inform the guest that GPU operations completed more quickly than they did.
226# so only turn this off if you notice a speed difference.
227# 0: Off, 1 (default): On 276# 0: Off, 1 (default): On
228use_vsync = 277use_fast_gpu_time =
229 278
230# Whether to use garbage collection or not for GPU caches. 279# Whether to use garbage collection or not for GPU caches.
231# 0 (default): Off, 1: On 280# 0 (default): Off, 1: On
232use_caches_gc = 281use_caches_gc =
233 282
234# The clear color for the renderer. What shows up on the sides of the bottom screen. 283# The clear color for the renderer. What shows up on the sides of the bottom screen.
235# Must be in range of 0.0-1.0. Defaults to 1.0 for all. 284# Must be in range of 0-255. Defaults to 0 for all.
236bg_red = 285bg_red =
237bg_blue = 286bg_blue =
238bg_green = 287bg_green =
239 288
240[Layout]
241# Layout for the screen inside the render window.
242# 0 (default): Default Top Bottom Screen, 1: Single Screen Only, 2: Large Screen Small Screen
243layout_option =
244
245# Toggle custom layout (using the settings below) on or off.
246# 0 (default): Off, 1: On
247custom_layout =
248
249# Screen placement when using Custom layout option
250# 0x, 0y is the top left corner of the render window.
251custom_top_left =
252custom_top_top =
253custom_top_right =
254custom_top_bottom =
255custom_bottom_left =
256custom_bottom_top =
257custom_bottom_right =
258custom_bottom_bottom =
259
260# Swaps the prominent screen with the other screen.
261# For example, if Single Screen is chosen, setting this to 1 will display the bottom screen instead of the top screen.
262# 0 (default): Top Screen is prominent, 1: Bottom Screen is prominent
263swap_screen =
264
265[Audio] 289[Audio]
266# Which audio output engine to use. 290# Which audio output engine to use.
267# auto (default): Auto-select 291# auto (default): Auto-select
@@ -281,7 +305,7 @@ enable_audio_stretching =
281output_device = 305output_device =
282 306
283# Output volume. 307# Output volume.
284# 1.0 (default): 100%, 0.0; mute 308# 100 (default): 100%, 0; mute
285volume = 309volume =
286 310
287[Data Storage] 311[Data Storage]
@@ -308,10 +332,6 @@ gamecard_path =
308# 1 (default): Yes, 0: No 332# 1 (default): Yes, 0: No
309use_docked_mode = 333use_docked_mode =
310 334
311# Allow the use of NFC in games
312# 1 (default): Yes, 0 : No
313enable_nfc =
314
315# Sets the seed for the RNG generator built into the switch 335# Sets the seed for the RNG generator built into the switch
316# rng_seed will be ignored and randomly generated if rng_seed_enabled is false 336# rng_seed will be ignored and randomly generated if rng_seed_enabled is false
317rng_seed_enabled = 337rng_seed_enabled =
@@ -323,10 +343,6 @@ rng_seed =
323custom_rtc_enabled = 343custom_rtc_enabled =
324custom_rtc = 344custom_rtc =
325 345
326# Sets the account username, max length is 32 characters
327# yuzu (default)
328username = yuzu
329
330# Sets the systems language index 346# Sets the systems language index
331# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese, 347# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
332# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French, 348# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
@@ -335,17 +351,25 @@ language_index =
335 351
336# The system region that yuzu will use during emulation 352# The system region that yuzu will use during emulation
337# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan 353# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
338region_value = 354region_index =
339 355
340# The system time zone that yuzu will use during emulation 356# The system time zone that yuzu will use during emulation
341# 0: Auto-select (default), 1: Default (system archive value), Others: Index for specified time zone 357# 0: Auto-select (default), 1: Default (system archive value), Others: Index for specified time zone
342time_zone_index = 358time_zone_index =
343 359
360# Sets the sound output mode.
361# 0: Mono, 1 (default): Stereo, 2: Surround
362sound_index =
363
344[Miscellaneous] 364[Miscellaneous]
345# A filter which removes logs below a certain logging level. 365# A filter which removes logs below a certain logging level.
346# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical 366# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical
347log_filter = *:Trace 367log_filter = *:Trace
348 368
369# Use developer keys
370# 0 (default): Disabled, 1: Enabled
371use_dev_keys =
372
349[Debugging] 373[Debugging]
350# Record frame time data, can be found in the log directory. Boolean value 374# Record frame time data, can be found in the log directory. Boolean value
351record_frame_times = 375record_frame_times =
@@ -355,6 +379,8 @@ dump_exefs=false
355dump_nso=false 379dump_nso=false
356# Determines whether or not yuzu will save the filesystem access log. 380# Determines whether or not yuzu will save the filesystem access log.
357enable_fs_access_log=false 381enable_fs_access_log=false
382# Enables verbose reporting services
383reporting_services =
358# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode 384# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
359# false: Retail/Normal Mode (default), true: Kiosk Mode 385# false: Retail/Normal Mode (default), true: Kiosk Mode
360quest_flag = 386quest_flag =
@@ -393,4 +419,4 @@ title_ids =
393# For each title ID, have a key/value pair called `disabled_<title_id>` equal to the names of the add-ons to disable (sep. by '|') 419# For each title ID, have a key/value pair called `disabled_<title_id>` equal to the names of the add-ons to disable (sep. by '|')
394# e.x. disabled_0100000000010000 = Update|DLC <- disables Updates and DLC on Super Mario Odyssey 420# e.x. disabled_0100000000010000 = Update|DLC <- disables Updates and DLC on Super Mario Odyssey
395)"; 421)";
396} 422} // namespace DefaultINI
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 06b20c975..896181f0b 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -2,15 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
6#ifdef __clang__
7#pragma clang diagnostic push
8#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
9#endif
10#include <SDL.h> 5#include <SDL.h>
11#ifdef __clang__
12#pragma clang diagnostic pop
13#endif
14 6
15#include "common/logging/log.h" 7#include "common/logging/log.h"
16#include "common/scm_rev.h" 8#include "common/scm_rev.h"
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
index 837a44be7..eadb41790 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
@@ -7,15 +7,7 @@
7#include <string> 7#include <string>
8 8
9#define SDL_MAIN_HANDLED 9#define SDL_MAIN_HANDLED
10// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
11#ifdef __clang__
12#pragma clang diagnostic push
13#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
14#endif
15#include <SDL.h> 10#include <SDL.h>
16#ifdef __clang__
17#pragma clang diagnostic pop
18#endif
19 11
20#include <fmt/format.h> 12#include <fmt/format.h>
21#include <glad/glad.h> 13#include <glad/glad.h>
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
index 3401ad4b4..152e56db8 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
@@ -15,16 +15,13 @@
15#include "video_core/renderer_vulkan/renderer_vulkan.h" 15#include "video_core/renderer_vulkan/renderer_vulkan.h"
16#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h" 16#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h"
17 17
18// Include these late to avoid polluting everything with Xlib macros 18#ifdef YUZU_USE_EXTERNAL_SDL2
19// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307 19// Include this before SDL.h to prevent the external from including a dummy
20#ifdef __clang__ 20#define USING_GENERATED_CONFIG_H
21#pragma clang diagnostic push 21#include <SDL_config.h>
22#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
23#endif 22#endif
23
24#include <SDL.h> 24#include <SDL.h>
25#ifdef __clang__
26#pragma clang diagnostic pop
27#endif
28#include <SDL_syswm.h> 25#include <SDL_syswm.h>
29 26
30EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem) 27EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem)
@@ -51,6 +48,11 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste
51 window_info.type = Core::Frontend::WindowSystemType::Windows; 48 window_info.type = Core::Frontend::WindowSystemType::Windows;
52 window_info.render_surface = reinterpret_cast<void*>(wm.info.win.window); 49 window_info.render_surface = reinterpret_cast<void*>(wm.info.win.window);
53 break; 50 break;
51#else
52 case SDL_SYSWM_TYPE::SDL_SYSWM_WINDOWS:
53 LOG_CRITICAL(Frontend, "Window manager subsystem Windows not compiled");
54 std::exit(EXIT_FAILURE);
55 break;
54#endif 56#endif
55#ifdef SDL_VIDEO_DRIVER_X11 57#ifdef SDL_VIDEO_DRIVER_X11
56 case SDL_SYSWM_TYPE::SDL_SYSWM_X11: 58 case SDL_SYSWM_TYPE::SDL_SYSWM_X11:
@@ -58,6 +60,11 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste
58 window_info.display_connection = wm.info.x11.display; 60 window_info.display_connection = wm.info.x11.display;
59 window_info.render_surface = reinterpret_cast<void*>(wm.info.x11.window); 61 window_info.render_surface = reinterpret_cast<void*>(wm.info.x11.window);
60 break; 62 break;
63#else
64 case SDL_SYSWM_TYPE::SDL_SYSWM_X11:
65 LOG_CRITICAL(Frontend, "Window manager subsystem X11 not compiled");
66 std::exit(EXIT_FAILURE);
67 break;
61#endif 68#endif
62#ifdef SDL_VIDEO_DRIVER_WAYLAND 69#ifdef SDL_VIDEO_DRIVER_WAYLAND
63 case SDL_SYSWM_TYPE::SDL_SYSWM_WAYLAND: 70 case SDL_SYSWM_TYPE::SDL_SYSWM_WAYLAND:
@@ -65,6 +72,11 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste
65 window_info.display_connection = wm.info.wl.display; 72 window_info.display_connection = wm.info.wl.display;
66 window_info.render_surface = wm.info.wl.surface; 73 window_info.render_surface = wm.info.wl.surface;
67 break; 74 break;
75#else
76 case SDL_SYSWM_TYPE::SDL_SYSWM_WAYLAND:
77 LOG_CRITICAL(Frontend, "Window manager subsystem Wayland not compiled");
78 std::exit(EXIT_FAILURE);
79 break;
68#endif 80#endif
69 default: 81 default:
70 LOG_CRITICAL(Frontend, "Window manager subsystem not implemented"); 82 LOG_CRITICAL(Frontend, "Window manager subsystem not implemented");