summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CMakeModules/CopyYuzuQt5Deps.cmake3
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--appveyor.yml4
m---------externals/dynarmic0
-rw-r--r--src/common/assert.h7
-rw-r--r--src/common/common_funcs.h4
-rw-r--r--src/common/common_paths.h3
-rw-r--r--src/common/file_util.cpp113
-rw-r--r--src/common/file_util.h11
-rw-r--r--src/common/logging/backend.cpp157
-rw-r--r--src/common/logging/backend.h87
-rw-r--r--src/common/logging/filter.cpp8
-rw-r--r--src/common/logging/log.h14
-rw-r--r--src/common/memory_util.cpp24
-rw-r--r--src/common/param_package.cpp12
-rw-r--r--src/common/string_util.cpp8
-rw-r--r--src/common/swap.h2
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp4
-rw-r--r--src/core/core.cpp18
-rw-r--r--src/core/core_cpu.cpp4
-rw-r--r--src/core/core_timing.cpp16
-rw-r--r--src/core/file_sys/disk_filesystem.cpp20
-rw-r--r--src/core/file_sys/filesystem.cpp6
-rw-r--r--src/core/file_sys/partition_filesystem.cpp12
-rw-r--r--src/core/file_sys/program_metadata.cpp38
-rw-r--r--src/core/file_sys/romfs_factory.cpp6
-rw-r--r--src/core/file_sys/romfs_filesystem.cpp34
-rw-r--r--src/core/file_sys/savedata_factory.cpp13
-rw-r--r--src/core/file_sys/sdmc_factory.cpp4
-rw-r--r--src/core/frontend/input.h6
-rw-r--r--src/core/gdbstub/gdbstub.cpp71
-rw-r--r--src/core/hle/kernel/handle_table.cpp4
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp8
-rw-r--r--src/core/hle/kernel/process.cpp8
-rw-r--r--src/core/hle/kernel/resource_limit.cpp6
-rw-r--r--src/core/hle/kernel/scheduler.cpp6
-rw-r--r--src/core/hle/kernel/server_session.cpp6
-rw-r--r--src/core/hle/kernel/shared_memory.cpp10
-rw-r--r--src/core/hle/kernel/svc.cpp139
-rw-r--r--src/core/hle/kernel/thread.cpp12
-rw-r--r--src/core/hle/kernel/timer.cpp4
-rw-r--r--src/core/hle/kernel/vm_manager.cpp20
-rw-r--r--src/core/hle/service/acc/acc.cpp20
-rw-r--r--src/core/hle/service/am/am.cpp86
-rw-r--r--src/core/hle/service/am/applet_ae.cpp44
-rw-r--r--src/core/hle/service/am/applet_oe.cpp18
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp4
-rw-r--r--src/core/hle/service/apm/interface.cpp6
-rw-r--r--src/core/hle/service/audio/audio.cpp2
-rw-r--r--src/core/hle/service/audio/audout_u.cpp16
-rw-r--r--src/core/hle/service/audio/audren_u.cpp113
-rw-r--r--src/core/hle/service/audio/hwopus.cpp29
-rw-r--r--src/core/hle/service/audio/hwopus.h20
-rw-r--r--src/core/hle/service/bcat/module.cpp2
-rw-r--r--src/core/hle/service/fatal/fatal.cpp4
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp8
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp50
-rw-r--r--src/core/hle/service/friend/friend.cpp2
-rw-r--r--src/core/hle/service/hid/hid.cpp62
-rw-r--r--src/core/hle/service/lm/lm.cpp12
-rw-r--r--src/core/hle/service/mm/mm_u.cpp6
-rw-r--r--src/core/hle/service/nfp/nfp.cpp18
-rw-r--r--src/core/hle/service/nifm/nifm.cpp24
-rw-r--r--src/core/hle/service/ns/pl_u.cpp14
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp39
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp33
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp22
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp42
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp25
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.h2
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp14
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp4
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp2
-rw-r--r--src/core/hle/service/pctl/module.cpp6
-rw-r--r--src/core/hle/service/prepo/prepo.cpp2
-rw-r--r--src/core/hle/service/service.cpp8
-rw-r--r--src/core/hle/service/set/set.cpp2
-rw-r--r--src/core/hle/service/set/set_sys.cpp2
-rw-r--r--src/core/hle/service/sm/controller.cpp8
-rw-r--r--src/core/hle/service/sm/sm.cpp7
-rw-r--r--src/core/hle/service/sockets/bsd.cpp13
-rw-r--r--src/core/hle/service/sockets/sfdnsres.cpp2
-rw-r--r--src/core/hle/service/spl/module.cpp2
-rw-r--r--src/core/hle/service/ssl/ssl.cpp8
-rw-r--r--src/core/hle/service/time/time.cpp26
-rw-r--r--src/core/hle/service/vi/vi.cpp54
-rw-r--r--src/core/hw/hw.cpp8
-rw-r--r--src/core/hw/lcd.cpp8
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp8
-rw-r--r--src/core/loader/elf.cpp26
-rw-r--r--src/core/loader/linker.cpp4
-rw-r--r--src/core/loader/loader.cpp8
-rw-r--r--src/core/loader/nca.cpp14
-rw-r--r--src/core/loader/nso.cpp4
-rw-r--r--src/core/memory.cpp48
-rw-r--r--src/core/settings.h1
-rw-r--r--src/core/telemetry_session.cpp8
-rw-r--r--src/core/tracer/recorder.cpp2
-rw-r--r--src/input_common/sdl/sdl.cpp6
-rw-r--r--src/video_core/command_processor.cpp12
-rw-r--r--src/video_core/debug_utils/debug_utils.h6
-rw-r--r--src/video_core/engines/fermi_2d.cpp4
-rw-r--r--src/video_core/engines/maxwell_3d.cpp16
-rw-r--r--src/video_core/engines/maxwell_3d.h156
-rw-r--r--src/video_core/engines/maxwell_dma.cpp8
-rw-r--r--src/video_core/engines/shader_bytecode.h45
-rw-r--r--src/video_core/gpu.h10
-rw-r--r--src/video_core/memory_manager.cpp4
-rw-r--r--src/video_core/rasterizer_interface.h8
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp302
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h16
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp1535
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h432
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.h2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp173
-rw-r--r--src/video_core/renderer_opengl/gl_shader_util.cpp6
-rw-r--r--src/video_core/renderer_opengl/gl_shader_util.h8
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp79
-rw-r--r--src/video_core/renderer_opengl/gl_state.h43
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h89
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp17
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h2
-rw-r--r--src/video_core/textures/decoders.cpp42
-rw-r--r--src/video_core/textures/decoders.h6
-rw-r--r--src/video_core/video_core.cpp6
-rw-r--r--src/yuzu/CMakeLists.txt10
-rw-r--r--src/yuzu/bootmanager.cpp13
-rw-r--r--src/yuzu/configuration/config.cpp6
-rw-r--r--src/yuzu/configuration/configure_debug.cpp22
-rw-r--r--src/yuzu/configuration/configure_debug.ui41
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp2
-rw-r--r--src/yuzu/configuration/configure_graphics.ui7
-rw-r--r--src/yuzu/debugger/console.cpp45
-rw-r--r--src/yuzu/debugger/console.h14
-rw-r--r--src/yuzu/game_list.cpp5
-rw-r--r--src/yuzu/main.cpp24
-rw-r--r--src/yuzu/ui_settings.h3
-rw-r--r--src/yuzu_cmd/config.cpp8
-rw-r--r--src/yuzu_cmd/default_ini.h6
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp20
-rw-r--r--src/yuzu_cmd/yuzu.cpp34
145 files changed, 2670 insertions, 2594 deletions
diff --git a/.gitignore b/.gitignore
index 7999a40e1..5ec0d110b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@ src/common/scm_rev.cpp
11.idea/ 11.idea/
12.vs/ 12.vs/
13.vscode/ 13.vscode/
14CMakeLists.txt.user
14 15
15# *nix related 16# *nix related
16# Common convention for backup or temporary files 17# Common convention for backup or temporary files
diff --git a/CMakeModules/CopyYuzuQt5Deps.cmake b/CMakeModules/CopyYuzuQt5Deps.cmake
index ed24c742c..e4a9796c8 100644
--- a/CMakeModules/CopyYuzuQt5Deps.cmake
+++ b/CMakeModules/CopyYuzuQt5Deps.cmake
@@ -3,7 +3,9 @@ function(copy_yuzu_Qt5_deps target_dir)
3 set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/") 3 set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
4 set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin") 4 set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin")
5 set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/") 5 set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/")
6 set(Qt5_STYLES_DIR "${Qt5_DIR}/../../../plugins/styles/")
6 set(PLATFORMS ${DLL_DEST}platforms/) 7 set(PLATFORMS ${DLL_DEST}platforms/)
8 set(STYLES ${DLL_DEST}styles/)
7 windows_copy_files(${target_dir} ${Qt5_DLL_DIR} ${DLL_DEST} 9 windows_copy_files(${target_dir} ${Qt5_DLL_DIR} ${DLL_DEST}
8 icudt*.dll 10 icudt*.dll
9 icuin*.dll 11 icuin*.dll
@@ -14,4 +16,5 @@ function(copy_yuzu_Qt5_deps target_dir)
14 Qt5Widgets$<$<CONFIG:Debug>:d>.* 16 Qt5Widgets$<$<CONFIG:Debug>:d>.*
15 ) 17 )
16 windows_copy_files(yuzu ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*) 18 windows_copy_files(yuzu ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*)
19 windows_copy_files(yuzu ${Qt5_STYLES_DIR} ${STYLES} qwindowsvistastyle$<$<CONFIG:Debug>:d>.*)
17endfunction(copy_yuzu_Qt5_deps) 20endfunction(copy_yuzu_Qt5_deps)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ce0608db2..008dc5b50 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,6 @@
1# Reporting Issues 1# Reporting Issues
2 2
3**The issue tracker is not a support forum.** Unless you can provide precise *technical information* regarding an issue, you *should not post in it*. If you need support, first read the [FAQ](https://github.com/yuzu-emu/yuzu/wiki/FAQ) and then either visit our Discord server, [our forum](https://community.citra-emu.org) or ask in a general emulation forum such as [/r/emulation](https://www.reddit.com/r/emulation/). If you post support questions, generic messages to the developers or vague reports without technical details, they will be closed and locked. 3**The issue tracker is not a support forum.** Unless you can provide precise *technical information* regarding an issue, you *should not post in it*. If you need support, first read the [FAQ](https://github.com/yuzu-emu/yuzu/wiki/FAQ) and then either visit our [Discord server](https://discordapp.com/invite/u77vRWY), [our forum](https://community.citra-emu.org) or ask in a general emulation forum such as [/r/emulation](https://www.reddit.com/r/emulation/). If you post support questions, generic messages to the developers or vague reports without technical details, they will be closed and locked.
4 4
5If you believe you have a valid issue report, please post text or a screenshot from the log (the console window that opens alongside yuzu) and build version (hex string visible in the titlebar and zip filename), as well as your hardware and software information if applicable. 5If you believe you have a valid issue report, please post text or a screenshot from the log (the console window that opens alongside yuzu) and build version (hex string visible in the titlebar and zip filename), as well as your hardware and software information if applicable.
6 6
diff --git a/appveyor.yml b/appveyor.yml
index 72cda26a7..17d1b5fee 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -116,6 +116,7 @@ after_build:
116 116
117 mkdir $RELEASE_DIST 117 mkdir $RELEASE_DIST
118 mkdir $RELEASE_DIST/platforms 118 mkdir $RELEASE_DIST/platforms
119 mkdir $RELEASE_DIST/styles
119 120
120 # copy the compiled binaries and other release files to the release folder 121 # copy the compiled binaries and other release files to the release folder
121 Get-ChildItem "$CMAKE_BINARY_DIR" -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST 122 Get-ChildItem "$CMAKE_BINARY_DIR" -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST
@@ -136,6 +137,9 @@ after_build:
136 # copy the qt windows plugin dll to platforms 137 # copy the qt windows plugin dll to platforms
137 Copy-Item -path "C:/msys64/mingw64/share/qt5/plugins/platforms/qwindows.dll" -force -destination "$RELEASE_DIST/platforms" 138 Copy-Item -path "C:/msys64/mingw64/share/qt5/plugins/platforms/qwindows.dll" -force -destination "$RELEASE_DIST/platforms"
138 139
140 # copy the qt windows vista style dll to platforms
141 Copy-Item -path "C:/msys64/mingw64/share/qt5/plugins/styles/qwindowsvistastyle.dll" -force -destination "$RELEASE_DIST/styles"
142
139 7z a -tzip $MINGW_BUILD_ZIP $RELEASE_DIST\* 143 7z a -tzip $MINGW_BUILD_ZIP $RELEASE_DIST\*
140 7z a $MINGW_SEVENZIP $RELEASE_DIST 144 7z a $MINGW_SEVENZIP $RELEASE_DIST
141 } 145 }
diff --git a/externals/dynarmic b/externals/dynarmic
Subproject 990a569b7a5f2518fe08682f5ebf8536e5388d6 Subproject f7d11baa1cba82f7926058bebdeb6b1c23cff8e
diff --git a/src/common/assert.h b/src/common/assert.h
index 3ee07f6a2..0d4eddc19 100644
--- a/src/common/assert.h
+++ b/src/common/assert.h
@@ -30,15 +30,14 @@ __declspec(noinline, noreturn)
30#define ASSERT(_a_) \ 30#define ASSERT(_a_) \
31 do \ 31 do \
32 if (!(_a_)) { \ 32 if (!(_a_)) { \
33 assert_noinline_call([] { NGLOG_CRITICAL(Debug, "Assertion Failed!"); }); \ 33 assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); }); \
34 } \ 34 } \
35 while (0) 35 while (0)
36 36
37#define ASSERT_MSG(_a_, ...) \ 37#define ASSERT_MSG(_a_, ...) \
38 do \ 38 do \
39 if (!(_a_)) { \ 39 if (!(_a_)) { \
40 assert_noinline_call( \ 40 assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \
41 [&] { NGLOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \
42 } \ 41 } \
43 while (0) 42 while (0)
44 43
@@ -53,5 +52,5 @@ __declspec(noinline, noreturn)
53#define DEBUG_ASSERT_MSG(_a_, _desc_, ...) 52#define DEBUG_ASSERT_MSG(_a_, _desc_, ...)
54#endif 53#endif
55 54
56#define UNIMPLEMENTED() DEBUG_ASSERT_MSG(false, "Unimplemented code!") 55#define UNIMPLEMENTED() LOG_CRITICAL(Debug, "Unimplemented code!")
57#define UNIMPLEMENTED_MSG(...) ASSERT_MSG(false, __VA_ARGS__) 56#define UNIMPLEMENTED_MSG(...) ASSERT_MSG(false, __VA_ARGS__)
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index 7cf7b7997..995938d0b 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -4,7 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#if !defined(ARCHITECTURE_x86_64) && !defined(_M_ARM) 7#if !defined(ARCHITECTURE_x86_64) && !defined(ARCHITECTURE_ARM)
8#include <cstdlib> // for exit 8#include <cstdlib> // for exit
9#endif 9#endif
10#include "common/common_types.h" 10#include "common/common_types.h"
@@ -30,7 +30,7 @@
30 30
31#ifdef ARCHITECTURE_x86_64 31#ifdef ARCHITECTURE_x86_64
32#define Crash() __asm__ __volatile__("int $3") 32#define Crash() __asm__ __volatile__("int $3")
33#elif defined(_M_ARM) 33#elif defined(ARCHITECTURE_ARM)
34#define Crash() __asm__ __volatile__("trap") 34#define Crash() __asm__ __volatile__("trap")
35#else 35#else
36#define Crash() exit(1) 36#define Crash() exit(1)
diff --git a/src/common/common_paths.h b/src/common/common_paths.h
index 0a6132dab..9bf3efaf2 100644
--- a/src/common/common_paths.h
+++ b/src/common/common_paths.h
@@ -32,12 +32,15 @@
32#define SDMC_DIR "sdmc" 32#define SDMC_DIR "sdmc"
33#define NAND_DIR "nand" 33#define NAND_DIR "nand"
34#define SYSDATA_DIR "sysdata" 34#define SYSDATA_DIR "sysdata"
35#define LOG_DIR "log"
35 36
36// Filenames 37// Filenames
37// Files in the directory returned by GetUserPath(D_CONFIG_IDX) 38// Files in the directory returned by GetUserPath(D_CONFIG_IDX)
38#define EMU_CONFIG "emu.ini" 39#define EMU_CONFIG "emu.ini"
39#define DEBUGGER_CONFIG "debugger.ini" 40#define DEBUGGER_CONFIG "debugger.ini"
40#define LOGGER_CONFIG "logger.ini" 41#define LOGGER_CONFIG "logger.ini"
42// Files in the directory returned by GetUserPath(D_LOGS_IDX)
43#define LOG_FILE "yuzu_log.txt"
41 44
42// Sys files 45// Sys files
43#define SHARED_FONT "shared_font.bin" 46#define SHARED_FONT "shared_font.bin"
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 2d0b81c6e..7213abe18 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -118,7 +118,7 @@ bool IsDirectory(const std::string& filename) {
118#endif 118#endif
119 119
120 if (result < 0) { 120 if (result < 0) {
121 NGLOG_DEBUG(Common_Filesystem, "stat failed on {}: {}", filename, GetLastErrorMsg()); 121 LOG_DEBUG(Common_Filesystem, "stat failed on {}: {}", filename, GetLastErrorMsg());
122 return false; 122 return false;
123 } 123 }
124 124
@@ -128,29 +128,29 @@ bool IsDirectory(const std::string& filename) {
128// Deletes a given filename, return true on success 128// Deletes a given filename, return true on success
129// Doesn't supports deleting a directory 129// Doesn't supports deleting a directory
130bool Delete(const std::string& filename) { 130bool Delete(const std::string& filename) {
131 NGLOG_TRACE(Common_Filesystem, "file {}", filename); 131 LOG_TRACE(Common_Filesystem, "file {}", filename);
132 132
133 // Return true because we care about the file no 133 // Return true because we care about the file no
134 // being there, not the actual delete. 134 // being there, not the actual delete.
135 if (!Exists(filename)) { 135 if (!Exists(filename)) {
136 NGLOG_DEBUG(Common_Filesystem, "{} does not exist", filename); 136 LOG_DEBUG(Common_Filesystem, "{} does not exist", filename);
137 return true; 137 return true;
138 } 138 }
139 139
140 // We can't delete a directory 140 // We can't delete a directory
141 if (IsDirectory(filename)) { 141 if (IsDirectory(filename)) {
142 NGLOG_ERROR(Common_Filesystem, "Failed: {} is a directory", filename); 142 LOG_ERROR(Common_Filesystem, "Failed: {} is a directory", filename);
143 return false; 143 return false;
144 } 144 }
145 145
146#ifdef _WIN32 146#ifdef _WIN32
147 if (!DeleteFileW(Common::UTF8ToUTF16W(filename).c_str())) { 147 if (!DeleteFileW(Common::UTF8ToUTF16W(filename).c_str())) {
148 NGLOG_ERROR(Common_Filesystem, "DeleteFile failed on {}: {}", filename, GetLastErrorMsg()); 148 LOG_ERROR(Common_Filesystem, "DeleteFile failed on {}: {}", filename, GetLastErrorMsg());
149 return false; 149 return false;
150 } 150 }
151#else 151#else
152 if (unlink(filename.c_str()) == -1) { 152 if (unlink(filename.c_str()) == -1) {
153 NGLOG_ERROR(Common_Filesystem, "unlink failed on {}: {}", filename, GetLastErrorMsg()); 153 LOG_ERROR(Common_Filesystem, "unlink failed on {}: {}", filename, GetLastErrorMsg());
154 return false; 154 return false;
155 } 155 }
156#endif 156#endif
@@ -160,16 +160,16 @@ bool Delete(const std::string& filename) {
160 160
161// Returns true if successful, or path already exists. 161// Returns true if successful, or path already exists.
162bool CreateDir(const std::string& path) { 162bool CreateDir(const std::string& path) {
163 NGLOG_TRACE(Common_Filesystem, "directory {}", path); 163 LOG_TRACE(Common_Filesystem, "directory {}", path);
164#ifdef _WIN32 164#ifdef _WIN32
165 if (::CreateDirectoryW(Common::UTF8ToUTF16W(path).c_str(), nullptr)) 165 if (::CreateDirectoryW(Common::UTF8ToUTF16W(path).c_str(), nullptr))
166 return true; 166 return true;
167 DWORD error = GetLastError(); 167 DWORD error = GetLastError();
168 if (error == ERROR_ALREADY_EXISTS) { 168 if (error == ERROR_ALREADY_EXISTS) {
169 NGLOG_DEBUG(Common_Filesystem, "CreateDirectory failed on {}: already exists", path); 169 LOG_DEBUG(Common_Filesystem, "CreateDirectory failed on {}: already exists", path);
170 return true; 170 return true;
171 } 171 }
172 NGLOG_ERROR(Common_Filesystem, "CreateDirectory failed on {}: {}", path, error); 172 LOG_ERROR(Common_Filesystem, "CreateDirectory failed on {}: {}", path, error);
173 return false; 173 return false;
174#else 174#else
175 if (mkdir(path.c_str(), 0755) == 0) 175 if (mkdir(path.c_str(), 0755) == 0)
@@ -178,11 +178,11 @@ bool CreateDir(const std::string& path) {
178 int err = errno; 178 int err = errno;
179 179
180 if (err == EEXIST) { 180 if (err == EEXIST) {
181 NGLOG_DEBUG(Common_Filesystem, "mkdir failed on {}: already exists", path); 181 LOG_DEBUG(Common_Filesystem, "mkdir failed on {}: already exists", path);
182 return true; 182 return true;
183 } 183 }
184 184
185 NGLOG_ERROR(Common_Filesystem, "mkdir failed on {}: {}", path, strerror(err)); 185 LOG_ERROR(Common_Filesystem, "mkdir failed on {}: {}", path, strerror(err));
186 return false; 186 return false;
187#endif 187#endif
188} 188}
@@ -190,10 +190,10 @@ bool CreateDir(const std::string& path) {
190// Creates the full path of fullPath returns true on success 190// Creates the full path of fullPath returns true on success
191bool CreateFullPath(const std::string& fullPath) { 191bool CreateFullPath(const std::string& fullPath) {
192 int panicCounter = 100; 192 int panicCounter = 100;
193 NGLOG_TRACE(Common_Filesystem, "path {}", fullPath); 193 LOG_TRACE(Common_Filesystem, "path {}", fullPath);
194 194
195 if (FileUtil::Exists(fullPath)) { 195 if (FileUtil::Exists(fullPath)) {
196 NGLOG_DEBUG(Common_Filesystem, "path exists {}", fullPath); 196 LOG_DEBUG(Common_Filesystem, "path exists {}", fullPath);
197 return true; 197 return true;
198 } 198 }
199 199
@@ -209,14 +209,14 @@ bool CreateFullPath(const std::string& fullPath) {
209 // Include the '/' so the first call is CreateDir("/") rather than CreateDir("") 209 // Include the '/' so the first call is CreateDir("/") rather than CreateDir("")
210 std::string const subPath(fullPath.substr(0, position + 1)); 210 std::string const subPath(fullPath.substr(0, position + 1));
211 if (!FileUtil::IsDirectory(subPath) && !FileUtil::CreateDir(subPath)) { 211 if (!FileUtil::IsDirectory(subPath) && !FileUtil::CreateDir(subPath)) {
212 NGLOG_ERROR(Common, "CreateFullPath: directory creation failed"); 212 LOG_ERROR(Common, "CreateFullPath: directory creation failed");
213 return false; 213 return false;
214 } 214 }
215 215
216 // A safety check 216 // A safety check
217 panicCounter--; 217 panicCounter--;
218 if (panicCounter <= 0) { 218 if (panicCounter <= 0) {
219 NGLOG_ERROR(Common, "CreateFullPath: directory structure is too deep"); 219 LOG_ERROR(Common, "CreateFullPath: directory structure is too deep");
220 return false; 220 return false;
221 } 221 }
222 position++; 222 position++;
@@ -225,11 +225,11 @@ bool CreateFullPath(const std::string& fullPath) {
225 225
226// Deletes a directory filename, returns true on success 226// Deletes a directory filename, returns true on success
227bool DeleteDir(const std::string& filename) { 227bool DeleteDir(const std::string& filename) {
228 NGLOG_TRACE(Common_Filesystem, "directory {}", filename); 228 LOG_TRACE(Common_Filesystem, "directory {}", filename);
229 229
230 // check if a directory 230 // check if a directory
231 if (!FileUtil::IsDirectory(filename)) { 231 if (!FileUtil::IsDirectory(filename)) {
232 NGLOG_ERROR(Common_Filesystem, "Not a directory {}", filename); 232 LOG_ERROR(Common_Filesystem, "Not a directory {}", filename);
233 return false; 233 return false;
234 } 234 }
235 235
@@ -240,14 +240,14 @@ bool DeleteDir(const std::string& filename) {
240 if (rmdir(filename.c_str()) == 0) 240 if (rmdir(filename.c_str()) == 0)
241 return true; 241 return true;
242#endif 242#endif
243 NGLOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg()); 243 LOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg());
244 244
245 return false; 245 return false;
246} 246}
247 247
248// renames file srcFilename to destFilename, returns true on success 248// renames file srcFilename to destFilename, returns true on success
249bool Rename(const std::string& srcFilename, const std::string& destFilename) { 249bool Rename(const std::string& srcFilename, const std::string& destFilename) {
250 NGLOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename); 250 LOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename);
251#ifdef _WIN32 251#ifdef _WIN32
252 if (_wrename(Common::UTF8ToUTF16W(srcFilename).c_str(), 252 if (_wrename(Common::UTF8ToUTF16W(srcFilename).c_str(),
253 Common::UTF8ToUTF16W(destFilename).c_str()) == 0) 253 Common::UTF8ToUTF16W(destFilename).c_str()) == 0)
@@ -256,21 +256,21 @@ bool Rename(const std::string& srcFilename, const std::string& destFilename) {
256 if (rename(srcFilename.c_str(), destFilename.c_str()) == 0) 256 if (rename(srcFilename.c_str(), destFilename.c_str()) == 0)
257 return true; 257 return true;
258#endif 258#endif
259 NGLOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename, 259 LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename,
260 GetLastErrorMsg()); 260 GetLastErrorMsg());
261 return false; 261 return false;
262} 262}
263 263
264// copies file srcFilename to destFilename, returns true on success 264// copies file srcFilename to destFilename, returns true on success
265bool Copy(const std::string& srcFilename, const std::string& destFilename) { 265bool Copy(const std::string& srcFilename, const std::string& destFilename) {
266 NGLOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename); 266 LOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename);
267#ifdef _WIN32 267#ifdef _WIN32
268 if (CopyFileW(Common::UTF8ToUTF16W(srcFilename).c_str(), 268 if (CopyFileW(Common::UTF8ToUTF16W(srcFilename).c_str(),
269 Common::UTF8ToUTF16W(destFilename).c_str(), FALSE)) 269 Common::UTF8ToUTF16W(destFilename).c_str(), FALSE))
270 return true; 270 return true;
271 271
272 NGLOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename, 272 LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename,
273 GetLastErrorMsg()); 273 GetLastErrorMsg());
274 return false; 274 return false;
275#else 275#else
276 276
@@ -282,8 +282,8 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
282 // Open input file 282 // Open input file
283 FILE* input = fopen(srcFilename.c_str(), "rb"); 283 FILE* input = fopen(srcFilename.c_str(), "rb");
284 if (!input) { 284 if (!input) {
285 NGLOG_ERROR(Common_Filesystem, "opening input failed {} --> {}: {}", srcFilename, 285 LOG_ERROR(Common_Filesystem, "opening input failed {} --> {}: {}", srcFilename,
286 destFilename, GetLastErrorMsg()); 286 destFilename, GetLastErrorMsg());
287 return false; 287 return false;
288 } 288 }
289 289
@@ -291,8 +291,8 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
291 FILE* output = fopen(destFilename.c_str(), "wb"); 291 FILE* output = fopen(destFilename.c_str(), "wb");
292 if (!output) { 292 if (!output) {
293 fclose(input); 293 fclose(input);
294 NGLOG_ERROR(Common_Filesystem, "opening output failed {} --> {}: {}", srcFilename, 294 LOG_ERROR(Common_Filesystem, "opening output failed {} --> {}: {}", srcFilename,
295 destFilename, GetLastErrorMsg()); 295 destFilename, GetLastErrorMsg());
296 return false; 296 return false;
297 } 297 }
298 298
@@ -302,8 +302,8 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
302 size_t rnum = fread(buffer, sizeof(char), BSIZE, input); 302 size_t rnum = fread(buffer, sizeof(char), BSIZE, input);
303 if (rnum != BSIZE) { 303 if (rnum != BSIZE) {
304 if (ferror(input) != 0) { 304 if (ferror(input) != 0) {
305 NGLOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}", 305 LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}",
306 srcFilename, destFilename, GetLastErrorMsg()); 306 srcFilename, destFilename, GetLastErrorMsg());
307 goto bail; 307 goto bail;
308 } 308 }
309 } 309 }
@@ -311,8 +311,8 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
311 // write output 311 // write output
312 size_t wnum = fwrite(buffer, sizeof(char), rnum, output); 312 size_t wnum = fwrite(buffer, sizeof(char), rnum, output);
313 if (wnum != rnum) { 313 if (wnum != rnum) {
314 NGLOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename, 314 LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename,
315 destFilename, GetLastErrorMsg()); 315 destFilename, GetLastErrorMsg());
316 goto bail; 316 goto bail;
317 } 317 }
318 } 318 }
@@ -332,12 +332,12 @@ bail:
332// Returns the size of filename (64bit) 332// Returns the size of filename (64bit)
333u64 GetSize(const std::string& filename) { 333u64 GetSize(const std::string& filename) {
334 if (!Exists(filename)) { 334 if (!Exists(filename)) {
335 NGLOG_ERROR(Common_Filesystem, "failed {}: No such file", filename); 335 LOG_ERROR(Common_Filesystem, "failed {}: No such file", filename);
336 return 0; 336 return 0;
337 } 337 }
338 338
339 if (IsDirectory(filename)) { 339 if (IsDirectory(filename)) {
340 NGLOG_ERROR(Common_Filesystem, "failed {}: is a directory", filename); 340 LOG_ERROR(Common_Filesystem, "failed {}: is a directory", filename);
341 return 0; 341 return 0;
342 } 342 }
343 343
@@ -348,11 +348,11 @@ u64 GetSize(const std::string& filename) {
348 if (stat(filename.c_str(), &buf) == 0) 348 if (stat(filename.c_str(), &buf) == 0)
349#endif 349#endif
350 { 350 {
351 NGLOG_TRACE(Common_Filesystem, "{}: {}", filename, buf.st_size); 351 LOG_TRACE(Common_Filesystem, "{}: {}", filename, buf.st_size);
352 return buf.st_size; 352 return buf.st_size;
353 } 353 }
354 354
355 NGLOG_ERROR(Common_Filesystem, "Stat failed {}: {}", filename, GetLastErrorMsg()); 355 LOG_ERROR(Common_Filesystem, "Stat failed {}: {}", filename, GetLastErrorMsg());
356 return 0; 356 return 0;
357} 357}
358 358
@@ -360,7 +360,7 @@ u64 GetSize(const std::string& filename) {
360u64 GetSize(const int fd) { 360u64 GetSize(const int fd) {
361 struct stat buf; 361 struct stat buf;
362 if (fstat(fd, &buf) != 0) { 362 if (fstat(fd, &buf) != 0) {
363 NGLOG_ERROR(Common_Filesystem, "GetSize: stat failed {}: {}", fd, GetLastErrorMsg()); 363 LOG_ERROR(Common_Filesystem, "GetSize: stat failed {}: {}", fd, GetLastErrorMsg());
364 return 0; 364 return 0;
365 } 365 }
366 return buf.st_size; 366 return buf.st_size;
@@ -371,14 +371,12 @@ u64 GetSize(FILE* f) {
371 // can't use off_t here because it can be 32-bit 371 // can't use off_t here because it can be 32-bit
372 u64 pos = ftello(f); 372 u64 pos = ftello(f);
373 if (fseeko(f, 0, SEEK_END) != 0) { 373 if (fseeko(f, 0, SEEK_END) != 0) {
374 NGLOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", fmt::ptr(f), 374 LOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", fmt::ptr(f), GetLastErrorMsg());
375 GetLastErrorMsg());
376 return 0; 375 return 0;
377 } 376 }
378 u64 size = ftello(f); 377 u64 size = ftello(f);
379 if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { 378 if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) {
380 NGLOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", fmt::ptr(f), 379 LOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", fmt::ptr(f), GetLastErrorMsg());
381 GetLastErrorMsg());
382 return 0; 380 return 0;
383 } 381 }
384 return size; 382 return size;
@@ -386,10 +384,10 @@ u64 GetSize(FILE* f) {
386 384
387// creates an empty file filename, returns true on success 385// creates an empty file filename, returns true on success
388bool CreateEmptyFile(const std::string& filename) { 386bool CreateEmptyFile(const std::string& filename) {
389 NGLOG_TRACE(Common_Filesystem, "{}", filename); 387 LOG_TRACE(Common_Filesystem, "{}", filename);
390 388
391 if (!FileUtil::IOFile(filename, "wb")) { 389 if (!FileUtil::IOFile(filename, "wb")) {
392 NGLOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg()); 390 LOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg());
393 return false; 391 return false;
394 } 392 }
395 393
@@ -398,7 +396,7 @@ bool CreateEmptyFile(const std::string& filename) {
398 396
399bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string& directory, 397bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string& directory,
400 DirectoryEntryCallable callback) { 398 DirectoryEntryCallable callback) {
401 NGLOG_TRACE(Common_Filesystem, "directory {}", directory); 399 LOG_TRACE(Common_Filesystem, "directory {}", directory);
402 400
403 // How many files + directories we found 401 // How many files + directories we found
404 unsigned found_entries = 0; 402 unsigned found_entries = 0;
@@ -556,7 +554,7 @@ std::string GetCurrentDir() {
556 char* dir; 554 char* dir;
557 if (!(dir = getcwd(nullptr, 0))) { 555 if (!(dir = getcwd(nullptr, 0))) {
558#endif 556#endif
559 NGLOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: {}", GetLastErrorMsg()); 557 LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: {}", GetLastErrorMsg());
560 return nullptr; 558 return nullptr;
561 } 559 }
562#ifdef _WIN32 560#ifdef _WIN32
@@ -676,11 +674,11 @@ std::string GetSysDirectory() {
676#endif 674#endif
677 sysDir += DIR_SEP; 675 sysDir += DIR_SEP;
678 676
679 NGLOG_DEBUG(Common_Filesystem, "Setting to {}:", sysDir); 677 LOG_DEBUG(Common_Filesystem, "Setting to {}:", sysDir);
680 return sysDir; 678 return sysDir;
681} 679}
682 680
683// Returns a string with a Citra data dir or file in the user's home 681// Returns a string with a yuzu data dir or file in the user's home
684// directory. To be used in "multi-user" mode (that is, installed). 682// directory. To be used in "multi-user" mode (that is, installed).
685const std::string& GetUserPath(const unsigned int DirIDX, const std::string& newPath) { 683const std::string& GetUserPath(const unsigned int DirIDX, const std::string& newPath) {
686 static std::string paths[NUM_PATH_INDICES]; 684 static std::string paths[NUM_PATH_INDICES];
@@ -692,7 +690,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string& new
692 if (!FileUtil::IsDirectory(paths[D_USER_IDX])) { 690 if (!FileUtil::IsDirectory(paths[D_USER_IDX])) {
693 paths[D_USER_IDX] = AppDataRoamingDirectory() + DIR_SEP EMU_DATA_DIR DIR_SEP; 691 paths[D_USER_IDX] = AppDataRoamingDirectory() + DIR_SEP EMU_DATA_DIR DIR_SEP;
694 } else { 692 } else {
695 NGLOG_INFO(Common_Filesystem, "Using the local user directory"); 693 LOG_INFO(Common_Filesystem, "Using the local user directory");
696 } 694 }
697 695
698 paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; 696 paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
@@ -715,11 +713,13 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string& new
715 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; 713 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
716 paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; 714 paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP;
717 paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; 715 paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP;
716 // TODO: Put the logs in a better location for each OS
717 paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOG_DIR DIR_SEP;
718 } 718 }
719 719
720 if (!newPath.empty()) { 720 if (!newPath.empty()) {
721 if (!FileUtil::IsDirectory(newPath)) { 721 if (!FileUtil::IsDirectory(newPath)) {
722 NGLOG_ERROR(Common_Filesystem, "Invalid path specified {}", newPath); 722 LOG_ERROR(Common_Filesystem, "Invalid path specified {}", newPath);
723 return paths[DirIDX]; 723 return paths[DirIDX];
724 } else { 724 } else {
725 paths[DirIDX] = newPath; 725 paths[DirIDX] = newPath;
@@ -801,8 +801,8 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
801 801
802IOFile::IOFile() {} 802IOFile::IOFile() {}
803 803
804IOFile::IOFile(const std::string& filename, const char openmode[]) { 804IOFile::IOFile(const std::string& filename, const char openmode[], int flags) {
805 Open(filename, openmode); 805 Open(filename, openmode, flags);
806} 806}
807 807
808IOFile::~IOFile() { 808IOFile::~IOFile() {
@@ -823,11 +823,16 @@ void IOFile::Swap(IOFile& other) noexcept {
823 std::swap(m_good, other.m_good); 823 std::swap(m_good, other.m_good);
824} 824}
825 825
826bool IOFile::Open(const std::string& filename, const char openmode[]) { 826bool IOFile::Open(const std::string& filename, const char openmode[], int flags) {
827 Close(); 827 Close();
828#ifdef _WIN32 828#ifdef _WIN32
829 _wfopen_s(&m_file, Common::UTF8ToUTF16W(filename).c_str(), 829 if (flags != 0) {
830 Common::UTF8ToUTF16W(openmode).c_str()); 830 m_file = _wfsopen(Common::UTF8ToUTF16W(filename).c_str(),
831 Common::UTF8ToUTF16W(openmode).c_str(), flags);
832 } else {
833 _wfopen_s(&m_file, Common::UTF8ToUTF16W(filename).c_str(),
834 Common::UTF8ToUTF16W(openmode).c_str());
835 }
831#else 836#else
832 m_file = fopen(filename.c_str(), openmode); 837 m_file = fopen(filename.c_str(), openmode);
833#endif 838#endif
diff --git a/src/common/file_util.h b/src/common/file_util.h
index fc6b3ea46..5bc7fbf7c 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -156,7 +156,10 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
156class IOFile : public NonCopyable { 156class IOFile : public NonCopyable {
157public: 157public:
158 IOFile(); 158 IOFile();
159 IOFile(const std::string& filename, const char openmode[]); 159 // flags is used for windows specific file open mode flags, which
160 // allows yuzu to open the logs in shared write mode, so that the file
161 // isn't considered "locked" while yuzu is open and people can open the log file and view it
162 IOFile(const std::string& filename, const char openmode[], int flags = 0);
160 163
161 ~IOFile(); 164 ~IOFile();
162 165
@@ -165,7 +168,7 @@ public:
165 168
166 void Swap(IOFile& other) noexcept; 169 void Swap(IOFile& other) noexcept;
167 170
168 bool Open(const std::string& filename, const char openmode[]); 171 bool Open(const std::string& filename, const char openmode[], int flags = 0);
169 bool Close(); 172 bool Close();
170 173
171 template <typename T> 174 template <typename T>
@@ -220,6 +223,10 @@ public:
220 return WriteArray(&object, 1); 223 return WriteArray(&object, 1);
221 } 224 }
222 225
226 size_t WriteString(const std::string& str) {
227 return WriteArray(str.c_str(), str.length());
228 }
229
223 bool IsOpen() const { 230 bool IsOpen() const {
224 return nullptr != m_file; 231 return nullptr != m_file;
225 } 232 }
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index c26b20062..242914c6a 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -2,16 +2,145 @@
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 <utility> 5#include <algorithm>
6#include <array>
7#include <chrono>
8#include <condition_variable>
9#include <memory>
10#include <thread>
11#ifdef _WIN32
12#include <share.h> // For _SH_DENYWR
13#else
14#define _SH_DENYWR 0
15#endif
6#include "common/assert.h" 16#include "common/assert.h"
17#include "common/common_funcs.h" // snprintf compatibility define
7#include "common/logging/backend.h" 18#include "common/logging/backend.h"
8#include "common/logging/filter.h"
9#include "common/logging/log.h" 19#include "common/logging/log.h"
10#include "common/logging/text_formatter.h" 20#include "common/logging/text_formatter.h"
11#include "common/string_util.h" 21#include "common/string_util.h"
22#include "common/threadsafe_queue.h"
12 23
13namespace Log { 24namespace Log {
14 25
26/**
27 * Static state as a singleton.
28 */
29class Impl {
30public:
31 static Impl& Instance() {
32 static Impl backend;
33 return backend;
34 }
35
36 Impl(Impl const&) = delete;
37 const Impl& operator=(Impl const&) = delete;
38
39 void PushEntry(Entry e) {
40 std::lock_guard<std::mutex> lock(message_mutex);
41 message_queue.Push(std::move(e));
42 message_cv.notify_one();
43 }
44
45 void AddBackend(std::unique_ptr<Backend> backend) {
46 std::lock_guard<std::mutex> lock(writing_mutex);
47 backends.push_back(std::move(backend));
48 }
49
50 void RemoveBackend(const std::string& backend_name) {
51 std::lock_guard<std::mutex> lock(writing_mutex);
52 auto it = std::remove_if(backends.begin(), backends.end(), [&backend_name](const auto& i) {
53 return !strcmp(i->GetName(), backend_name.c_str());
54 });
55 backends.erase(it, backends.end());
56 }
57
58 const Filter& GetGlobalFilter() const {
59 return filter;
60 }
61
62 void SetGlobalFilter(const Filter& f) {
63 filter = f;
64 }
65
66 Backend* GetBackend(const std::string& backend_name) {
67 auto it = std::find_if(backends.begin(), backends.end(), [&backend_name](const auto& i) {
68 return !strcmp(i->GetName(), backend_name.c_str());
69 });
70 if (it == backends.end())
71 return nullptr;
72 return it->get();
73 }
74
75private:
76 Impl() {
77 backend_thread = std::thread([&] {
78 Entry entry;
79 auto write_logs = [&](Entry& e) {
80 std::lock_guard<std::mutex> lock(writing_mutex);
81 for (const auto& backend : backends) {
82 backend->Write(e);
83 }
84 };
85 while (true) {
86 std::unique_lock<std::mutex> lock(message_mutex);
87 message_cv.wait(lock, [&] { return !running || message_queue.Pop(entry); });
88 if (!running) {
89 break;
90 }
91 write_logs(entry);
92 }
93 // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case
94 // where a system is repeatedly spamming logs even on close.
95 constexpr int MAX_LOGS_TO_WRITE = 100;
96 int logs_written = 0;
97 while (logs_written++ < MAX_LOGS_TO_WRITE && message_queue.Pop(entry)) {
98 write_logs(entry);
99 }
100 });
101 }
102
103 ~Impl() {
104 running = false;
105 message_cv.notify_one();
106 backend_thread.join();
107 }
108
109 std::atomic_bool running{true};
110 std::mutex message_mutex, writing_mutex;
111 std::condition_variable message_cv;
112 std::thread backend_thread;
113 std::vector<std::unique_ptr<Backend>> backends;
114 Common::MPSCQueue<Log::Entry> message_queue;
115 Filter filter;
116};
117
118void ConsoleBackend::Write(const Entry& entry) {
119 PrintMessage(entry);
120}
121
122void ColorConsoleBackend::Write(const Entry& entry) {
123 PrintColoredMessage(entry);
124}
125
126// _SH_DENYWR allows read only access to the file for other programs.
127// It is #defined to 0 on other platforms
128FileBackend::FileBackend(const std::string& filename)
129 : file(filename, "w", _SH_DENYWR), bytes_written(0) {}
130
131void FileBackend::Write(const Entry& entry) {
132 // prevent logs from going over the maximum size (in case its spamming and the user doesn't
133 // know)
134 constexpr size_t MAX_BYTES_WRITTEN = 50 * 1024L * 1024L;
135 if (!file.IsOpen() || bytes_written > MAX_BYTES_WRITTEN) {
136 return;
137 }
138 bytes_written += file.WriteString(FormatLogMessage(entry) + '\n');
139 if (entry.log_level >= Level::Error) {
140 file.Flush();
141 }
142}
143
15/// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this. 144/// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this.
16#define ALL_LOG_CLASSES() \ 145#define ALL_LOG_CLASSES() \
17 CLS(Log) \ 146 CLS(Log) \
@@ -125,20 +254,32 @@ Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsign
125 return entry; 254 return entry;
126} 255}
127 256
128static Filter* filter = nullptr; 257void SetGlobalFilter(const Filter& filter) {
258 Impl::Instance().SetGlobalFilter(filter);
259}
260
261void AddBackend(std::unique_ptr<Backend> backend) {
262 Impl::Instance().AddBackend(std::move(backend));
263}
129 264
130void SetFilter(Filter* new_filter) { 265void RemoveBackend(const std::string& backend_name) {
131 filter = new_filter; 266 Impl::Instance().RemoveBackend(backend_name);
267}
268
269Backend* GetBackend(const std::string& backend_name) {
270 return Impl::Instance().GetBackend(backend_name);
132} 271}
133 272
134void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, 273void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
135 unsigned int line_num, const char* function, const char* format, 274 unsigned int line_num, const char* function, const char* format,
136 const fmt::format_args& args) { 275 const fmt::format_args& args) {
137 if (filter && !filter->CheckMessage(log_class, log_level)) 276 auto filter = Impl::Instance().GetGlobalFilter();
277 if (!filter.CheckMessage(log_class, log_level))
138 return; 278 return;
279
139 Entry entry = 280 Entry entry =
140 CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args)); 281 CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args));
141 282
142 PrintColoredMessage(entry); 283 Impl::Instance().PushEntry(std::move(entry));
143} 284}
144} // namespace Log 285} // namespace Log \ No newline at end of file
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h
index 7e81efb23..57cdf6b2d 100644
--- a/src/common/logging/backend.h
+++ b/src/common/logging/backend.h
@@ -1,13 +1,15 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
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
5#pragma once 4#pragma once
6 5
7#include <chrono> 6#include <chrono>
8#include <cstdarg> 7#include <cstdarg>
8#include <memory>
9#include <string> 9#include <string>
10#include <utility> 10#include <utility>
11#include "common/file_util.h"
12#include "common/logging/filter.h"
11#include "common/logging/log.h" 13#include "common/logging/log.h"
12 14
13namespace Log { 15namespace Log {
@@ -35,6 +37,80 @@ struct Entry {
35}; 37};
36 38
37/** 39/**
40 * Interface for logging backends. As loggers can be created and removed at runtime, this can be
41 * used by a frontend for adding a custom logging backend as needed
42 */
43class Backend {
44public:
45 virtual ~Backend() = default;
46 virtual void SetFilter(const Filter& new_filter) {
47 filter = new_filter;
48 }
49 virtual const char* GetName() const = 0;
50 virtual void Write(const Entry& entry) = 0;
51
52private:
53 Filter filter;
54};
55
56/**
57 * Backend that writes to stderr without any color commands
58 */
59class ConsoleBackend : public Backend {
60public:
61 static const char* Name() {
62 return "console";
63 }
64 const char* GetName() const override {
65 return Name();
66 }
67 void Write(const Entry& entry) override;
68};
69
70/**
71 * Backend that writes to stderr and with color
72 */
73class ColorConsoleBackend : public Backend {
74public:
75 static const char* Name() {
76 return "color_console";
77 }
78
79 const char* GetName() const override {
80 return Name();
81 }
82 void Write(const Entry& entry) override;
83};
84
85/**
86 * Backend that writes to a file passed into the constructor
87 */
88class FileBackend : public Backend {
89public:
90 explicit FileBackend(const std::string& filename);
91
92 static const char* Name() {
93 return "file";
94 }
95
96 const char* GetName() const override {
97 return Name();
98 }
99
100 void Write(const Entry& entry) override;
101
102private:
103 FileUtil::IOFile file;
104 size_t bytes_written;
105};
106
107void AddBackend(std::unique_ptr<Backend> backend);
108
109void RemoveBackend(const std::string& backend_name);
110
111Backend* GetBackend(const std::string& backend_name);
112
113/**
38 * Returns the name of the passed log class as a C-string. Subclasses are separated by periods 114 * Returns the name of the passed log class as a C-string. Subclasses are separated by periods
39 * instead of underscores as in the enumeration. 115 * instead of underscores as in the enumeration.
40 */ 116 */
@@ -49,5 +125,10 @@ const char* GetLevelName(Level log_level);
49Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, 125Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
50 const char* function, std::string message); 126 const char* function, std::string message);
51 127
52void SetFilter(Filter* filter); 128/**
53} // namespace Log 129 * The global filter will prevent any messages from even being processed if they are filtered. Each
130 * backend can have a filter, but if the level is lower than the global filter, the backend will
131 * never get the message
132 */
133void SetGlobalFilter(const Filter& filter);
134} // namespace Log \ No newline at end of file
diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp
index 428723dce..4e783a577 100644
--- a/src/common/logging/filter.cpp
+++ b/src/common/logging/filter.cpp
@@ -65,14 +65,14 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
65 const std::string::const_iterator end) { 65 const std::string::const_iterator end) {
66 auto level_separator = std::find(begin, end, ':'); 66 auto level_separator = std::find(begin, end, ':');
67 if (level_separator == end) { 67 if (level_separator == end) {
68 NGLOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: %s", 68 LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: {}",
69 std::string(begin, end).c_str()); 69 std::string(begin, end));
70 return false; 70 return false;
71 } 71 }
72 72
73 const Level level = GetLevelByName(level_separator + 1, end); 73 const Level level = GetLevelByName(level_separator + 1, end);
74 if (level == Level::Count) { 74 if (level == Level::Count) {
75 NGLOG_ERROR(Log, "Unknown log level in filter: %s", std::string(begin, end).c_str()); 75 LOG_ERROR(Log, "Unknown log level in filter: {}", std::string(begin, end));
76 return false; 76 return false;
77 } 77 }
78 78
@@ -83,7 +83,7 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
83 83
84 const Class log_class = GetClassByName(begin, level_separator); 84 const Class log_class = GetClassByName(begin, level_separator);
85 if (log_class == Class::Count) { 85 if (log_class == Class::Count) {
86 NGLOG_ERROR(Log, "Unknown log class in filter: %s", std::string(begin, end).c_str()); 86 LOG_ERROR(Log, "Unknown log class in filter: {}", std::string(begin, end));
87 return false; 87 return false;
88 } 88 }
89 89
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index c5015531c..e96c90e16 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -109,25 +109,25 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
109} // namespace Log 109} // namespace Log
110 110
111#ifdef _DEBUG 111#ifdef _DEBUG
112#define NGLOG_TRACE(log_class, ...) \ 112#define LOG_TRACE(log_class, ...) \
113 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Trace, __FILE__, __LINE__, \ 113 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Trace, __FILE__, __LINE__, \
114 __func__, __VA_ARGS__) 114 __func__, __VA_ARGS__)
115#else 115#else
116#define NGLOG_TRACE(log_class, fmt, ...) (void(0)) 116#define LOG_TRACE(log_class, fmt, ...) (void(0))
117#endif 117#endif
118 118
119#define NGLOG_DEBUG(log_class, ...) \ 119#define LOG_DEBUG(log_class, ...) \
120 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Debug, __FILE__, __LINE__, \ 120 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Debug, __FILE__, __LINE__, \
121 __func__, __VA_ARGS__) 121 __func__, __VA_ARGS__)
122#define NGLOG_INFO(log_class, ...) \ 122#define LOG_INFO(log_class, ...) \
123 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Info, __FILE__, __LINE__, \ 123 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Info, __FILE__, __LINE__, \
124 __func__, __VA_ARGS__) 124 __func__, __VA_ARGS__)
125#define NGLOG_WARNING(log_class, ...) \ 125#define LOG_WARNING(log_class, ...) \
126 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Warning, __FILE__, __LINE__, \ 126 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Warning, __FILE__, __LINE__, \
127 __func__, __VA_ARGS__) 127 __func__, __VA_ARGS__)
128#define NGLOG_ERROR(log_class, ...) \ 128#define LOG_ERROR(log_class, ...) \
129 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Error, __FILE__, __LINE__, \ 129 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Error, __FILE__, __LINE__, \
130 __func__, __VA_ARGS__) 130 __func__, __VA_ARGS__)
131#define NGLOG_CRITICAL(log_class, ...) \ 131#define LOG_CRITICAL(log_class, ...) \
132 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Critical, __FILE__, __LINE__, \ 132 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Critical, __FILE__, __LINE__, \
133 __func__, __VA_ARGS__) 133 __func__, __VA_ARGS__)
diff --git a/src/common/memory_util.cpp b/src/common/memory_util.cpp
index 4d1ec8fb9..09462ccee 100644
--- a/src/common/memory_util.cpp
+++ b/src/common/memory_util.cpp
@@ -16,7 +16,7 @@
16#include <sys/mman.h> 16#include <sys/mman.h>
17#endif 17#endif
18 18
19#if !defined(_WIN32) && defined(ARCHITECTURE_X64) && !defined(MAP_32BIT) 19#if !defined(_WIN32) && defined(ARCHITECTURE_x86_64) && !defined(MAP_32BIT)
20#include <unistd.h> 20#include <unistd.h>
21#define PAGE_MASK (getpagesize() - 1) 21#define PAGE_MASK (getpagesize() - 1)
22#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK)) 22#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
@@ -30,7 +30,7 @@ void* AllocateExecutableMemory(size_t size, bool low) {
30 void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 30 void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
31#else 31#else
32 static char* map_hint = nullptr; 32 static char* map_hint = nullptr;
33#if defined(ARCHITECTURE_X64) && !defined(MAP_32BIT) 33#if defined(ARCHITECTURE_x86_64) && !defined(MAP_32BIT)
34 // This OS has no flag to enforce allocation below the 4 GB boundary, 34 // This OS has no flag to enforce allocation below the 4 GB boundary,
35 // but if we hint that we want a low address it is very likely we will 35 // but if we hint that we want a low address it is very likely we will
36 // get one. 36 // get one.
@@ -42,7 +42,7 @@ void* AllocateExecutableMemory(size_t size, bool low) {
42#endif 42#endif
43 void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, 43 void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
44 MAP_ANON | MAP_PRIVATE 44 MAP_ANON | MAP_PRIVATE
45#if defined(ARCHITECTURE_X64) && defined(MAP_32BIT) 45#if defined(ARCHITECTURE_x86_64) && defined(MAP_32BIT)
46 | (low ? MAP_32BIT : 0) 46 | (low ? MAP_32BIT : 0)
47#endif 47#endif
48 , 48 ,
@@ -55,9 +55,9 @@ void* AllocateExecutableMemory(size_t size, bool low) {
55 if (ptr == MAP_FAILED) { 55 if (ptr == MAP_FAILED) {
56 ptr = nullptr; 56 ptr = nullptr;
57#endif 57#endif
58 NGLOG_ERROR(Common_Memory, "Failed to allocate executable memory"); 58 LOG_ERROR(Common_Memory, "Failed to allocate executable memory");
59 } 59 }
60#if !defined(_WIN32) && defined(ARCHITECTURE_X64) && !defined(MAP_32BIT) 60#if !defined(_WIN32) && defined(ARCHITECTURE_x86_64) && !defined(MAP_32BIT)
61 else { 61 else {
62 if (low) { 62 if (low) {
63 map_hint += size; 63 map_hint += size;
@@ -68,7 +68,7 @@ void* AllocateExecutableMemory(size_t size, bool low) {
68 68
69#if EMU_ARCH_BITS == 64 69#if EMU_ARCH_BITS == 64
70 if ((u64)ptr >= 0x80000000 && low == true) 70 if ((u64)ptr >= 0x80000000 && low == true)
71 NGLOG_ERROR(Common_Memory, "Executable memory ended up above 2GB!"); 71 LOG_ERROR(Common_Memory, "Executable memory ended up above 2GB!");
72#endif 72#endif
73 73
74 return ptr; 74 return ptr;
@@ -85,7 +85,7 @@ void* AllocateMemoryPages(size_t size) {
85#endif 85#endif
86 86
87 if (ptr == nullptr) 87 if (ptr == nullptr)
88 NGLOG_ERROR(Common_Memory, "Failed to allocate raw memory"); 88 LOG_ERROR(Common_Memory, "Failed to allocate raw memory");
89 89
90 return ptr; 90 return ptr;
91} 91}
@@ -99,12 +99,12 @@ void* AllocateAlignedMemory(size_t size, size_t alignment) {
99 ptr = memalign(alignment, size); 99 ptr = memalign(alignment, size);
100#else 100#else
101 if (posix_memalign(&ptr, alignment, size) != 0) 101 if (posix_memalign(&ptr, alignment, size) != 0)
102 NGLOG_ERROR(Common_Memory, "Failed to allocate aligned memory"); 102 LOG_ERROR(Common_Memory, "Failed to allocate aligned memory");
103#endif 103#endif
104#endif 104#endif
105 105
106 if (ptr == nullptr) 106 if (ptr == nullptr)
107 NGLOG_ERROR(Common_Memory, "Failed to allocate aligned memory"); 107 LOG_ERROR(Common_Memory, "Failed to allocate aligned memory");
108 108
109 return ptr; 109 return ptr;
110} 110}
@@ -113,7 +113,7 @@ void FreeMemoryPages(void* ptr, size_t size) {
113 if (ptr) { 113 if (ptr) {
114#ifdef _WIN32 114#ifdef _WIN32
115 if (!VirtualFree(ptr, 0, MEM_RELEASE)) 115 if (!VirtualFree(ptr, 0, MEM_RELEASE))
116 NGLOG_ERROR(Common_Memory, "FreeMemoryPages failed!\n{}", GetLastErrorMsg()); 116 LOG_ERROR(Common_Memory, "FreeMemoryPages failed!\n{}", GetLastErrorMsg());
117#else 117#else
118 munmap(ptr, size); 118 munmap(ptr, size);
119#endif 119#endif
@@ -134,7 +134,7 @@ void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) {
134#ifdef _WIN32 134#ifdef _WIN32
135 DWORD oldValue; 135 DWORD oldValue;
136 if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) 136 if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
137 NGLOG_ERROR(Common_Memory, "WriteProtectMemory failed!\n{}", GetLastErrorMsg()); 137 LOG_ERROR(Common_Memory, "WriteProtectMemory failed!\n{}", GetLastErrorMsg());
138#else 138#else
139 mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ); 139 mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ);
140#endif 140#endif
@@ -145,7 +145,7 @@ void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) {
145 DWORD oldValue; 145 DWORD oldValue;
146 if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, 146 if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
147 &oldValue)) 147 &oldValue))
148 NGLOG_ERROR(Common_Memory, "UnWriteProtectMemory failed!\n{}", GetLastErrorMsg()); 148 LOG_ERROR(Common_Memory, "UnWriteProtectMemory failed!\n{}", GetLastErrorMsg());
149#else 149#else
150 mprotect(ptr, size, 150 mprotect(ptr, size,
151 allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ); 151 allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ);
diff --git a/src/common/param_package.cpp b/src/common/param_package.cpp
index ab0154133..e0df430ab 100644
--- a/src/common/param_package.cpp
+++ b/src/common/param_package.cpp
@@ -25,7 +25,7 @@ ParamPackage::ParamPackage(const std::string& serialized) {
25 std::vector<std::string> key_value; 25 std::vector<std::string> key_value;
26 Common::SplitString(pair, KEY_VALUE_SEPARATOR, key_value); 26 Common::SplitString(pair, KEY_VALUE_SEPARATOR, key_value);
27 if (key_value.size() != 2) { 27 if (key_value.size() != 2) {
28 NGLOG_ERROR(Common, "invalid key pair {}", pair); 28 LOG_ERROR(Common, "invalid key pair {}", pair);
29 continue; 29 continue;
30 } 30 }
31 31
@@ -64,7 +64,7 @@ std::string ParamPackage::Serialize() const {
64std::string ParamPackage::Get(const std::string& key, const std::string& default_value) const { 64std::string ParamPackage::Get(const std::string& key, const std::string& default_value) const {
65 auto pair = data.find(key); 65 auto pair = data.find(key);
66 if (pair == data.end()) { 66 if (pair == data.end()) {
67 NGLOG_DEBUG(Common, "key '{}' not found", key); 67 LOG_DEBUG(Common, "key '{}' not found", key);
68 return default_value; 68 return default_value;
69 } 69 }
70 70
@@ -74,14 +74,14 @@ std::string ParamPackage::Get(const std::string& key, const std::string& default
74int ParamPackage::Get(const std::string& key, int default_value) const { 74int ParamPackage::Get(const std::string& key, int default_value) const {
75 auto pair = data.find(key); 75 auto pair = data.find(key);
76 if (pair == data.end()) { 76 if (pair == data.end()) {
77 NGLOG_DEBUG(Common, "key '{}' not found", key); 77 LOG_DEBUG(Common, "key '{}' not found", key);
78 return default_value; 78 return default_value;
79 } 79 }
80 80
81 try { 81 try {
82 return std::stoi(pair->second); 82 return std::stoi(pair->second);
83 } catch (const std::logic_error&) { 83 } catch (const std::logic_error&) {
84 NGLOG_ERROR(Common, "failed to convert {} to int", pair->second); 84 LOG_ERROR(Common, "failed to convert {} to int", pair->second);
85 return default_value; 85 return default_value;
86 } 86 }
87} 87}
@@ -89,14 +89,14 @@ int ParamPackage::Get(const std::string& key, int default_value) const {
89float ParamPackage::Get(const std::string& key, float default_value) const { 89float ParamPackage::Get(const std::string& key, float default_value) const {
90 auto pair = data.find(key); 90 auto pair = data.find(key);
91 if (pair == data.end()) { 91 if (pair == data.end()) {
92 NGLOG_DEBUG(Common, "key {} not found", key); 92 LOG_DEBUG(Common, "key {} not found", key);
93 return default_value; 93 return default_value;
94 } 94 }
95 95
96 try { 96 try {
97 return std::stof(pair->second); 97 return std::stof(pair->second);
98 } catch (const std::logic_error&) { 98 } catch (const std::logic_error&) {
99 NGLOG_ERROR(Common, "failed to convert {} to float", pair->second); 99 LOG_ERROR(Common, "failed to convert {} to float", pair->second);
100 return default_value; 100 return default_value;
101 } 101 }
102} 102}
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index 646400db0..ea9d8f77c 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -281,7 +281,7 @@ static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>&
281 281
282 iconv_t const conv_desc = iconv_open("UTF-8", fromcode); 282 iconv_t const conv_desc = iconv_open("UTF-8", fromcode);
283 if ((iconv_t)(-1) == conv_desc) { 283 if ((iconv_t)(-1) == conv_desc) {
284 NGLOG_ERROR(Common, "Iconv initialization failure [{}]: {}", fromcode, strerror(errno)); 284 LOG_ERROR(Common, "Iconv initialization failure [{}]: {}", fromcode, strerror(errno));
285 iconv_close(conv_desc); 285 iconv_close(conv_desc);
286 return {}; 286 return {};
287 } 287 }
@@ -310,7 +310,7 @@ static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>&
310 ++src_buffer; 310 ++src_buffer;
311 } 311 }
312 } else { 312 } else {
313 NGLOG_ERROR(Common, "iconv failure [{}]: {}", fromcode, strerror(errno)); 313 LOG_ERROR(Common, "iconv failure [{}]: {}", fromcode, strerror(errno));
314 break; 314 break;
315 } 315 }
316 } 316 }
@@ -329,7 +329,7 @@ std::u16string UTF8ToUTF16(const std::string& input) {
329 329
330 iconv_t const conv_desc = iconv_open("UTF-16LE", "UTF-8"); 330 iconv_t const conv_desc = iconv_open("UTF-16LE", "UTF-8");
331 if ((iconv_t)(-1) == conv_desc) { 331 if ((iconv_t)(-1) == conv_desc) {
332 NGLOG_ERROR(Common, "Iconv initialization failure [UTF-8]: {}", strerror(errno)); 332 LOG_ERROR(Common, "Iconv initialization failure [UTF-8]: {}", strerror(errno));
333 iconv_close(conv_desc); 333 iconv_close(conv_desc);
334 return {}; 334 return {};
335 } 335 }
@@ -358,7 +358,7 @@ std::u16string UTF8ToUTF16(const std::string& input) {
358 ++src_buffer; 358 ++src_buffer;
359 } 359 }
360 } else { 360 } else {
361 NGLOG_ERROR(Common, "iconv failure [UTF-8]: {}", strerror(errno)); 361 LOG_ERROR(Common, "iconv failure [UTF-8]: {}", strerror(errno));
362 break; 362 break;
363 } 363 }
364 } 364 }
diff --git a/src/common/swap.h b/src/common/swap.h
index 4a4012d1a..f025f7450 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -69,7 +69,7 @@ inline u32 swap32(u32 _data) {
69inline u64 swap64(u64 _data) { 69inline u64 swap64(u64 _data) {
70 return _byteswap_uint64(_data); 70 return _byteswap_uint64(_data);
71} 71}
72#elif _M_ARM 72#elif ARCHITECTURE_ARM
73inline u16 swap16(u16 _data) { 73inline u16 swap16(u16 _data) {
74 u32 data = _data; 74 u32 data = _data;
75 __asm__("rev16 %0, %1\n" : "=l"(data) : "l"(data)); 75 __asm__("rev16 %0, %1\n" : "=l"(data) : "l"(data));
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 51e4088d2..3dff068df 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -126,6 +126,8 @@ add_library(core STATIC
126 hle/service/audio/audren_u.h 126 hle/service/audio/audren_u.h
127 hle/service/audio/codecctl.cpp 127 hle/service/audio/codecctl.cpp
128 hle/service/audio/codecctl.h 128 hle/service/audio/codecctl.h
129 hle/service/audio/hwopus.cpp
130 hle/service/audio/hwopus.h
129 hle/service/bcat/module.cpp 131 hle/service/bcat/module.cpp
130 hle/service/bcat/module.h 132 hle/service/bcat/module.h
131 hle/service/bcat/bcat.cpp 133 hle/service/bcat/bcat.cpp
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index b5db47667..42605374b 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -55,8 +55,8 @@ public:
55 } 55 }
56 56
57 void InterpreterFallback(u64 pc, size_t num_instructions) override { 57 void InterpreterFallback(u64 pc, size_t num_instructions) override {
58 NGLOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc, 58 LOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc,
59 num_instructions, MemoryReadCode(pc)); 59 num_instructions, MemoryReadCode(pc));
60 60
61 ARM_Interface::ThreadContext ctx; 61 ARM_Interface::ThreadContext ctx;
62 parent.SaveContext(ctx); 62 parent.SaveContext(ctx);
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 84ab876cc..8335d502e 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -87,15 +87,15 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
87 app_loader = Loader::GetLoader(filepath); 87 app_loader = Loader::GetLoader(filepath);
88 88
89 if (!app_loader) { 89 if (!app_loader) {
90 NGLOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); 90 LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
91 return ResultStatus::ErrorGetLoader; 91 return ResultStatus::ErrorGetLoader;
92 } 92 }
93 std::pair<boost::optional<u32>, Loader::ResultStatus> system_mode = 93 std::pair<boost::optional<u32>, Loader::ResultStatus> system_mode =
94 app_loader->LoadKernelSystemMode(); 94 app_loader->LoadKernelSystemMode();
95 95
96 if (system_mode.second != Loader::ResultStatus::Success) { 96 if (system_mode.second != Loader::ResultStatus::Success) {
97 NGLOG_CRITICAL(Core, "Failed to determine system mode (Error {})!", 97 LOG_CRITICAL(Core, "Failed to determine system mode (Error {})!",
98 static_cast<int>(system_mode.second)); 98 static_cast<int>(system_mode.second));
99 99
100 switch (system_mode.second) { 100 switch (system_mode.second) {
101 case Loader::ResultStatus::ErrorEncrypted: 101 case Loader::ResultStatus::ErrorEncrypted:
@@ -111,15 +111,15 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
111 111
112 ResultStatus init_result{Init(emu_window, system_mode.first.get())}; 112 ResultStatus init_result{Init(emu_window, system_mode.first.get())};
113 if (init_result != ResultStatus::Success) { 113 if (init_result != ResultStatus::Success) {
114 NGLOG_CRITICAL(Core, "Failed to initialize system (Error {})!", 114 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
115 static_cast<int>(init_result)); 115 static_cast<int>(init_result));
116 System::Shutdown(); 116 System::Shutdown();
117 return init_result; 117 return init_result;
118 } 118 }
119 119
120 const Loader::ResultStatus load_result{app_loader->Load(current_process)}; 120 const Loader::ResultStatus load_result{app_loader->Load(current_process)};
121 if (Loader::ResultStatus::Success != load_result) { 121 if (Loader::ResultStatus::Success != load_result) {
122 NGLOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result)); 122 LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result));
123 System::Shutdown(); 123 System::Shutdown();
124 124
125 switch (load_result) { 125 switch (load_result) {
@@ -161,7 +161,7 @@ Cpu& System::CpuCore(size_t core_index) {
161} 161}
162 162
163System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { 163System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
164 NGLOG_DEBUG(HW_Memory, "initialized OK"); 164 LOG_DEBUG(HW_Memory, "initialized OK");
165 165
166 CoreTiming::Init(); 166 CoreTiming::Init();
167 167
@@ -196,7 +196,7 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
196 } 196 }
197 } 197 }
198 198
199 NGLOG_DEBUG(Core, "Initialized OK"); 199 LOG_DEBUG(Core, "Initialized OK");
200 200
201 // Reset counters and set time origin to current frame 201 // Reset counters and set time origin to current frame
202 GetAndResetPerfStats(); 202 GetAndResetPerfStats();
@@ -245,7 +245,7 @@ void System::Shutdown() {
245 // Close app loader 245 // Close app loader
246 app_loader.reset(); 246 app_loader.reset();
247 247
248 NGLOG_DEBUG(Core, "Shutdown OK"); 248 LOG_DEBUG(Core, "Shutdown OK");
249} 249}
250 250
251Service::SM::ServiceManager& System::ServiceManager() { 251Service::SM::ServiceManager& System::ServiceManager() {
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index 099f2bb1a..f22d6a9d0 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -56,7 +56,7 @@ Cpu::Cpu(std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index)
56 arm_interface = std::make_shared<ARM_Dynarmic>(); 56 arm_interface = std::make_shared<ARM_Dynarmic>();
57#else 57#else
58 cpu_core = std::make_shared<ARM_Unicorn>(); 58 cpu_core = std::make_shared<ARM_Unicorn>();
59 NGLOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); 59 LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
60#endif 60#endif
61 } else { 61 } else {
62 arm_interface = std::make_shared<ARM_Unicorn>(); 62 arm_interface = std::make_shared<ARM_Unicorn>();
@@ -75,7 +75,7 @@ void Cpu::RunLoop(bool tight_loop) {
75 // If we don't have a currently active thread then don't execute instructions, 75 // If we don't have a currently active thread then don't execute instructions,
76 // instead advance to the next event and try to yield to the next thread 76 // instead advance to the next event and try to yield to the next thread
77 if (Kernel::GetCurrentThread() == nullptr) { 77 if (Kernel::GetCurrentThread() == nullptr) {
78 NGLOG_TRACE(Core, "Core-{} idling", core_index); 78 LOG_TRACE(Core, "Core-{} idling", core_index);
79 79
80 if (IsMainCore()) { 80 if (IsMainCore()) {
81 CoreTiming::Idle(); 81 CoreTiming::Idle();
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index dc1d8668f..50d1e3fc9 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -74,11 +74,11 @@ static void EmptyTimedCallback(u64 userdata, s64 cyclesLate) {}
74 74
75s64 usToCycles(s64 us) { 75s64 usToCycles(s64 us) {
76 if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) { 76 if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) {
77 NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); 77 LOG_ERROR(Core_Timing, "Integer overflow, use max value");
78 return std::numeric_limits<s64>::max(); 78 return std::numeric_limits<s64>::max();
79 } 79 }
80 if (us > MAX_VALUE_TO_MULTIPLY) { 80 if (us > MAX_VALUE_TO_MULTIPLY) {
81 NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); 81 LOG_DEBUG(Core_Timing, "Time very big, do rounding");
82 return BASE_CLOCK_RATE * (us / 1000000); 82 return BASE_CLOCK_RATE * (us / 1000000);
83 } 83 }
84 return (BASE_CLOCK_RATE * us) / 1000000; 84 return (BASE_CLOCK_RATE * us) / 1000000;
@@ -86,11 +86,11 @@ s64 usToCycles(s64 us) {
86 86
87s64 usToCycles(u64 us) { 87s64 usToCycles(u64 us) {
88 if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) { 88 if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) {
89 NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); 89 LOG_ERROR(Core_Timing, "Integer overflow, use max value");
90 return std::numeric_limits<s64>::max(); 90 return std::numeric_limits<s64>::max();
91 } 91 }
92 if (us > MAX_VALUE_TO_MULTIPLY) { 92 if (us > MAX_VALUE_TO_MULTIPLY) {
93 NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); 93 LOG_DEBUG(Core_Timing, "Time very big, do rounding");
94 return BASE_CLOCK_RATE * static_cast<s64>(us / 1000000); 94 return BASE_CLOCK_RATE * static_cast<s64>(us / 1000000);
95 } 95 }
96 return (BASE_CLOCK_RATE * static_cast<s64>(us)) / 1000000; 96 return (BASE_CLOCK_RATE * static_cast<s64>(us)) / 1000000;
@@ -98,11 +98,11 @@ s64 usToCycles(u64 us) {
98 98
99s64 nsToCycles(s64 ns) { 99s64 nsToCycles(s64 ns) {
100 if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) { 100 if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) {
101 NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); 101 LOG_ERROR(Core_Timing, "Integer overflow, use max value");
102 return std::numeric_limits<s64>::max(); 102 return std::numeric_limits<s64>::max();
103 } 103 }
104 if (ns > MAX_VALUE_TO_MULTIPLY) { 104 if (ns > MAX_VALUE_TO_MULTIPLY) {
105 NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); 105 LOG_DEBUG(Core_Timing, "Time very big, do rounding");
106 return BASE_CLOCK_RATE * (ns / 1000000000); 106 return BASE_CLOCK_RATE * (ns / 1000000000);
107 } 107 }
108 return (BASE_CLOCK_RATE * ns) / 1000000000; 108 return (BASE_CLOCK_RATE * ns) / 1000000000;
@@ -110,11 +110,11 @@ s64 nsToCycles(s64 ns) {
110 110
111s64 nsToCycles(u64 ns) { 111s64 nsToCycles(u64 ns) {
112 if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) { 112 if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) {
113 NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); 113 LOG_ERROR(Core_Timing, "Integer overflow, use max value");
114 return std::numeric_limits<s64>::max(); 114 return std::numeric_limits<s64>::max();
115 } 115 }
116 if (ns > MAX_VALUE_TO_MULTIPLY) { 116 if (ns > MAX_VALUE_TO_MULTIPLY) {
117 NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); 117 LOG_DEBUG(Core_Timing, "Time very big, do rounding");
118 return BASE_CLOCK_RATE * (static_cast<s64>(ns) / 1000000000); 118 return BASE_CLOCK_RATE * (static_cast<s64>(ns) / 1000000000);
119 } 119 }
120 return (BASE_CLOCK_RATE * static_cast<s64>(ns)) / 1000000000; 120 return (BASE_CLOCK_RATE * static_cast<s64>(ns)) / 1000000000;
diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp
index 8aa0e0aa4..8c6f15bb5 100644
--- a/src/core/file_sys/disk_filesystem.cpp
+++ b/src/core/file_sys/disk_filesystem.cpp
@@ -80,19 +80,19 @@ ResultCode Disk_FileSystem::RenameFile(const std::string& src_path,
80} 80}
81 81
82ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const { 82ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const {
83 NGLOG_WARNING(Service_FS, "(STUBBED) called"); 83 LOG_WARNING(Service_FS, "(STUBBED) called");
84 // TODO(wwylele): Use correct error code 84 // TODO(wwylele): Use correct error code
85 return ResultCode(-1); 85 return ResultCode(-1);
86} 86}
87 87
88ResultCode Disk_FileSystem::DeleteDirectoryRecursively(const Path& path) const { 88ResultCode Disk_FileSystem::DeleteDirectoryRecursively(const Path& path) const {
89 NGLOG_WARNING(Service_FS, "(STUBBED) called"); 89 LOG_WARNING(Service_FS, "(STUBBED) called");
90 // TODO(wwylele): Use correct error code 90 // TODO(wwylele): Use correct error code
91 return ResultCode(-1); 91 return ResultCode(-1);
92} 92}
93 93
94ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const { 94ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const {
95 NGLOG_WARNING(Service_FS, "(STUBBED) called"); 95 LOG_WARNING(Service_FS, "(STUBBED) called");
96 96
97 std::string full_path = base_directory + path; 97 std::string full_path = base_directory + path;
98 if (size == 0) { 98 if (size == 0) {
@@ -107,7 +107,7 @@ ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const
107 return RESULT_SUCCESS; 107 return RESULT_SUCCESS;
108 } 108 }
109 109
110 NGLOG_ERROR(Service_FS, "Too large file"); 110 LOG_ERROR(Service_FS, "Too large file");
111 // TODO(Subv): Find out the correct error code 111 // TODO(Subv): Find out the correct error code
112 return ResultCode(-1); 112 return ResultCode(-1);
113} 113}
@@ -120,13 +120,13 @@ ResultCode Disk_FileSystem::CreateDirectory(const std::string& path) const {
120 return RESULT_SUCCESS; 120 return RESULT_SUCCESS;
121 } 121 }
122 122
123 NGLOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", full_path); 123 LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", full_path);
124 // TODO(wwylele): Use correct error code 124 // TODO(wwylele): Use correct error code
125 return ResultCode(-1); 125 return ResultCode(-1);
126} 126}
127 127
128ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const { 128ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const {
129 NGLOG_WARNING(Service_FS, "(STUBBED) called"); 129 LOG_WARNING(Service_FS, "(STUBBED) called");
130 // TODO(wwylele): Use correct error code 130 // TODO(wwylele): Use correct error code
131 return ResultCode(-1); 131 return ResultCode(-1);
132} 132}
@@ -146,7 +146,7 @@ ResultVal<std::unique_ptr<DirectoryBackend>> Disk_FileSystem::OpenDirectory(
146} 146}
147 147
148u64 Disk_FileSystem::GetFreeSpaceSize() const { 148u64 Disk_FileSystem::GetFreeSpaceSize() const {
149 NGLOG_WARNING(Service_FS, "(STUBBED) called"); 149 LOG_WARNING(Service_FS, "(STUBBED) called");
150 return 0; 150 return 0;
151} 151}
152 152
@@ -163,14 +163,14 @@ ResultVal<FileSys::EntryType> Disk_FileSystem::GetEntryType(const std::string& p
163} 163}
164 164
165ResultVal<size_t> Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const { 165ResultVal<size_t> Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const {
166 NGLOG_TRACE(Service_FS, "called offset={}, length={}", offset, length); 166 LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
167 file->Seek(offset, SEEK_SET); 167 file->Seek(offset, SEEK_SET);
168 return MakeResult<size_t>(file->ReadBytes(buffer, length)); 168 return MakeResult<size_t>(file->ReadBytes(buffer, length));
169} 169}
170 170
171ResultVal<size_t> Disk_Storage::Write(const u64 offset, const size_t length, const bool flush, 171ResultVal<size_t> Disk_Storage::Write(const u64 offset, const size_t length, const bool flush,
172 const u8* buffer) const { 172 const u8* buffer) const {
173 NGLOG_WARNING(Service_FS, "(STUBBED) called"); 173 LOG_WARNING(Service_FS, "(STUBBED) called");
174 file->Seek(offset, SEEK_SET); 174 file->Seek(offset, SEEK_SET);
175 size_t written = file->WriteBytes(buffer, length); 175 size_t written = file->WriteBytes(buffer, length);
176 if (flush) { 176 if (flush) {
@@ -204,7 +204,7 @@ u64 Disk_Directory::Read(const u64 count, Entry* entries) {
204 const std::string& filename = file.virtualName; 204 const std::string& filename = file.virtualName;
205 Entry& entry = entries[entries_read]; 205 Entry& entry = entries[entries_read];
206 206
207 NGLOG_TRACE(Service_FS, "File {}: size={} dir={}", filename, file.size, file.isDirectory); 207 LOG_TRACE(Service_FS, "File {}: size={} dir={}", filename, file.size, file.isDirectory);
208 208
209 // TODO(Link Mauve): use a proper conversion to UTF-16. 209 // TODO(Link Mauve): use a proper conversion to UTF-16.
210 for (size_t j = 0; j < FILENAME_LENGTH; ++j) { 210 for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
diff --git a/src/core/file_sys/filesystem.cpp b/src/core/file_sys/filesystem.cpp
index 87083878b..82fdb3c46 100644
--- a/src/core/file_sys/filesystem.cpp
+++ b/src/core/file_sys/filesystem.cpp
@@ -71,7 +71,7 @@ std::string Path::AsString() const {
71 case Binary: 71 case Binary:
72 default: 72 default:
73 // TODO(yuriks): Add assert 73 // TODO(yuriks): Add assert
74 NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); 74 LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
75 return {}; 75 return {};
76 } 76 }
77} 77}
@@ -87,7 +87,7 @@ std::u16string Path::AsU16Str() const {
87 case Invalid: 87 case Invalid:
88 case Binary: 88 case Binary:
89 // TODO(yuriks): Add assert 89 // TODO(yuriks): Add assert
90 NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!"); 90 LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!");
91 return {}; 91 return {};
92 } 92 }
93 93
@@ -115,7 +115,7 @@ std::vector<u8> Path::AsBinary() const {
115 case Invalid: 115 case Invalid:
116 default: 116 default:
117 // TODO(yuriks): Add assert 117 // TODO(yuriks): Add assert
118 NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); 118 LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
119 return {}; 119 return {};
120 } 120 }
121} 121}
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp
index 874b9e23b..46d438aca 100644
--- a/src/core/file_sys/partition_filesystem.cpp
+++ b/src/core/file_sys/partition_filesystem.cpp
@@ -46,7 +46,7 @@ Loader::ResultStatus PartitionFilesystem::Load(const std::string& file_path, siz
46 46
47 Loader::ResultStatus result = Load(file_data); 47 Loader::ResultStatus result = Load(file_data);
48 if (result != Loader::ResultStatus::Success) 48 if (result != Loader::ResultStatus::Success)
49 NGLOG_ERROR(Service_FS, "Failed to load PFS from file {}!", file_path); 49 LOG_ERROR(Service_FS, "Failed to load PFS from file {}!", file_path);
50 50
51 return result; 51 return result;
52} 52}
@@ -125,12 +125,12 @@ u64 PartitionFilesystem::GetFileSize(const std::string& name) const {
125} 125}
126 126
127void PartitionFilesystem::Print() const { 127void PartitionFilesystem::Print() const {
128 NGLOG_DEBUG(Service_FS, "Magic: {}", pfs_header.magic); 128 LOG_DEBUG(Service_FS, "Magic: {}", pfs_header.magic);
129 NGLOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries); 129 LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries);
130 for (u32 i = 0; i < pfs_header.num_entries; i++) { 130 for (u32 i = 0; i < pfs_header.num_entries; i++) {
131 NGLOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes, at 0x{:X})", i, 131 LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes, at 0x{:X})", i,
132 pfs_entries[i].name.c_str(), pfs_entries[i].fs_entry.size, 132 pfs_entries[i].name.c_str(), pfs_entries[i].fs_entry.size,
133 GetFileOffset(pfs_entries[i].name)); 133 GetFileOffset(pfs_entries[i].name));
134 } 134 }
135} 135}
136} // namespace FileSys 136} // namespace FileSys
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp
index 25a822891..226811115 100644
--- a/src/core/file_sys/program_metadata.cpp
+++ b/src/core/file_sys/program_metadata.cpp
@@ -21,7 +21,7 @@ Loader::ResultStatus ProgramMetadata::Load(const std::string& file_path) {
21 21
22 Loader::ResultStatus result = Load(file_data); 22 Loader::ResultStatus result = Load(file_data);
23 if (result != Loader::ResultStatus::Success) 23 if (result != Loader::ResultStatus::Success)
24 NGLOG_ERROR(Service_FS, "Failed to load NPDM from file {}!", file_path); 24 LOG_ERROR(Service_FS, "Failed to load NPDM from file {}!", file_path);
25 25
26 return result; 26 return result;
27} 27}
@@ -76,14 +76,14 @@ u64 ProgramMetadata::GetFilesystemPermissions() const {
76} 76}
77 77
78void ProgramMetadata::Print() const { 78void ProgramMetadata::Print() const {
79 NGLOG_DEBUG(Service_FS, "Magic: {:.4}", npdm_header.magic.data()); 79 LOG_DEBUG(Service_FS, "Magic: {:.4}", npdm_header.magic.data());
80 NGLOG_DEBUG(Service_FS, "Main thread priority: 0x{:02X}", npdm_header.main_thread_priority); 80 LOG_DEBUG(Service_FS, "Main thread priority: 0x{:02X}", npdm_header.main_thread_priority);
81 NGLOG_DEBUG(Service_FS, "Main thread core: {}", npdm_header.main_thread_cpu); 81 LOG_DEBUG(Service_FS, "Main thread core: {}", npdm_header.main_thread_cpu);
82 NGLOG_DEBUG(Service_FS, "Main thread stack size: 0x{:X} bytes", npdm_header.main_stack_size); 82 LOG_DEBUG(Service_FS, "Main thread stack size: 0x{:X} bytes", npdm_header.main_stack_size);
83 NGLOG_DEBUG(Service_FS, "Process category: {}", npdm_header.process_category); 83 LOG_DEBUG(Service_FS, "Process category: {}", npdm_header.process_category);
84 NGLOG_DEBUG(Service_FS, "Flags: 0x{:02X}", npdm_header.flags); 84 LOG_DEBUG(Service_FS, "Flags: 0x{:02X}", npdm_header.flags);
85 NGLOG_DEBUG(Service_FS, " > 64-bit instructions: {}", 85 LOG_DEBUG(Service_FS, " > 64-bit instructions: {}",
86 npdm_header.has_64_bit_instructions ? "YES" : "NO"); 86 npdm_header.has_64_bit_instructions ? "YES" : "NO");
87 87
88 auto address_space = "Unknown"; 88 auto address_space = "Unknown";
89 switch (npdm_header.address_space_type) { 89 switch (npdm_header.address_space_type) {
@@ -95,19 +95,19 @@ void ProgramMetadata::Print() const {
95 break; 95 break;
96 } 96 }
97 97
98 NGLOG_DEBUG(Service_FS, " > Address space: {}\n", address_space); 98 LOG_DEBUG(Service_FS, " > Address space: {}\n", address_space);
99 99
100 // Begin ACID printing (potential perms, signed) 100 // Begin ACID printing (potential perms, signed)
101 NGLOG_DEBUG(Service_FS, "Magic: {:.4}", acid_header.magic.data()); 101 LOG_DEBUG(Service_FS, "Magic: {:.4}", acid_header.magic.data());
102 NGLOG_DEBUG(Service_FS, "Flags: 0x{:02X}", acid_header.flags); 102 LOG_DEBUG(Service_FS, "Flags: 0x{:02X}", acid_header.flags);
103 NGLOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO"); 103 LOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO");
104 NGLOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min); 104 LOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min);
105 NGLOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max); 105 LOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max);
106 NGLOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", acid_file_access.permissions); 106 LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", acid_file_access.permissions);
107 107
108 // Begin ACI0 printing (actual perms, unsigned) 108 // Begin ACI0 printing (actual perms, unsigned)
109 NGLOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data()); 109 LOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data());
110 NGLOG_DEBUG(Service_FS, "Title ID: 0x{:016X}", aci_header.title_id); 110 LOG_DEBUG(Service_FS, "Title ID: 0x{:016X}", aci_header.title_id);
111 NGLOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", aci_file_access.permissions); 111 LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", aci_file_access.permissions);
112} 112}
113} // namespace FileSys 113} // namespace FileSys
diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp
index dc7591aca..84ae0d99b 100644
--- a/src/core/file_sys/romfs_factory.cpp
+++ b/src/core/file_sys/romfs_factory.cpp
@@ -14,7 +14,7 @@ namespace FileSys {
14RomFS_Factory::RomFS_Factory(Loader::AppLoader& app_loader) { 14RomFS_Factory::RomFS_Factory(Loader::AppLoader& app_loader) {
15 // Load the RomFS from the app 15 // Load the RomFS from the app
16 if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) { 16 if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) {
17 NGLOG_ERROR(Service_FS, "Unable to read RomFS!"); 17 LOG_ERROR(Service_FS, "Unable to read RomFS!");
18 } 18 }
19} 19}
20 20
@@ -24,13 +24,13 @@ ResultVal<std::unique_ptr<FileSystemBackend>> RomFS_Factory::Open(const Path& pa
24} 24}
25 25
26ResultCode RomFS_Factory::Format(const Path& path) { 26ResultCode RomFS_Factory::Format(const Path& path) {
27 NGLOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName()); 27 LOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName());
28 // TODO(bunnei): Find the right error code for this 28 // TODO(bunnei): Find the right error code for this
29 return ResultCode(-1); 29 return ResultCode(-1);
30} 30}
31 31
32ResultVal<ArchiveFormatInfo> RomFS_Factory::GetFormatInfo(const Path& path) const { 32ResultVal<ArchiveFormatInfo> RomFS_Factory::GetFormatInfo(const Path& path) const {
33 NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); 33 LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
34 // TODO(bunnei): Find the right error code for this 34 // TODO(bunnei): Find the right error code for this
35 return ResultCode(-1); 35 return ResultCode(-1);
36} 36}
diff --git a/src/core/file_sys/romfs_filesystem.cpp b/src/core/file_sys/romfs_filesystem.cpp
index 8e2bce687..83162622b 100644
--- a/src/core/file_sys/romfs_filesystem.cpp
+++ b/src/core/file_sys/romfs_filesystem.cpp
@@ -21,72 +21,70 @@ ResultVal<std::unique_ptr<StorageBackend>> RomFS_FileSystem::OpenFile(const std:
21} 21}
22 22
23ResultCode RomFS_FileSystem::DeleteFile(const std::string& path) const { 23ResultCode RomFS_FileSystem::DeleteFile(const std::string& path) const {
24 NGLOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive ({}).", GetName()); 24 LOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive ({}).", GetName());
25 // TODO(bunnei): Use correct error code 25 // TODO(bunnei): Use correct error code
26 return ResultCode(-1); 26 return ResultCode(-1);
27} 27}
28 28
29ResultCode RomFS_FileSystem::RenameFile(const std::string& src_path, 29ResultCode RomFS_FileSystem::RenameFile(const std::string& src_path,
30 const std::string& dest_path) const { 30 const std::string& dest_path) const {
31 NGLOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).", 31 LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).", GetName());
32 GetName());
33 // TODO(wwylele): Use correct error code 32 // TODO(wwylele): Use correct error code
34 return ResultCode(-1); 33 return ResultCode(-1);
35} 34}
36 35
37ResultCode RomFS_FileSystem::DeleteDirectory(const Path& path) const { 36ResultCode RomFS_FileSystem::DeleteDirectory(const Path& path) const {
38 NGLOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).", 37 LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).",
39 GetName()); 38 GetName());
40 // TODO(wwylele): Use correct error code 39 // TODO(wwylele): Use correct error code
41 return ResultCode(-1); 40 return ResultCode(-1);
42} 41}
43 42
44ResultCode RomFS_FileSystem::DeleteDirectoryRecursively(const Path& path) const { 43ResultCode RomFS_FileSystem::DeleteDirectoryRecursively(const Path& path) const {
45 NGLOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).", 44 LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).",
46 GetName()); 45 GetName());
47 // TODO(wwylele): Use correct error code 46 // TODO(wwylele): Use correct error code
48 return ResultCode(-1); 47 return ResultCode(-1);
49} 48}
50 49
51ResultCode RomFS_FileSystem::CreateFile(const std::string& path, u64 size) const { 50ResultCode RomFS_FileSystem::CreateFile(const std::string& path, u64 size) const {
52 NGLOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive ({}).", GetName()); 51 LOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive ({}).", GetName());
53 // TODO(bunnei): Use correct error code 52 // TODO(bunnei): Use correct error code
54 return ResultCode(-1); 53 return ResultCode(-1);
55} 54}
56 55
57ResultCode RomFS_FileSystem::CreateDirectory(const std::string& path) const { 56ResultCode RomFS_FileSystem::CreateDirectory(const std::string& path) const {
58 NGLOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive ({}).", 57 LOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive ({}).",
59 GetName()); 58 GetName());
60 // TODO(wwylele): Use correct error code 59 // TODO(wwylele): Use correct error code
61 return ResultCode(-1); 60 return ResultCode(-1);
62} 61}
63 62
64ResultCode RomFS_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const { 63ResultCode RomFS_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const {
65 NGLOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).", 64 LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).", GetName());
66 GetName());
67 // TODO(wwylele): Use correct error code 65 // TODO(wwylele): Use correct error code
68 return ResultCode(-1); 66 return ResultCode(-1);
69} 67}
70 68
71ResultVal<std::unique_ptr<DirectoryBackend>> RomFS_FileSystem::OpenDirectory( 69ResultVal<std::unique_ptr<DirectoryBackend>> RomFS_FileSystem::OpenDirectory(
72 const std::string& path) const { 70 const std::string& path) const {
73 NGLOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive"); 71 LOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive");
74 return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<ROMFSDirectory>()); 72 return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<ROMFSDirectory>());
75} 73}
76 74
77u64 RomFS_FileSystem::GetFreeSpaceSize() const { 75u64 RomFS_FileSystem::GetFreeSpaceSize() const {
78 NGLOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive"); 76 LOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive");
79 return 0; 77 return 0;
80} 78}
81 79
82ResultVal<FileSys::EntryType> RomFS_FileSystem::GetEntryType(const std::string& path) const { 80ResultVal<FileSys::EntryType> RomFS_FileSystem::GetEntryType(const std::string& path) const {
83 NGLOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path {}).", path); 81 LOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path {}).", path);
84 // TODO(wwylele): Use correct error code 82 // TODO(wwylele): Use correct error code
85 return ResultCode(-1); 83 return ResultCode(-1);
86} 84}
87 85
88ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8* buffer) const { 86ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8* buffer) const {
89 NGLOG_TRACE(Service_FS, "called offset={}, length={}", offset, length); 87 LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
90 romfs_file->Seek(data_offset + offset, SEEK_SET); 88 romfs_file->Seek(data_offset + offset, SEEK_SET);
91 size_t read_length = (size_t)std::min((u64)length, data_size - offset); 89 size_t read_length = (size_t)std::min((u64)length, data_size - offset);
92 90
@@ -95,7 +93,7 @@ ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8*
95 93
96ResultVal<size_t> RomFS_Storage::Write(const u64 offset, const size_t length, const bool flush, 94ResultVal<size_t> RomFS_Storage::Write(const u64 offset, const size_t length, const bool flush,
97 const u8* buffer) const { 95 const u8* buffer) const {
98 NGLOG_ERROR(Service_FS, "Attempted to write to ROMFS file"); 96 LOG_ERROR(Service_FS, "Attempted to write to ROMFS file");
99 // TODO(Subv): Find error code 97 // TODO(Subv): Find error code
100 return MakeResult<size_t>(0); 98 return MakeResult<size_t>(0);
101} 99}
@@ -105,7 +103,7 @@ u64 RomFS_Storage::GetSize() const {
105} 103}
106 104
107bool RomFS_Storage::SetSize(const u64 size) const { 105bool RomFS_Storage::SetSize(const u64 size) const {
108 NGLOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file"); 106 LOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file");
109 return false; 107 return false;
110} 108}
111 109
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp
index c1be8fee4..f3aa213af 100644
--- a/src/core/file_sys/savedata_factory.cpp
+++ b/src/core/file_sys/savedata_factory.cpp
@@ -17,6 +17,15 @@ SaveData_Factory::SaveData_Factory(std::string nand_directory)
17 17
18ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path& path) { 18ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path& path) {
19 std::string save_directory = GetFullPath(); 19 std::string save_directory = GetFullPath();
20
21 if (!FileUtil::Exists(save_directory)) {
22 // TODO(bunnei): This is a work-around to always create a save data directory if it does not
23 // already exist. This is a hack, as we do not understand yet how this works on hardware.
24 // Without a save data directory, many games will assert on boot. This should not have any
25 // bad side-effects.
26 FileUtil::CreateFullPath(save_directory);
27 }
28
20 // Return an error if the save data doesn't actually exist. 29 // Return an error if the save data doesn't actually exist.
21 if (!FileUtil::IsDirectory(save_directory)) { 30 if (!FileUtil::IsDirectory(save_directory)) {
22 // TODO(Subv): Find out correct error code. 31 // TODO(Subv): Find out correct error code.
@@ -28,7 +37,7 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path&
28} 37}
29 38
30ResultCode SaveData_Factory::Format(const Path& path) { 39ResultCode SaveData_Factory::Format(const Path& path) {
31 NGLOG_WARNING(Service_FS, "Format archive {}", GetName()); 40 LOG_WARNING(Service_FS, "Format archive {}", GetName());
32 // Create the save data directory. 41 // Create the save data directory.
33 if (!FileUtil::CreateFullPath(GetFullPath())) { 42 if (!FileUtil::CreateFullPath(GetFullPath())) {
34 // TODO(Subv): Find the correct error code. 43 // TODO(Subv): Find the correct error code.
@@ -39,7 +48,7 @@ ResultCode SaveData_Factory::Format(const Path& path) {
39} 48}
40 49
41ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const { 50ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const {
42 NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); 51 LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
43 // TODO(bunnei): Find the right error code for this 52 // TODO(bunnei): Find the right error code for this
44 return ResultCode(-1); 53 return ResultCode(-1);
45} 54}
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp
index 59ac3e0be..2e5ffb764 100644
--- a/src/core/file_sys/sdmc_factory.cpp
+++ b/src/core/file_sys/sdmc_factory.cpp
@@ -25,13 +25,13 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SDMC_Factory::Open(const Path& pat
25} 25}
26 26
27ResultCode SDMC_Factory::Format(const Path& path) { 27ResultCode SDMC_Factory::Format(const Path& path) {
28 NGLOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName()); 28 LOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName());
29 // TODO(Subv): Find the right error code for this 29 // TODO(Subv): Find the right error code for this
30 return ResultCode(-1); 30 return ResultCode(-1);
31} 31}
32 32
33ResultVal<ArchiveFormatInfo> SDMC_Factory::GetFormatInfo(const Path& path) const { 33ResultVal<ArchiveFormatInfo> SDMC_Factory::GetFormatInfo(const Path& path) const {
34 NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); 34 LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
35 // TODO(bunnei): Find the right error code for this 35 // TODO(bunnei): Find the right error code for this
36 return ResultCode(-1); 36 return ResultCode(-1);
37} 37}
diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h
index 79e52488f..39bdf4e21 100644
--- a/src/core/frontend/input.h
+++ b/src/core/frontend/input.h
@@ -59,7 +59,7 @@ template <typename InputDeviceType>
59void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDeviceType>> factory) { 59void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDeviceType>> factory) {
60 auto pair = std::make_pair(name, std::move(factory)); 60 auto pair = std::make_pair(name, std::move(factory));
61 if (!Impl::FactoryList<InputDeviceType>::list.insert(std::move(pair)).second) { 61 if (!Impl::FactoryList<InputDeviceType>::list.insert(std::move(pair)).second) {
62 NGLOG_ERROR(Input, "Factory '{}' already registered", name); 62 LOG_ERROR(Input, "Factory '{}' already registered", name);
63 } 63 }
64} 64}
65 65
@@ -71,7 +71,7 @@ void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDevic
71template <typename InputDeviceType> 71template <typename InputDeviceType>
72void UnregisterFactory(const std::string& name) { 72void UnregisterFactory(const std::string& name) {
73 if (Impl::FactoryList<InputDeviceType>::list.erase(name) == 0) { 73 if (Impl::FactoryList<InputDeviceType>::list.erase(name) == 0) {
74 NGLOG_ERROR(Input, "Factory '{}' not registered", name); 74 LOG_ERROR(Input, "Factory '{}' not registered", name);
75 } 75 }
76} 76}
77 77
@@ -88,7 +88,7 @@ std::unique_ptr<InputDeviceType> CreateDevice(const std::string& params) {
88 const auto pair = factory_list.find(engine); 88 const auto pair = factory_list.find(engine);
89 if (pair == factory_list.end()) { 89 if (pair == factory_list.end()) {
90 if (engine != "null") { 90 if (engine != "null") {
91 NGLOG_ERROR(Input, "Unknown engine name: {}", engine); 91 LOG_ERROR(Input, "Unknown engine name: {}", engine);
92 } 92 }
93 return std::make_unique<InputDeviceType>(); 93 return std::make_unique<InputDeviceType>();
94 } 94 }
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 2603192fe..938852a1a 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -232,7 +232,7 @@ static u8 HexCharToValue(u8 hex) {
232 return hex - 'A' + 0xA; 232 return hex - 'A' + 0xA;
233 } 233 }
234 234
235 NGLOG_ERROR(Debug_GDBStub, "Invalid nibble: {} ({:02X})", hex, hex); 235 LOG_ERROR(Debug_GDBStub, "Invalid nibble: {} ({:02X})", hex, hex);
236 return 0; 236 return 0;
237} 237}
238 238
@@ -372,7 +372,7 @@ static u8 ReadByte() {
372 u8 c; 372 u8 c;
373 size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL); 373 size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL);
374 if (received_size != 1) { 374 if (received_size != 1) {
375 NGLOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size); 375 LOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size);
376 Shutdown(); 376 Shutdown();
377 } 377 }
378 378
@@ -413,8 +413,8 @@ static void RemoveBreakpoint(BreakpointType type, PAddr addr) {
413 413
414 auto bp = p.find(static_cast<u64>(addr)); 414 auto bp = p.find(static_cast<u64>(addr));
415 if (bp != p.end()) { 415 if (bp != p.end()) {
416 NGLOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}", 416 LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
417 bp->second.len, bp->second.addr, static_cast<int>(type)); 417 bp->second.len, bp->second.addr, static_cast<int>(type));
418 p.erase(static_cast<u64>(addr)); 418 p.erase(static_cast<u64>(addr));
419 } 419 }
420} 420}
@@ -459,10 +459,10 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) {
459 } 459 }
460 460
461 if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { 461 if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
462 NGLOG_DEBUG(Debug_GDBStub, 462 LOG_DEBUG(Debug_GDBStub,
463 "Found breakpoint type {} @ {:016X}, range: {:016X}" 463 "Found breakpoint type {} @ {:016X}, range: {:016X}"
464 " - {:016X} ({:X} bytes)", 464 " - {:016X} ({:X} bytes)",
465 static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len); 465 static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
466 return true; 466 return true;
467 } 467 }
468 } 468 }
@@ -478,7 +478,7 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) {
478static void SendPacket(const char packet) { 478static void SendPacket(const char packet) {
479 size_t sent_size = send(gdbserver_socket, &packet, 1, 0); 479 size_t sent_size = send(gdbserver_socket, &packet, 1, 0);
480 if (sent_size != 1) { 480 if (sent_size != 1) {
481 NGLOG_ERROR(Debug_GDBStub, "send failed"); 481 LOG_ERROR(Debug_GDBStub, "send failed");
482 } 482 }
483} 483}
484 484
@@ -492,13 +492,13 @@ static void SendReply(const char* reply) {
492 return; 492 return;
493 } 493 }
494 494
495 NGLOG_DEBUG(Debug_GDBStub, "Reply: {}", reply); 495 LOG_DEBUG(Debug_GDBStub, "Reply: {}", reply);
496 496
497 memset(command_buffer, 0, sizeof(command_buffer)); 497 memset(command_buffer, 0, sizeof(command_buffer));
498 498
499 command_length = static_cast<u32>(strlen(reply)); 499 command_length = static_cast<u32>(strlen(reply));
500 if (command_length + 4 > sizeof(command_buffer)) { 500 if (command_length + 4 > sizeof(command_buffer)) {
501 NGLOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply"); 501 LOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply");
502 return; 502 return;
503 } 503 }
504 504
@@ -515,7 +515,7 @@ static void SendReply(const char* reply) {
515 while (left > 0) { 515 while (left > 0) {
516 int sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0); 516 int sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0);
517 if (sent_size < 0) { 517 if (sent_size < 0) {
518 NGLOG_ERROR(Debug_GDBStub, "gdb: send failed"); 518 LOG_ERROR(Debug_GDBStub, "gdb: send failed");
519 return Shutdown(); 519 return Shutdown();
520 } 520 }
521 521
@@ -526,7 +526,7 @@ static void SendReply(const char* reply) {
526 526
527/// Handle query command from gdb client. 527/// Handle query command from gdb client.
528static void HandleQuery() { 528static void HandleQuery() {
529 NGLOG_DEBUG(Debug_GDBStub, "gdb: query '{}'", command_buffer + 1); 529 LOG_DEBUG(Debug_GDBStub, "gdb: query '{}'", command_buffer + 1);
530 530
531 const char* query = reinterpret_cast<const char*>(command_buffer + 1); 531 const char* query = reinterpret_cast<const char*>(command_buffer + 1);
532 532
@@ -634,18 +634,18 @@ static void ReadCommand() {
634 // ignore ack 634 // ignore ack
635 return; 635 return;
636 } else if (c == 0x03) { 636 } else if (c == 0x03) {
637 NGLOG_INFO(Debug_GDBStub, "gdb: found break command"); 637 LOG_INFO(Debug_GDBStub, "gdb: found break command");
638 halt_loop = true; 638 halt_loop = true;
639 SendSignal(current_thread, SIGTRAP); 639 SendSignal(current_thread, SIGTRAP);
640 return; 640 return;
641 } else if (c != GDB_STUB_START) { 641 } else if (c != GDB_STUB_START) {
642 NGLOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte {:02X}", c); 642 LOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte {:02X}", c);
643 return; 643 return;
644 } 644 }
645 645
646 while ((c = ReadByte()) != GDB_STUB_END) { 646 while ((c = ReadByte()) != GDB_STUB_END) {
647 if (command_length >= sizeof(command_buffer)) { 647 if (command_length >= sizeof(command_buffer)) {
648 NGLOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow"); 648 LOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow");
649 SendPacket(GDB_STUB_NACK); 649 SendPacket(GDB_STUB_NACK);
650 return; 650 return;
651 } 651 }
@@ -658,10 +658,9 @@ static void ReadCommand() {
658 u8 checksum_calculated = CalculateChecksum(command_buffer, command_length); 658 u8 checksum_calculated = CalculateChecksum(command_buffer, command_length);
659 659
660 if (checksum_received != checksum_calculated) { 660 if (checksum_received != checksum_calculated) {
661 NGLOG_ERROR( 661 LOG_ERROR(Debug_GDBStub,
662 Debug_GDBStub, 662 "gdb: invalid checksum: calculated {:02X} and read {:02X} for ${}# (length: {})",
663 "gdb: invalid checksum: calculated {:02X} and read {:02X} for ${}# (length: {})", 663 checksum_calculated, checksum_received, command_buffer, command_length);
664 checksum_calculated, checksum_received, command_buffer, command_length);
665 664
666 command_length = 0; 665 command_length = 0;
667 666
@@ -688,7 +687,7 @@ static bool IsDataAvailable() {
688 t.tv_usec = 0; 687 t.tv_usec = 0;
689 688
690 if (select(gdbserver_socket + 1, &fd_socket, nullptr, nullptr, &t) < 0) { 689 if (select(gdbserver_socket + 1, &fd_socket, nullptr, nullptr, &t) < 0) {
691 NGLOG_ERROR(Debug_GDBStub, "select failed"); 690 LOG_ERROR(Debug_GDBStub, "select failed");
692 return false; 691 return false;
693 } 692 }
694 693
@@ -801,7 +800,7 @@ static void ReadMemory() {
801 u64 len = 800 u64 len =
802 HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset)); 801 HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
803 802
804 NGLOG_DEBUG(Debug_GDBStub, "gdb: addr: {:016X} len: {:016X}", addr, len); 803 LOG_DEBUG(Debug_GDBStub, "gdb: addr: {:016X} len: {:016X}", addr, len);
805 804
806 if (len * 2 > sizeof(reply)) { 805 if (len * 2 > sizeof(reply)) {
807 SendReply("E01"); 806 SendReply("E01");
@@ -888,8 +887,8 @@ static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) {
888 breakpoint.len = len; 887 breakpoint.len = len;
889 p.insert({addr, breakpoint}); 888 p.insert({addr, breakpoint});
890 889
891 NGLOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}", 890 LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",
892 static_cast<int>(type), breakpoint.len, breakpoint.addr); 891 static_cast<int>(type), breakpoint.len, breakpoint.addr);
893 892
894 return true; 893 return true;
895} 894}
@@ -996,7 +995,7 @@ void HandlePacket() {
996 return; 995 return;
997 } 996 }
998 997
999 NGLOG_DEBUG(Debug_GDBStub, "Packet: {}", command_buffer); 998 LOG_DEBUG(Debug_GDBStub, "Packet: {}", command_buffer);
1000 999
1001 switch (command_buffer[0]) { 1000 switch (command_buffer[0]) {
1002 case 'q': 1001 case 'q':
@@ -1010,7 +1009,7 @@ void HandlePacket() {
1010 break; 1009 break;
1011 case 'k': 1010 case 'k':
1012 Shutdown(); 1011 Shutdown();
1013 NGLOG_INFO(Debug_GDBStub, "killed by gdb"); 1012 LOG_INFO(Debug_GDBStub, "killed by gdb");
1014 return; 1013 return;
1015 case 'g': 1014 case 'g':
1016 ReadRegisters(); 1015 ReadRegisters();
@@ -1092,7 +1091,7 @@ static void Init(u16 port) {
1092 breakpoints_write.clear(); 1091 breakpoints_write.clear();
1093 1092
1094 // Start gdb server 1093 // Start gdb server
1095 NGLOG_INFO(Debug_GDBStub, "Starting GDB server on port {}...", port); 1094 LOG_INFO(Debug_GDBStub, "Starting GDB server on port {}...", port);
1096 1095
1097 sockaddr_in saddr_server = {}; 1096 sockaddr_in saddr_server = {};
1098 saddr_server.sin_family = AF_INET; 1097 saddr_server.sin_family = AF_INET;
@@ -1105,28 +1104,28 @@ static void Init(u16 port) {
1105 1104
1106 int tmpsock = static_cast<int>(socket(PF_INET, SOCK_STREAM, 0)); 1105 int tmpsock = static_cast<int>(socket(PF_INET, SOCK_STREAM, 0));
1107 if (tmpsock == -1) { 1106 if (tmpsock == -1) {
1108 NGLOG_ERROR(Debug_GDBStub, "Failed to create gdb socket"); 1107 LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket");
1109 } 1108 }
1110 1109
1111 // Set socket to SO_REUSEADDR so it can always bind on the same port 1110 // Set socket to SO_REUSEADDR so it can always bind on the same port
1112 int reuse_enabled = 1; 1111 int reuse_enabled = 1;
1113 if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled, 1112 if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled,
1114 sizeof(reuse_enabled)) < 0) { 1113 sizeof(reuse_enabled)) < 0) {
1115 NGLOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option"); 1114 LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option");
1116 } 1115 }
1117 1116
1118 const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server); 1117 const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server);
1119 socklen_t server_addrlen = sizeof(saddr_server); 1118 socklen_t server_addrlen = sizeof(saddr_server);
1120 if (bind(tmpsock, server_addr, server_addrlen) < 0) { 1119 if (bind(tmpsock, server_addr, server_addrlen) < 0) {
1121 NGLOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket"); 1120 LOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket");
1122 } 1121 }
1123 1122
1124 if (listen(tmpsock, 1) < 0) { 1123 if (listen(tmpsock, 1) < 0) {
1125 NGLOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket"); 1124 LOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket");
1126 } 1125 }
1127 1126
1128 // Wait for gdb to connect 1127 // Wait for gdb to connect
1129 NGLOG_INFO(Debug_GDBStub, "Waiting for gdb to connect..."); 1128 LOG_INFO(Debug_GDBStub, "Waiting for gdb to connect...");
1130 sockaddr_in saddr_client; 1129 sockaddr_in saddr_client;
1131 sockaddr* client_addr = reinterpret_cast<sockaddr*>(&saddr_client); 1130 sockaddr* client_addr = reinterpret_cast<sockaddr*>(&saddr_client);
1132 socklen_t client_addrlen = sizeof(saddr_client); 1131 socklen_t client_addrlen = sizeof(saddr_client);
@@ -1137,9 +1136,9 @@ static void Init(u16 port) {
1137 halt_loop = false; 1136 halt_loop = false;
1138 step_loop = false; 1137 step_loop = false;
1139 1138
1140 NGLOG_ERROR(Debug_GDBStub, "Failed to accept gdb client"); 1139 LOG_ERROR(Debug_GDBStub, "Failed to accept gdb client");
1141 } else { 1140 } else {
1142 NGLOG_INFO(Debug_GDBStub, "Client connected."); 1141 LOG_INFO(Debug_GDBStub, "Client connected.");
1143 saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr); 1142 saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr);
1144 } 1143 }
1145 1144
@@ -1158,7 +1157,7 @@ void Shutdown() {
1158 return; 1157 return;
1159 } 1158 }
1160 1159
1161 NGLOG_INFO(Debug_GDBStub, "Stopping GDB ..."); 1160 LOG_INFO(Debug_GDBStub, "Stopping GDB ...");
1162 if (gdbserver_socket != -1) { 1161 if (gdbserver_socket != -1) {
1163 shutdown(gdbserver_socket, SHUT_RDWR); 1162 shutdown(gdbserver_socket, SHUT_RDWR);
1164 gdbserver_socket = -1; 1163 gdbserver_socket = -1;
@@ -1168,7 +1167,7 @@ void Shutdown() {
1168 WSACleanup(); 1167 WSACleanup();
1169#endif 1168#endif
1170 1169
1171 NGLOG_INFO(Debug_GDBStub, "GDB stopped."); 1170 LOG_INFO(Debug_GDBStub, "GDB stopped.");
1172} 1171}
1173 1172
1174bool IsServerEnabled() { 1173bool IsServerEnabled() {
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp
index f7a9920d8..7dd67f80f 100644
--- a/src/core/hle/kernel/handle_table.cpp
+++ b/src/core/hle/kernel/handle_table.cpp
@@ -26,7 +26,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
26 26
27 u16 slot = next_free_slot; 27 u16 slot = next_free_slot;
28 if (slot >= generations.size()) { 28 if (slot >= generations.size()) {
29 NGLOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); 29 LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use.");
30 return ERR_OUT_OF_HANDLES; 30 return ERR_OUT_OF_HANDLES;
31 } 31 }
32 next_free_slot = generations[slot]; 32 next_free_slot = generations[slot];
@@ -48,7 +48,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
48ResultVal<Handle> HandleTable::Duplicate(Handle handle) { 48ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
49 SharedPtr<Object> object = GetGeneric(handle); 49 SharedPtr<Object> object = GetGeneric(handle);
50 if (object == nullptr) { 50 if (object == nullptr) {
51 NGLOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle); 51 LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle);
52 return ERR_INVALID_HANDLE; 52 return ERR_INVALID_HANDLE;
53 } 53 }
54 return Create(std::move(object)); 54 return Create(std::move(object));
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index b0d83f401..609cdbff2 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -120,7 +120,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
120 std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>()); 120 std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>());
121 } else { 121 } else {
122 if (Session()->IsDomain()) 122 if (Session()->IsDomain())
123 NGLOG_WARNING(IPC, "Domain request has no DomainMessageHeader!"); 123 LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
124 } 124 }
125 } 125 }
126 126
@@ -272,15 +272,15 @@ std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const {
272 272
273size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size, int buffer_index) const { 273size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size, int buffer_index) const {
274 if (size == 0) { 274 if (size == 0) {
275 NGLOG_WARNING(Core, "skip empty buffer write"); 275 LOG_WARNING(Core, "skip empty buffer write");
276 return 0; 276 return 0;
277 } 277 }
278 278
279 const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()}; 279 const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()};
280 const size_t buffer_size{GetWriteBufferSize(buffer_index)}; 280 const size_t buffer_size{GetWriteBufferSize(buffer_index)};
281 if (size > buffer_size) { 281 if (size > buffer_size) {
282 NGLOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size, 282 LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
283 buffer_size); 283 buffer_size);
284 size = buffer_size; // TODO(bunnei): This needs to be HW tested 284 size = buffer_size; // TODO(bunnei): This needs to be HW tested
285 } 285 }
286 286
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 651d932d3..0c0506085 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -54,7 +54,7 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
54 continue; 54 continue;
55 } else if ((type & 0xF00) == 0xE00) { // 0x0FFF 55 } else if ((type & 0xF00) == 0xE00) { // 0x0FFF
56 // Allowed interrupts list 56 // Allowed interrupts list
57 NGLOG_WARNING(Loader, "ExHeader allowed interrupts list ignored"); 57 LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored");
58 } else if ((type & 0xF80) == 0xF00) { // 0x07FF 58 } else if ((type & 0xF80) == 0xF00) { // 0x07FF
59 // Allowed syscalls mask 59 // Allowed syscalls mask
60 unsigned int index = ((descriptor >> 24) & 7) * 24; 60 unsigned int index = ((descriptor >> 24) & 7) * 24;
@@ -74,7 +74,7 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
74 } else if ((type & 0xFFE) == 0xFF8) { // 0x001F 74 } else if ((type & 0xFFE) == 0xFF8) { // 0x001F
75 // Mapped memory range 75 // Mapped memory range
76 if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) { 76 if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) {
77 NGLOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); 77 LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored.");
78 continue; 78 continue;
79 } 79 }
80 u32 end_desc = kernel_caps[i + 1]; 80 u32 end_desc = kernel_caps[i + 1];
@@ -109,9 +109,9 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
109 109
110 int minor = kernel_version & 0xFF; 110 int minor = kernel_version & 0xFF;
111 int major = (kernel_version >> 8) & 0xFF; 111 int major = (kernel_version >> 8) & 0xFF;
112 NGLOG_INFO(Loader, "ExHeader kernel version: {}.{}", major, minor); 112 LOG_INFO(Loader, "ExHeader kernel version: {}.{}", major, minor);
113 } else { 113 } else {
114 NGLOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x{:08X}", descriptor); 114 LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x{:08X}", descriptor);
115 } 115 }
116 } 116 }
117} 117}
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp
index 0ef5fc57d..17a3e8a74 100644
--- a/src/core/hle/kernel/resource_limit.cpp
+++ b/src/core/hle/kernel/resource_limit.cpp
@@ -29,7 +29,7 @@ SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory cat
29 case ResourceLimitCategory::OTHER: 29 case ResourceLimitCategory::OTHER:
30 return resource_limits[static_cast<u8>(category)]; 30 return resource_limits[static_cast<u8>(category)];
31 default: 31 default:
32 NGLOG_CRITICAL(Kernel, "Unknown resource limit category"); 32 LOG_CRITICAL(Kernel, "Unknown resource limit category");
33 UNREACHABLE(); 33 UNREACHABLE();
34 } 34 }
35} 35}
@@ -55,7 +55,7 @@ s32 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const {
55 case ResourceType::CPUTime: 55 case ResourceType::CPUTime:
56 return current_cpu_time; 56 return current_cpu_time;
57 default: 57 default:
58 NGLOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource)); 58 LOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource));
59 UNIMPLEMENTED(); 59 UNIMPLEMENTED();
60 return 0; 60 return 0;
61 } 61 }
@@ -84,7 +84,7 @@ u32 ResourceLimit::GetMaxResourceValue(ResourceType resource) const {
84 case ResourceType::CPUTime: 84 case ResourceType::CPUTime:
85 return max_cpu_time; 85 return max_cpu_time;
86 default: 86 default:
87 NGLOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource)); 87 LOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource));
88 UNIMPLEMENTED(); 88 UNIMPLEMENTED();
89 return 0; 89 return 0;
90 } 90 }
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 9cb9e0e5c..11c2cb69e 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -99,11 +99,11 @@ void Scheduler::Reschedule() {
99 Thread* next = PopNextReadyThread(); 99 Thread* next = PopNextReadyThread();
100 100
101 if (cur && next) { 101 if (cur && next) {
102 NGLOG_TRACE(Kernel, "context switch {} -> {}", cur->GetObjectId(), next->GetObjectId()); 102 LOG_TRACE(Kernel, "context switch {} -> {}", cur->GetObjectId(), next->GetObjectId());
103 } else if (cur) { 103 } else if (cur) {
104 NGLOG_TRACE(Kernel, "context switch {} -> idle", cur->GetObjectId()); 104 LOG_TRACE(Kernel, "context switch {} -> idle", cur->GetObjectId());
105 } else if (next) { 105 } else if (next) {
106 NGLOG_TRACE(Kernel, "context switch idle -> {}", next->GetObjectId()); 106 LOG_TRACE(Kernel, "context switch idle -> {}", next->GetObjectId());
107 } 107 }
108 108
109 SwitchContext(next); 109 SwitchContext(next);
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index bf812c543..0d5cba1d9 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -71,7 +71,7 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
71 return domain_request_handlers[object_id - 1]->HandleSyncRequest(context); 71 return domain_request_handlers[object_id - 1]->HandleSyncRequest(context);
72 72
73 case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: { 73 case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
74 NGLOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id); 74 LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id);
75 75
76 domain_request_handlers[object_id - 1] = nullptr; 76 domain_request_handlers[object_id - 1] = nullptr;
77 77
@@ -81,8 +81,8 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
81 } 81 }
82 } 82 }
83 83
84 NGLOG_CRITICAL(IPC, "Unknown domain command={}", 84 LOG_CRITICAL(IPC, "Unknown domain command={}",
85 static_cast<int>(domain_message_header->command.Value())); 85 static_cast<int>(domain_message_header->command.Value()));
86 ASSERT(false); 86 ASSERT(false);
87 } 87 }
88 88
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index ac4921298..93f7f2772 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -107,16 +107,16 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
107 107
108 // Error out if the requested permissions don't match what the creator process allows. 108 // Error out if the requested permissions don't match what the creator process allows.
109 if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) { 109 if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) {
110 NGLOG_ERROR(Kernel, "cannot map id={}, address=0x{:X} name={}, permissions don't match", 110 LOG_ERROR(Kernel, "cannot map id={}, address=0x{:X} name={}, permissions don't match",
111 GetObjectId(), address, name); 111 GetObjectId(), address, name);
112 return ERR_INVALID_COMBINATION; 112 return ERR_INVALID_COMBINATION;
113 } 113 }
114 114
115 // Error out if the provided permissions are not compatible with what the creator process needs. 115 // Error out if the provided permissions are not compatible with what the creator process needs.
116 if (other_permissions != MemoryPermission::DontCare && 116 if (other_permissions != MemoryPermission::DontCare &&
117 static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) { 117 static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) {
118 NGLOG_ERROR(Kernel, "cannot map id={}, address=0x{:X} name={}, permissions don't match", 118 LOG_ERROR(Kernel, "cannot map id={}, address=0x{:X} name={}, permissions don't match",
119 GetObjectId(), address, name); 119 GetObjectId(), address, name);
120 return ERR_WRONG_PERMISSION; 120 return ERR_WRONG_PERMISSION;
121 } 121 }
122 122
@@ -131,7 +131,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
131 auto result = target_process->vm_manager.MapMemoryBlock( 131 auto result = target_process->vm_manager.MapMemoryBlock(
132 target_address, backing_block, backing_block_offset, size, MemoryState::Shared); 132 target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
133 if (result.Failed()) { 133 if (result.Failed()) {
134 NGLOG_ERROR( 134 LOG_ERROR(
135 Kernel, 135 Kernel,
136 "cannot map id={}, target_address=0x{:X} name={}, error mapping to virtual memory", 136 "cannot map id={}, target_address=0x{:X} name={}, error mapping to virtual memory",
137 GetObjectId(), target_address, name); 137 GetObjectId(), target_address, name);
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 1a36e0d02..5ad923fe7 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -32,7 +32,7 @@ namespace Kernel {
32 32
33/// Set the process heap to a given Size. It can both extend and shrink the heap. 33/// Set the process heap to a given Size. It can both extend and shrink the heap.
34static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { 34static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
35 NGLOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); 35 LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size);
36 auto& process = *Core::CurrentProcess(); 36 auto& process = *Core::CurrentProcess();
37 CASCADE_RESULT(*heap_addr, 37 CASCADE_RESULT(*heap_addr,
38 process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite)); 38 process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite));
@@ -40,21 +40,21 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
40} 40}
41 41
42static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) { 42static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) {
43 NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x{:X}", addr); 43 LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x{:X}", addr);
44 return RESULT_SUCCESS; 44 return RESULT_SUCCESS;
45} 45}
46 46
47/// Maps a memory range into a different range. 47/// Maps a memory range into a different range.
48static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { 48static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
49 NGLOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, 49 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
50 src_addr, size); 50 src_addr, size);
51 return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size); 51 return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size);
52} 52}
53 53
54/// Unmaps a region that was previously mapped with svcMapMemory 54/// Unmaps a region that was previously mapped with svcMapMemory
55static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { 55static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
56 NGLOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, 56 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
57 src_addr, size); 57 src_addr, size);
58 return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size); 58 return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size);
59} 59}
60 60
@@ -69,11 +69,11 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
69 if (port_name.size() > PortNameMaxLength) 69 if (port_name.size() > PortNameMaxLength)
70 return ERR_PORT_NAME_TOO_LONG; 70 return ERR_PORT_NAME_TOO_LONG;
71 71
72 NGLOG_TRACE(Kernel_SVC, "called port_name={}", port_name); 72 LOG_TRACE(Kernel_SVC, "called port_name={}", port_name);
73 73
74 auto it = Service::g_kernel_named_ports.find(port_name); 74 auto it = Service::g_kernel_named_ports.find(port_name);
75 if (it == Service::g_kernel_named_ports.end()) { 75 if (it == Service::g_kernel_named_ports.end()) {
76 NGLOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name); 76 LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
77 return ERR_NOT_FOUND; 77 return ERR_NOT_FOUND;
78 } 78 }
79 79
@@ -91,11 +91,11 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
91static ResultCode SendSyncRequest(Handle handle) { 91static ResultCode SendSyncRequest(Handle handle) {
92 SharedPtr<ClientSession> session = g_handle_table.Get<ClientSession>(handle); 92 SharedPtr<ClientSession> session = g_handle_table.Get<ClientSession>(handle);
93 if (!session) { 93 if (!session) {
94 NGLOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); 94 LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
95 return ERR_INVALID_HANDLE; 95 return ERR_INVALID_HANDLE;
96 } 96 }
97 97
98 NGLOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); 98 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
99 99
100 Core::System::GetInstance().PrepareReschedule(); 100 Core::System::GetInstance().PrepareReschedule();
101 101
@@ -106,7 +106,7 @@ static ResultCode SendSyncRequest(Handle handle) {
106 106
107/// Get the ID for the specified thread. 107/// Get the ID for the specified thread.
108static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { 108static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
109 NGLOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); 109 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
110 110
111 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 111 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
112 if (!thread) { 112 if (!thread) {
@@ -119,7 +119,7 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
119 119
120/// Get the ID of the specified process 120/// Get the ID of the specified process
121static ResultCode GetProcessId(u32* process_id, Handle process_handle) { 121static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
122 NGLOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); 122 LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle);
123 123
124 const SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle); 124 const SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle);
125 if (!process) { 125 if (!process) {
@@ -149,8 +149,8 @@ static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thr
149/// Wait for the given handles to synchronize, timeout after the specified nanoseconds 149/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
150static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count, 150static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count,
151 s64 nano_seconds) { 151 s64 nano_seconds) {
152 NGLOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", 152 LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}",
153 handles_address, handle_count, nano_seconds); 153 handles_address, handle_count, nano_seconds);
154 154
155 if (!Memory::IsValidVirtualAddress(handles_address)) 155 if (!Memory::IsValidVirtualAddress(handles_address))
156 return ERR_INVALID_POINTER; 156 return ERR_INVALID_POINTER;
@@ -210,7 +210,7 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
210 210
211/// Resumes a thread waiting on WaitSynchronization 211/// Resumes a thread waiting on WaitSynchronization
212static ResultCode CancelSynchronization(Handle thread_handle) { 212static ResultCode CancelSynchronization(Handle thread_handle) {
213 NGLOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); 213 LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle);
214 214
215 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 215 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
216 if (!thread) { 216 if (!thread) {
@@ -227,24 +227,24 @@ static ResultCode CancelSynchronization(Handle thread_handle) {
227/// Attempts to locks a mutex, creating it if it does not already exist 227/// Attempts to locks a mutex, creating it if it does not already exist
228static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, 228static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
229 Handle requesting_thread_handle) { 229 Handle requesting_thread_handle) {
230 NGLOG_TRACE(Kernel_SVC, 230 LOG_TRACE(Kernel_SVC,
231 "called holding_thread_handle=0x{:08X}, mutex_addr=0x{:X}, " 231 "called holding_thread_handle=0x{:08X}, mutex_addr=0x{:X}, "
232 "requesting_current_thread_handle=0x{:08X}", 232 "requesting_current_thread_handle=0x{:08X}",
233 holding_thread_handle, mutex_addr, requesting_thread_handle); 233 holding_thread_handle, mutex_addr, requesting_thread_handle);
234 234
235 return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle); 235 return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle);
236} 236}
237 237
238/// Unlock a mutex 238/// Unlock a mutex
239static ResultCode ArbitrateUnlock(VAddr mutex_addr) { 239static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
240 NGLOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); 240 LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr);
241 241
242 return Mutex::Release(mutex_addr); 242 return Mutex::Release(mutex_addr);
243} 243}
244 244
245/// Break program execution 245/// Break program execution
246static void Break(u64 unk_0, u64 unk_1, u64 unk_2) { 246static void Break(u64 unk_0, u64 unk_1, u64 unk_2) {
247 NGLOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!"); 247 LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!");
248 ASSERT(false); 248 ASSERT(false);
249} 249}
250 250
@@ -252,13 +252,13 @@ static void Break(u64 unk_0, u64 unk_1, u64 unk_2) {
252static void OutputDebugString(VAddr address, s32 len) { 252static void OutputDebugString(VAddr address, s32 len) {
253 std::string str(len, '\0'); 253 std::string str(len, '\0');
254 Memory::ReadBlock(address, str.data(), str.size()); 254 Memory::ReadBlock(address, str.data(), str.size());
255 NGLOG_DEBUG(Debug_Emulated, "{}", str); 255 LOG_DEBUG(Debug_Emulated, "{}", str);
256} 256}
257 257
258/// Gets system/memory information for the current process 258/// Gets system/memory information for the current process
259static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) { 259static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) {
260 NGLOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, 260 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
261 info_sub_id, handle); 261 info_sub_id, handle);
262 262
263 auto& vm_manager = Core::CurrentProcess()->vm_manager; 263 auto& vm_manager = Core::CurrentProcess()->vm_manager;
264 264
@@ -309,17 +309,17 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
309 *result = Core::CurrentProcess()->is_virtual_address_memory_enabled; 309 *result = Core::CurrentProcess()->is_virtual_address_memory_enabled;
310 break; 310 break;
311 case GetInfoType::TitleId: 311 case GetInfoType::TitleId:
312 NGLOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0"); 312 LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0");
313 *result = 0; 313 *result = 0;
314 break; 314 break;
315 case GetInfoType::PrivilegedProcessId: 315 case GetInfoType::PrivilegedProcessId:
316 NGLOG_WARNING(Kernel_SVC, 316 LOG_WARNING(Kernel_SVC,
317 "(STUBBED) Attempted to query privileged process id bounds, returned 0"); 317 "(STUBBED) Attempted to query privileged process id bounds, returned 0");
318 *result = 0; 318 *result = 0;
319 break; 319 break;
320 case GetInfoType::UserExceptionContextAddr: 320 case GetInfoType::UserExceptionContextAddr:
321 NGLOG_WARNING(Kernel_SVC, 321 LOG_WARNING(Kernel_SVC,
322 "(STUBBED) Attempted to query user exception context address, returned 0"); 322 "(STUBBED) Attempted to query user exception context address, returned 0");
323 *result = 0; 323 *result = 0;
324 break; 324 break;
325 default: 325 default:
@@ -331,14 +331,13 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
331 331
332/// Sets the thread activity 332/// Sets the thread activity
333static ResultCode SetThreadActivity(Handle handle, u32 unknown) { 333static ResultCode SetThreadActivity(Handle handle, u32 unknown) {
334 NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, unknown=0x{:08X}", handle, 334 LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, unknown=0x{:08X}", handle, unknown);
335 unknown);
336 return RESULT_SUCCESS; 335 return RESULT_SUCCESS;
337} 336}
338 337
339/// Gets the thread context 338/// Gets the thread context
340static ResultCode GetThreadContext(Handle handle, VAddr addr) { 339static ResultCode GetThreadContext(Handle handle, VAddr addr) {
341 NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, addr=0x{:X}", handle, addr); 340 LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, addr=0x{:X}", handle, addr);
342 return RESULT_SUCCESS; 341 return RESULT_SUCCESS;
343} 342}
344 343
@@ -377,16 +376,15 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
377 376
378/// Get which CPU core is executing the current thread 377/// Get which CPU core is executing the current thread
379static u32 GetCurrentProcessorNumber() { 378static u32 GetCurrentProcessorNumber() {
380 NGLOG_TRACE(Kernel_SVC, "called"); 379 LOG_TRACE(Kernel_SVC, "called");
381 return GetCurrentThread()->processor_id; 380 return GetCurrentThread()->processor_id;
382} 381}
383 382
384static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size, 383static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size,
385 u32 permissions) { 384 u32 permissions) {
386 NGLOG_TRACE( 385 LOG_TRACE(Kernel_SVC,
387 Kernel_SVC, 386 "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
388 "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", 387 shared_memory_handle, addr, size, permissions);
389 shared_memory_handle, addr, size, permissions);
390 388
391 SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); 389 SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
392 if (!shared_memory) { 390 if (!shared_memory) {
@@ -406,15 +404,15 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
406 return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type, 404 return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type,
407 MemoryPermission::DontCare); 405 MemoryPermission::DontCare);
408 default: 406 default:
409 NGLOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions); 407 LOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions);
410 } 408 }
411 409
412 return RESULT_SUCCESS; 410 return RESULT_SUCCESS;
413} 411}
414 412
415static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { 413static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) {
416 NGLOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}", 414 LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}",
417 shared_memory_handle, addr, size); 415 shared_memory_handle, addr, size);
418 416
419 SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); 417 SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
420 418
@@ -442,19 +440,19 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
442 memory_info->type = static_cast<u32>(vma->second.meminfo_state); 440 memory_info->type = static_cast<u32>(vma->second.meminfo_state);
443 } 441 }
444 442
445 NGLOG_TRACE(Kernel_SVC, "called process=0x{:08X} addr={:X}", process_handle, addr); 443 LOG_TRACE(Kernel_SVC, "called process=0x{:08X} addr={:X}", process_handle, addr);
446 return RESULT_SUCCESS; 444 return RESULT_SUCCESS;
447} 445}
448 446
449/// Query memory 447/// Query memory
450static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAddr addr) { 448static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAddr addr) {
451 NGLOG_TRACE(Kernel_SVC, "called, addr={:X}", addr); 449 LOG_TRACE(Kernel_SVC, "called, addr={:X}", addr);
452 return QueryProcessMemory(memory_info, page_info, CurrentProcess, addr); 450 return QueryProcessMemory(memory_info, page_info, CurrentProcess, addr);
453} 451}
454 452
455/// Exits the current process 453/// Exits the current process
456static void ExitProcess() { 454static void ExitProcess() {
457 NGLOG_INFO(Kernel_SVC, "Process {} exiting", Core::CurrentProcess()->process_id); 455 LOG_INFO(Kernel_SVC, "Process {} exiting", Core::CurrentProcess()->process_id);
458 456
459 ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running, 457 ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running,
460 "Process has already exited"); 458 "Process has already exited");
@@ -530,17 +528,17 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
530 Core::System::GetInstance().PrepareReschedule(); 528 Core::System::GetInstance().PrepareReschedule();
531 Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule(); 529 Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule();
532 530
533 NGLOG_TRACE(Kernel_SVC, 531 LOG_TRACE(Kernel_SVC,
534 "called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, " 532 "called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, "
535 "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", 533 "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}",
536 entry_point, name, arg, stack_top, priority, processor_id, *out_handle); 534 entry_point, name, arg, stack_top, priority, processor_id, *out_handle);
537 535
538 return RESULT_SUCCESS; 536 return RESULT_SUCCESS;
539} 537}
540 538
541/// Starts the thread for the provided handle 539/// Starts the thread for the provided handle
542static ResultCode StartThread(Handle thread_handle) { 540static ResultCode StartThread(Handle thread_handle) {
543 NGLOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); 541 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
544 542
545 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 543 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
546 if (!thread) { 544 if (!thread) {
@@ -557,7 +555,7 @@ static ResultCode StartThread(Handle thread_handle) {
557 555
558/// Called when a thread exits 556/// Called when a thread exits
559static void ExitThread() { 557static void ExitThread() {
560 NGLOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", Core::CurrentArmInterface().GetPC()); 558 LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", Core::CurrentArmInterface().GetPC());
561 559
562 ExitCurrentThread(); 560 ExitCurrentThread();
563 Core::System::GetInstance().PrepareReschedule(); 561 Core::System::GetInstance().PrepareReschedule();
@@ -565,7 +563,7 @@ static void ExitThread() {
565 563
566/// Sleep the current thread 564/// Sleep the current thread
567static void SleepThread(s64 nanoseconds) { 565static void SleepThread(s64 nanoseconds) {
568 NGLOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); 566 LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds);
569 567
570 // Don't attempt to yield execution if there are no available threads to run, 568 // Don't attempt to yield execution if there are no available threads to run,
571 // this way we avoid a useless reschedule to the idle thread. 569 // this way we avoid a useless reschedule to the idle thread.
@@ -584,7 +582,7 @@ static void SleepThread(s64 nanoseconds) {
584/// Wait process wide key atomic 582/// Wait process wide key atomic
585static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr, 583static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr,
586 Handle thread_handle, s64 nano_seconds) { 584 Handle thread_handle, s64 nano_seconds) {
587 NGLOG_TRACE( 585 LOG_TRACE(
588 Kernel_SVC, 586 Kernel_SVC,
589 "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}", 587 "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}",
590 mutex_addr, condition_variable_addr, thread_handle, nano_seconds); 588 mutex_addr, condition_variable_addr, thread_handle, nano_seconds);
@@ -611,8 +609,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
611 609
612/// Signal process wide key 610/// Signal process wide key
613static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) { 611static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) {
614 NGLOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}", 612 LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}",
615 condition_variable_addr, target); 613 condition_variable_addr, target);
616 614
617 auto RetrieveWaitingThreads = 615 auto RetrieveWaitingThreads =
618 [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr condvar_addr) { 616 [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr condvar_addr) {
@@ -692,8 +690,8 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
692 690
693// Wait for an address (via Address Arbiter) 691// Wait for an address (via Address Arbiter)
694static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout) { 692static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout) {
695 NGLOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, timeout={}", 693 LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, timeout={}",
696 address, type, value, timeout); 694 address, type, value, timeout);
697 // If the passed address is a kernel virtual address, return invalid memory state. 695 // If the passed address is a kernel virtual address, return invalid memory state.
698 if (Memory::IsKernelVirtualAddress(address)) { 696 if (Memory::IsKernelVirtualAddress(address)) {
699 return ERR_INVALID_ADDRESS_STATE; 697 return ERR_INVALID_ADDRESS_STATE;
@@ -717,9 +715,8 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout
717 715
718// Signals to an address (via Address Arbiter) 716// Signals to an address (via Address Arbiter)
719static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to_wake) { 717static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to_wake) {
720 NGLOG_WARNING(Kernel_SVC, 718 LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, num_to_wake=0x{:X}",
721 "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, num_to_wake=0x{:X}", address, 719 address, type, value, num_to_wake);
722 type, value, num_to_wake);
723 // If the passed address is a kernel virtual address, return invalid memory state. 720 // If the passed address is a kernel virtual address, return invalid memory state.
724 if (Memory::IsKernelVirtualAddress(address)) { 721 if (Memory::IsKernelVirtualAddress(address)) {
725 return ERR_INVALID_ADDRESS_STATE; 722 return ERR_INVALID_ADDRESS_STATE;
@@ -754,13 +751,13 @@ static u64 GetSystemTick() {
754 751
755/// Close a handle 752/// Close a handle
756static ResultCode CloseHandle(Handle handle) { 753static ResultCode CloseHandle(Handle handle) {
757 NGLOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); 754 LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
758 return g_handle_table.Close(handle); 755 return g_handle_table.Close(handle);
759} 756}
760 757
761/// Reset an event 758/// Reset an event
762static ResultCode ResetSignal(Handle handle) { 759static ResultCode ResetSignal(Handle handle) {
763 NGLOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x{:08X}", handle); 760 LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x{:08X}", handle);
764 auto event = g_handle_table.Get<Event>(handle); 761 auto event = g_handle_table.Get<Event>(handle);
765 ASSERT(event != nullptr); 762 ASSERT(event != nullptr);
766 event->Clear(); 763 event->Clear();
@@ -769,14 +766,14 @@ static ResultCode ResetSignal(Handle handle) {
769 766
770/// Creates a TransferMemory object 767/// Creates a TransferMemory object
771static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) { 768static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) {
772 NGLOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, 769 LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size,
773 size, permissions); 770 permissions);
774 *handle = 0; 771 *handle = 0;
775 return RESULT_SUCCESS; 772 return RESULT_SUCCESS;
776} 773}
777 774
778static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { 775static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) {
779 NGLOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); 776 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
780 777
781 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 778 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
782 if (!thread) { 779 if (!thread) {
@@ -790,8 +787,8 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask)
790} 787}
791 788
792static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { 789static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
793 NGLOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle, 790 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle,
794 mask, core); 791 mask, core);
795 792
796 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 793 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
797 if (!thread) { 794 if (!thread) {
@@ -830,8 +827,8 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
830 827
831static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions, 828static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions,
832 u32 remote_permissions) { 829 u32 remote_permissions) {
833 NGLOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, 830 LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size,
834 local_permissions, remote_permissions); 831 local_permissions, remote_permissions);
835 auto sharedMemHandle = 832 auto sharedMemHandle =
836 SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size, 833 SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size,
837 static_cast<MemoryPermission>(local_permissions), 834 static_cast<MemoryPermission>(local_permissions),
@@ -842,7 +839,7 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
842} 839}
843 840
844static ResultCode ClearEvent(Handle handle) { 841static ResultCode ClearEvent(Handle handle) {
845 NGLOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); 842 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
846 843
847 SharedPtr<Event> evt = g_handle_table.Get<Event>(handle); 844 SharedPtr<Event> evt = g_handle_table.Get<Event>(handle);
848 if (evt == nullptr) 845 if (evt == nullptr)
@@ -994,7 +991,7 @@ static const FunctionDef SVC_Table[] = {
994 991
995static const FunctionDef* GetSVCInfo(u32 func_num) { 992static const FunctionDef* GetSVCInfo(u32 func_num) {
996 if (func_num >= std::size(SVC_Table)) { 993 if (func_num >= std::size(SVC_Table)) {
997 NGLOG_ERROR(Kernel_SVC, "Unknown svc=0x{:02X}", func_num); 994 LOG_ERROR(Kernel_SVC, "Unknown svc=0x{:02X}", func_num);
998 return nullptr; 995 return nullptr;
999 } 996 }
1000 return &SVC_Table[func_num]; 997 return &SVC_Table[func_num];
@@ -1013,10 +1010,10 @@ void CallSVC(u32 immediate) {
1013 if (info->func) { 1010 if (info->func) {
1014 info->func(); 1011 info->func();
1015 } else { 1012 } else {
1016 NGLOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name); 1013 LOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name);
1017 } 1014 }
1018 } else { 1015 } else {
1019 NGLOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate); 1016 LOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate);
1020 } 1017 }
1021} 1018}
1022 1019
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 2f333ec34..9a9746585 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -104,7 +104,7 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
104 const auto proper_handle = static_cast<Handle>(thread_handle); 104 const auto proper_handle = static_cast<Handle>(thread_handle);
105 SharedPtr<Thread> thread = wakeup_callback_handle_table.Get<Thread>(proper_handle); 105 SharedPtr<Thread> thread = wakeup_callback_handle_table.Get<Thread>(proper_handle);
106 if (thread == nullptr) { 106 if (thread == nullptr) {
107 NGLOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle); 107 LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle);
108 return; 108 return;
109 } 109 }
110 110
@@ -290,19 +290,19 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
290 SharedPtr<Process> owner_process) { 290 SharedPtr<Process> owner_process) {
291 // Check if priority is in ranged. Lowest priority -> highest priority id. 291 // Check if priority is in ranged. Lowest priority -> highest priority id.
292 if (priority > THREADPRIO_LOWEST) { 292 if (priority > THREADPRIO_LOWEST) {
293 NGLOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); 293 LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
294 return ERR_OUT_OF_RANGE; 294 return ERR_OUT_OF_RANGE;
295 } 295 }
296 296
297 if (processor_id > THREADPROCESSORID_MAX) { 297 if (processor_id > THREADPROCESSORID_MAX) {
298 NGLOG_ERROR(Kernel_SVC, "Invalid processor id: {}", processor_id); 298 LOG_ERROR(Kernel_SVC, "Invalid processor id: {}", processor_id);
299 return ERR_OUT_OF_RANGE_KERNEL; 299 return ERR_OUT_OF_RANGE_KERNEL;
300 } 300 }
301 301
302 // TODO(yuriks): Other checks, returning 0xD9001BEA 302 // TODO(yuriks): Other checks, returning 0xD9001BEA
303 303
304 if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) { 304 if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) {
305 NGLOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point); 305 LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point);
306 // TODO (bunnei): Find the correct error code to use here 306 // TODO (bunnei): Find the correct error code to use here
307 return ResultCode(-1); 307 return ResultCode(-1);
308 } 308 }
@@ -343,8 +343,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
343 auto& linheap_memory = memory_region->linear_heap_memory; 343 auto& linheap_memory = memory_region->linear_heap_memory;
344 344
345 if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) { 345 if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) {
346 NGLOG_ERROR(Kernel_SVC, 346 LOG_ERROR(Kernel_SVC,
347 "Not enough space in region to allocate a new TLS page for thread"); 347 "Not enough space in region to allocate a new TLS page for thread");
348 return ERR_OUT_OF_MEMORY; 348 return ERR_OUT_OF_MEMORY;
349 } 349 }
350 350
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 661356a97..0141125e4 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -78,7 +78,7 @@ void Timer::WakeupAllWaitingThreads() {
78} 78}
79 79
80void Timer::Signal(int cycles_late) { 80void Timer::Signal(int cycles_late) {
81 NGLOG_TRACE(Kernel, "Timer {} fired", GetObjectId()); 81 LOG_TRACE(Kernel, "Timer {} fired", GetObjectId());
82 82
83 signaled = true; 83 signaled = true;
84 84
@@ -98,7 +98,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
98 timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle)); 98 timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle));
99 99
100 if (timer == nullptr) { 100 if (timer == nullptr) {
101 NGLOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle); 101 LOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle);
102 return; 102 return;
103 } 103 }
104 104
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index 676e5b282..034dd490e 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -242,12 +242,12 @@ void VMManager::RefreshMemoryBlockMappings(const std::vector<u8>* block) {
242void VMManager::LogLayout() const { 242void VMManager::LogLayout() const {
243 for (const auto& p : vma_map) { 243 for (const auto& p : vma_map) {
244 const VirtualMemoryArea& vma = p.second; 244 const VirtualMemoryArea& vma = p.second;
245 NGLOG_DEBUG(Kernel, "{:016X} - {:016X} size: {:016X} {}{}{} {}", vma.base, 245 LOG_DEBUG(Kernel, "{:016X} - {:016X} size: {:016X} {}{}{} {}", vma.base,
246 vma.base + vma.size, vma.size, 246 vma.base + vma.size, vma.size,
247 (u8)vma.permissions & (u8)VMAPermission::Read ? 'R' : '-', 247 (u8)vma.permissions & (u8)VMAPermission::Read ? 'R' : '-',
248 (u8)vma.permissions & (u8)VMAPermission::Write ? 'W' : '-', 248 (u8)vma.permissions & (u8)VMAPermission::Write ? 'W' : '-',
249 (u8)vma.permissions & (u8)VMAPermission::Execute ? 'X' : '-', 249 (u8)vma.permissions & (u8)VMAPermission::Execute ? 'X' : '-',
250 GetMemoryStateName(vma.meminfo_state)); 250 GetMemoryStateName(vma.meminfo_state));
251 } 251 }
252} 252}
253 253
@@ -392,22 +392,22 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
392} 392}
393 393
394u64 VMManager::GetTotalMemoryUsage() { 394u64 VMManager::GetTotalMemoryUsage() {
395 NGLOG_WARNING(Kernel, "(STUBBED) called"); 395 LOG_WARNING(Kernel, "(STUBBED) called");
396 return 0xF8000000; 396 return 0xF8000000;
397} 397}
398 398
399u64 VMManager::GetTotalHeapUsage() { 399u64 VMManager::GetTotalHeapUsage() {
400 NGLOG_WARNING(Kernel, "(STUBBED) called"); 400 LOG_WARNING(Kernel, "(STUBBED) called");
401 return 0x0; 401 return 0x0;
402} 402}
403 403
404VAddr VMManager::GetAddressSpaceBaseAddr() { 404VAddr VMManager::GetAddressSpaceBaseAddr() {
405 NGLOG_WARNING(Kernel, "(STUBBED) called"); 405 LOG_WARNING(Kernel, "(STUBBED) called");
406 return 0x8000000; 406 return 0x8000000;
407} 407}
408 408
409u64 VMManager::GetAddressSpaceSize() { 409u64 VMManager::GetAddressSpaceSize() {
410 NGLOG_WARNING(Kernel, "(STUBBED) called"); 410 LOG_WARNING(Kernel, "(STUBBED) called");
411 return MAX_ADDRESS; 411 return MAX_ADDRESS;
412} 412}
413 413
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index f2fffa760..6bafb2dce 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -47,7 +47,7 @@ public:
47 47
48private: 48private:
49 void GetBase(Kernel::HLERequestContext& ctx) { 49 void GetBase(Kernel::HLERequestContext& ctx) {
50 NGLOG_WARNING(Service_ACC, "(STUBBED) called"); 50 LOG_WARNING(Service_ACC, "(STUBBED) called");
51 ProfileBase profile_base{}; 51 ProfileBase profile_base{};
52 IPC::ResponseBuilder rb{ctx, 16}; 52 IPC::ResponseBuilder rb{ctx, 16};
53 rb.Push(RESULT_SUCCESS); 53 rb.Push(RESULT_SUCCESS);
@@ -72,14 +72,14 @@ public:
72 72
73private: 73private:
74 void CheckAvailability(Kernel::HLERequestContext& ctx) { 74 void CheckAvailability(Kernel::HLERequestContext& ctx) {
75 NGLOG_WARNING(Service_ACC, "(STUBBED) called"); 75 LOG_WARNING(Service_ACC, "(STUBBED) called");
76 IPC::ResponseBuilder rb{ctx, 3}; 76 IPC::ResponseBuilder rb{ctx, 3};
77 rb.Push(RESULT_SUCCESS); 77 rb.Push(RESULT_SUCCESS);
78 rb.Push(true); // TODO: Check when this is supposed to return true and when not 78 rb.Push(true); // TODO: Check when this is supposed to return true and when not
79 } 79 }
80 80
81 void GetAccountId(Kernel::HLERequestContext& ctx) { 81 void GetAccountId(Kernel::HLERequestContext& ctx) {
82 NGLOG_WARNING(Service_ACC, "(STUBBED) called"); 82 LOG_WARNING(Service_ACC, "(STUBBED) called");
83 IPC::ResponseBuilder rb{ctx, 4}; 83 IPC::ResponseBuilder rb{ctx, 4};
84 rb.Push(RESULT_SUCCESS); 84 rb.Push(RESULT_SUCCESS);
85 rb.Push<u64>(0x12345678ABCDEF); 85 rb.Push<u64>(0x12345678ABCDEF);
@@ -87,14 +87,14 @@ private:
87}; 87};
88 88
89void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { 89void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) {
90 NGLOG_WARNING(Service_ACC, "(STUBBED) called"); 90 LOG_WARNING(Service_ACC, "(STUBBED) called");
91 IPC::ResponseBuilder rb{ctx, 3}; 91 IPC::ResponseBuilder rb{ctx, 3};
92 rb.Push(RESULT_SUCCESS); 92 rb.Push(RESULT_SUCCESS);
93 rb.Push(true); // TODO: Check when this is supposed to return true and when not 93 rb.Push(true); // TODO: Check when this is supposed to return true and when not
94} 94}
95 95
96void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { 96void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) {
97 NGLOG_WARNING(Service_ACC, "(STUBBED) called"); 97 LOG_WARNING(Service_ACC, "(STUBBED) called");
98 constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID}; 98 constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID};
99 ctx.WriteBuffer(user_ids.data(), user_ids.size()); 99 ctx.WriteBuffer(user_ids.data(), user_ids.size());
100 IPC::ResponseBuilder rb{ctx, 2}; 100 IPC::ResponseBuilder rb{ctx, 2};
@@ -102,7 +102,7 @@ void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) {
102} 102}
103 103
104void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { 104void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) {
105 NGLOG_WARNING(Service_ACC, "(STUBBED) called"); 105 LOG_WARNING(Service_ACC, "(STUBBED) called");
106 constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID}; 106 constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID};
107 ctx.WriteBuffer(user_ids.data(), user_ids.size()); 107 ctx.WriteBuffer(user_ids.data(), user_ids.size());
108 IPC::ResponseBuilder rb{ctx, 2}; 108 IPC::ResponseBuilder rb{ctx, 2};
@@ -113,11 +113,11 @@ void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) {
113 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 113 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
114 rb.Push(RESULT_SUCCESS); 114 rb.Push(RESULT_SUCCESS);
115 rb.PushIpcInterface<IProfile>(); 115 rb.PushIpcInterface<IProfile>();
116 NGLOG_DEBUG(Service_ACC, "called"); 116 LOG_DEBUG(Service_ACC, "called");
117} 117}
118 118
119void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { 119void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
120 NGLOG_WARNING(Service_ACC, "(STUBBED) called"); 120 LOG_WARNING(Service_ACC, "(STUBBED) called");
121 IPC::ResponseBuilder rb{ctx, 2}; 121 IPC::ResponseBuilder rb{ctx, 2};
122 rb.Push(RESULT_SUCCESS); 122 rb.Push(RESULT_SUCCESS);
123} 123}
@@ -126,11 +126,11 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
126 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 126 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
127 rb.Push(RESULT_SUCCESS); 127 rb.Push(RESULT_SUCCESS);
128 rb.PushIpcInterface<IManagerForApplication>(); 128 rb.PushIpcInterface<IManagerForApplication>();
129 NGLOG_DEBUG(Service_ACC, "called"); 129 LOG_DEBUG(Service_ACC, "called");
130} 130}
131 131
132void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { 132void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) {
133 NGLOG_WARNING(Service_ACC, "(STUBBED) called"); 133 LOG_WARNING(Service_ACC, "(STUBBED) called");
134 IPC::ResponseBuilder rb{ctx, 6}; 134 IPC::ResponseBuilder rb{ctx, 6};
135 rb.Push(RESULT_SUCCESS); 135 rb.Push(RESULT_SUCCESS);
136 rb.PushRaw(DEFAULT_USER_ID); 136 rb.PushRaw(DEFAULT_USER_ID);
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index b8d6b8d4d..a871b3eaa 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -30,14 +30,14 @@ IWindowController::IWindowController() : ServiceFramework("IWindowController") {
30} 30}
31 31
32void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) { 32void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
33 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 33 LOG_WARNING(Service_AM, "(STUBBED) called");
34 IPC::ResponseBuilder rb{ctx, 4}; 34 IPC::ResponseBuilder rb{ctx, 4};
35 rb.Push(RESULT_SUCCESS); 35 rb.Push(RESULT_SUCCESS);
36 rb.Push<u64>(0); 36 rb.Push<u64>(0);
37} 37}
38 38
39void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) { 39void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
40 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 40 LOG_WARNING(Service_AM, "(STUBBED) called");
41 IPC::ResponseBuilder rb{ctx, 2}; 41 IPC::ResponseBuilder rb{ctx, 2};
42 rb.Push(RESULT_SUCCESS); 42 rb.Push(RESULT_SUCCESS);
43} 43}
@@ -56,20 +56,20 @@ IAudioController::IAudioController() : ServiceFramework("IAudioController") {
56} 56}
57 57
58void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) { 58void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
59 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 59 LOG_WARNING(Service_AM, "(STUBBED) called");
60 IPC::ResponseBuilder rb{ctx, 2}; 60 IPC::ResponseBuilder rb{ctx, 2};
61 rb.Push(RESULT_SUCCESS); 61 rb.Push(RESULT_SUCCESS);
62} 62}
63 63
64void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { 64void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
65 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 65 LOG_WARNING(Service_AM, "(STUBBED) called");
66 IPC::ResponseBuilder rb{ctx, 3}; 66 IPC::ResponseBuilder rb{ctx, 3};
67 rb.Push(RESULT_SUCCESS); 67 rb.Push(RESULT_SUCCESS);
68 rb.Push(volume); 68 rb.Push(volume);
69} 69}
70 70
71void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { 71void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
72 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 72 LOG_WARNING(Service_AM, "(STUBBED) called");
73 IPC::ResponseBuilder rb{ctx, 3}; 73 IPC::ResponseBuilder rb{ctx, 3};
74 rb.Push(RESULT_SUCCESS); 74 rb.Push(RESULT_SUCCESS);
75 rb.Push(volume); 75 rb.Push(volume);
@@ -174,14 +174,14 @@ void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
174 IPC::ResponseBuilder rb{ctx, 2}; 174 IPC::ResponseBuilder rb{ctx, 2};
175 rb.Push(RESULT_SUCCESS); 175 rb.Push(RESULT_SUCCESS);
176 176
177 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 177 LOG_WARNING(Service_AM, "(STUBBED) called");
178} 178}
179 179
180void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) { 180void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
181 IPC::ResponseBuilder rb{ctx, 2}; 181 IPC::ResponseBuilder rb{ctx, 2};
182 rb.Push(RESULT_SUCCESS); 182 rb.Push(RESULT_SUCCESS);
183 183
184 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 184 LOG_WARNING(Service_AM, "(STUBBED) called");
185} 185}
186 186
187void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) { 187void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
@@ -192,14 +192,14 @@ void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestCo
192 IPC::ResponseBuilder rb{ctx, 2}; 192 IPC::ResponseBuilder rb{ctx, 2};
193 rb.Push(RESULT_SUCCESS); 193 rb.Push(RESULT_SUCCESS);
194 194
195 NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag); 195 LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
196} 196}
197 197
198void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { 198void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
199 IPC::ResponseBuilder rb{ctx, 2}; 199 IPC::ResponseBuilder rb{ctx, 2};
200 rb.Push(RESULT_SUCCESS); 200 rb.Push(RESULT_SUCCESS);
201 201
202 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 202 LOG_WARNING(Service_AM, "(STUBBED) called");
203} 203}
204 204
205void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) { 205void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
@@ -210,7 +210,7 @@ void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestCont
210 IPC::ResponseBuilder rb{ctx, 2}; 210 IPC::ResponseBuilder rb{ctx, 2};
211 rb.Push(RESULT_SUCCESS); 211 rb.Push(RESULT_SUCCESS);
212 212
213 NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag); 213 LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
214} 214}
215 215
216void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) { 216void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
@@ -223,21 +223,21 @@ void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext&
223 IPC::ResponseBuilder rb{ctx, 2}; 223 IPC::ResponseBuilder rb{ctx, 2};
224 rb.Push(RESULT_SUCCESS); 224 rb.Push(RESULT_SUCCESS);
225 225
226 NGLOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled); 226 LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
227} 227}
228 228
229void ISelfController::LockExit(Kernel::HLERequestContext& ctx) { 229void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
230 IPC::ResponseBuilder rb{ctx, 2}; 230 IPC::ResponseBuilder rb{ctx, 2};
231 rb.Push(RESULT_SUCCESS); 231 rb.Push(RESULT_SUCCESS);
232 232
233 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 233 LOG_WARNING(Service_AM, "(STUBBED) called");
234} 234}
235 235
236void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) { 236void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
237 IPC::ResponseBuilder rb{ctx, 2}; 237 IPC::ResponseBuilder rb{ctx, 2};
238 rb.Push(RESULT_SUCCESS); 238 rb.Push(RESULT_SUCCESS);
239 239
240 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 240 LOG_WARNING(Service_AM, "(STUBBED) called");
241} 241}
242 242
243void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { 243void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
@@ -247,7 +247,7 @@ void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext&
247 rb.Push(RESULT_SUCCESS); 247 rb.Push(RESULT_SUCCESS);
248 rb.PushCopyObjects(launchable_event); 248 rb.PushCopyObjects(launchable_event);
249 249
250 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 250 LOG_WARNING(Service_AM, "(STUBBED) called");
251} 251}
252 252
253void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) { 253void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
@@ -260,14 +260,14 @@ void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx)
260 rb.Push(RESULT_SUCCESS); 260 rb.Push(RESULT_SUCCESS);
261 rb.Push(layer_id); 261 rb.Push(layer_id);
262 262
263 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 263 LOG_WARNING(Service_AM, "(STUBBED) called");
264} 264}
265 265
266void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) { 266void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) {
267 IPC::ResponseBuilder rb{ctx, 2}; 267 IPC::ResponseBuilder rb{ctx, 2};
268 rb.Push(RESULT_SUCCESS); 268 rb.Push(RESULT_SUCCESS);
269 269
270 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 270 LOG_WARNING(Service_AM, "(STUBBED) called");
271} 271}
272 272
273ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") { 273ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
@@ -311,7 +311,7 @@ void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
311 rb.Push(RESULT_SUCCESS); 311 rb.Push(RESULT_SUCCESS);
312 rb.PushCopyObjects(event); 312 rb.PushCopyObjects(event);
313 313
314 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 314 LOG_WARNING(Service_AM, "(STUBBED) called");
315} 315}
316 316
317void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { 317void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
@@ -319,7 +319,7 @@ void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
319 rb.Push(RESULT_SUCCESS); 319 rb.Push(RESULT_SUCCESS);
320 rb.Push<u32>(15); 320 rb.Push<u32>(15);
321 321
322 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 322 LOG_WARNING(Service_AM, "(STUBBED) called");
323} 323}
324 324
325void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { 325void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
@@ -327,7 +327,7 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
327 rb.Push(RESULT_SUCCESS); 327 rb.Push(RESULT_SUCCESS);
328 rb.Push(static_cast<u8>(FocusState::InFocus)); 328 rb.Push(static_cast<u8>(FocusState::InFocus));
329 329
330 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 330 LOG_WARNING(Service_AM, "(STUBBED) called");
331} 331}
332 332
333void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { 333void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
@@ -336,7 +336,7 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
336 rb.Push(RESULT_SUCCESS); 336 rb.Push(RESULT_SUCCESS);
337 rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld)); 337 rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
338 338
339 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 339 LOG_WARNING(Service_AM, "(STUBBED) called");
340} 340}
341 341
342void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { 342void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
@@ -346,7 +346,7 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
346 rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked 346 rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
347 : APM::PerformanceMode::Handheld)); 347 : APM::PerformanceMode::Handheld));
348 348
349 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 349 LOG_WARNING(Service_AM, "(STUBBED) called");
350} 350}
351 351
352class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { 352class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
@@ -370,7 +370,7 @@ private:
370 rb.Push(RESULT_SUCCESS); 370 rb.Push(RESULT_SUCCESS);
371 rb.Push(static_cast<u64>(buffer.size())); 371 rb.Push(static_cast<u64>(buffer.size()));
372 372
373 NGLOG_DEBUG(Service_AM, "called"); 373 LOG_DEBUG(Service_AM, "called");
374 } 374 }
375 375
376 void Write(Kernel::HLERequestContext& ctx) { 376 void Write(Kernel::HLERequestContext& ctx) {
@@ -386,7 +386,7 @@ private:
386 IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)}; 386 IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)};
387 rb.Push(RESULT_SUCCESS); 387 rb.Push(RESULT_SUCCESS);
388 388
389 NGLOG_DEBUG(Service_AM, "called, offset={}", offset); 389 LOG_DEBUG(Service_AM, "called, offset={}", offset);
390 } 390 }
391 391
392 void Read(Kernel::HLERequestContext& ctx) { 392 void Read(Kernel::HLERequestContext& ctx) {
@@ -402,7 +402,7 @@ private:
402 IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)}; 402 IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)};
403 rb.Push(RESULT_SUCCESS); 403 rb.Push(RESULT_SUCCESS);
404 404
405 NGLOG_DEBUG(Service_AM, "called, offset={}", offset); 405 LOG_DEBUG(Service_AM, "called, offset={}", offset);
406 } 406 }
407}; 407};
408 408
@@ -426,7 +426,7 @@ private:
426 rb.Push(RESULT_SUCCESS); 426 rb.Push(RESULT_SUCCESS);
427 rb.PushIpcInterface<AM::IStorageAccessor>(buffer); 427 rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
428 428
429 NGLOG_DEBUG(Service_AM, "called"); 429 LOG_DEBUG(Service_AM, "called");
430 } 430 }
431}; 431};
432 432
@@ -467,21 +467,21 @@ private:
467 rb.Push(RESULT_SUCCESS); 467 rb.Push(RESULT_SUCCESS);
468 rb.PushCopyObjects(state_changed_event); 468 rb.PushCopyObjects(state_changed_event);
469 469
470 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 470 LOG_WARNING(Service_AM, "(STUBBED) called");
471 } 471 }
472 472
473 void GetResult(Kernel::HLERequestContext& ctx) { 473 void GetResult(Kernel::HLERequestContext& ctx) {
474 IPC::ResponseBuilder rb{ctx, 2}; 474 IPC::ResponseBuilder rb{ctx, 2};
475 rb.Push(RESULT_SUCCESS); 475 rb.Push(RESULT_SUCCESS);
476 476
477 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 477 LOG_WARNING(Service_AM, "(STUBBED) called");
478 } 478 }
479 479
480 void Start(Kernel::HLERequestContext& ctx) { 480 void Start(Kernel::HLERequestContext& ctx) {
481 IPC::ResponseBuilder rb{ctx, 2}; 481 IPC::ResponseBuilder rb{ctx, 2};
482 rb.Push(RESULT_SUCCESS); 482 rb.Push(RESULT_SUCCESS);
483 483
484 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 484 LOG_WARNING(Service_AM, "(STUBBED) called");
485 } 485 }
486 486
487 void PushInData(Kernel::HLERequestContext& ctx) { 487 void PushInData(Kernel::HLERequestContext& ctx) {
@@ -491,7 +491,7 @@ private:
491 IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)}; 491 IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)};
492 rb.Push(RESULT_SUCCESS); 492 rb.Push(RESULT_SUCCESS);
493 493
494 NGLOG_DEBUG(Service_AM, "called"); 494 LOG_DEBUG(Service_AM, "called");
495 } 495 }
496 496
497 void PopOutData(Kernel::HLERequestContext& ctx) { 497 void PopOutData(Kernel::HLERequestContext& ctx) {
@@ -501,7 +501,7 @@ private:
501 501
502 storage_stack.pop(); 502 storage_stack.pop();
503 503
504 NGLOG_DEBUG(Service_AM, "called"); 504 LOG_DEBUG(Service_AM, "called");
505 } 505 }
506 506
507 std::stack<std::shared_ptr<AM::IStorage>> storage_stack; 507 std::stack<std::shared_ptr<AM::IStorage>> storage_stack;
@@ -526,7 +526,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
526 rb.Push(RESULT_SUCCESS); 526 rb.Push(RESULT_SUCCESS);
527 rb.PushIpcInterface<AM::ILibraryAppletAccessor>(); 527 rb.PushIpcInterface<AM::ILibraryAppletAccessor>();
528 528
529 NGLOG_DEBUG(Service_AM, "called"); 529 LOG_DEBUG(Service_AM, "called");
530} 530}
531 531
532void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { 532void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
@@ -538,7 +538,7 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
538 rb.Push(RESULT_SUCCESS); 538 rb.Push(RESULT_SUCCESS);
539 rb.PushIpcInterface<AM::IStorage>(std::move(buffer)); 539 rb.PushIpcInterface<AM::IStorage>(std::move(buffer));
540 540
541 NGLOG_DEBUG(Service_AM, "called, size={}", size); 541 LOG_DEBUG(Service_AM, "called, size={}", size);
542} 542}
543 543
544IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") { 544IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
@@ -602,21 +602,21 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
602 rb.Push(RESULT_SUCCESS); 602 rb.Push(RESULT_SUCCESS);
603 rb.PushIpcInterface<AM::IStorage>(buffer); 603 rb.PushIpcInterface<AM::IStorage>(buffer);
604 604
605 NGLOG_DEBUG(Service_AM, "called"); 605 LOG_DEBUG(Service_AM, "called");
606} 606}
607 607
608void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest( 608void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(
609 Kernel::HLERequestContext& ctx) { 609 Kernel::HLERequestContext& ctx) {
610 IPC::ResponseBuilder rb{ctx, 2}; 610 IPC::ResponseBuilder rb{ctx, 2};
611 rb.Push(RESULT_SUCCESS); 611 rb.Push(RESULT_SUCCESS);
612 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 612 LOG_WARNING(Service_AM, "(STUBBED) called");
613} 613}
614 614
615void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { 615void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {
616 IPC::RequestParser rp{ctx}; 616 IPC::RequestParser rp{ctx};
617 u128 uid = rp.PopRaw<u128>(); 617 u128 uid = rp.PopRaw<u128>();
618 618
619 NGLOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); 619 LOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]);
620 620
621 IPC::ResponseBuilder rb{ctx, 4}; 621 IPC::ResponseBuilder rb{ctx, 4};
622 622
@@ -644,7 +644,7 @@ void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
644 IPC::ResponseBuilder rb{ctx, 2}; 644 IPC::ResponseBuilder rb{ctx, 2};
645 rb.Push(RESULT_SUCCESS); 645 rb.Push(RESULT_SUCCESS);
646 646
647 NGLOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result); 647 LOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result);
648} 648}
649 649
650void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) { 650void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
@@ -652,7 +652,7 @@ void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
652 rb.Push(RESULT_SUCCESS); 652 rb.Push(RESULT_SUCCESS);
653 rb.Push<u64>(1); 653 rb.Push<u64>(1);
654 rb.Push<u64>(0); 654 rb.Push<u64>(0);
655 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 655 LOG_WARNING(Service_AM, "(STUBBED) called");
656} 656}
657 657
658void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { 658void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
@@ -660,20 +660,20 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
660 IPC::ResponseBuilder rb{ctx, 4}; 660 IPC::ResponseBuilder rb{ctx, 4};
661 rb.Push(RESULT_SUCCESS); 661 rb.Push(RESULT_SUCCESS);
662 rb.Push(static_cast<u64>(Service::Set::LanguageCode::EN_US)); 662 rb.Push(static_cast<u64>(Service::Set::LanguageCode::EN_US));
663 NGLOG_DEBUG(Service_AM, "called"); 663 LOG_DEBUG(Service_AM, "called");
664} 664}
665 665
666void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) { 666void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
667 IPC::ResponseBuilder rb{ctx, 2}; 667 IPC::ResponseBuilder rb{ctx, 2};
668 rb.Push(RESULT_SUCCESS); 668 rb.Push(RESULT_SUCCESS);
669 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 669 LOG_WARNING(Service_AM, "(STUBBED) called");
670} 670}
671 671
672void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) { 672void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
673 IPC::ResponseBuilder rb{ctx, 2}; 673 IPC::ResponseBuilder rb{ctx, 2};
674 rb.Push(RESULT_SUCCESS); 674 rb.Push(RESULT_SUCCESS);
675 675
676 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 676 LOG_WARNING(Service_AM, "(STUBBED) called");
677} 677}
678 678
679void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) { 679void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
@@ -681,7 +681,7 @@ void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
681 rb.Push(RESULT_SUCCESS); 681 rb.Push(RESULT_SUCCESS);
682 rb.Push<u8>(0); // Unknown, seems to be ignored by official processes 682 rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
683 683
684 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 684 LOG_WARNING(Service_AM, "(STUBBED) called");
685} 685}
686 686
687void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) { 687void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
@@ -692,7 +692,7 @@ void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
692 rb.Push<u64>(0); 692 rb.Push<u64>(0);
693 rb.Push<u64>(0); 693 rb.Push<u64>(0);
694 694
695 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 695 LOG_WARNING(Service_AM, "(STUBBED) called");
696} 696}
697 697
698void InstallInterfaces(SM::ServiceManager& service_manager, 698void InstallInterfaces(SM::ServiceManager& service_manager,
@@ -717,7 +717,7 @@ IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions"
717void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) { 717void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) {
718 IPC::ResponseBuilder rb{ctx, 2}; 718 IPC::ResponseBuilder rb{ctx, 2};
719 rb.Push(RESULT_SUCCESS); 719 rb.Push(RESULT_SUCCESS);
720 NGLOG_WARNING(Service_AM, "(STUBBED) called"); 720 LOG_WARNING(Service_AM, "(STUBBED) called");
721} 721}
722 722
723IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") { 723IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") {
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp
index 7ce551de3..180057ec2 100644
--- a/src/core/hle/service/am/applet_ae.cpp
+++ b/src/core/hle/service/am/applet_ae.cpp
@@ -33,63 +33,63 @@ private:
33 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 33 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
34 rb.Push(RESULT_SUCCESS); 34 rb.Push(RESULT_SUCCESS);
35 rb.PushIpcInterface<ICommonStateGetter>(); 35 rb.PushIpcInterface<ICommonStateGetter>();
36 NGLOG_DEBUG(Service_AM, "called"); 36 LOG_DEBUG(Service_AM, "called");
37 } 37 }
38 38
39 void GetSelfController(Kernel::HLERequestContext& ctx) { 39 void GetSelfController(Kernel::HLERequestContext& ctx) {
40 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 40 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
41 rb.Push(RESULT_SUCCESS); 41 rb.Push(RESULT_SUCCESS);
42 rb.PushIpcInterface<ISelfController>(nvflinger); 42 rb.PushIpcInterface<ISelfController>(nvflinger);
43 NGLOG_DEBUG(Service_AM, "called"); 43 LOG_DEBUG(Service_AM, "called");
44 } 44 }
45 45
46 void GetWindowController(Kernel::HLERequestContext& ctx) { 46 void GetWindowController(Kernel::HLERequestContext& ctx) {
47 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 47 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
48 rb.Push(RESULT_SUCCESS); 48 rb.Push(RESULT_SUCCESS);
49 rb.PushIpcInterface<IWindowController>(); 49 rb.PushIpcInterface<IWindowController>();
50 NGLOG_DEBUG(Service_AM, "called"); 50 LOG_DEBUG(Service_AM, "called");
51 } 51 }
52 52
53 void GetAudioController(Kernel::HLERequestContext& ctx) { 53 void GetAudioController(Kernel::HLERequestContext& ctx) {
54 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 54 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
55 rb.Push(RESULT_SUCCESS); 55 rb.Push(RESULT_SUCCESS);
56 rb.PushIpcInterface<IAudioController>(); 56 rb.PushIpcInterface<IAudioController>();
57 NGLOG_DEBUG(Service_AM, "called"); 57 LOG_DEBUG(Service_AM, "called");
58 } 58 }
59 59
60 void GetDisplayController(Kernel::HLERequestContext& ctx) { 60 void GetDisplayController(Kernel::HLERequestContext& ctx) {
61 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 61 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
62 rb.Push(RESULT_SUCCESS); 62 rb.Push(RESULT_SUCCESS);
63 rb.PushIpcInterface<IDisplayController>(); 63 rb.PushIpcInterface<IDisplayController>();
64 NGLOG_DEBUG(Service_AM, "called"); 64 LOG_DEBUG(Service_AM, "called");
65 } 65 }
66 66
67 void GetProcessWindingController(Kernel::HLERequestContext& ctx) { 67 void GetProcessWindingController(Kernel::HLERequestContext& ctx) {
68 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 68 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
69 rb.Push(RESULT_SUCCESS); 69 rb.Push(RESULT_SUCCESS);
70 rb.PushIpcInterface<IProcessWindingController>(); 70 rb.PushIpcInterface<IProcessWindingController>();
71 NGLOG_DEBUG(Service_AM, "called"); 71 LOG_DEBUG(Service_AM, "called");
72 } 72 }
73 73
74 void GetDebugFunctions(Kernel::HLERequestContext& ctx) { 74 void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
75 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 75 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
76 rb.Push(RESULT_SUCCESS); 76 rb.Push(RESULT_SUCCESS);
77 rb.PushIpcInterface<IDebugFunctions>(); 77 rb.PushIpcInterface<IDebugFunctions>();
78 NGLOG_DEBUG(Service_AM, "called"); 78 LOG_DEBUG(Service_AM, "called");
79 } 79 }
80 80
81 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { 81 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
82 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 82 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
83 rb.Push(RESULT_SUCCESS); 83 rb.Push(RESULT_SUCCESS);
84 rb.PushIpcInterface<ILibraryAppletCreator>(); 84 rb.PushIpcInterface<ILibraryAppletCreator>();
85 NGLOG_DEBUG(Service_AM, "called"); 85 LOG_DEBUG(Service_AM, "called");
86 } 86 }
87 87
88 void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { 88 void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
89 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 89 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
90 rb.Push(RESULT_SUCCESS); 90 rb.Push(RESULT_SUCCESS);
91 rb.PushIpcInterface<IApplicationFunctions>(); 91 rb.PushIpcInterface<IApplicationFunctions>();
92 NGLOG_DEBUG(Service_AM, "called"); 92 LOG_DEBUG(Service_AM, "called");
93 } 93 }
94 94
95 std::shared_ptr<NVFlinger::NVFlinger> nvflinger; 95 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
@@ -120,70 +120,70 @@ private:
120 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 120 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
121 rb.Push(RESULT_SUCCESS); 121 rb.Push(RESULT_SUCCESS);
122 rb.PushIpcInterface<ICommonStateGetter>(); 122 rb.PushIpcInterface<ICommonStateGetter>();
123 NGLOG_DEBUG(Service_AM, "called"); 123 LOG_DEBUG(Service_AM, "called");
124 } 124 }
125 125
126 void GetSelfController(Kernel::HLERequestContext& ctx) { 126 void GetSelfController(Kernel::HLERequestContext& ctx) {
127 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 127 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
128 rb.Push(RESULT_SUCCESS); 128 rb.Push(RESULT_SUCCESS);
129 rb.PushIpcInterface<ISelfController>(nvflinger); 129 rb.PushIpcInterface<ISelfController>(nvflinger);
130 NGLOG_DEBUG(Service_AM, "called"); 130 LOG_DEBUG(Service_AM, "called");
131 } 131 }
132 132
133 void GetWindowController(Kernel::HLERequestContext& ctx) { 133 void GetWindowController(Kernel::HLERequestContext& ctx) {
134 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 134 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
135 rb.Push(RESULT_SUCCESS); 135 rb.Push(RESULT_SUCCESS);
136 rb.PushIpcInterface<IWindowController>(); 136 rb.PushIpcInterface<IWindowController>();
137 NGLOG_DEBUG(Service_AM, "called"); 137 LOG_DEBUG(Service_AM, "called");
138 } 138 }
139 139
140 void GetAudioController(Kernel::HLERequestContext& ctx) { 140 void GetAudioController(Kernel::HLERequestContext& ctx) {
141 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 141 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
142 rb.Push(RESULT_SUCCESS); 142 rb.Push(RESULT_SUCCESS);
143 rb.PushIpcInterface<IAudioController>(); 143 rb.PushIpcInterface<IAudioController>();
144 NGLOG_DEBUG(Service_AM, "called"); 144 LOG_DEBUG(Service_AM, "called");
145 } 145 }
146 146
147 void GetDisplayController(Kernel::HLERequestContext& ctx) { 147 void GetDisplayController(Kernel::HLERequestContext& ctx) {
148 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 148 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
149 rb.Push(RESULT_SUCCESS); 149 rb.Push(RESULT_SUCCESS);
150 rb.PushIpcInterface<IDisplayController>(); 150 rb.PushIpcInterface<IDisplayController>();
151 NGLOG_DEBUG(Service_AM, "called"); 151 LOG_DEBUG(Service_AM, "called");
152 } 152 }
153 153
154 void GetDebugFunctions(Kernel::HLERequestContext& ctx) { 154 void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
155 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 155 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
156 rb.Push(RESULT_SUCCESS); 156 rb.Push(RESULT_SUCCESS);
157 rb.PushIpcInterface<IDebugFunctions>(); 157 rb.PushIpcInterface<IDebugFunctions>();
158 NGLOG_DEBUG(Service_AM, "called"); 158 LOG_DEBUG(Service_AM, "called");
159 } 159 }
160 160
161 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { 161 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
162 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 162 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
163 rb.Push(RESULT_SUCCESS); 163 rb.Push(RESULT_SUCCESS);
164 rb.PushIpcInterface<ILibraryAppletCreator>(); 164 rb.PushIpcInterface<ILibraryAppletCreator>();
165 NGLOG_DEBUG(Service_AM, "called"); 165 LOG_DEBUG(Service_AM, "called");
166 } 166 }
167 167
168 void GetHomeMenuFunctions(Kernel::HLERequestContext& ctx) { 168 void GetHomeMenuFunctions(Kernel::HLERequestContext& ctx) {
169 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 169 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
170 rb.Push(RESULT_SUCCESS); 170 rb.Push(RESULT_SUCCESS);
171 rb.PushIpcInterface<IHomeMenuFunctions>(); 171 rb.PushIpcInterface<IHomeMenuFunctions>();
172 NGLOG_DEBUG(Service_AM, "called"); 172 LOG_DEBUG(Service_AM, "called");
173 } 173 }
174 174
175 void GetGlobalStateController(Kernel::HLERequestContext& ctx) { 175 void GetGlobalStateController(Kernel::HLERequestContext& ctx) {
176 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 176 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
177 rb.Push(RESULT_SUCCESS); 177 rb.Push(RESULT_SUCCESS);
178 rb.PushIpcInterface<IGlobalStateController>(); 178 rb.PushIpcInterface<IGlobalStateController>();
179 NGLOG_DEBUG(Service_AM, "called"); 179 LOG_DEBUG(Service_AM, "called");
180 } 180 }
181 181
182 void GetApplicationCreator(Kernel::HLERequestContext& ctx) { 182 void GetApplicationCreator(Kernel::HLERequestContext& ctx) {
183 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 183 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
184 rb.Push(RESULT_SUCCESS); 184 rb.Push(RESULT_SUCCESS);
185 rb.PushIpcInterface<IApplicationCreator>(); 185 rb.PushIpcInterface<IApplicationCreator>();
186 NGLOG_DEBUG(Service_AM, "called"); 186 LOG_DEBUG(Service_AM, "called");
187 } 187 }
188 std::shared_ptr<NVFlinger::NVFlinger> nvflinger; 188 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
189}; 189};
@@ -192,21 +192,21 @@ void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) {
192 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 192 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
193 rb.Push(RESULT_SUCCESS); 193 rb.Push(RESULT_SUCCESS);
194 rb.PushIpcInterface<ISystemAppletProxy>(nvflinger); 194 rb.PushIpcInterface<ISystemAppletProxy>(nvflinger);
195 NGLOG_DEBUG(Service_AM, "called"); 195 LOG_DEBUG(Service_AM, "called");
196} 196}
197 197
198void AppletAE::OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx) { 198void AppletAE::OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx) {
199 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 199 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
200 rb.Push(RESULT_SUCCESS); 200 rb.Push(RESULT_SUCCESS);
201 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger); 201 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger);
202 NGLOG_DEBUG(Service_AM, "called"); 202 LOG_DEBUG(Service_AM, "called");
203} 203}
204 204
205void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) { 205void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
206 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 206 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
207 rb.Push(RESULT_SUCCESS); 207 rb.Push(RESULT_SUCCESS);
208 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger); 208 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger);
209 NGLOG_DEBUG(Service_AM, "called"); 209 LOG_DEBUG(Service_AM, "called");
210} 210}
211 211
212AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) 212AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp
index 587a922fe..278259eda 100644
--- a/src/core/hle/service/am/applet_oe.cpp
+++ b/src/core/hle/service/am/applet_oe.cpp
@@ -33,56 +33,56 @@ private:
33 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 33 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
34 rb.Push(RESULT_SUCCESS); 34 rb.Push(RESULT_SUCCESS);
35 rb.PushIpcInterface<IAudioController>(); 35 rb.PushIpcInterface<IAudioController>();
36 NGLOG_DEBUG(Service_AM, "called"); 36 LOG_DEBUG(Service_AM, "called");
37 } 37 }
38 38
39 void GetDisplayController(Kernel::HLERequestContext& ctx) { 39 void GetDisplayController(Kernel::HLERequestContext& ctx) {
40 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 40 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
41 rb.Push(RESULT_SUCCESS); 41 rb.Push(RESULT_SUCCESS);
42 rb.PushIpcInterface<IDisplayController>(); 42 rb.PushIpcInterface<IDisplayController>();
43 NGLOG_DEBUG(Service_AM, "called"); 43 LOG_DEBUG(Service_AM, "called");
44 } 44 }
45 45
46 void GetDebugFunctions(Kernel::HLERequestContext& ctx) { 46 void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
47 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 47 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
48 rb.Push(RESULT_SUCCESS); 48 rb.Push(RESULT_SUCCESS);
49 rb.PushIpcInterface<IDebugFunctions>(); 49 rb.PushIpcInterface<IDebugFunctions>();
50 NGLOG_DEBUG(Service_AM, "called"); 50 LOG_DEBUG(Service_AM, "called");
51 } 51 }
52 52
53 void GetWindowController(Kernel::HLERequestContext& ctx) { 53 void GetWindowController(Kernel::HLERequestContext& ctx) {
54 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 54 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
55 rb.Push(RESULT_SUCCESS); 55 rb.Push(RESULT_SUCCESS);
56 rb.PushIpcInterface<IWindowController>(); 56 rb.PushIpcInterface<IWindowController>();
57 NGLOG_DEBUG(Service_AM, "called"); 57 LOG_DEBUG(Service_AM, "called");
58 } 58 }
59 59
60 void GetSelfController(Kernel::HLERequestContext& ctx) { 60 void GetSelfController(Kernel::HLERequestContext& ctx) {
61 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 61 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
62 rb.Push(RESULT_SUCCESS); 62 rb.Push(RESULT_SUCCESS);
63 rb.PushIpcInterface<ISelfController>(nvflinger); 63 rb.PushIpcInterface<ISelfController>(nvflinger);
64 NGLOG_DEBUG(Service_AM, "called"); 64 LOG_DEBUG(Service_AM, "called");
65 } 65 }
66 66
67 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { 67 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
68 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 68 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
69 rb.Push(RESULT_SUCCESS); 69 rb.Push(RESULT_SUCCESS);
70 rb.PushIpcInterface<ICommonStateGetter>(); 70 rb.PushIpcInterface<ICommonStateGetter>();
71 NGLOG_DEBUG(Service_AM, "called"); 71 LOG_DEBUG(Service_AM, "called");
72 } 72 }
73 73
74 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { 74 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
75 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 75 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
76 rb.Push(RESULT_SUCCESS); 76 rb.Push(RESULT_SUCCESS);
77 rb.PushIpcInterface<ILibraryAppletCreator>(); 77 rb.PushIpcInterface<ILibraryAppletCreator>();
78 NGLOG_DEBUG(Service_AM, "called"); 78 LOG_DEBUG(Service_AM, "called");
79 } 79 }
80 80
81 void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { 81 void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
82 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 82 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
83 rb.Push(RESULT_SUCCESS); 83 rb.Push(RESULT_SUCCESS);
84 rb.PushIpcInterface<IApplicationFunctions>(); 84 rb.PushIpcInterface<IApplicationFunctions>();
85 NGLOG_DEBUG(Service_AM, "called"); 85 LOG_DEBUG(Service_AM, "called");
86 } 86 }
87 87
88 std::shared_ptr<NVFlinger::NVFlinger> nvflinger; 88 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
@@ -92,7 +92,7 @@ void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
92 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 92 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
93 rb.Push(RESULT_SUCCESS); 93 rb.Push(RESULT_SUCCESS);
94 rb.PushIpcInterface<IApplicationProxy>(nvflinger); 94 rb.PushIpcInterface<IApplicationProxy>(nvflinger);
95 NGLOG_DEBUG(Service_AM, "called"); 95 LOG_DEBUG(Service_AM, "called");
96} 96}
97 97
98AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) 98AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index 5b6dfb48f..6e7438580 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -27,14 +27,14 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) {
27 IPC::ResponseBuilder rb{ctx, 4}; 27 IPC::ResponseBuilder rb{ctx, 4};
28 rb.Push(RESULT_SUCCESS); 28 rb.Push(RESULT_SUCCESS);
29 rb.Push<u64>(0); 29 rb.Push<u64>(0);
30 NGLOG_WARNING(Service_AOC, "(STUBBED) called"); 30 LOG_WARNING(Service_AOC, "(STUBBED) called");
31} 31}
32 32
33void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) { 33void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) {
34 IPC::ResponseBuilder rb{ctx, 4}; 34 IPC::ResponseBuilder rb{ctx, 4};
35 rb.Push(RESULT_SUCCESS); 35 rb.Push(RESULT_SUCCESS);
36 rb.Push<u64>(0); 36 rb.Push<u64>(0);
37 NGLOG_WARNING(Service_AOC, "(STUBBED) called"); 37 LOG_WARNING(Service_AOC, "(STUBBED) called");
38} 38}
39 39
40void InstallInterfaces(SM::ServiceManager& service_manager) { 40void InstallInterfaces(SM::ServiceManager& service_manager) {
diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp
index 3a03188ce..751d73f8d 100644
--- a/src/core/hle/service/apm/interface.cpp
+++ b/src/core/hle/service/apm/interface.cpp
@@ -29,8 +29,8 @@ private:
29 IPC::ResponseBuilder rb{ctx, 2}; 29 IPC::ResponseBuilder rb{ctx, 2};
30 rb.Push(RESULT_SUCCESS); 30 rb.Push(RESULT_SUCCESS);
31 31
32 NGLOG_WARNING(Service_APM, "(STUBBED) called mode={} config={}", static_cast<u32>(mode), 32 LOG_WARNING(Service_APM, "(STUBBED) called mode={} config={}", static_cast<u32>(mode),
33 config); 33 config);
34 } 34 }
35 35
36 void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { 36 void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
@@ -42,7 +42,7 @@ private:
42 rb.Push(RESULT_SUCCESS); 42 rb.Push(RESULT_SUCCESS);
43 rb.Push<u32>(0); // Performance configuration 43 rb.Push<u32>(0); // Performance configuration
44 44
45 NGLOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode)); 45 LOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode));
46 } 46 }
47}; 47};
48 48
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp
index 92f910b5f..d231e91e1 100644
--- a/src/core/hle/service/audio/audio.cpp
+++ b/src/core/hle/service/audio/audio.cpp
@@ -8,6 +8,7 @@
8#include "core/hle/service/audio/audrec_u.h" 8#include "core/hle/service/audio/audrec_u.h"
9#include "core/hle/service/audio/audren_u.h" 9#include "core/hle/service/audio/audren_u.h"
10#include "core/hle/service/audio/codecctl.h" 10#include "core/hle/service/audio/codecctl.h"
11#include "core/hle/service/audio/hwopus.h"
11 12
12namespace Service::Audio { 13namespace Service::Audio {
13 14
@@ -17,6 +18,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager) {
17 std::make_shared<AudRecU>()->InstallAsService(service_manager); 18 std::make_shared<AudRecU>()->InstallAsService(service_manager);
18 std::make_shared<AudRenU>()->InstallAsService(service_manager); 19 std::make_shared<AudRenU>()->InstallAsService(service_manager);
19 std::make_shared<CodecCtl>()->InstallAsService(service_manager); 20 std::make_shared<CodecCtl>()->InstallAsService(service_manager);
21 std::make_shared<HwOpus>()->InstallAsService(service_manager);
20} 22}
21 23
22} // namespace Service::Audio 24} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 402eaa306..1b4b649d8 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -60,14 +60,14 @@ public:
60 60
61private: 61private:
62 void GetAudioOutState(Kernel::HLERequestContext& ctx) { 62 void GetAudioOutState(Kernel::HLERequestContext& ctx) {
63 NGLOG_DEBUG(Service_Audio, "called"); 63 LOG_DEBUG(Service_Audio, "called");
64 IPC::ResponseBuilder rb{ctx, 3}; 64 IPC::ResponseBuilder rb{ctx, 3};
65 rb.Push(RESULT_SUCCESS); 65 rb.Push(RESULT_SUCCESS);
66 rb.Push(static_cast<u32>(audio_out_state)); 66 rb.Push(static_cast<u32>(audio_out_state));
67 } 67 }
68 68
69 void StartAudioOut(Kernel::HLERequestContext& ctx) { 69 void StartAudioOut(Kernel::HLERequestContext& ctx) {
70 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 70 LOG_WARNING(Service_Audio, "(STUBBED) called");
71 71
72 // Start audio 72 // Start audio
73 audio_out_state = AudioState::Started; 73 audio_out_state = AudioState::Started;
@@ -77,7 +77,7 @@ private:
77 } 77 }
78 78
79 void StopAudioOut(Kernel::HLERequestContext& ctx) { 79 void StopAudioOut(Kernel::HLERequestContext& ctx) {
80 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 80 LOG_WARNING(Service_Audio, "(STUBBED) called");
81 81
82 // Stop audio 82 // Stop audio
83 audio_out_state = AudioState::Stopped; 83 audio_out_state = AudioState::Stopped;
@@ -89,7 +89,7 @@ private:
89 } 89 }
90 90
91 void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { 91 void RegisterBufferEvent(Kernel::HLERequestContext& ctx) {
92 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 92 LOG_WARNING(Service_Audio, "(STUBBED) called");
93 93
94 IPC::ResponseBuilder rb{ctx, 2, 1}; 94 IPC::ResponseBuilder rb{ctx, 2, 1};
95 rb.Push(RESULT_SUCCESS); 95 rb.Push(RESULT_SUCCESS);
@@ -97,7 +97,7 @@ private:
97 } 97 }
98 98
99 void AppendAudioOutBuffer(Kernel::HLERequestContext& ctx) { 99 void AppendAudioOutBuffer(Kernel::HLERequestContext& ctx) {
100 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 100 LOG_WARNING(Service_Audio, "(STUBBED) called");
101 IPC::RequestParser rp{ctx}; 101 IPC::RequestParser rp{ctx};
102 102
103 const u64 key{rp.Pop<u64>()}; 103 const u64 key{rp.Pop<u64>()};
@@ -108,7 +108,7 @@ private:
108 } 108 }
109 109
110 void GetReleasedAudioOutBuffer(Kernel::HLERequestContext& ctx) { 110 void GetReleasedAudioOutBuffer(Kernel::HLERequestContext& ctx) {
111 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 111 LOG_WARNING(Service_Audio, "(STUBBED) called");
112 112
113 // TODO(st4rk): This is how libtransistor currently implements the 113 // TODO(st4rk): This is how libtransistor currently implements the
114 // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address 114 // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address
@@ -164,7 +164,7 @@ private:
164}; 164};
165 165
166void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { 166void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) {
167 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 167 LOG_WARNING(Service_Audio, "(STUBBED) called");
168 IPC::RequestParser rp{ctx}; 168 IPC::RequestParser rp{ctx};
169 169
170 const std::string audio_interface = "AudioInterface"; 170 const std::string audio_interface = "AudioInterface";
@@ -180,7 +180,7 @@ void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) {
180} 180}
181 181
182void AudOutU::OpenAudioOut(Kernel::HLERequestContext& ctx) { 182void AudOutU::OpenAudioOut(Kernel::HLERequestContext& ctx) {
183 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 183 LOG_WARNING(Service_Audio, "(STUBBED) called");
184 184
185 if (!audio_out_interface) { 185 if (!audio_out_interface) {
186 audio_out_interface = std::make_shared<IAudioOut>(); 186 audio_out_interface = std::make_shared<IAudioOut>();
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 2188b5625..2da936b27 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -47,6 +47,7 @@ public:
47 47
48 // Start the audio event 48 // Start the audio event
49 CoreTiming::ScheduleEvent(audio_ticks, audio_event); 49 CoreTiming::ScheduleEvent(audio_ticks, audio_event);
50 voice_status_list.reserve(worker_params.voice_count);
50 } 51 }
51 ~IAudioRenderer() { 52 ~IAudioRenderer() {
52 CoreTiming::UnscheduleEvent(audio_event, 0); 53 CoreTiming::UnscheduleEvent(audio_event, 0);
@@ -68,6 +69,12 @@ private:
68 buf.data() + sizeof(UpdateDataHeader) + config.behavior_size, 69 buf.data() + sizeof(UpdateDataHeader) + config.behavior_size,
69 memory_pool_count * sizeof(MemoryPoolInfo)); 70 memory_pool_count * sizeof(MemoryPoolInfo));
70 71
72 std::vector<VoiceInfo> voice_info(worker_params.voice_count);
73 std::memcpy(voice_info.data(),
74 buf.data() + sizeof(UpdateDataHeader) + config.behavior_size +
75 config.memory_pools_size + config.voice_resource_size,
76 worker_params.voice_count * sizeof(VoiceInfo));
77
71 UpdateDataHeader response_data{worker_params}; 78 UpdateDataHeader response_data{worker_params};
72 79
73 ASSERT(ctx.GetWriteBufferSize() == response_data.total_size); 80 ASSERT(ctx.GetWriteBufferSize() == response_data.total_size);
@@ -86,12 +93,29 @@ private:
86 std::memcpy(output.data() + sizeof(UpdateDataHeader), memory_pool.data(), 93 std::memcpy(output.data() + sizeof(UpdateDataHeader), memory_pool.data(),
87 response_data.memory_pools_size); 94 response_data.memory_pools_size);
88 95
96 for (unsigned i = 0; i < voice_info.size(); i++) {
97 if (voice_info[i].is_new) {
98 voice_status_list[i].played_sample_count = 0;
99 voice_status_list[i].wave_buffer_consumed = 0;
100 } else if (voice_info[i].play_state == (u8)PlayStates::Started) {
101 for (u32 buff_idx = 0; buff_idx < voice_info[i].wave_buffer_count; buff_idx++) {
102 voice_status_list[i].played_sample_count +=
103 (voice_info[i].wave_buffer[buff_idx].end_sample_offset -
104 voice_info[i].wave_buffer[buff_idx].start_sample_offset) /
105 2;
106 voice_status_list[i].wave_buffer_consumed++;
107 }
108 }
109 }
110 std::memcpy(output.data() + sizeof(UpdateDataHeader) + response_data.memory_pools_size,
111 voice_status_list.data(), response_data.voices_size);
112
89 ctx.WriteBuffer(output); 113 ctx.WriteBuffer(output);
90 114
91 IPC::ResponseBuilder rb{ctx, 2}; 115 IPC::ResponseBuilder rb{ctx, 2};
92 rb.Push(RESULT_SUCCESS); 116 rb.Push(RESULT_SUCCESS);
93 117
94 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 118 LOG_WARNING(Service_Audio, "(STUBBED) called");
95 } 119 }
96 120
97 void StartAudioRenderer(Kernel::HLERequestContext& ctx) { 121 void StartAudioRenderer(Kernel::HLERequestContext& ctx) {
@@ -99,7 +123,7 @@ private:
99 123
100 rb.Push(RESULT_SUCCESS); 124 rb.Push(RESULT_SUCCESS);
101 125
102 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 126 LOG_WARNING(Service_Audio, "(STUBBED) called");
103 } 127 }
104 128
105 void StopAudioRenderer(Kernel::HLERequestContext& ctx) { 129 void StopAudioRenderer(Kernel::HLERequestContext& ctx) {
@@ -107,7 +131,7 @@ private:
107 131
108 rb.Push(RESULT_SUCCESS); 132 rb.Push(RESULT_SUCCESS);
109 133
110 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 134 LOG_WARNING(Service_Audio, "(STUBBED) called");
111 } 135 }
112 136
113 void QuerySystemEvent(Kernel::HLERequestContext& ctx) { 137 void QuerySystemEvent(Kernel::HLERequestContext& ctx) {
@@ -117,7 +141,7 @@ private:
117 rb.Push(RESULT_SUCCESS); 141 rb.Push(RESULT_SUCCESS);
118 rb.PushCopyObjects(system_event); 142 rb.PushCopyObjects(system_event);
119 143
120 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 144 LOG_WARNING(Service_Audio, "(STUBBED) called");
121 } 145 }
122 146
123 enum class MemoryPoolStates : u32 { // Should be LE 147 enum class MemoryPoolStates : u32 { // Should be LE
@@ -130,6 +154,11 @@ private:
130 Released = 0x6, 154 Released = 0x6,
131 }; 155 };
132 156
157 enum class PlayStates : u8 {
158 Started = 0,
159 Stopped = 1,
160 };
161
133 struct MemoryPoolEntry { 162 struct MemoryPoolEntry {
134 MemoryPoolStates state; 163 MemoryPoolStates state;
135 u32_le unknown_4; 164 u32_le unknown_4;
@@ -150,7 +179,7 @@ private:
150 UpdateDataHeader() {} 179 UpdateDataHeader() {}
151 180
152 UpdateDataHeader(const AudioRendererParameter& config) { 181 UpdateDataHeader(const AudioRendererParameter& config) {
153 revision = config.revision; 182 revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision
154 behavior_size = 0xb0; 183 behavior_size = 0xb0;
155 memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10; 184 memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10;
156 voices_size = config.voice_count * 0x10; 185 voices_size = config.voice_count * 0x10;
@@ -175,11 +204,69 @@ private:
175 }; 204 };
176 static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); 205 static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");
177 206
207 struct BiquadFilter {
208 u8 enable;
209 INSERT_PADDING_BYTES(1);
210 s16_le numerator[3];
211 s16_le denominator[2];
212 };
213 static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size");
214
215 struct WaveBuffer {
216 u64_le buffer_addr;
217 u64_le buffer_sz;
218 s32_le start_sample_offset;
219 s32_le end_sample_offset;
220 u8 loop;
221 u8 end_of_stream;
222 u8 sent_to_server;
223 INSERT_PADDING_BYTES(5);
224 u64 context_addr;
225 u64 context_sz;
226 INSERT_PADDING_BYTES(8);
227 };
228 static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
229
230 struct VoiceInfo {
231 u32_le id;
232 u32_le node_id;
233 u8 is_new;
234 u8 is_in_use;
235 u8 play_state;
236 u8 sample_format;
237 u32_le sample_rate;
238 u32_le priority;
239 u32_le sorting_order;
240 u32_le channel_count;
241 float_le pitch;
242 float_le volume;
243 BiquadFilter biquad_filter[2];
244 u32_le wave_buffer_count;
245 u16_le wave_buffer_head;
246 INSERT_PADDING_BYTES(6);
247 u64_le additional_params_addr;
248 u64_le additional_params_sz;
249 u32_le mix_id;
250 u32_le splitter_info_id;
251 WaveBuffer wave_buffer[4];
252 u32_le voice_channel_resource_ids[6];
253 INSERT_PADDING_BYTES(24);
254 };
255 static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size");
256
257 struct VoiceOutStatus {
258 u64_le played_sample_count;
259 u32_le wave_buffer_consumed;
260 INSERT_PADDING_WORDS(1);
261 };
262 static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
263
178 /// This is used to trigger the audio event callback. 264 /// This is used to trigger the audio event callback.
179 CoreTiming::EventType* audio_event; 265 CoreTiming::EventType* audio_event;
180 266
181 Kernel::SharedPtr<Kernel::Event> system_event; 267 Kernel::SharedPtr<Kernel::Event> system_event;
182 AudioRendererParameter worker_params; 268 AudioRendererParameter worker_params;
269 std::vector<VoiceOutStatus> voice_status_list;
183}; 270};
184 271
185class IAudioDevice final : public ServiceFramework<IAudioDevice> { 272class IAudioDevice final : public ServiceFramework<IAudioDevice> {
@@ -208,7 +295,7 @@ public:
208 295
209private: 296private:
210 void ListAudioDeviceName(Kernel::HLERequestContext& ctx) { 297 void ListAudioDeviceName(Kernel::HLERequestContext& ctx) {
211 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 298 LOG_WARNING(Service_Audio, "(STUBBED) called");
212 IPC::RequestParser rp{ctx}; 299 IPC::RequestParser rp{ctx};
213 300
214 const std::string audio_interface = "AudioInterface"; 301 const std::string audio_interface = "AudioInterface";
@@ -220,7 +307,7 @@ private:
220 } 307 }
221 308
222 void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { 309 void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) {
223 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 310 LOG_WARNING(Service_Audio, "(STUBBED) called");
224 311
225 IPC::RequestParser rp{ctx}; 312 IPC::RequestParser rp{ctx};
226 f32 volume = static_cast<f32>(rp.Pop<u32>()); 313 f32 volume = static_cast<f32>(rp.Pop<u32>());
@@ -233,7 +320,7 @@ private:
233 } 320 }
234 321
235 void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) { 322 void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) {
236 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 323 LOG_WARNING(Service_Audio, "(STUBBED) called");
237 IPC::RequestParser rp{ctx}; 324 IPC::RequestParser rp{ctx};
238 325
239 const std::string audio_interface = "AudioDevice"; 326 const std::string audio_interface = "AudioDevice";
@@ -245,7 +332,7 @@ private:
245 } 332 }
246 333
247 void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { 334 void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
248 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 335 LOG_WARNING(Service_Audio, "(STUBBED) called");
249 336
250 buffer_event->Signal(); 337 buffer_event->Signal();
251 338
@@ -255,7 +342,7 @@ private:
255 } 342 }
256 343
257 void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { 344 void GetActiveChannelCount(Kernel::HLERequestContext& ctx) {
258 NGLOG_WARNING(Service_Audio, "(STUBBED) called"); 345 LOG_WARNING(Service_Audio, "(STUBBED) called");
259 IPC::ResponseBuilder rb{ctx, 3}; 346 IPC::ResponseBuilder rb{ctx, 3};
260 rb.Push(RESULT_SUCCESS); 347 rb.Push(RESULT_SUCCESS);
261 rb.Push<u32>(1); 348 rb.Push<u32>(1);
@@ -284,7 +371,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
284 rb.Push(RESULT_SUCCESS); 371 rb.Push(RESULT_SUCCESS);
285 rb.PushIpcInterface<Audio::IAudioRenderer>(std::move(params)); 372 rb.PushIpcInterface<Audio::IAudioRenderer>(std::move(params));
286 373
287 NGLOG_DEBUG(Service_Audio, "called"); 374 LOG_DEBUG(Service_Audio, "called");
288} 375}
289 376
290void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { 377void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
@@ -343,7 +430,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
343 rb.Push(RESULT_SUCCESS); 430 rb.Push(RESULT_SUCCESS);
344 rb.Push<u64>(output_sz); 431 rb.Push<u64>(output_sz);
345 432
346 NGLOG_DEBUG(Service_Audio, "called, buffer_size=0x{:X}", output_sz); 433 LOG_DEBUG(Service_Audio, "called, buffer_size=0x{:X}", output_sz);
347} 434}
348 435
349void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { 436void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) {
@@ -352,7 +439,7 @@ void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) {
352 rb.Push(RESULT_SUCCESS); 439 rb.Push(RESULT_SUCCESS);
353 rb.PushIpcInterface<Audio::IAudioDevice>(); 440 rb.PushIpcInterface<Audio::IAudioDevice>();
354 441
355 NGLOG_DEBUG(Service_Audio, "called"); 442 LOG_DEBUG(Service_Audio, "called");
356} 443}
357 444
358bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const { 445bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const {
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
new file mode 100644
index 000000000..844df382c
--- /dev/null
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -0,0 +1,29 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6#include "core/hle/ipc_helpers.h"
7#include "core/hle/kernel/hle_ipc.h"
8#include "core/hle/service/audio/hwopus.h"
9
10namespace Service::Audio {
11
12void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
13 LOG_WARNING(Service_Audio, "(STUBBED) called");
14 IPC::ResponseBuilder rb{ctx, 3};
15 rb.Push(RESULT_SUCCESS);
16 rb.Push<u32>(0x4000);
17}
18
19HwOpus::HwOpus() : ServiceFramework("hwopus") {
20 static const FunctionInfo functions[] = {
21 {0, nullptr, "Initialize"},
22 {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"},
23 {2, nullptr, "InitializeMultiStream"},
24 {3, nullptr, "GetWorkBufferSizeMultiStream"},
25 };
26 RegisterHandlers(functions);
27}
28
29} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hwopus.h
new file mode 100644
index 000000000..090b8c825
--- /dev/null
+++ b/src/core/hle/service/audio/hwopus.h
@@ -0,0 +1,20 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/service/service.h"
8
9namespace Service::Audio {
10
11class HwOpus final : public ServiceFramework<HwOpus> {
12public:
13 explicit HwOpus();
14 ~HwOpus() = default;
15
16private:
17 void GetWorkBufferSize(Kernel::HLERequestContext& ctx);
18};
19
20} // namespace Service::Audio
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp
index 52be9db22..35e024c3d 100644
--- a/src/core/hle/service/bcat/module.cpp
+++ b/src/core/hle/service/bcat/module.cpp
@@ -36,7 +36,7 @@ void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) {
36 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 36 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
37 rb.Push(RESULT_SUCCESS); 37 rb.Push(RESULT_SUCCESS);
38 rb.PushIpcInterface<IBcatService>(); 38 rb.PushIpcInterface<IBcatService>();
39 NGLOG_DEBUG(Service_BCAT, "called"); 39 LOG_DEBUG(Service_BCAT, "called");
40} 40}
41 41
42Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) 42Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp
index 2d4282209..299b9474f 100644
--- a/src/core/hle/service/fatal/fatal.cpp
+++ b/src/core/hle/service/fatal/fatal.cpp
@@ -16,13 +16,13 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
16void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) { 16void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) {
17 IPC::RequestParser rp(ctx); 17 IPC::RequestParser rp(ctx);
18 u32 error_code = rp.Pop<u32>(); 18 u32 error_code = rp.Pop<u32>();
19 NGLOG_WARNING(Service_Fatal, "(STUBBED) called, error_code=0x{:X}", error_code); 19 LOG_WARNING(Service_Fatal, "(STUBBED) called, error_code=0x{:X}", error_code);
20 IPC::ResponseBuilder rb{ctx, 2}; 20 IPC::ResponseBuilder rb{ctx, 2};
21 rb.Push(RESULT_SUCCESS); 21 rb.Push(RESULT_SUCCESS);
22} 22}
23 23
24void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx) { 24void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx) {
25 NGLOG_WARNING(Service_Fatal, "(STUBBED) called"); 25 LOG_WARNING(Service_Fatal, "(STUBBED) called");
26 IPC::ResponseBuilder rb{ctx, 2}; 26 IPC::ResponseBuilder rb{ctx, 2};
27 rb.Push(RESULT_SUCCESS); 27 rb.Push(RESULT_SUCCESS);
28} 28}
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 68d1c90a5..f58b518b6 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -25,14 +25,14 @@ ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& fact
25 ASSERT_MSG(inserted, "Tried to register more than one system with same id code"); 25 ASSERT_MSG(inserted, "Tried to register more than one system with same id code");
26 26
27 auto& filesystem = result.first->second; 27 auto& filesystem = result.first->second;
28 NGLOG_DEBUG(Service_FS, "Registered file system {} with id code 0x{:08X}", 28 LOG_DEBUG(Service_FS, "Registered file system {} with id code 0x{:08X}", filesystem->GetName(),
29 filesystem->GetName(), static_cast<u32>(type)); 29 static_cast<u32>(type));
30 return RESULT_SUCCESS; 30 return RESULT_SUCCESS;
31} 31}
32 32
33ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, 33ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
34 FileSys::Path& path) { 34 FileSys::Path& path) {
35 NGLOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type)); 35 LOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type));
36 36
37 auto itr = filesystem_map.find(type); 37 auto itr = filesystem_map.find(type);
38 if (itr == filesystem_map.end()) { 38 if (itr == filesystem_map.end()) {
@@ -44,7 +44,7 @@ ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
44} 44}
45 45
46ResultCode FormatFileSystem(Type type) { 46ResultCode FormatFileSystem(Type type) {
47 NGLOG_TRACE(Service_FS, "Formatting FileSystem with type={}", static_cast<u32>(type)); 47 LOG_TRACE(Service_FS, "Formatting FileSystem with type={}", static_cast<u32>(type));
48 48
49 auto itr = filesystem_map.find(type); 49 auto itr = filesystem_map.find(type);
50 if (itr == filesystem_map.end()) { 50 if (itr == filesystem_map.end()) {
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 1cf97e876..216bfea0a 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -36,7 +36,7 @@ private:
36 const s64 offset = rp.Pop<s64>(); 36 const s64 offset = rp.Pop<s64>();
37 const s64 length = rp.Pop<s64>(); 37 const s64 length = rp.Pop<s64>();
38 38
39 NGLOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length); 39 LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length);
40 40
41 // Error checking 41 // Error checking
42 if (length < 0) { 42 if (length < 0) {
@@ -88,7 +88,7 @@ private:
88 const s64 offset = rp.Pop<s64>(); 88 const s64 offset = rp.Pop<s64>();
89 const s64 length = rp.Pop<s64>(); 89 const s64 length = rp.Pop<s64>();
90 90
91 NGLOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length); 91 LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length);
92 92
93 // Error checking 93 // Error checking
94 if (length < 0) { 94 if (length < 0) {
@@ -125,7 +125,7 @@ private:
125 const s64 offset = rp.Pop<s64>(); 125 const s64 offset = rp.Pop<s64>();
126 const s64 length = rp.Pop<s64>(); 126 const s64 length = rp.Pop<s64>();
127 127
128 NGLOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length); 128 LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length);
129 129
130 // Error checking 130 // Error checking
131 if (length < 0) { 131 if (length < 0) {
@@ -153,7 +153,7 @@ private:
153 } 153 }
154 154
155 void Flush(Kernel::HLERequestContext& ctx) { 155 void Flush(Kernel::HLERequestContext& ctx) {
156 NGLOG_DEBUG(Service_FS, "called"); 156 LOG_DEBUG(Service_FS, "called");
157 backend->Flush(); 157 backend->Flush();
158 158
159 IPC::ResponseBuilder rb{ctx, 2}; 159 IPC::ResponseBuilder rb{ctx, 2};
@@ -164,7 +164,7 @@ private:
164 IPC::RequestParser rp{ctx}; 164 IPC::RequestParser rp{ctx};
165 const u64 size = rp.Pop<u64>(); 165 const u64 size = rp.Pop<u64>();
166 backend->SetSize(size); 166 backend->SetSize(size);
167 NGLOG_DEBUG(Service_FS, "called, size={}", size); 167 LOG_DEBUG(Service_FS, "called, size={}", size);
168 168
169 IPC::ResponseBuilder rb{ctx, 2}; 169 IPC::ResponseBuilder rb{ctx, 2};
170 rb.Push(RESULT_SUCCESS); 170 rb.Push(RESULT_SUCCESS);
@@ -172,7 +172,7 @@ private:
172 172
173 void GetSize(Kernel::HLERequestContext& ctx) { 173 void GetSize(Kernel::HLERequestContext& ctx) {
174 const u64 size = backend->GetSize(); 174 const u64 size = backend->GetSize();
175 NGLOG_DEBUG(Service_FS, "called, size={}", size); 175 LOG_DEBUG(Service_FS, "called, size={}", size);
176 176
177 IPC::ResponseBuilder rb{ctx, 4}; 177 IPC::ResponseBuilder rb{ctx, 4};
178 rb.Push(RESULT_SUCCESS); 178 rb.Push(RESULT_SUCCESS);
@@ -198,7 +198,7 @@ private:
198 IPC::RequestParser rp{ctx}; 198 IPC::RequestParser rp{ctx};
199 const u64 unk = rp.Pop<u64>(); 199 const u64 unk = rp.Pop<u64>();
200 200
201 NGLOG_DEBUG(Service_FS, "called, unk=0x{:X}", unk); 201 LOG_DEBUG(Service_FS, "called, unk=0x{:X}", unk);
202 202
203 // Calculate how many entries we can fit in the output buffer 203 // Calculate how many entries we can fit in the output buffer
204 u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry); 204 u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry);
@@ -220,7 +220,7 @@ private:
220 } 220 }
221 221
222 void GetEntryCount(Kernel::HLERequestContext& ctx) { 222 void GetEntryCount(Kernel::HLERequestContext& ctx) {
223 NGLOG_DEBUG(Service_FS, "called"); 223 LOG_DEBUG(Service_FS, "called");
224 224
225 u64 count = backend->GetEntryCount(); 225 u64 count = backend->GetEntryCount();
226 226
@@ -264,7 +264,7 @@ public:
264 u64 mode = rp.Pop<u64>(); 264 u64 mode = rp.Pop<u64>();
265 u32 size = rp.Pop<u32>(); 265 u32 size = rp.Pop<u32>();
266 266
267 NGLOG_DEBUG(Service_FS, "called file {} mode 0x{:X} size 0x{:08X}", name, mode, size); 267 LOG_DEBUG(Service_FS, "called file {} mode 0x{:X} size 0x{:08X}", name, mode, size);
268 268
269 IPC::ResponseBuilder rb{ctx, 2}; 269 IPC::ResponseBuilder rb{ctx, 2};
270 rb.Push(backend->CreateFile(name, size)); 270 rb.Push(backend->CreateFile(name, size));
@@ -276,7 +276,7 @@ public:
276 auto file_buffer = ctx.ReadBuffer(); 276 auto file_buffer = ctx.ReadBuffer();
277 std::string name = Common::StringFromBuffer(file_buffer); 277 std::string name = Common::StringFromBuffer(file_buffer);
278 278
279 NGLOG_DEBUG(Service_FS, "called file {}", name); 279 LOG_DEBUG(Service_FS, "called file {}", name);
280 280
281 IPC::ResponseBuilder rb{ctx, 2}; 281 IPC::ResponseBuilder rb{ctx, 2};
282 rb.Push(backend->DeleteFile(name)); 282 rb.Push(backend->DeleteFile(name));
@@ -288,7 +288,7 @@ public:
288 auto file_buffer = ctx.ReadBuffer(); 288 auto file_buffer = ctx.ReadBuffer();
289 std::string name = Common::StringFromBuffer(file_buffer); 289 std::string name = Common::StringFromBuffer(file_buffer);
290 290
291 NGLOG_DEBUG(Service_FS, "called directory {}", name); 291 LOG_DEBUG(Service_FS, "called directory {}", name);
292 292
293 IPC::ResponseBuilder rb{ctx, 2}; 293 IPC::ResponseBuilder rb{ctx, 2};
294 rb.Push(backend->CreateDirectory(name)); 294 rb.Push(backend->CreateDirectory(name));
@@ -306,7 +306,7 @@ public:
306 Memory::ReadBlock(ctx.BufferDescriptorX()[1].Address(), buffer.data(), buffer.size()); 306 Memory::ReadBlock(ctx.BufferDescriptorX()[1].Address(), buffer.data(), buffer.size());
307 std::string dst_name = Common::StringFromBuffer(buffer); 307 std::string dst_name = Common::StringFromBuffer(buffer);
308 308
309 NGLOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name); 309 LOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name);
310 310
311 IPC::ResponseBuilder rb{ctx, 2}; 311 IPC::ResponseBuilder rb{ctx, 2};
312 rb.Push(backend->RenameFile(src_name, dst_name)); 312 rb.Push(backend->RenameFile(src_name, dst_name));
@@ -320,7 +320,7 @@ public:
320 320
321 auto mode = static_cast<FileSys::Mode>(rp.Pop<u32>()); 321 auto mode = static_cast<FileSys::Mode>(rp.Pop<u32>());
322 322
323 NGLOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode)); 323 LOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode));
324 324
325 auto result = backend->OpenFile(name, mode); 325 auto result = backend->OpenFile(name, mode);
326 if (result.Failed()) { 326 if (result.Failed()) {
@@ -345,7 +345,7 @@ public:
345 // TODO(Subv): Implement this filter. 345 // TODO(Subv): Implement this filter.
346 u32 filter_flags = rp.Pop<u32>(); 346 u32 filter_flags = rp.Pop<u32>();
347 347
348 NGLOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags); 348 LOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags);
349 349
350 auto result = backend->OpenDirectory(name); 350 auto result = backend->OpenDirectory(name);
351 if (result.Failed()) { 351 if (result.Failed()) {
@@ -367,7 +367,7 @@ public:
367 auto file_buffer = ctx.ReadBuffer(); 367 auto file_buffer = ctx.ReadBuffer();
368 std::string name = Common::StringFromBuffer(file_buffer); 368 std::string name = Common::StringFromBuffer(file_buffer);
369 369
370 NGLOG_DEBUG(Service_FS, "called file {}", name); 370 LOG_DEBUG(Service_FS, "called file {}", name);
371 371
372 auto result = backend->GetEntryType(name); 372 auto result = backend->GetEntryType(name);
373 if (result.Failed()) { 373 if (result.Failed()) {
@@ -382,7 +382,7 @@ public:
382 } 382 }
383 383
384 void Commit(Kernel::HLERequestContext& ctx) { 384 void Commit(Kernel::HLERequestContext& ctx) {
385 NGLOG_WARNING(Service_FS, "(STUBBED) called"); 385 LOG_WARNING(Service_FS, "(STUBBED) called");
386 386
387 IPC::ResponseBuilder rb{ctx, 2}; 387 IPC::ResponseBuilder rb{ctx, 2};
388 rb.Push(RESULT_SUCCESS); 388 rb.Push(RESULT_SUCCESS);
@@ -498,14 +498,14 @@ void FSP_SRV::TryLoadRomFS() {
498} 498}
499 499
500void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { 500void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) {
501 NGLOG_WARNING(Service_FS, "(STUBBED) called"); 501 LOG_WARNING(Service_FS, "(STUBBED) called");
502 502
503 IPC::ResponseBuilder rb{ctx, 2}; 503 IPC::ResponseBuilder rb{ctx, 2};
504 rb.Push(RESULT_SUCCESS); 504 rb.Push(RESULT_SUCCESS);
505} 505}
506 506
507void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { 507void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {
508 NGLOG_DEBUG(Service_FS, "called"); 508 LOG_DEBUG(Service_FS, "called");
509 509
510 FileSys::Path unused; 510 FileSys::Path unused;
511 auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap(); 511 auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap();
@@ -522,14 +522,14 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) {
522 auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>(); 522 auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>();
523 u128 uid = rp.PopRaw<u128>(); 523 u128 uid = rp.PopRaw<u128>();
524 524
525 NGLOG_WARNING(Service_FS, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); 525 LOG_WARNING(Service_FS, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]);
526 526
527 IPC::ResponseBuilder rb{ctx, 2}; 527 IPC::ResponseBuilder rb{ctx, 2};
528 rb.Push(RESULT_SUCCESS); 528 rb.Push(RESULT_SUCCESS);
529} 529}
530 530
531void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { 531void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
532 NGLOG_WARNING(Service_FS, "(STUBBED) called"); 532 LOG_WARNING(Service_FS, "(STUBBED) called");
533 533
534 FileSys::Path unused; 534 FileSys::Path unused;
535 auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap(); 535 auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap();
@@ -540,7 +540,7 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
540} 540}
541 541
542void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { 542void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
543 NGLOG_WARNING(Service_FS, "(STUBBED) called"); 543 LOG_WARNING(Service_FS, "(STUBBED) called");
544 544
545 IPC::ResponseBuilder rb{ctx, 3}; 545 IPC::ResponseBuilder rb{ctx, 3};
546 rb.Push(RESULT_SUCCESS); 546 rb.Push(RESULT_SUCCESS);
@@ -548,12 +548,12 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
548} 548}
549 549
550void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { 550void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
551 NGLOG_DEBUG(Service_FS, "called"); 551 LOG_DEBUG(Service_FS, "called");
552 552
553 TryLoadRomFS(); 553 TryLoadRomFS();
554 if (!romfs) { 554 if (!romfs) {
555 // TODO (bunnei): Find the right error code to use here 555 // TODO (bunnei): Find the right error code to use here
556 NGLOG_CRITICAL(Service_FS, "no file system interface available!"); 556 LOG_CRITICAL(Service_FS, "no file system interface available!");
557 IPC::ResponseBuilder rb{ctx, 2}; 557 IPC::ResponseBuilder rb{ctx, 2};
558 rb.Push(ResultCode(-1)); 558 rb.Push(ResultCode(-1));
559 return; 559 return;
@@ -562,7 +562,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
562 // Attempt to open a StorageBackend interface to the RomFS 562 // Attempt to open a StorageBackend interface to the RomFS
563 auto storage = romfs->OpenFile({}, {}); 563 auto storage = romfs->OpenFile({}, {});
564 if (storage.Failed()) { 564 if (storage.Failed()) {
565 NGLOG_CRITICAL(Service_FS, "no storage interface available!"); 565 LOG_CRITICAL(Service_FS, "no storage interface available!");
566 IPC::ResponseBuilder rb{ctx, 2}; 566 IPC::ResponseBuilder rb{ctx, 2};
567 rb.Push(storage.Code()); 567 rb.Push(storage.Code());
568 return; 568 return;
@@ -574,7 +574,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
574} 574}
575 575
576void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { 576void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
577 NGLOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess"); 577 LOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess");
578 OpenDataStorageByCurrentProcess(ctx); 578 OpenDataStorageByCurrentProcess(ctx);
579} 579}
580 580
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index 94d9fbf25..c98a46e05 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -13,7 +13,7 @@ namespace Service::Friend {
13void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) { 13void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) {
14 IPC::ResponseBuilder rb{ctx, 2}; 14 IPC::ResponseBuilder rb{ctx, 2};
15 rb.Push(RESULT_SUCCESS); 15 rb.Push(RESULT_SUCCESS);
16 NGLOG_WARNING(Service_Friend, "(STUBBED) called"); 16 LOG_WARNING(Service_Friend, "(STUBBED) called");
17} 17}
18 18
19Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) 19Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 2696a8bf0..b0f4a384e 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -53,7 +53,7 @@ private:
53 IPC::ResponseBuilder rb{ctx, 2, 1}; 53 IPC::ResponseBuilder rb{ctx, 2, 1};
54 rb.Push(RESULT_SUCCESS); 54 rb.Push(RESULT_SUCCESS);
55 rb.PushCopyObjects(shared_mem); 55 rb.PushCopyObjects(shared_mem);
56 NGLOG_DEBUG(Service_HID, "called"); 56 LOG_DEBUG(Service_HID, "called");
57 } 57 }
58 58
59 void LoadInputDevices() { 59 void LoadInputDevices() {
@@ -75,7 +75,7 @@ private:
75 75
76 // Set up controllers as neon red+blue Joy-Con attached to console 76 // Set up controllers as neon red+blue Joy-Con attached to console
77 ControllerHeader& controller_header = mem.controllers[Controller_Handheld].header; 77 ControllerHeader& controller_header = mem.controllers[Controller_Handheld].header;
78 controller_header.type = ControllerType_Handheld | ControllerType_JoyconPair; 78 controller_header.type = ControllerType_Handheld;
79 controller_header.single_colors_descriptor = ColorDesc_ColorsNonexistent; 79 controller_header.single_colors_descriptor = ColorDesc_ColorsNonexistent;
80 controller_header.right_color_body = JOYCON_BODY_NEON_RED; 80 controller_header.right_color_body = JOYCON_BODY_NEON_RED;
81 controller_header.right_color_buttons = JOYCON_BUTTONS_NEON_RED; 81 controller_header.right_color_buttons = JOYCON_BUTTONS_NEON_RED;
@@ -84,23 +84,21 @@ private:
84 84
85 for (size_t controller = 0; controller < mem.controllers.size(); controller++) { 85 for (size_t controller = 0; controller < mem.controllers.size(); controller++) {
86 for (int index = 0; index < HID_NUM_LAYOUTS; index++) { 86 for (int index = 0; index < HID_NUM_LAYOUTS; index++) {
87 // TODO(DarkLordZach): Is this layout/controller config actually invalid?
88 if (controller == Controller_Handheld && index == Layout_Single)
89 continue;
90
91 ControllerLayout& layout = mem.controllers[controller].layouts[index]; 87 ControllerLayout& layout = mem.controllers[controller].layouts[index];
92 layout.header.num_entries = HID_NUM_ENTRIES; 88 layout.header.num_entries = HID_NUM_ENTRIES;
93 layout.header.max_entry_index = HID_NUM_ENTRIES - 1; 89 layout.header.max_entry_index = HID_NUM_ENTRIES - 1;
94 90
95 // HID shared memory stores the state of the past 17 samples in a circlular buffer, 91 // HID shared memory stores the state of the past 17 samples in a circlular buffer,
96 // each with a timestamp in number of samples since boot. 92 // each with a timestamp in number of samples since boot.
93 const ControllerInputEntry& last_entry = layout.entries[layout.header.latest_entry];
94
97 layout.header.timestamp_ticks = CoreTiming::GetTicks(); 95 layout.header.timestamp_ticks = CoreTiming::GetTicks();
98 layout.header.latest_entry = (layout.header.latest_entry + 1) % HID_NUM_ENTRIES; 96 layout.header.latest_entry = (layout.header.latest_entry + 1) % HID_NUM_ENTRIES;
99 97
100 ControllerInputEntry& entry = layout.entries[layout.header.latest_entry]; 98 ControllerInputEntry& entry = layout.entries[layout.header.latest_entry];
101 entry.timestamp++; 99 entry.timestamp = last_entry.timestamp + 1;
102 // TODO(shinyquagsire23): Is this always identical to timestamp? 100 // TODO(shinyquagsire23): Is this always identical to timestamp?
103 entry.timestamp_2++; 101 entry.timestamp_2 = entry.timestamp;
104 102
105 // TODO(shinyquagsire23): More than just handheld input 103 // TODO(shinyquagsire23): More than just handheld input
106 if (controller != Controller_Handheld) 104 if (controller != Controller_Handheld)
@@ -267,7 +265,7 @@ private:
267 void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) { 265 void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) {
268 IPC::ResponseBuilder rb{ctx, 2}; 266 IPC::ResponseBuilder rb{ctx, 2};
269 rb.Push(RESULT_SUCCESS); 267 rb.Push(RESULT_SUCCESS);
270 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 268 LOG_WARNING(Service_HID, "(STUBBED) called");
271 } 269 }
272}; 270};
273 271
@@ -399,144 +397,144 @@ private:
399 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 397 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
400 rb.Push(RESULT_SUCCESS); 398 rb.Push(RESULT_SUCCESS);
401 rb.PushIpcInterface<IAppletResource>(applet_resource); 399 rb.PushIpcInterface<IAppletResource>(applet_resource);
402 NGLOG_DEBUG(Service_HID, "called"); 400 LOG_DEBUG(Service_HID, "called");
403 } 401 }
404 402
405 void ActivateDebugPad(Kernel::HLERequestContext& ctx) { 403 void ActivateDebugPad(Kernel::HLERequestContext& ctx) {
406 IPC::ResponseBuilder rb{ctx, 2}; 404 IPC::ResponseBuilder rb{ctx, 2};
407 rb.Push(RESULT_SUCCESS); 405 rb.Push(RESULT_SUCCESS);
408 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 406 LOG_WARNING(Service_HID, "(STUBBED) called");
409 } 407 }
410 408
411 void ActivateTouchScreen(Kernel::HLERequestContext& ctx) { 409 void ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
412 IPC::ResponseBuilder rb{ctx, 2}; 410 IPC::ResponseBuilder rb{ctx, 2};
413 rb.Push(RESULT_SUCCESS); 411 rb.Push(RESULT_SUCCESS);
414 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 412 LOG_WARNING(Service_HID, "(STUBBED) called");
415 } 413 }
416 414
417 void ActivateMouse(Kernel::HLERequestContext& ctx) { 415 void ActivateMouse(Kernel::HLERequestContext& ctx) {
418 IPC::ResponseBuilder rb{ctx, 2}; 416 IPC::ResponseBuilder rb{ctx, 2};
419 rb.Push(RESULT_SUCCESS); 417 rb.Push(RESULT_SUCCESS);
420 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 418 LOG_WARNING(Service_HID, "(STUBBED) called");
421 } 419 }
422 420
423 void ActivateKeyboard(Kernel::HLERequestContext& ctx) { 421 void ActivateKeyboard(Kernel::HLERequestContext& ctx) {
424 IPC::ResponseBuilder rb{ctx, 2}; 422 IPC::ResponseBuilder rb{ctx, 2};
425 rb.Push(RESULT_SUCCESS); 423 rb.Push(RESULT_SUCCESS);
426 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 424 LOG_WARNING(Service_HID, "(STUBBED) called");
427 } 425 }
428 426
429 void StartSixAxisSensor(Kernel::HLERequestContext& ctx) { 427 void StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
430 IPC::ResponseBuilder rb{ctx, 2}; 428 IPC::ResponseBuilder rb{ctx, 2};
431 rb.Push(RESULT_SUCCESS); 429 rb.Push(RESULT_SUCCESS);
432 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 430 LOG_WARNING(Service_HID, "(STUBBED) called");
433 } 431 }
434 432
435 void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { 433 void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
436 IPC::ResponseBuilder rb{ctx, 2}; 434 IPC::ResponseBuilder rb{ctx, 2};
437 rb.Push(RESULT_SUCCESS); 435 rb.Push(RESULT_SUCCESS);
438 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 436 LOG_WARNING(Service_HID, "(STUBBED) called");
439 } 437 }
440 438
441 void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { 439 void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
442 IPC::ResponseBuilder rb{ctx, 2}; 440 IPC::ResponseBuilder rb{ctx, 2};
443 rb.Push(RESULT_SUCCESS); 441 rb.Push(RESULT_SUCCESS);
444 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 442 LOG_WARNING(Service_HID, "(STUBBED) called");
445 } 443 }
446 444
447 void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { 445 void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
448 IPC::ResponseBuilder rb{ctx, 3}; 446 IPC::ResponseBuilder rb{ctx, 3};
449 rb.Push(RESULT_SUCCESS); 447 rb.Push(RESULT_SUCCESS);
450 rb.Push<u32>(0); 448 rb.Push<u32>(0);
451 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 449 LOG_WARNING(Service_HID, "(STUBBED) called");
452 } 450 }
453 451
454 void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) { 452 void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
455 IPC::ResponseBuilder rb{ctx, 2}; 453 IPC::ResponseBuilder rb{ctx, 2};
456 rb.Push(RESULT_SUCCESS); 454 rb.Push(RESULT_SUCCESS);
457 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 455 LOG_WARNING(Service_HID, "(STUBBED) called");
458 } 456 }
459 457
460 void ActivateNpad(Kernel::HLERequestContext& ctx) { 458 void ActivateNpad(Kernel::HLERequestContext& ctx) {
461 IPC::ResponseBuilder rb{ctx, 2}; 459 IPC::ResponseBuilder rb{ctx, 2};
462 rb.Push(RESULT_SUCCESS); 460 rb.Push(RESULT_SUCCESS);
463 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 461 LOG_WARNING(Service_HID, "(STUBBED) called");
464 } 462 }
465 463
466 void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) { 464 void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
467 IPC::ResponseBuilder rb{ctx, 2, 1}; 465 IPC::ResponseBuilder rb{ctx, 2, 1};
468 rb.Push(RESULT_SUCCESS); 466 rb.Push(RESULT_SUCCESS);
469 rb.PushCopyObjects(event); 467 rb.PushCopyObjects(event);
470 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 468 LOG_WARNING(Service_HID, "(STUBBED) called");
471 } 469 }
472 470
473 void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { 471 void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
474 IPC::ResponseBuilder rb{ctx, 2}; 472 IPC::ResponseBuilder rb{ctx, 2};
475 rb.Push(RESULT_SUCCESS); 473 rb.Push(RESULT_SUCCESS);
476 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 474 LOG_WARNING(Service_HID, "(STUBBED) called");
477 } 475 }
478 476
479 void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { 477 void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
480 IPC::ResponseBuilder rb{ctx, 2}; 478 IPC::ResponseBuilder rb{ctx, 2};
481 rb.Push(RESULT_SUCCESS); 479 rb.Push(RESULT_SUCCESS);
482 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 480 LOG_WARNING(Service_HID, "(STUBBED) called");
483 } 481 }
484 482
485 void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { 483 void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
486 IPC::ResponseBuilder rb{ctx, 3}; 484 IPC::ResponseBuilder rb{ctx, 3};
487 rb.Push(RESULT_SUCCESS); 485 rb.Push(RESULT_SUCCESS);
488 rb.Push(joy_hold_type); 486 rb.Push(joy_hold_type);
489 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 487 LOG_WARNING(Service_HID, "(STUBBED) called");
490 } 488 }
491 489
492 void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) { 490 void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) {
493 IPC::ResponseBuilder rb{ctx, 2}; 491 IPC::ResponseBuilder rb{ctx, 2};
494 rb.Push(RESULT_SUCCESS); 492 rb.Push(RESULT_SUCCESS);
495 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 493 LOG_WARNING(Service_HID, "(STUBBED) called");
496 } 494 }
497 495
498 void SendVibrationValue(Kernel::HLERequestContext& ctx) { 496 void SendVibrationValue(Kernel::HLERequestContext& ctx) {
499 IPC::ResponseBuilder rb{ctx, 2}; 497 IPC::ResponseBuilder rb{ctx, 2};
500 rb.Push(RESULT_SUCCESS); 498 rb.Push(RESULT_SUCCESS);
501 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 499 LOG_WARNING(Service_HID, "(STUBBED) called");
502 } 500 }
503 501
504 void GetActualVibrationValue(Kernel::HLERequestContext& ctx) { 502 void GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
505 IPC::ResponseBuilder rb{ctx, 2}; 503 IPC::ResponseBuilder rb{ctx, 2};
506 rb.Push(RESULT_SUCCESS); 504 rb.Push(RESULT_SUCCESS);
507 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 505 LOG_WARNING(Service_HID, "(STUBBED) called");
508 } 506 }
509 507
510 void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { 508 void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
511 IPC::ResponseBuilder rb{ctx, 2}; 509 IPC::ResponseBuilder rb{ctx, 2};
512 rb.Push(RESULT_SUCCESS); 510 rb.Push(RESULT_SUCCESS);
513 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 511 LOG_WARNING(Service_HID, "(STUBBED) called");
514 } 512 }
515 513
516 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { 514 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
517 IPC::ResponseBuilder rb{ctx, 2}; 515 IPC::ResponseBuilder rb{ctx, 2};
518 rb.Push(RESULT_SUCCESS); 516 rb.Push(RESULT_SUCCESS);
519 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 517 LOG_WARNING(Service_HID, "(STUBBED) called");
520 } 518 }
521 519
522 void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { 520 void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
523 IPC::ResponseBuilder rb{ctx, 4}; 521 IPC::ResponseBuilder rb{ctx, 4};
524 rb.Push(RESULT_SUCCESS); 522 rb.Push(RESULT_SUCCESS);
525 rb.Push<u64>(0); 523 rb.Push<u64>(0);
526 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 524 LOG_WARNING(Service_HID, "(STUBBED) called");
527 } 525 }
528 526
529 void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { 527 void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
530 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 528 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
531 rb.Push(RESULT_SUCCESS); 529 rb.Push(RESULT_SUCCESS);
532 rb.PushIpcInterface<IActiveVibrationDeviceList>(); 530 rb.PushIpcInterface<IActiveVibrationDeviceList>();
533 NGLOG_DEBUG(Service_HID, "called"); 531 LOG_DEBUG(Service_HID, "called");
534 } 532 }
535 533
536 void SendVibrationValues(Kernel::HLERequestContext& ctx) { 534 void SendVibrationValues(Kernel::HLERequestContext& ctx) {
537 IPC::ResponseBuilder rb{ctx, 2}; 535 IPC::ResponseBuilder rb{ctx, 2};
538 rb.Push(RESULT_SUCCESS); 536 rb.Push(RESULT_SUCCESS);
539 NGLOG_WARNING(Service_HID, "(STUBBED) called"); 537 LOG_WARNING(Service_HID, "(STUBBED) called");
540 } 538 }
541}; 539};
542 540
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index 46194643e..e85a8bdb9 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -141,19 +141,19 @@ private:
141 if (header.IsTailLog()) { 141 if (header.IsTailLog()) {
142 switch (header.severity) { 142 switch (header.severity) {
143 case MessageHeader::Severity::Trace: 143 case MessageHeader::Severity::Trace:
144 NGLOG_TRACE(Debug_Emulated, "{}", log_stream.str()); 144 LOG_TRACE(Debug_Emulated, "{}", log_stream.str());
145 break; 145 break;
146 case MessageHeader::Severity::Info: 146 case MessageHeader::Severity::Info:
147 NGLOG_INFO(Debug_Emulated, "{}", log_stream.str()); 147 LOG_INFO(Debug_Emulated, "{}", log_stream.str());
148 break; 148 break;
149 case MessageHeader::Severity::Warning: 149 case MessageHeader::Severity::Warning:
150 NGLOG_WARNING(Debug_Emulated, "{}", log_stream.str()); 150 LOG_WARNING(Debug_Emulated, "{}", log_stream.str());
151 break; 151 break;
152 case MessageHeader::Severity::Error: 152 case MessageHeader::Severity::Error:
153 NGLOG_ERROR(Debug_Emulated, "{}", log_stream.str()); 153 LOG_ERROR(Debug_Emulated, "{}", log_stream.str());
154 break; 154 break;
155 case MessageHeader::Severity::Critical: 155 case MessageHeader::Severity::Critical:
156 NGLOG_CRITICAL(Debug_Emulated, "{}", log_stream.str()); 156 LOG_CRITICAL(Debug_Emulated, "{}", log_stream.str());
157 break; 157 break;
158 } 158 }
159 } 159 }
@@ -178,7 +178,7 @@ void LM::Initialize(Kernel::HLERequestContext& ctx) {
178 rb.Push(RESULT_SUCCESS); 178 rb.Push(RESULT_SUCCESS);
179 rb.PushIpcInterface<Logger>(); 179 rb.PushIpcInterface<Logger>();
180 180
181 NGLOG_DEBUG(Service_LM, "called"); 181 LOG_DEBUG(Service_LM, "called");
182} 182}
183 183
184LM::LM() : ServiceFramework("lm") { 184LM::LM() : ServiceFramework("lm") {
diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp
index b3a85b818..08f45b78a 100644
--- a/src/core/hle/service/mm/mm_u.cpp
+++ b/src/core/hle/service/mm/mm_u.cpp
@@ -14,7 +14,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager) {
14} 14}
15 15
16void MM_U::Initialize(Kernel::HLERequestContext& ctx) { 16void MM_U::Initialize(Kernel::HLERequestContext& ctx) {
17 NGLOG_WARNING(Service_MM, "(STUBBED) called"); 17 LOG_WARNING(Service_MM, "(STUBBED) called");
18 IPC::ResponseBuilder rb{ctx, 2}; 18 IPC::ResponseBuilder rb{ctx, 2};
19 rb.Push(RESULT_SUCCESS); 19 rb.Push(RESULT_SUCCESS);
20} 20}
@@ -25,13 +25,13 @@ void MM_U::SetAndWait(Kernel::HLERequestContext& ctx) {
25 max = rp.Pop<u32>(); 25 max = rp.Pop<u32>();
26 current = min; 26 current = min;
27 27
28 NGLOG_WARNING(Service_MM, "(STUBBED) called, min=0x{:X}, max=0x{:X}", min, max); 28 LOG_WARNING(Service_MM, "(STUBBED) called, min=0x{:X}, max=0x{:X}", min, max);
29 IPC::ResponseBuilder rb{ctx, 2}; 29 IPC::ResponseBuilder rb{ctx, 2};
30 rb.Push(RESULT_SUCCESS); 30 rb.Push(RESULT_SUCCESS);
31} 31}
32 32
33void MM_U::Get(Kernel::HLERequestContext& ctx) { 33void MM_U::Get(Kernel::HLERequestContext& ctx) {
34 NGLOG_WARNING(Service_MM, "(STUBBED) called"); 34 LOG_WARNING(Service_MM, "(STUBBED) called");
35 IPC::ResponseBuilder rb{ctx, 3}; 35 IPC::ResponseBuilder rb{ctx, 3};
36 rb.Push(RESULT_SUCCESS); 36 rb.Push(RESULT_SUCCESS);
37 rb.Push(current); 37 rb.Push(current);
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index 2a9f84037..56b05e9e8 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -64,7 +64,7 @@ private:
64 }; 64 };
65 65
66 void Initialize(Kernel::HLERequestContext& ctx) { 66 void Initialize(Kernel::HLERequestContext& ctx) {
67 NGLOG_WARNING(Service_NFP, "(STUBBED) called"); 67 LOG_WARNING(Service_NFP, "(STUBBED) called");
68 68
69 state = State::Initialized; 69 state = State::Initialized;
70 70
@@ -78,7 +78,7 @@ private:
78 78
79 ctx.WriteBuffer(&device_handle, sizeof(device_handle)); 79 ctx.WriteBuffer(&device_handle, sizeof(device_handle));
80 80
81 NGLOG_WARNING(Service_NFP, "(STUBBED) called, array_size={}", array_size); 81 LOG_WARNING(Service_NFP, "(STUBBED) called, array_size={}", array_size);
82 82
83 IPC::ResponseBuilder rb{ctx, 3}; 83 IPC::ResponseBuilder rb{ctx, 3};
84 rb.Push(RESULT_SUCCESS); 84 rb.Push(RESULT_SUCCESS);
@@ -88,7 +88,7 @@ private:
88 void AttachActivateEvent(Kernel::HLERequestContext& ctx) { 88 void AttachActivateEvent(Kernel::HLERequestContext& ctx) {
89 IPC::RequestParser rp{ctx}; 89 IPC::RequestParser rp{ctx};
90 const u64 dev_handle = rp.Pop<u64>(); 90 const u64 dev_handle = rp.Pop<u64>();
91 NGLOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle); 91 LOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle);
92 92
93 IPC::ResponseBuilder rb{ctx, 2, 1}; 93 IPC::ResponseBuilder rb{ctx, 2, 1};
94 rb.Push(RESULT_SUCCESS); 94 rb.Push(RESULT_SUCCESS);
@@ -98,7 +98,7 @@ private:
98 void AttachDeactivateEvent(Kernel::HLERequestContext& ctx) { 98 void AttachDeactivateEvent(Kernel::HLERequestContext& ctx) {
99 IPC::RequestParser rp{ctx}; 99 IPC::RequestParser rp{ctx};
100 const u64 dev_handle = rp.Pop<u64>(); 100 const u64 dev_handle = rp.Pop<u64>();
101 NGLOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle); 101 LOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle);
102 102
103 IPC::ResponseBuilder rb{ctx, 2, 1}; 103 IPC::ResponseBuilder rb{ctx, 2, 1};
104 rb.Push(RESULT_SUCCESS); 104 rb.Push(RESULT_SUCCESS);
@@ -106,14 +106,14 @@ private:
106 } 106 }
107 107
108 void GetState(Kernel::HLERequestContext& ctx) { 108 void GetState(Kernel::HLERequestContext& ctx) {
109 NGLOG_WARNING(Service_NFP, "(STUBBED) called"); 109 LOG_WARNING(Service_NFP, "(STUBBED) called");
110 IPC::ResponseBuilder rb{ctx, 3}; 110 IPC::ResponseBuilder rb{ctx, 3};
111 rb.Push(RESULT_SUCCESS); 111 rb.Push(RESULT_SUCCESS);
112 rb.Push<u32>(static_cast<u32>(state)); 112 rb.Push<u32>(static_cast<u32>(state));
113 } 113 }
114 114
115 void GetDeviceState(Kernel::HLERequestContext& ctx) { 115 void GetDeviceState(Kernel::HLERequestContext& ctx) {
116 NGLOG_WARNING(Service_NFP, "(STUBBED) called"); 116 LOG_WARNING(Service_NFP, "(STUBBED) called");
117 IPC::ResponseBuilder rb{ctx, 3}; 117 IPC::ResponseBuilder rb{ctx, 3};
118 rb.Push(RESULT_SUCCESS); 118 rb.Push(RESULT_SUCCESS);
119 rb.Push<u32>(static_cast<u32>(device_state)); 119 rb.Push<u32>(static_cast<u32>(device_state));
@@ -122,7 +122,7 @@ private:
122 void GetNpadId(Kernel::HLERequestContext& ctx) { 122 void GetNpadId(Kernel::HLERequestContext& ctx) {
123 IPC::RequestParser rp{ctx}; 123 IPC::RequestParser rp{ctx};
124 const u64 dev_handle = rp.Pop<u64>(); 124 const u64 dev_handle = rp.Pop<u64>();
125 NGLOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle); 125 LOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle);
126 IPC::ResponseBuilder rb{ctx, 3}; 126 IPC::ResponseBuilder rb{ctx, 3};
127 rb.Push(RESULT_SUCCESS); 127 rb.Push(RESULT_SUCCESS);
128 rb.Push<u32>(npad_id); 128 rb.Push<u32>(npad_id);
@@ -131,7 +131,7 @@ private:
131 void AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx) { 131 void AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx) {
132 IPC::RequestParser rp{ctx}; 132 IPC::RequestParser rp{ctx};
133 const u64 dev_handle = rp.Pop<u64>(); 133 const u64 dev_handle = rp.Pop<u64>();
134 NGLOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle); 134 LOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle);
135 135
136 IPC::ResponseBuilder rb{ctx, 2, 1}; 136 IPC::ResponseBuilder rb{ctx, 2, 1};
137 rb.Push(RESULT_SUCCESS); 137 rb.Push(RESULT_SUCCESS);
@@ -148,7 +148,7 @@ private:
148}; 148};
149 149
150void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) { 150void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
151 NGLOG_DEBUG(Service_NFP, "called"); 151 LOG_DEBUG(Service_NFP, "called");
152 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 152 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
153 rb.Push(RESULT_SUCCESS); 153 rb.Push(RESULT_SUCCESS);
154 rb.PushIpcInterface<IUser>(); 154 rb.PushIpcInterface<IUser>();
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index 62489c7fe..54a151c26 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -62,33 +62,33 @@ public:
62 62
63private: 63private:
64 void GetRequestState(Kernel::HLERequestContext& ctx) { 64 void GetRequestState(Kernel::HLERequestContext& ctx) {
65 NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); 65 LOG_WARNING(Service_NIFM, "(STUBBED) called");
66 IPC::ResponseBuilder rb{ctx, 3}; 66 IPC::ResponseBuilder rb{ctx, 3};
67 rb.Push(RESULT_SUCCESS); 67 rb.Push(RESULT_SUCCESS);
68 rb.Push<u32>(0); 68 rb.Push<u32>(0);
69 } 69 }
70 70
71 void GetResult(Kernel::HLERequestContext& ctx) { 71 void GetResult(Kernel::HLERequestContext& ctx) {
72 NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); 72 LOG_WARNING(Service_NIFM, "(STUBBED) called");
73 IPC::ResponseBuilder rb{ctx, 2}; 73 IPC::ResponseBuilder rb{ctx, 2};
74 rb.Push(RESULT_SUCCESS); 74 rb.Push(RESULT_SUCCESS);
75 } 75 }
76 76
77 void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) { 77 void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) {
78 NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); 78 LOG_WARNING(Service_NIFM, "(STUBBED) called");
79 IPC::ResponseBuilder rb{ctx, 2, 2}; 79 IPC::ResponseBuilder rb{ctx, 2, 2};
80 rb.Push(RESULT_SUCCESS); 80 rb.Push(RESULT_SUCCESS);
81 rb.PushCopyObjects(event1, event2); 81 rb.PushCopyObjects(event1, event2);
82 } 82 }
83 83
84 void Cancel(Kernel::HLERequestContext& ctx) { 84 void Cancel(Kernel::HLERequestContext& ctx) {
85 NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); 85 LOG_WARNING(Service_NIFM, "(STUBBED) called");
86 IPC::ResponseBuilder rb{ctx, 2}; 86 IPC::ResponseBuilder rb{ctx, 2};
87 rb.Push(RESULT_SUCCESS); 87 rb.Push(RESULT_SUCCESS);
88 } 88 }
89 89
90 void SetConnectionConfirmationOption(Kernel::HLERequestContext& ctx) { 90 void SetConnectionConfirmationOption(Kernel::HLERequestContext& ctx) {
91 NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); 91 LOG_WARNING(Service_NIFM, "(STUBBED) called");
92 IPC::ResponseBuilder rb{ctx, 2}; 92 IPC::ResponseBuilder rb{ctx, 2};
93 rb.Push(RESULT_SUCCESS); 93 rb.Push(RESULT_SUCCESS);
94 } 94 }
@@ -114,7 +114,7 @@ public:
114 114
115private: 115private:
116 void GetClientId(Kernel::HLERequestContext& ctx) { 116 void GetClientId(Kernel::HLERequestContext& ctx) {
117 NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); 117 LOG_WARNING(Service_NIFM, "(STUBBED) called");
118 IPC::ResponseBuilder rb{ctx, 4}; 118 IPC::ResponseBuilder rb{ctx, 4};
119 rb.Push(RESULT_SUCCESS); 119 rb.Push(RESULT_SUCCESS);
120 rb.Push<u64>(0); 120 rb.Push<u64>(0);
@@ -125,7 +125,7 @@ private:
125 rb.Push(RESULT_SUCCESS); 125 rb.Push(RESULT_SUCCESS);
126 rb.PushIpcInterface<IScanRequest>(); 126 rb.PushIpcInterface<IScanRequest>();
127 127
128 NGLOG_DEBUG(Service_NIFM, "called"); 128 LOG_DEBUG(Service_NIFM, "called");
129 } 129 }
130 void CreateRequest(Kernel::HLERequestContext& ctx) { 130 void CreateRequest(Kernel::HLERequestContext& ctx) {
131 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 131 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -133,10 +133,10 @@ private:
133 rb.Push(RESULT_SUCCESS); 133 rb.Push(RESULT_SUCCESS);
134 rb.PushIpcInterface<IRequest>(); 134 rb.PushIpcInterface<IRequest>();
135 135
136 NGLOG_DEBUG(Service_NIFM, "called"); 136 LOG_DEBUG(Service_NIFM, "called");
137 } 137 }
138 void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) { 138 void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
139 NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); 139 LOG_WARNING(Service_NIFM, "(STUBBED) called");
140 IPC::ResponseBuilder rb{ctx, 2}; 140 IPC::ResponseBuilder rb{ctx, 2};
141 rb.Push(RESULT_SUCCESS); 141 rb.Push(RESULT_SUCCESS);
142 } 142 }
@@ -146,7 +146,7 @@ private:
146 rb.Push(RESULT_SUCCESS); 146 rb.Push(RESULT_SUCCESS);
147 rb.PushIpcInterface<INetworkProfile>(); 147 rb.PushIpcInterface<INetworkProfile>();
148 148
149 NGLOG_DEBUG(Service_NIFM, "called"); 149 LOG_DEBUG(Service_NIFM, "called");
150 } 150 }
151}; 151};
152 152
@@ -196,14 +196,14 @@ void Module::Interface::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx)
196 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 196 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
197 rb.Push(RESULT_SUCCESS); 197 rb.Push(RESULT_SUCCESS);
198 rb.PushIpcInterface<IGeneralService>(); 198 rb.PushIpcInterface<IGeneralService>();
199 NGLOG_DEBUG(Service_NIFM, "called"); 199 LOG_DEBUG(Service_NIFM, "called");
200} 200}
201 201
202void Module::Interface::CreateGeneralService(Kernel::HLERequestContext& ctx) { 202void Module::Interface::CreateGeneralService(Kernel::HLERequestContext& ctx) {
203 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 203 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
204 rb.Push(RESULT_SUCCESS); 204 rb.Push(RESULT_SUCCESS);
205 rb.PushIpcInterface<IGeneralService>(); 205 rb.PushIpcInterface<IGeneralService>();
206 NGLOG_DEBUG(Service_NIFM, "called"); 206 LOG_DEBUG(Service_NIFM, "called");
207} 207}
208 208
209Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) 209Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 636af9a1e..d6a12ede5 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -52,7 +52,7 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
52 ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE); 52 ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE);
53 file.ReadBytes(shared_font->data(), shared_font->size()); 53 file.ReadBytes(shared_font->data(), shared_font->size());
54 } else { 54 } else {
55 NGLOG_WARNING(Service_NS, "Unable to load shared font: {}", filepath); 55 LOG_WARNING(Service_NS, "Unable to load shared font: {}", filepath);
56 } 56 }
57} 57}
58 58
@@ -60,7 +60,7 @@ void PL_U::RequestLoad(Kernel::HLERequestContext& ctx) {
60 IPC::RequestParser rp{ctx}; 60 IPC::RequestParser rp{ctx};
61 const u32 shared_font_type{rp.Pop<u32>()}; 61 const u32 shared_font_type{rp.Pop<u32>()};
62 62
63 NGLOG_DEBUG(Service_NS, "called, shared_font_type={}", shared_font_type); 63 LOG_DEBUG(Service_NS, "called, shared_font_type={}", shared_font_type);
64 IPC::ResponseBuilder rb{ctx, 2}; 64 IPC::ResponseBuilder rb{ctx, 2};
65 rb.Push(RESULT_SUCCESS); 65 rb.Push(RESULT_SUCCESS);
66} 66}
@@ -69,7 +69,7 @@ void PL_U::GetLoadState(Kernel::HLERequestContext& ctx) {
69 IPC::RequestParser rp{ctx}; 69 IPC::RequestParser rp{ctx};
70 const u32 font_id{rp.Pop<u32>()}; 70 const u32 font_id{rp.Pop<u32>()};
71 71
72 NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); 72 LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
73 IPC::ResponseBuilder rb{ctx, 3}; 73 IPC::ResponseBuilder rb{ctx, 3};
74 rb.Push(RESULT_SUCCESS); 74 rb.Push(RESULT_SUCCESS);
75 rb.Push<u32>(static_cast<u32>(LoadState::Done)); 75 rb.Push<u32>(static_cast<u32>(LoadState::Done));
@@ -79,7 +79,7 @@ void PL_U::GetSize(Kernel::HLERequestContext& ctx) {
79 IPC::RequestParser rp{ctx}; 79 IPC::RequestParser rp{ctx};
80 const u32 font_id{rp.Pop<u32>()}; 80 const u32 font_id{rp.Pop<u32>()};
81 81
82 NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); 82 LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
83 IPC::ResponseBuilder rb{ctx, 3}; 83 IPC::ResponseBuilder rb{ctx, 3};
84 rb.Push(RESULT_SUCCESS); 84 rb.Push(RESULT_SUCCESS);
85 rb.Push<u32>(SHARED_FONT_REGIONS[font_id].size); 85 rb.Push<u32>(SHARED_FONT_REGIONS[font_id].size);
@@ -89,7 +89,7 @@ void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) {
89 IPC::RequestParser rp{ctx}; 89 IPC::RequestParser rp{ctx};
90 const u32 font_id{rp.Pop<u32>()}; 90 const u32 font_id{rp.Pop<u32>()};
91 91
92 NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); 92 LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
93 IPC::ResponseBuilder rb{ctx, 3}; 93 IPC::ResponseBuilder rb{ctx, 3};
94 rb.Push(RESULT_SUCCESS); 94 rb.Push(RESULT_SUCCESS);
95 rb.Push<u32>(SHARED_FONT_REGIONS[font_id].offset); 95 rb.Push<u32>(SHARED_FONT_REGIONS[font_id].offset);
@@ -110,7 +110,7 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
110 Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE, 110 Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE,
111 "PL_U:shared_font_mem"); 111 "PL_U:shared_font_mem");
112 112
113 NGLOG_DEBUG(Service_NS, "called"); 113 LOG_DEBUG(Service_NS, "called");
114 IPC::ResponseBuilder rb{ctx, 2, 1}; 114 IPC::ResponseBuilder rb{ctx, 2, 1};
115 rb.Push(RESULT_SUCCESS); 115 rb.Push(RESULT_SUCCESS);
116 rb.PushCopyObjects(shared_font_mem); 116 rb.PushCopyObjects(shared_font_mem);
@@ -119,7 +119,7 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
119void PL_U::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) { 119void PL_U::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) {
120 IPC::RequestParser rp{ctx}; 120 IPC::RequestParser rp{ctx};
121 const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for 121 const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for
122 NGLOG_DEBUG(Service_NS, "called, language_code=%lx", language_code); 122 LOG_DEBUG(Service_NS, "called, language_code=%lx", language_code);
123 IPC::ResponseBuilder rb{ctx, 4}; 123 IPC::ResponseBuilder rb{ctx, 4};
124 std::vector<u32> font_codes; 124 std::vector<u32> font_codes;
125 std::vector<u32> font_offsets; 125 std::vector<u32> font_offsets;
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index 103e66d0c..c39d5a164 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -20,9 +20,9 @@ u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector
20void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, 20void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height,
21 u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) { 21 u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) {
22 VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); 22 VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle);
23 NGLOG_WARNING(Service, 23 LOG_WARNING(Service,
24 "Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}", 24 "Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}",
25 addr, offset, width, height, stride, format); 25 addr, offset, width, height, stride, format);
26 26
27 using PixelFormat = Tegra::FramebufferConfig::PixelFormat; 27 using PixelFormat = Tegra::FramebufferConfig::PixelFormat;
28 const Tegra::FramebufferConfig framebuffer{ 28 const Tegra::FramebufferConfig framebuffer{
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index c1eea861d..57b128b40 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -8,12 +8,14 @@
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" 9#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h"
10#include "core/hle/service/nvdrv/devices/nvmap.h" 10#include "core/hle/service/nvdrv/devices/nvmap.h"
11#include "video_core/renderer_base.h"
12#include "video_core/video_core.h"
11 13
12namespace Service::Nvidia::Devices { 14namespace Service::Nvidia::Devices {
13 15
14u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 16u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
15 NGLOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 17 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
16 command.raw, input.size(), output.size()); 18 command.raw, input.size(), output.size());
17 19
18 switch (static_cast<IoctlCommand>(command.raw)) { 20 switch (static_cast<IoctlCommand>(command.raw)) {
19 case IoctlCommand::IocInitalizeExCommand: 21 case IoctlCommand::IocInitalizeExCommand:
@@ -40,15 +42,15 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vecto
40u32 nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output) { 42u32 nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output) {
41 IoctlInitalizeEx params{}; 43 IoctlInitalizeEx params{};
42 std::memcpy(&params, input.data(), input.size()); 44 std::memcpy(&params, input.data(), input.size());
43 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x{:X}", params.big_page_size); 45 LOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x{:X}", params.big_page_size);
44 return 0; 46 return 0;
45} 47}
46 48
47u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output) { 49u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output) {
48 IoctlAllocSpace params{}; 50 IoctlAllocSpace params{};
49 std::memcpy(&params, input.data(), input.size()); 51 std::memcpy(&params, input.data(), input.size());
50 NGLOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages, 52 LOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages,
51 params.page_size, params.flags); 53 params.page_size, params.flags);
52 54
53 auto& gpu = Core::System::GetInstance().GPU(); 55 auto& gpu = Core::System::GetInstance().GPU();
54 const u64 size{static_cast<u64>(params.pages) * static_cast<u64>(params.page_size)}; 56 const u64 size{static_cast<u64>(params.pages) * static_cast<u64>(params.page_size)};
@@ -65,7 +67,7 @@ u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>&
65u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) { 67u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) {
66 size_t num_entries = input.size() / sizeof(IoctlRemapEntry); 68 size_t num_entries = input.size() / sizeof(IoctlRemapEntry);
67 69
68 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries=0x{:X}", num_entries); 70 LOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries=0x{:X}", num_entries);
69 71
70 std::vector<IoctlRemapEntry> entries(num_entries); 72 std::vector<IoctlRemapEntry> entries(num_entries);
71 std::memcpy(entries.data(), input.data(), input.size()); 73 std::memcpy(entries.data(), input.data(), input.size());
@@ -73,8 +75,8 @@ u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output)
73 auto& gpu = Core::System::GetInstance().GPU(); 75 auto& gpu = Core::System::GetInstance().GPU();
74 76
75 for (const auto& entry : entries) { 77 for (const auto& entry : entries) {
76 NGLOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}", 78 LOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}",
77 entry.offset, entry.nvmap_handle, entry.pages); 79 entry.offset, entry.nvmap_handle, entry.pages);
78 Tegra::GPUVAddr offset = static_cast<Tegra::GPUVAddr>(entry.offset) << 0x10; 80 Tegra::GPUVAddr offset = static_cast<Tegra::GPUVAddr>(entry.offset) << 0x10;
79 81
80 auto object = nvmap_dev->GetObject(entry.nvmap_handle); 82 auto object = nvmap_dev->GetObject(entry.nvmap_handle);
@@ -96,11 +98,11 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& ou
96 IoctlMapBufferEx params{}; 98 IoctlMapBufferEx params{};
97 std::memcpy(&params, input.data(), input.size()); 99 std::memcpy(&params, input.data(), input.size());
98 100
99 NGLOG_DEBUG(Service_NVDRV, 101 LOG_DEBUG(Service_NVDRV,
100 "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" 102 "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}"
101 ", offset={}", 103 ", offset={}",
102 params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size, 104 params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size,
103 params.offset); 105 params.offset);
104 106
105 if (!params.nvmap_handle) { 107 if (!params.nvmap_handle) {
106 return 0; 108 return 0;
@@ -146,7 +148,7 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou
146 IoctlUnmapBuffer params{}; 148 IoctlUnmapBuffer params{};
147 std::memcpy(&params, input.data(), input.size()); 149 std::memcpy(&params, input.data(), input.size());
148 150
149 NGLOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); 151 LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
150 152
151 auto& gpu = Core::System::GetInstance().GPU(); 153 auto& gpu = Core::System::GetInstance().GPU();
152 154
@@ -154,6 +156,9 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou
154 156
155 ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping"); 157 ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping");
156 158
159 // Remove this memory region from the rasterizer cache.
160 VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(params.offset, itr->second.size);
161
157 params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size); 162 params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size);
158 163
159 buffer_mappings.erase(itr->second.offset); 164 buffer_mappings.erase(itr->second.offset);
@@ -165,7 +170,7 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou
165u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& output) { 170u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& output) {
166 IoctlBindChannel params{}; 171 IoctlBindChannel params{};
167 std::memcpy(&params, input.data(), input.size()); 172 std::memcpy(&params, input.data(), input.size());
168 NGLOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); 173 LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd);
169 channel = params.fd; 174 channel = params.fd;
170 return 0; 175 return 0;
171} 176}
@@ -173,8 +178,8 @@ u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& ou
173u32 nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u8>& output) { 178u32 nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u8>& output) {
174 IoctlGetVaRegions params{}; 179 IoctlGetVaRegions params{};
175 std::memcpy(&params, input.data(), input.size()); 180 std::memcpy(&params, input.data(), input.size());
176 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr={:X}, buf_size={:X}", params.buf_addr, 181 LOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr={:X}, buf_size={:X}", params.buf_addr,
177 params.buf_size); 182 params.buf_size);
178 183
179 params.buf_size = 0x30; 184 params.buf_size = 0x30;
180 params.regions[0].offset = 0x04000000; 185 params.regions[0].offset = 0x04000000;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 7872d1e09..671b092e1 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -9,8 +9,8 @@
9namespace Service::Nvidia::Devices { 9namespace Service::Nvidia::Devices {
10 10
11u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 11u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
12 NGLOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 12 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
13 command.raw, input.size(), output.size()); 13 command.raw, input.size(), output.size());
14 14
15 switch (static_cast<IoctlCommand>(command.raw)) { 15 switch (static_cast<IoctlCommand>(command.raw)) {
16 case IoctlCommand::IocGetConfigCommand: 16 case IoctlCommand::IocGetConfigCommand:
@@ -29,33 +29,18 @@ u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<
29u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output) { 29u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output) {
30 IocGetConfigParams params{}; 30 IocGetConfigParams params{};
31 std::memcpy(&params, input.data(), sizeof(params)); 31 std::memcpy(&params, input.data(), sizeof(params));
32 NGLOG_DEBUG(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), 32 LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(),
33 params.param_str.data()); 33 params.param_str.data());
34 34 return 0x30006; // Returns error on production mode
35 if (!strcmp(params.domain_str.data(), "nv")) {
36 if (!strcmp(params.param_str.data(), "NV_MEMORY_PROFILER")) {
37 params.config_str[0] = '0';
38 } else if (!strcmp(params.param_str.data(), "NVN_THROUGH_OPENGL")) {
39 params.config_str[0] = '0';
40 } else if (!strcmp(params.param_str.data(), "NVRM_GPU_PREVENT_USE")) {
41 params.config_str[0] = '0';
42 } else {
43 params.config_str[0] = '\0';
44 }
45 } else {
46 UNIMPLEMENTED(); // unknown domain? Only nv has been seen so far on hardware
47 }
48 std::memcpy(output.data(), &params, sizeof(params));
49 return 0;
50} 35}
51 36
52u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, 37u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output,
53 bool is_async) { 38 bool is_async) {
54 IocCtrlEventWaitParams params{}; 39 IocCtrlEventWaitParams params{};
55 std::memcpy(&params, input.data(), sizeof(params)); 40 std::memcpy(&params, input.data(), sizeof(params));
56 NGLOG_WARNING(Service_NVDRV, 41 LOG_WARNING(Service_NVDRV,
57 "(STUBBED) called, syncpt_id={}, threshold={}, timeout={}, is_async={}", 42 "(STUBBED) called, syncpt_id={}, threshold={}, timeout={}, is_async={}",
58 params.syncpt_id, params.threshold, params.timeout, is_async); 43 params.syncpt_id, params.threshold, params.timeout, is_async);
59 44
60 // TODO(Subv): Implement actual syncpt waiting. 45 // TODO(Subv): Implement actual syncpt waiting.
61 params.value = 0; 46 params.value = 0;
@@ -64,7 +49,7 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
64} 49}
65 50
66u32 nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output) { 51u32 nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output) {
67 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); 52 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
68 // TODO(bunnei): Implement this. 53 // TODO(bunnei): Implement this.
69 return 0; 54 return 0;
70} 55}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index 0abc0de83..44e062f50 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -10,8 +10,8 @@
10namespace Service::Nvidia::Devices { 10namespace Service::Nvidia::Devices {
11 11
12u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 12u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
13 NGLOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 13 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
14 command.raw, input.size(), output.size()); 14 command.raw, input.size(), output.size());
15 15
16 switch (static_cast<IoctlCommand>(command.raw)) { 16 switch (static_cast<IoctlCommand>(command.raw)) {
17 case IoctlCommand::IocGetCharacteristicsCommand: 17 case IoctlCommand::IocGetCharacteristicsCommand:
@@ -36,7 +36,7 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vec
36} 36}
37 37
38u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output) { 38u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output) {
39 NGLOG_DEBUG(Service_NVDRV, "called"); 39 LOG_DEBUG(Service_NVDRV, "called");
40 IoctlCharacteristics params{}; 40 IoctlCharacteristics params{};
41 std::memcpy(&params, input.data(), input.size()); 41 std::memcpy(&params, input.data(), input.size());
42 params.gc.arch = 0x120; 42 params.gc.arch = 0x120;
@@ -83,8 +83,8 @@ u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vecto
83u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output) { 83u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output) {
84 IoctlGpuGetTpcMasksArgs params{}; 84 IoctlGpuGetTpcMasksArgs params{};
85 std::memcpy(&params, input.data(), input.size()); 85 std::memcpy(&params, input.data(), input.size());
86 NGLOG_INFO(Service_NVDRV, "called, mask=0x{:X}, mask_buf_addr=0x{:X}", params.mask_buf_size, 86 LOG_INFO(Service_NVDRV, "called, mask=0x{:X}, mask_buf_addr=0x{:X}", params.mask_buf_size,
87 params.mask_buf_addr); 87 params.mask_buf_addr);
88 // TODO(ogniK): Confirm value on hardware 88 // TODO(ogniK): Confirm value on hardware
89 if (params.mask_buf_size) 89 if (params.mask_buf_size)
90 params.tpc_mask_size = 4 * 1; // 4 * num_gpc 90 params.tpc_mask_size = 4 * 1; // 4 * num_gpc
@@ -95,7 +95,7 @@ u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>&
95} 95}
96 96
97u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { 97u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) {
98 NGLOG_DEBUG(Service_NVDRV, "called"); 98 LOG_DEBUG(Service_NVDRV, "called");
99 IoctlActiveSlotMask params{}; 99 IoctlActiveSlotMask params{};
100 std::memcpy(&params, input.data(), input.size()); 100 std::memcpy(&params, input.data(), input.size());
101 params.slot = 0x07; 101 params.slot = 0x07;
@@ -105,7 +105,7 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector
105} 105}
106 106
107u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { 107u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) {
108 NGLOG_DEBUG(Service_NVDRV, "called"); 108 LOG_DEBUG(Service_NVDRV, "called");
109 IoctlZcullGetCtxSize params{}; 109 IoctlZcullGetCtxSize params{};
110 std::memcpy(&params, input.data(), input.size()); 110 std::memcpy(&params, input.data(), input.size());
111 params.size = 0x1; 111 params.size = 0x1;
@@ -114,7 +114,7 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u
114} 114}
115 115
116u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { 116u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) {
117 NGLOG_DEBUG(Service_NVDRV, "called"); 117 LOG_DEBUG(Service_NVDRV, "called");
118 IoctlNvgpuGpuZcullGetInfoArgs params{}; 118 IoctlNvgpuGpuZcullGetInfoArgs params{};
119 std::memcpy(&params, input.data(), input.size()); 119 std::memcpy(&params, input.data(), input.size());
120 params.width_align_pixels = 0x20; 120 params.width_align_pixels = 0x20;
@@ -132,7 +132,7 @@ u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>&
132} 132}
133 133
134u32 nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector<u8>& output) { 134u32 nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector<u8>& output) {
135 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); 135 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
136 IoctlZbcSetTable params{}; 136 IoctlZbcSetTable params{};
137 std::memcpy(&params, input.data(), input.size()); 137 std::memcpy(&params, input.data(), input.size());
138 // TODO(ogniK): What does this even actually do? 138 // TODO(ogniK): What does this even actually do?
@@ -141,7 +141,7 @@ u32 nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector<u8>&
141} 141}
142 142
143u32 nvhost_ctrl_gpu::ZBCQueryTable(const std::vector<u8>& input, std::vector<u8>& output) { 143u32 nvhost_ctrl_gpu::ZBCQueryTable(const std::vector<u8>& input, std::vector<u8>& output) {
144 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); 144 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
145 IoctlZbcQueryTable params{}; 145 IoctlZbcQueryTable params{};
146 std::memcpy(&params, input.data(), input.size()); 146 std::memcpy(&params, input.data(), input.size());
147 // TODO : To implement properly 147 // TODO : To implement properly
@@ -150,7 +150,7 @@ u32 nvhost_ctrl_gpu::ZBCQueryTable(const std::vector<u8>& input, std::vector<u8>
150} 150}
151 151
152u32 nvhost_ctrl_gpu::FlushL2(const std::vector<u8>& input, std::vector<u8>& output) { 152u32 nvhost_ctrl_gpu::FlushL2(const std::vector<u8>& input, std::vector<u8>& output) {
153 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); 153 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
154 IoctlFlushL2 params{}; 154 IoctlFlushL2 params{};
155 std::memcpy(&params, input.data(), input.size()); 155 std::memcpy(&params, input.data(), input.size());
156 // TODO : To implement properly 156 // TODO : To implement properly
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index ed7b6dc03..8de870596 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -12,8 +12,8 @@
12namespace Service::Nvidia::Devices { 12namespace Service::Nvidia::Devices {
13 13
14u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 14u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
15 NGLOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 15 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
16 command.raw, input.size(), output.size()); 16 command.raw, input.size(), output.size());
17 17
18 switch (static_cast<IoctlCommand>(command.raw)) { 18 switch (static_cast<IoctlCommand>(command.raw)) {
19 case IoctlCommand::IocSetNVMAPfdCommand: 19 case IoctlCommand::IocSetNVMAPfdCommand:
@@ -51,13 +51,13 @@ u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u
51u32 nvhost_gpu::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { 51u32 nvhost_gpu::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
52 IoctlSetNvmapFD params{}; 52 IoctlSetNvmapFD params{};
53 std::memcpy(&params, input.data(), input.size()); 53 std::memcpy(&params, input.data(), input.size());
54 NGLOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); 54 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
55 nvmap_fd = params.nvmap_fd; 55 nvmap_fd = params.nvmap_fd;
56 return 0; 56 return 0;
57} 57}
58 58
59u32 nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& output) { 59u32 nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& output) {
60 NGLOG_DEBUG(Service_NVDRV, "called"); 60 LOG_DEBUG(Service_NVDRV, "called");
61 IoctlClientData params{}; 61 IoctlClientData params{};
62 std::memcpy(&params, input.data(), input.size()); 62 std::memcpy(&params, input.data(), input.size());
63 user_data = params.data; 63 user_data = params.data;
@@ -65,7 +65,7 @@ u32 nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& out
65} 65}
66 66
67u32 nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& output) { 67u32 nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& output) {
68 NGLOG_DEBUG(Service_NVDRV, "called"); 68 LOG_DEBUG(Service_NVDRV, "called");
69 IoctlClientData params{}; 69 IoctlClientData params{};
70 std::memcpy(&params, input.data(), input.size()); 70 std::memcpy(&params, input.data(), input.size());
71 params.data = user_data; 71 params.data = user_data;
@@ -75,8 +75,8 @@ u32 nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& out
75 75
76u32 nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output) { 76u32 nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output) {
77 std::memcpy(&zcull_params, input.data(), input.size()); 77 std::memcpy(&zcull_params, input.data(), input.size());
78 NGLOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, 78 LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va,
79 zcull_params.mode); 79 zcull_params.mode);
80 std::memcpy(output.data(), &zcull_params, output.size()); 80 std::memcpy(output.data(), &zcull_params, output.size());
81 return 0; 81 return 0;
82} 82}
@@ -84,26 +84,26 @@ u32 nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output)
84u32 nvhost_gpu::SetErrorNotifier(const std::vector<u8>& input, std::vector<u8>& output) { 84u32 nvhost_gpu::SetErrorNotifier(const std::vector<u8>& input, std::vector<u8>& output) {
85 IoctlSetErrorNotifier params{}; 85 IoctlSetErrorNotifier params{};
86 std::memcpy(&params, input.data(), input.size()); 86 std::memcpy(&params, input.data(), input.size());
87 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", 87 LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset,
88 params.offset, params.size, params.mem); 88 params.size, params.mem);
89 std::memcpy(output.data(), &params, output.size()); 89 std::memcpy(output.data(), &params, output.size());
90 return 0; 90 return 0;
91} 91}
92 92
93u32 nvhost_gpu::SetChannelPriority(const std::vector<u8>& input, std::vector<u8>& output) { 93u32 nvhost_gpu::SetChannelPriority(const std::vector<u8>& input, std::vector<u8>& output) {
94 std::memcpy(&channel_priority, input.data(), input.size()); 94 std::memcpy(&channel_priority, input.data(), input.size());
95 NGLOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); 95 LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority);
96 return 0; 96 return 0;
97} 97}
98 98
99u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output) { 99u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output) {
100 IoctlAllocGpfifoEx2 params{}; 100 IoctlAllocGpfifoEx2 params{};
101 std::memcpy(&params, input.data(), input.size()); 101 std::memcpy(&params, input.data(), input.size());
102 NGLOG_WARNING(Service_NVDRV, 102 LOG_WARNING(Service_NVDRV,
103 "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " 103 "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, "
104 "unk1={:X}, unk2={:X}, unk3={:X}", 104 "unk1={:X}, unk2={:X}, unk3={:X}",
105 params.num_entries, params.flags, params.unk0, params.unk1, params.unk2, 105 params.num_entries, params.flags, params.unk0, params.unk1, params.unk2,
106 params.unk3); 106 params.unk3);
107 params.fence_out.id = 0; 107 params.fence_out.id = 0;
108 params.fence_out.value = 0; 108 params.fence_out.value = 0;
109 std::memcpy(output.data(), &params, output.size()); 109 std::memcpy(output.data(), &params, output.size());
@@ -113,8 +113,8 @@ u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& ou
113u32 nvhost_gpu::AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output) { 113u32 nvhost_gpu::AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output) {
114 IoctlAllocObjCtx params{}; 114 IoctlAllocObjCtx params{};
115 std::memcpy(&params, input.data(), input.size()); 115 std::memcpy(&params, input.data(), input.size());
116 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, 116 LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num,
117 params.flags); 117 params.flags);
118 params.obj_id = 0x0; 118 params.obj_id = 0x0;
119 std::memcpy(output.data(), &params, output.size()); 119 std::memcpy(output.data(), &params, output.size());
120 return 0; 120 return 0;
@@ -126,8 +126,8 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
126 } 126 }
127 IoctlSubmitGpfifo params{}; 127 IoctlSubmitGpfifo params{};
128 std::memcpy(&params, input.data(), sizeof(IoctlSubmitGpfifo)); 128 std::memcpy(&params, input.data(), sizeof(IoctlSubmitGpfifo));
129 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", 129 LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}",
130 params.gpfifo, params.num_entries, params.flags); 130 params.gpfifo, params.num_entries, params.flags);
131 131
132 auto entries = std::vector<IoctlGpfifoEntry>(); 132 auto entries = std::vector<IoctlGpfifoEntry>();
133 entries.resize(params.num_entries); 133 entries.resize(params.num_entries);
@@ -146,7 +146,7 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
146u32 nvhost_gpu::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { 146u32 nvhost_gpu::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
147 IoctlGetWaitbase params{}; 147 IoctlGetWaitbase params{};
148 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase)); 148 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
149 NGLOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); 149 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
150 params.value = 0; // Seems to be hard coded at 0 150 params.value = 0; // Seems to be hard coded at 0
151 std::memcpy(output.data(), &params, output.size()); 151 std::memcpy(output.data(), &params, output.size());
152 return 0; 152 return 0;
@@ -155,7 +155,7 @@ u32 nvhost_gpu::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& outpu
155u32 nvhost_gpu::ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output) { 155u32 nvhost_gpu::ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output) {
156 IoctlChannelSetTimeout params{}; 156 IoctlChannelSetTimeout params{};
157 std::memcpy(&params, input.data(), sizeof(IoctlChannelSetTimeout)); 157 std::memcpy(&params, input.data(), sizeof(IoctlChannelSetTimeout));
158 NGLOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout); 158 LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout);
159 return 0; 159 return 0;
160} 160}
161 161
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index 0b6c22898..b51c73ee8 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -9,8 +9,8 @@
9namespace Service::Nvidia::Devices { 9namespace Service::Nvidia::Devices {
10 10
11u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { 11u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
12 NGLOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 12 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
13 command.raw, input.size(), output.size()); 13 command.raw, input.size(), output.size());
14 14
15 switch (static_cast<IoctlCommand>(command.raw)) { 15 switch (static_cast<IoctlCommand>(command.raw)) {
16 case IoctlCommand::IocSetNVMAPfdCommand: 16 case IoctlCommand::IocSetNVMAPfdCommand:
@@ -24,7 +24,7 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector
24u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { 24u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
25 IoctlSetNvmapFD params{}; 25 IoctlSetNvmapFD params{};
26 std::memcpy(&params, input.data(), input.size()); 26 std::memcpy(&params, input.data(), input.size());
27 NGLOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); 27 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
28 nvmap_fd = params.nvmap_fd; 28 nvmap_fd = params.nvmap_fd;
29 return 0; 29 return 0;
30} 30}
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 23fe98190..724eeb139 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -52,7 +52,7 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
52 u32 handle = next_handle++; 52 u32 handle = next_handle++;
53 handles[handle] = std::move(object); 53 handles[handle] = std::move(object);
54 54
55 NGLOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size); 55 LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
56 56
57 params.handle = handle; 57 params.handle = handle;
58 58
@@ -73,7 +73,7 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
73 object->addr = params.addr; 73 object->addr = params.addr;
74 object->status = Object::Status::Allocated; 74 object->status = Object::Status::Allocated;
75 75
76 NGLOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr); 76 LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
77 77
78 std::memcpy(output.data(), &params, sizeof(params)); 78 std::memcpy(output.data(), &params, sizeof(params));
79 return 0; 79 return 0;
@@ -83,7 +83,7 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) {
83 IocGetIdParams params; 83 IocGetIdParams params;
84 std::memcpy(&params, input.data(), sizeof(params)); 84 std::memcpy(&params, input.data(), sizeof(params));
85 85
86 NGLOG_WARNING(Service_NVDRV, "called"); 86 LOG_WARNING(Service_NVDRV, "called");
87 87
88 auto object = GetObject(params.handle); 88 auto object = GetObject(params.handle);
89 ASSERT(object); 89 ASSERT(object);
@@ -98,7 +98,7 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
98 IocFromIdParams params; 98 IocFromIdParams params;
99 std::memcpy(&params, input.data(), sizeof(params)); 99 std::memcpy(&params, input.data(), sizeof(params));
100 100
101 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); 101 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
102 102
103 auto itr = std::find_if(handles.begin(), handles.end(), 103 auto itr = std::find_if(handles.begin(), handles.end(),
104 [&](const auto& entry) { return entry.second->id == params.id; }); 104 [&](const auto& entry) { return entry.second->id == params.id; });
@@ -119,7 +119,7 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
119 IocParamParams params; 119 IocParamParams params;
120 std::memcpy(&params, input.data(), sizeof(params)); 120 std::memcpy(&params, input.data(), sizeof(params));
121 121
122 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param); 122 LOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param);
123 123
124 auto object = GetObject(params.handle); 124 auto object = GetObject(params.handle);
125 ASSERT(object); 125 ASSERT(object);
@@ -148,6 +148,7 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
148} 148}
149 149
150u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) { 150u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
151 // TODO(Subv): These flags are unconfirmed.
151 enum FreeFlags { 152 enum FreeFlags {
152 Freed = 0, 153 Freed = 0,
153 NotFreedYet = 1, 154 NotFreedYet = 1,
@@ -156,20 +157,26 @@ u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
156 IocFreeParams params; 157 IocFreeParams params;
157 std::memcpy(&params, input.data(), sizeof(params)); 158 std::memcpy(&params, input.data(), sizeof(params));
158 159
159 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); 160 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
160 161
161 auto itr = handles.find(params.handle); 162 auto itr = handles.find(params.handle);
162 ASSERT(itr != handles.end()); 163 ASSERT(itr != handles.end());
163 164
165 ASSERT(itr->second->refcount > 0);
166
164 itr->second->refcount--; 167 itr->second->refcount--;
165 168
166 params.refcount = itr->second->refcount;
167 params.size = itr->second->size; 169 params.size = itr->second->size;
168 170
169 if (itr->second->refcount == 0) 171 if (itr->second->refcount == 0) {
170 params.flags = Freed; 172 params.flags = Freed;
171 else 173 // The address of the nvmap is written to the output if we're finally freeing it, otherwise
174 // 0 is written.
175 params.address = itr->second->addr;
176 } else {
172 params.flags = NotFreedYet; 177 params.flags = NotFreedYet;
178 params.address = 0;
179 }
173 180
174 handles.erase(params.handle); 181 handles.erase(params.handle);
175 182
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h
index 39fafaa7c..f2eec6409 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.h
+++ b/src/core/hle/service/nvdrv/devices/nvmap.h
@@ -94,7 +94,7 @@ private:
94 struct IocFreeParams { 94 struct IocFreeParams {
95 u32_le handle; 95 u32_le handle;
96 INSERT_PADDING_BYTES(4); 96 INSERT_PADDING_BYTES(4);
97 u64_le refcount; 97 u64_le address;
98 u32_le size; 98 u32_le size;
99 u32_le flags; 99 u32_le flags;
100 }; 100 };
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index 45d2862ef..b10efd5c9 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -12,7 +12,7 @@
12namespace Service::Nvidia { 12namespace Service::Nvidia {
13 13
14void NVDRV::Open(Kernel::HLERequestContext& ctx) { 14void NVDRV::Open(Kernel::HLERequestContext& ctx) {
15 NGLOG_DEBUG(Service_NVDRV, "called"); 15 LOG_DEBUG(Service_NVDRV, "called");
16 16
17 const auto& buffer = ctx.ReadBuffer(); 17 const auto& buffer = ctx.ReadBuffer();
18 std::string device_name(buffer.begin(), buffer.end()); 18 std::string device_name(buffer.begin(), buffer.end());
@@ -25,7 +25,7 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) {
25} 25}
26 26
27void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { 27void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
28 NGLOG_DEBUG(Service_NVDRV, "called"); 28 LOG_DEBUG(Service_NVDRV, "called");
29 29
30 IPC::RequestParser rp{ctx}; 30 IPC::RequestParser rp{ctx};
31 u32 fd = rp.Pop<u32>(); 31 u32 fd = rp.Pop<u32>();
@@ -41,7 +41,7 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
41} 41}
42 42
43void NVDRV::Close(Kernel::HLERequestContext& ctx) { 43void NVDRV::Close(Kernel::HLERequestContext& ctx) {
44 NGLOG_DEBUG(Service_NVDRV, "called"); 44 LOG_DEBUG(Service_NVDRV, "called");
45 45
46 IPC::RequestParser rp{ctx}; 46 IPC::RequestParser rp{ctx};
47 u32 fd = rp.Pop<u32>(); 47 u32 fd = rp.Pop<u32>();
@@ -53,7 +53,7 @@ void NVDRV::Close(Kernel::HLERequestContext& ctx) {
53} 53}
54 54
55void NVDRV::Initialize(Kernel::HLERequestContext& ctx) { 55void NVDRV::Initialize(Kernel::HLERequestContext& ctx) {
56 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); 56 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
57 IPC::ResponseBuilder rb{ctx, 3}; 57 IPC::ResponseBuilder rb{ctx, 3};
58 rb.Push(RESULT_SUCCESS); 58 rb.Push(RESULT_SUCCESS);
59 rb.Push<u32>(0); 59 rb.Push<u32>(0);
@@ -63,7 +63,7 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
63 IPC::RequestParser rp{ctx}; 63 IPC::RequestParser rp{ctx};
64 u32 fd = rp.Pop<u32>(); 64 u32 fd = rp.Pop<u32>();
65 u32 event_id = rp.Pop<u32>(); 65 u32 event_id = rp.Pop<u32>();
66 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, fd={:X}, event_id={:X}", fd, event_id); 66 LOG_WARNING(Service_NVDRV, "(STUBBED) called, fd={:X}, event_id={:X}", fd, event_id);
67 67
68 IPC::ResponseBuilder rb{ctx, 3, 1}; 68 IPC::ResponseBuilder rb{ctx, 3, 1};
69 rb.Push(RESULT_SUCCESS); 69 rb.Push(RESULT_SUCCESS);
@@ -75,14 +75,14 @@ void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) {
75 IPC::RequestParser rp{ctx}; 75 IPC::RequestParser rp{ctx};
76 pid = rp.Pop<u64>(); 76 pid = rp.Pop<u64>();
77 77
78 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x{:X}", pid); 78 LOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x{:X}", pid);
79 IPC::ResponseBuilder rb{ctx, 3}; 79 IPC::ResponseBuilder rb{ctx, 3};
80 rb.Push(RESULT_SUCCESS); 80 rb.Push(RESULT_SUCCESS);
81 rb.Push<u32>(0); 81 rb.Push<u32>(0);
82} 82}
83 83
84void NVDRV::FinishInitialize(Kernel::HLERequestContext& ctx) { 84void NVDRV::FinishInitialize(Kernel::HLERequestContext& ctx) {
85 NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); 85 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
86 IPC::ResponseBuilder rb{ctx, 2}; 86 IPC::ResponseBuilder rb{ctx, 2};
87 rb.Push(RESULT_SUCCESS); 87 rb.Push(RESULT_SUCCESS);
88} 88}
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index 49e88b394..f7f2fe1b2 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -23,7 +23,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) {
23 buffer.igbp_buffer = igbp_buffer; 23 buffer.igbp_buffer = igbp_buffer;
24 buffer.status = Buffer::Status::Free; 24 buffer.status = Buffer::Status::Free;
25 25
26 NGLOG_WARNING(Service, "Adding graphics buffer {}", slot); 26 LOG_WARNING(Service, "Adding graphics buffer {}", slot);
27 27
28 queue.emplace_back(buffer); 28 queue.emplace_back(buffer);
29 29
@@ -94,7 +94,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) {
94} 94}
95 95
96u32 BufferQueue::Query(QueryType type) { 96u32 BufferQueue::Query(QueryType type) {
97 NGLOG_WARNING(Service, "(STUBBED) called type={}", static_cast<u32>(type)); 97 LOG_WARNING(Service, "(STUBBED) called type={}", static_cast<u32>(type));
98 switch (type) { 98 switch (type) {
99 case QueryType::NativeWindowFormat: 99 case QueryType::NativeWindowFormat:
100 // TODO(Subv): Use an enum for this 100 // TODO(Subv): Use an enum for this
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 5c50ed601..ef3c2cc98 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -48,7 +48,7 @@ NVFlinger::~NVFlinger() {
48} 48}
49 49
50u64 NVFlinger::OpenDisplay(const std::string& name) { 50u64 NVFlinger::OpenDisplay(const std::string& name) {
51 NGLOG_WARNING(Service, "Opening display {}", name); 51 LOG_WARNING(Service, "Opening display {}", name);
52 52
53 // TODO(Subv): Currently we only support the Default display. 53 // TODO(Subv): Currently we only support the Default display.
54 ASSERT(name == "Default"); 54 ASSERT(name == "Default");
diff --git a/src/core/hle/service/pctl/module.cpp b/src/core/hle/service/pctl/module.cpp
index dd20d5ae7..fcf1f3da3 100644
--- a/src/core/hle/service/pctl/module.cpp
+++ b/src/core/hle/service/pctl/module.cpp
@@ -112,7 +112,7 @@ public:
112 112
113private: 113private:
114 void Initialize(Kernel::HLERequestContext& ctx) { 114 void Initialize(Kernel::HLERequestContext& ctx) {
115 NGLOG_WARNING(Service_PCTL, "(STUBBED) called"); 115 LOG_WARNING(Service_PCTL, "(STUBBED) called");
116 IPC::ResponseBuilder rb{ctx, 2, 0, 0}; 116 IPC::ResponseBuilder rb{ctx, 2, 0, 0};
117 rb.Push(RESULT_SUCCESS); 117 rb.Push(RESULT_SUCCESS);
118 } 118 }
@@ -122,14 +122,14 @@ void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) {
122 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 122 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
123 rb.Push(RESULT_SUCCESS); 123 rb.Push(RESULT_SUCCESS);
124 rb.PushIpcInterface<IParentalControlService>(); 124 rb.PushIpcInterface<IParentalControlService>();
125 NGLOG_DEBUG(Service_PCTL, "called"); 125 LOG_DEBUG(Service_PCTL, "called");
126} 126}
127 127
128void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) { 128void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) {
129 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 129 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
130 rb.Push(RESULT_SUCCESS); 130 rb.Push(RESULT_SUCCESS);
131 rb.PushIpcInterface<IParentalControlService>(); 131 rb.PushIpcInterface<IParentalControlService>();
132 NGLOG_DEBUG(Service_PCTL, "called"); 132 LOG_DEBUG(Service_PCTL, "called");
133} 133}
134 134
135Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) 135Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index eaf30ee6b..3c43b8d8c 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -27,7 +27,7 @@ PlayReport::PlayReport(const char* name) : ServiceFramework(name) {
27 27
28void PlayReport::SaveReportWithUser(Kernel::HLERequestContext& ctx) { 28void PlayReport::SaveReportWithUser(Kernel::HLERequestContext& ctx) {
29 // TODO(ogniK): Do we want to add play report? 29 // TODO(ogniK): Do we want to add play report?
30 NGLOG_WARNING(Service_PREPO, "(STUBBED) called"); 30 LOG_WARNING(Service_PREPO, "(STUBBED) called");
31 31
32 IPC::ResponseBuilder rb{ctx, 2}; 32 IPC::ResponseBuilder rb{ctx, 2};
33 rb.Push(RESULT_SUCCESS); 33 rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index bdd9eb5a5..0d036bfaa 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -122,7 +122,7 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext
122 } 122 }
123 buf.push_back('}'); 123 buf.push_back('}');
124 124
125 NGLOG_ERROR(Service, "unknown / unimplemented {}", fmt::to_string(buf)); 125 LOG_ERROR(Service, "unknown / unimplemented {}", fmt::to_string(buf));
126 UNIMPLEMENTED(); 126 UNIMPLEMENTED();
127} 127}
128 128
@@ -133,7 +133,7 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) {
133 return ReportUnimplementedFunction(ctx, info); 133 return ReportUnimplementedFunction(ctx, info);
134 } 134 }
135 135
136 NGLOG_TRACE( 136 LOG_TRACE(
137 Service, "{}", 137 Service, "{}",
138 MakeFunctionString(info->name, GetServiceName().c_str(), ctx.CommandBuffer()).c_str()); 138 MakeFunctionString(info->name, GetServiceName().c_str(), ctx.CommandBuffer()).c_str());
139 handler_invoker(this, info->handler_callback, ctx); 139 handler_invoker(this, info->handler_callback, ctx);
@@ -206,12 +206,12 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
206 VI::InstallInterfaces(*sm, nv_flinger); 206 VI::InstallInterfaces(*sm, nv_flinger);
207 Set::InstallInterfaces(*sm); 207 Set::InstallInterfaces(*sm);
208 208
209 NGLOG_DEBUG(Service, "initialized OK"); 209 LOG_DEBUG(Service, "initialized OK");
210} 210}
211 211
212/// Shutdown ServiceManager 212/// Shutdown ServiceManager
213void Shutdown() { 213void Shutdown() {
214 g_kernel_named_ports.clear(); 214 g_kernel_named_ports.clear();
215 NGLOG_DEBUG(Service, "shutdown OK"); 215 LOG_DEBUG(Service, "shutdown OK");
216} 216}
217} // namespace Service 217} // namespace Service
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index baeecb0ec..bd295cdf6 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -37,7 +37,7 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
37 rb.Push(RESULT_SUCCESS); 37 rb.Push(RESULT_SUCCESS);
38 rb.Push(static_cast<u64>(available_language_codes.size())); 38 rb.Push(static_cast<u64>(available_language_codes.size()));
39 39
40 NGLOG_DEBUG(Service_SET, "called"); 40 LOG_DEBUG(Service_SET, "called");
41} 41}
42 42
43SET::SET() : ServiceFramework("set") { 43SET::SET() : ServiceFramework("set") {
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index 762a664c5..fa85277fe 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -16,7 +16,7 @@ void SET_SYS::GetColorSetId(Kernel::HLERequestContext& ctx) {
16 rb.Push(RESULT_SUCCESS); 16 rb.Push(RESULT_SUCCESS);
17 rb.Push<u32>(0); 17 rb.Push<u32>(0);
18 18
19 NGLOG_WARNING(Service_SET, "(STUBBED) called"); 19 LOG_WARNING(Service_SET, "(STUBBED) called");
20} 20}
21 21
22SET_SYS::SET_SYS() : ServiceFramework("set:sys") { 22SET_SYS::SET_SYS() : ServiceFramework("set:sys") {
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp
index fe5097cdc..518a0cc46 100644
--- a/src/core/hle/service/sm/controller.cpp
+++ b/src/core/hle/service/sm/controller.cpp
@@ -17,7 +17,7 @@ void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) {
17 rb.Push(RESULT_SUCCESS); 17 rb.Push(RESULT_SUCCESS);
18 rb.Push<u32>(1); // Converted sessions start with 1 request handler 18 rb.Push<u32>(1); // Converted sessions start with 1 request handler
19 19
20 NGLOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId()); 20 LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId());
21} 21}
22 22
23void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { 23void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) {
@@ -29,11 +29,11 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) {
29 Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->parent->client}; 29 Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->parent->client};
30 rb.PushMoveObjects(session); 30 rb.PushMoveObjects(session);
31 31
32 NGLOG_DEBUG(Service, "called, session={}", session->GetObjectId()); 32 LOG_DEBUG(Service, "called, session={}", session->GetObjectId());
33} 33}
34 34
35void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) { 35void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) {
36 NGLOG_WARNING(Service, "(STUBBED) called, using DuplicateSession"); 36 LOG_WARNING(Service, "(STUBBED) called, using DuplicateSession");
37 37
38 DuplicateSession(ctx); 38 DuplicateSession(ctx);
39} 39}
@@ -43,7 +43,7 @@ void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) {
43 rb.Push(RESULT_SUCCESS); 43 rb.Push(RESULT_SUCCESS);
44 rb.Push<u32>(0x500); 44 rb.Push<u32>(0x500);
45 45
46 NGLOG_WARNING(Service, "(STUBBED) called"); 46 LOG_WARNING(Service, "(STUBBED) called");
47} 47}
48 48
49Controller::Controller() : ServiceFramework("IpcController") { 49Controller::Controller() : ServiceFramework("IpcController") {
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index bded8421f..f22a2a79f 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -86,7 +86,7 @@ SM::~SM() = default;
86void SM::Initialize(Kernel::HLERequestContext& ctx) { 86void SM::Initialize(Kernel::HLERequestContext& ctx) {
87 IPC::ResponseBuilder rb{ctx, 2}; 87 IPC::ResponseBuilder rb{ctx, 2};
88 rb.Push(RESULT_SUCCESS); 88 rb.Push(RESULT_SUCCESS);
89 NGLOG_DEBUG(Service_SM, "called"); 89 LOG_DEBUG(Service_SM, "called");
90} 90}
91 91
92void SM::GetService(Kernel::HLERequestContext& ctx) { 92void SM::GetService(Kernel::HLERequestContext& ctx) {
@@ -102,8 +102,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
102 if (client_port.Failed()) { 102 if (client_port.Failed()) {
103 IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); 103 IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);
104 rb.Push(client_port.Code()); 104 rb.Push(client_port.Code());
105 NGLOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, 105 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, client_port.Code().raw);
106 client_port.Code().raw);
107 if (name.length() == 0) 106 if (name.length() == 0)
108 return; // LibNX Fix 107 return; // LibNX Fix
109 UNIMPLEMENTED(); 108 UNIMPLEMENTED();
@@ -113,7 +112,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
113 auto session = client_port.Unwrap()->Connect(); 112 auto session = client_port.Unwrap()->Connect();
114 ASSERT(session.Succeeded()); 113 ASSERT(session.Succeeded());
115 if (session.Succeeded()) { 114 if (session.Succeeded()) {
116 NGLOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId()); 115 LOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId());
117 IPC::ResponseBuilder rb = 116 IPC::ResponseBuilder rb =
118 rp.MakeBuilder(2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles); 117 rp.MakeBuilder(2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles);
119 rb.Push(session.Code()); 118 rb.Push(session.Code());
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index ab909fdaa..32648bdd9 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -8,7 +8,7 @@
8namespace Service::Sockets { 8namespace Service::Sockets {
9 9
10void BSD::RegisterClient(Kernel::HLERequestContext& ctx) { 10void BSD::RegisterClient(Kernel::HLERequestContext& ctx) {
11 NGLOG_WARNING(Service, "(STUBBED) called"); 11 LOG_WARNING(Service, "(STUBBED) called");
12 12
13 IPC::ResponseBuilder rb{ctx, 3}; 13 IPC::ResponseBuilder rb{ctx, 3};
14 14
@@ -17,7 +17,7 @@ void BSD::RegisterClient(Kernel::HLERequestContext& ctx) {
17} 17}
18 18
19void BSD::StartMonitoring(Kernel::HLERequestContext& ctx) { 19void BSD::StartMonitoring(Kernel::HLERequestContext& ctx) {
20 NGLOG_WARNING(Service, "(STUBBED) called"); 20 LOG_WARNING(Service, "(STUBBED) called");
21 21
22 IPC::ResponseBuilder rb{ctx, 3}; 22 IPC::ResponseBuilder rb{ctx, 3};
23 23
@@ -32,8 +32,7 @@ void BSD::Socket(Kernel::HLERequestContext& ctx) {
32 u32 type = rp.Pop<u32>(); 32 u32 type = rp.Pop<u32>();
33 u32 protocol = rp.Pop<u32>(); 33 u32 protocol = rp.Pop<u32>();
34 34
35 NGLOG_WARNING(Service, "(STUBBED) called domain={} type={} protocol={}", domain, type, 35 LOG_WARNING(Service, "(STUBBED) called domain={} type={} protocol={}", domain, type, protocol);
36 protocol);
37 36
38 u32 fd = next_fd++; 37 u32 fd = next_fd++;
39 38
@@ -45,7 +44,7 @@ void BSD::Socket(Kernel::HLERequestContext& ctx) {
45} 44}
46 45
47void BSD::Connect(Kernel::HLERequestContext& ctx) { 46void BSD::Connect(Kernel::HLERequestContext& ctx) {
48 NGLOG_WARNING(Service, "(STUBBED) called"); 47 LOG_WARNING(Service, "(STUBBED) called");
49 48
50 IPC::ResponseBuilder rb{ctx, 4}; 49 IPC::ResponseBuilder rb{ctx, 4};
51 50
@@ -55,7 +54,7 @@ void BSD::Connect(Kernel::HLERequestContext& ctx) {
55} 54}
56 55
57void BSD::SendTo(Kernel::HLERequestContext& ctx) { 56void BSD::SendTo(Kernel::HLERequestContext& ctx) {
58 NGLOG_WARNING(Service, "(STUBBED) called"); 57 LOG_WARNING(Service, "(STUBBED) called");
59 58
60 IPC::ResponseBuilder rb{ctx, 4}; 59 IPC::ResponseBuilder rb{ctx, 4};
61 60
@@ -65,7 +64,7 @@ void BSD::SendTo(Kernel::HLERequestContext& ctx) {
65} 64}
66 65
67void BSD::Close(Kernel::HLERequestContext& ctx) { 66void BSD::Close(Kernel::HLERequestContext& ctx) {
68 NGLOG_WARNING(Service, "(STUBBED) called"); 67 LOG_WARNING(Service, "(STUBBED) called");
69 68
70 IPC::ResponseBuilder rb{ctx, 4}; 69 IPC::ResponseBuilder rb{ctx, 4};
71 70
diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp
index f377e59f2..d235c4cfd 100644
--- a/src/core/hle/service/sockets/sfdnsres.cpp
+++ b/src/core/hle/service/sockets/sfdnsres.cpp
@@ -10,7 +10,7 @@ namespace Service::Sockets {
10void SFDNSRES::GetAddrInfo(Kernel::HLERequestContext& ctx) { 10void SFDNSRES::GetAddrInfo(Kernel::HLERequestContext& ctx) {
11 IPC::RequestParser rp{ctx}; 11 IPC::RequestParser rp{ctx};
12 12
13 NGLOG_WARNING(Service, "(STUBBED) called"); 13 LOG_WARNING(Service, "(STUBBED) called");
14 14
15 IPC::ResponseBuilder rb{ctx, 2}; 15 IPC::ResponseBuilder rb{ctx, 2};
16 16
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp
index 76ba97156..3f5a342a7 100644
--- a/src/core/hle/service/spl/module.cpp
+++ b/src/core/hle/service/spl/module.cpp
@@ -28,7 +28,7 @@ void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
28 28
29 IPC::ResponseBuilder rb{ctx, 2}; 29 IPC::ResponseBuilder rb{ctx, 2};
30 rb.Push(RESULT_SUCCESS); 30 rb.Push(RESULT_SUCCESS);
31 NGLOG_DEBUG(Service_SPL, "called"); 31 LOG_DEBUG(Service_SPL, "called");
32} 32}
33 33
34void InstallInterfaces(SM::ServiceManager& service_manager) { 34void InstallInterfaces(SM::ServiceManager& service_manager) {
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp
index b3dad8b06..40aea6090 100644
--- a/src/core/hle/service/ssl/ssl.cpp
+++ b/src/core/hle/service/ssl/ssl.cpp
@@ -65,7 +65,7 @@ public:
65 65
66private: 66private:
67 void SetOption(Kernel::HLERequestContext& ctx) { 67 void SetOption(Kernel::HLERequestContext& ctx) {
68 NGLOG_WARNING(Service_SSL, "(STUBBED) called"); 68 LOG_WARNING(Service_SSL, "(STUBBED) called");
69 IPC::RequestParser rp{ctx}; 69 IPC::RequestParser rp{ctx};
70 70
71 IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); 71 IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);
@@ -73,7 +73,7 @@ private:
73 } 73 }
74 74
75 void CreateConnection(Kernel::HLERequestContext& ctx) { 75 void CreateConnection(Kernel::HLERequestContext& ctx) {
76 NGLOG_WARNING(Service_SSL, "(STUBBED) called"); 76 LOG_WARNING(Service_SSL, "(STUBBED) called");
77 77
78 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 78 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
79 rb.Push(RESULT_SUCCESS); 79 rb.Push(RESULT_SUCCESS);
@@ -82,7 +82,7 @@ private:
82}; 82};
83 83
84void SSL::CreateContext(Kernel::HLERequestContext& ctx) { 84void SSL::CreateContext(Kernel::HLERequestContext& ctx) {
85 NGLOG_WARNING(Service_SSL, "(STUBBED) called"); 85 LOG_WARNING(Service_SSL, "(STUBBED) called");
86 86
87 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 87 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
88 rb.Push(RESULT_SUCCESS); 88 rb.Push(RESULT_SUCCESS);
@@ -103,7 +103,7 @@ SSL::SSL() : ServiceFramework("ssl") {
103} 103}
104 104
105void SSL::SetInterfaceVersion(Kernel::HLERequestContext& ctx) { 105void SSL::SetInterfaceVersion(Kernel::HLERequestContext& ctx) {
106 NGLOG_WARNING(Service_SSL, "(STUBBED) called"); 106 LOG_WARNING(Service_SSL, "(STUBBED) called");
107 IPC::RequestParser rp{ctx}; 107 IPC::RequestParser rp{ctx};
108 u32 unk1 = rp.Pop<u32>(); // Probably minor/major? 108 u32 unk1 = rp.Pop<u32>(); // Probably minor/major?
109 u32 unk2 = rp.Pop<u32>(); // TODO(ogniK): Figure out what this does 109 u32 unk2 = rp.Pop<u32>(); // TODO(ogniK): Figure out what this does
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 654012189..507ae95f4 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -33,14 +33,14 @@ private:
33 const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>( 33 const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>(
34 std::chrono::system_clock::now().time_since_epoch()) 34 std::chrono::system_clock::now().time_since_epoch())
35 .count()}; 35 .count()};
36 NGLOG_DEBUG(Service_Time, "called"); 36 LOG_DEBUG(Service_Time, "called");
37 IPC::ResponseBuilder rb{ctx, 4}; 37 IPC::ResponseBuilder rb{ctx, 4};
38 rb.Push(RESULT_SUCCESS); 38 rb.Push(RESULT_SUCCESS);
39 rb.Push<u64>(time_since_epoch); 39 rb.Push<u64>(time_since_epoch);
40 } 40 }
41 41
42 void GetSystemClockContext(Kernel::HLERequestContext& ctx) { 42 void GetSystemClockContext(Kernel::HLERequestContext& ctx) {
43 NGLOG_WARNING(Service_Time, "(STUBBED) called"); 43 LOG_WARNING(Service_Time, "(STUBBED) called");
44 SystemClockContext system_clock_ontext{}; 44 SystemClockContext system_clock_ontext{};
45 IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2}; 45 IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2};
46 rb.Push(RESULT_SUCCESS); 46 rb.Push(RESULT_SUCCESS);
@@ -59,7 +59,7 @@ public:
59 59
60private: 60private:
61 void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) { 61 void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) {
62 NGLOG_DEBUG(Service_Time, "called"); 62 LOG_DEBUG(Service_Time, "called");
63 SteadyClockTimePoint steady_clock_time_point{ 63 SteadyClockTimePoint steady_clock_time_point{
64 CoreTiming::cyclesToMs(CoreTiming::GetTicks()) / 1000}; 64 CoreTiming::cyclesToMs(CoreTiming::GetTicks()) / 1000};
65 IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2}; 65 IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2};
@@ -91,21 +91,21 @@ private:
91 TimeZoneRule my_time_zone_rule{}; 91 TimeZoneRule my_time_zone_rule{};
92 92
93 void GetDeviceLocationName(Kernel::HLERequestContext& ctx) { 93 void GetDeviceLocationName(Kernel::HLERequestContext& ctx) {
94 NGLOG_DEBUG(Service_Time, "called"); 94 LOG_DEBUG(Service_Time, "called");
95 IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2}; 95 IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2};
96 rb.Push(RESULT_SUCCESS); 96 rb.Push(RESULT_SUCCESS);
97 rb.PushRaw(location_name); 97 rb.PushRaw(location_name);
98 } 98 }
99 99
100 void GetTotalLocationNameCount(Kernel::HLERequestContext& ctx) { 100 void GetTotalLocationNameCount(Kernel::HLERequestContext& ctx) {
101 NGLOG_WARNING(Service_Time, "(STUBBED) called"); 101 LOG_WARNING(Service_Time, "(STUBBED) called");
102 IPC::ResponseBuilder rb{ctx, 3}; 102 IPC::ResponseBuilder rb{ctx, 3};
103 rb.Push(RESULT_SUCCESS); 103 rb.Push(RESULT_SUCCESS);
104 rb.Push<u32>(0); 104 rb.Push<u32>(0);
105 } 105 }
106 106
107 void LoadTimeZoneRule(Kernel::HLERequestContext& ctx) { 107 void LoadTimeZoneRule(Kernel::HLERequestContext& ctx) {
108 NGLOG_WARNING(Service_Time, "(STUBBED) called"); 108 LOG_WARNING(Service_Time, "(STUBBED) called");
109 109
110 ctx.WriteBuffer(&my_time_zone_rule, sizeof(TimeZoneRule)); 110 ctx.WriteBuffer(&my_time_zone_rule, sizeof(TimeZoneRule));
111 111
@@ -117,7 +117,7 @@ private:
117 IPC::RequestParser rp{ctx}; 117 IPC::RequestParser rp{ctx};
118 const u64 posix_time = rp.Pop<u64>(); 118 const u64 posix_time = rp.Pop<u64>();
119 119
120 NGLOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x{:016X}", posix_time); 120 LOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x{:016X}", posix_time);
121 121
122 TimeZoneRule time_zone_rule{}; 122 TimeZoneRule time_zone_rule{};
123 auto buffer = ctx.ReadBuffer(); 123 auto buffer = ctx.ReadBuffer();
@@ -138,7 +138,7 @@ private:
138 IPC::RequestParser rp{ctx}; 138 IPC::RequestParser rp{ctx};
139 const u64 posix_time = rp.Pop<u64>(); 139 const u64 posix_time = rp.Pop<u64>();
140 140
141 NGLOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x{:016X}", posix_time); 141 LOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x{:016X}", posix_time);
142 142
143 CalendarTime calendar_time{2018, 1, 1, 0, 0, 0}; 143 CalendarTime calendar_time{2018, 1, 1, 0, 0, 0};
144 CalendarAdditionalInfo additional_info{}; 144 CalendarAdditionalInfo additional_info{};
@@ -176,35 +176,35 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct
176 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 176 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
177 rb.Push(RESULT_SUCCESS); 177 rb.Push(RESULT_SUCCESS);
178 rb.PushIpcInterface<ISystemClock>(); 178 rb.PushIpcInterface<ISystemClock>();
179 NGLOG_DEBUG(Service_Time, "called"); 179 LOG_DEBUG(Service_Time, "called");
180} 180}
181 181
182void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) { 182void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) {
183 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 183 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
184 rb.Push(RESULT_SUCCESS); 184 rb.Push(RESULT_SUCCESS);
185 rb.PushIpcInterface<ISystemClock>(); 185 rb.PushIpcInterface<ISystemClock>();
186 NGLOG_DEBUG(Service_Time, "called"); 186 LOG_DEBUG(Service_Time, "called");
187} 187}
188 188
189void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { 189void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) {
190 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 190 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
191 rb.Push(RESULT_SUCCESS); 191 rb.Push(RESULT_SUCCESS);
192 rb.PushIpcInterface<ISteadyClock>(); 192 rb.PushIpcInterface<ISteadyClock>();
193 NGLOG_DEBUG(Service_Time, "called"); 193 LOG_DEBUG(Service_Time, "called");
194} 194}
195 195
196void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { 196void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
197 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 197 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
198 rb.Push(RESULT_SUCCESS); 198 rb.Push(RESULT_SUCCESS);
199 rb.PushIpcInterface<ITimeZoneService>(); 199 rb.PushIpcInterface<ITimeZoneService>();
200 NGLOG_DEBUG(Service_Time, "called"); 200 LOG_DEBUG(Service_Time, "called");
201} 201}
202 202
203void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { 203void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) {
204 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 204 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
205 rb.Push(RESULT_SUCCESS); 205 rb.Push(RESULT_SUCCESS);
206 rb.PushIpcInterface<ISystemClock>(); 206 rb.PushIpcInterface<ISystemClock>();
207 NGLOG_DEBUG(Service_Time, "called"); 207 LOG_DEBUG(Service_Time, "called");
208} 208}
209 209
210Module::Interface::Interface(std::shared_ptr<Module> time, const char* name) 210Module::Interface::Interface(std::shared_ptr<Module> time, const char* name)
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index e86556671..f3765b555 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -470,7 +470,7 @@ private:
470 u32 flags = rp.Pop<u32>(); 470 u32 flags = rp.Pop<u32>();
471 auto buffer_queue = nv_flinger->GetBufferQueue(id); 471 auto buffer_queue = nv_flinger->GetBufferQueue(id);
472 472
473 NGLOG_DEBUG(Service_VI, "called, transaction={:X}", static_cast<u32>(transaction)); 473 LOG_DEBUG(Service_VI, "called, transaction={:X}", static_cast<u32>(transaction));
474 474
475 if (transaction == TransactionId::Connect) { 475 if (transaction == TransactionId::Connect) {
476 IGBPConnectRequestParcel request{ctx.ReadBuffer()}; 476 IGBPConnectRequestParcel request{ctx.ReadBuffer()};
@@ -532,7 +532,7 @@ private:
532 IGBPQueryResponseParcel response{value}; 532 IGBPQueryResponseParcel response{value};
533 ctx.WriteBuffer(response.Serialize()); 533 ctx.WriteBuffer(response.Serialize());
534 } else if (transaction == TransactionId::CancelBuffer) { 534 } else if (transaction == TransactionId::CancelBuffer) {
535 NGLOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); 535 LOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer");
536 } else { 536 } else {
537 ASSERT_MSG(false, "Unimplemented"); 537 ASSERT_MSG(false, "Unimplemented");
538 } 538 }
@@ -547,8 +547,8 @@ private:
547 s32 addval = rp.PopRaw<s32>(); 547 s32 addval = rp.PopRaw<s32>();
548 u32 type = rp.Pop<u32>(); 548 u32 type = rp.Pop<u32>();
549 549
550 NGLOG_WARNING(Service_VI, "(STUBBED) called id={}, addval={:08X}, type={:08X}", id, addval, 550 LOG_WARNING(Service_VI, "(STUBBED) called id={}, addval={:08X}, type={:08X}", id, addval,
551 type); 551 type);
552 IPC::ResponseBuilder rb{ctx, 2}; 552 IPC::ResponseBuilder rb{ctx, 2};
553 rb.Push(RESULT_SUCCESS); 553 rb.Push(RESULT_SUCCESS);
554 } 554 }
@@ -562,7 +562,7 @@ private:
562 562
563 // TODO(Subv): Find out what this actually is. 563 // TODO(Subv): Find out what this actually is.
564 564
565 NGLOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown); 565 LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown);
566 IPC::ResponseBuilder rb{ctx, 2, 1}; 566 IPC::ResponseBuilder rb{ctx, 2, 1};
567 rb.Push(RESULT_SUCCESS); 567 rb.Push(RESULT_SUCCESS);
568 rb.PushCopyObjects(buffer_queue->GetNativeHandle()); 568 rb.PushCopyObjects(buffer_queue->GetNativeHandle());
@@ -625,7 +625,7 @@ public:
625 625
626private: 626private:
627 void SetLayerZ(Kernel::HLERequestContext& ctx) { 627 void SetLayerZ(Kernel::HLERequestContext& ctx) {
628 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 628 LOG_WARNING(Service_VI, "(STUBBED) called");
629 IPC::RequestParser rp{ctx}; 629 IPC::RequestParser rp{ctx};
630 u64 layer_id = rp.Pop<u64>(); 630 u64 layer_id = rp.Pop<u64>();
631 u64 z_value = rp.Pop<u64>(); 631 u64 z_value = rp.Pop<u64>();
@@ -640,8 +640,8 @@ private:
640 bool visibility = rp.Pop<bool>(); 640 bool visibility = rp.Pop<bool>();
641 IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); 641 IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);
642 rb.Push(RESULT_SUCCESS); 642 rb.Push(RESULT_SUCCESS);
643 NGLOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x{:08X}, visibility={}", layer_id, 643 LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x{:08X}, visibility={}", layer_id,
644 visibility); 644 visibility);
645 } 645 }
646}; 646};
647 647
@@ -723,7 +723,7 @@ public:
723 723
724private: 724private:
725 void CloseDisplay(Kernel::HLERequestContext& ctx) { 725 void CloseDisplay(Kernel::HLERequestContext& ctx) {
726 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 726 LOG_WARNING(Service_VI, "(STUBBED) called");
727 IPC::RequestParser rp{ctx}; 727 IPC::RequestParser rp{ctx};
728 u64 display = rp.Pop<u64>(); 728 u64 display = rp.Pop<u64>();
729 729
@@ -732,7 +732,7 @@ private:
732 } 732 }
733 733
734 void CreateManagedLayer(Kernel::HLERequestContext& ctx) { 734 void CreateManagedLayer(Kernel::HLERequestContext& ctx) {
735 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 735 LOG_WARNING(Service_VI, "(STUBBED) called");
736 IPC::RequestParser rp{ctx}; 736 IPC::RequestParser rp{ctx};
737 u32 unknown = rp.Pop<u32>(); 737 u32 unknown = rp.Pop<u32>();
738 rp.Skip(1, false); 738 rp.Skip(1, false);
@@ -747,7 +747,7 @@ private:
747 } 747 }
748 748
749 void AddToLayerStack(Kernel::HLERequestContext& ctx) { 749 void AddToLayerStack(Kernel::HLERequestContext& ctx) {
750 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 750 LOG_WARNING(Service_VI, "(STUBBED) called");
751 IPC::RequestParser rp{ctx}; 751 IPC::RequestParser rp{ctx};
752 u32 stack = rp.Pop<u32>(); 752 u32 stack = rp.Pop<u32>();
753 u64 layer_id = rp.Pop<u64>(); 753 u64 layer_id = rp.Pop<u64>();
@@ -762,8 +762,8 @@ private:
762 bool visibility = rp.Pop<bool>(); 762 bool visibility = rp.Pop<bool>();
763 IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); 763 IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);
764 rb.Push(RESULT_SUCCESS); 764 rb.Push(RESULT_SUCCESS);
765 NGLOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x{:X}, visibility={}", layer_id, 765 LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x{:X}, visibility={}", layer_id,
766 visibility); 766 visibility);
767 } 767 }
768 768
769 std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; 769 std::shared_ptr<NVFlinger::NVFlinger> nv_flinger;
@@ -776,7 +776,7 @@ public:
776 776
777private: 777private:
778 void GetRelayService(Kernel::HLERequestContext& ctx) { 778 void GetRelayService(Kernel::HLERequestContext& ctx) {
779 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 779 LOG_WARNING(Service_VI, "(STUBBED) called");
780 780
781 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 781 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
782 rb.Push(RESULT_SUCCESS); 782 rb.Push(RESULT_SUCCESS);
@@ -784,7 +784,7 @@ private:
784 } 784 }
785 785
786 void GetSystemDisplayService(Kernel::HLERequestContext& ctx) { 786 void GetSystemDisplayService(Kernel::HLERequestContext& ctx) {
787 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 787 LOG_WARNING(Service_VI, "(STUBBED) called");
788 788
789 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 789 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
790 rb.Push(RESULT_SUCCESS); 790 rb.Push(RESULT_SUCCESS);
@@ -792,7 +792,7 @@ private:
792 } 792 }
793 793
794 void GetManagerDisplayService(Kernel::HLERequestContext& ctx) { 794 void GetManagerDisplayService(Kernel::HLERequestContext& ctx) {
795 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 795 LOG_WARNING(Service_VI, "(STUBBED) called");
796 796
797 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 797 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
798 rb.Push(RESULT_SUCCESS); 798 rb.Push(RESULT_SUCCESS);
@@ -800,7 +800,7 @@ private:
800 } 800 }
801 801
802 void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx) { 802 void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx) {
803 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 803 LOG_WARNING(Service_VI, "(STUBBED) called");
804 804
805 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 805 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
806 rb.Push(RESULT_SUCCESS); 806 rb.Push(RESULT_SUCCESS);
@@ -808,7 +808,7 @@ private:
808 } 808 }
809 809
810 void OpenDisplay(Kernel::HLERequestContext& ctx) { 810 void OpenDisplay(Kernel::HLERequestContext& ctx) {
811 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 811 LOG_WARNING(Service_VI, "(STUBBED) called");
812 IPC::RequestParser rp{ctx}; 812 IPC::RequestParser rp{ctx};
813 auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); 813 auto name_buf = rp.PopRaw<std::array<u8, 0x40>>();
814 auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); 814 auto end = std::find(name_buf.begin(), name_buf.end(), '\0');
@@ -823,7 +823,7 @@ private:
823 } 823 }
824 824
825 void CloseDisplay(Kernel::HLERequestContext& ctx) { 825 void CloseDisplay(Kernel::HLERequestContext& ctx) {
826 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 826 LOG_WARNING(Service_VI, "(STUBBED) called");
827 IPC::RequestParser rp{ctx}; 827 IPC::RequestParser rp{ctx};
828 u64 display_id = rp.Pop<u64>(); 828 u64 display_id = rp.Pop<u64>();
829 829
@@ -832,7 +832,7 @@ private:
832 } 832 }
833 833
834 void GetDisplayResolution(Kernel::HLERequestContext& ctx) { 834 void GetDisplayResolution(Kernel::HLERequestContext& ctx) {
835 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 835 LOG_WARNING(Service_VI, "(STUBBED) called");
836 IPC::RequestParser rp{ctx}; 836 IPC::RequestParser rp{ctx};
837 u64 display_id = rp.Pop<u64>(); 837 u64 display_id = rp.Pop<u64>();
838 838
@@ -849,7 +849,7 @@ private:
849 } 849 }
850 850
851 void SetLayerScalingMode(Kernel::HLERequestContext& ctx) { 851 void SetLayerScalingMode(Kernel::HLERequestContext& ctx) {
852 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 852 LOG_WARNING(Service_VI, "(STUBBED) called");
853 IPC::RequestParser rp{ctx}; 853 IPC::RequestParser rp{ctx};
854 u32 scaling_mode = rp.Pop<u32>(); 854 u32 scaling_mode = rp.Pop<u32>();
855 u64 unknown = rp.Pop<u64>(); 855 u64 unknown = rp.Pop<u64>();
@@ -865,11 +865,11 @@ private:
865 IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); 865 IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0);
866 rb.Push(RESULT_SUCCESS); 866 rb.Push(RESULT_SUCCESS);
867 rb.Push<u64>(1); 867 rb.Push<u64>(1);
868 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 868 LOG_WARNING(Service_VI, "(STUBBED) called");
869 } 869 }
870 870
871 void OpenLayer(Kernel::HLERequestContext& ctx) { 871 void OpenLayer(Kernel::HLERequestContext& ctx) {
872 NGLOG_DEBUG(Service_VI, "called"); 872 LOG_DEBUG(Service_VI, "called");
873 IPC::RequestParser rp{ctx}; 873 IPC::RequestParser rp{ctx};
874 auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); 874 auto name_buf = rp.PopRaw<std::array<u8, 0x40>>();
875 auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); 875 auto end = std::find(name_buf.begin(), name_buf.end(), '\0');
@@ -889,7 +889,7 @@ private:
889 } 889 }
890 890
891 void CreateStrayLayer(Kernel::HLERequestContext& ctx) { 891 void CreateStrayLayer(Kernel::HLERequestContext& ctx) {
892 NGLOG_DEBUG(Service_VI, "called"); 892 LOG_DEBUG(Service_VI, "called");
893 893
894 IPC::RequestParser rp{ctx}; 894 IPC::RequestParser rp{ctx};
895 u32 flags = rp.Pop<u32>(); 895 u32 flags = rp.Pop<u32>();
@@ -909,7 +909,7 @@ private:
909 } 909 }
910 910
911 void DestroyStrayLayer(Kernel::HLERequestContext& ctx) { 911 void DestroyStrayLayer(Kernel::HLERequestContext& ctx) {
912 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 912 LOG_WARNING(Service_VI, "(STUBBED) called");
913 913
914 IPC::RequestParser rp{ctx}; 914 IPC::RequestParser rp{ctx};
915 u64 layer_id = rp.Pop<u64>(); 915 u64 layer_id = rp.Pop<u64>();
@@ -919,7 +919,7 @@ private:
919 } 919 }
920 920
921 void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx) { 921 void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx) {
922 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 922 LOG_WARNING(Service_VI, "(STUBBED) called");
923 IPC::RequestParser rp{ctx}; 923 IPC::RequestParser rp{ctx};
924 u64 display_id = rp.Pop<u64>(); 924 u64 display_id = rp.Pop<u64>();
925 925
@@ -968,7 +968,7 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name,
968 : ServiceFramework(name), module(std::move(module)), nv_flinger(std::move(nv_flinger)) {} 968 : ServiceFramework(name), module(std::move(module)), nv_flinger(std::move(nv_flinger)) {}
969 969
970void Module::Interface::GetDisplayService(Kernel::HLERequestContext& ctx) { 970void Module::Interface::GetDisplayService(Kernel::HLERequestContext& ctx) {
971 NGLOG_WARNING(Service_VI, "(STUBBED) called"); 971 LOG_WARNING(Service_VI, "(STUBBED) called");
972 972
973 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 973 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
974 rb.Push(RESULT_SUCCESS); 974 rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp
index 8fc91dc9c..2f48068c1 100644
--- a/src/core/hw/hw.cpp
+++ b/src/core/hw/hw.cpp
@@ -33,7 +33,7 @@ inline void Read(T& var, const u32 addr) {
33 LCD::Read(var, addr); 33 LCD::Read(var, addr);
34 break; 34 break;
35 default: 35 default:
36 NGLOG_ERROR(HW_Memory, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr); 36 LOG_ERROR(HW_Memory, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr);
37 break; 37 break;
38 } 38 }
39} 39}
@@ -62,7 +62,7 @@ inline void Write(u32 addr, const T data) {
62 LCD::Write(addr, data); 62 LCD::Write(addr, data);
63 break; 63 break;
64 default: 64 default:
65 NGLOG_ERROR(HW_Memory, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr); 65 LOG_ERROR(HW_Memory, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr);
66 break; 66 break;
67 } 67 }
68} 68}
@@ -85,12 +85,12 @@ void Update() {}
85/// Initialize hardware 85/// Initialize hardware
86void Init() { 86void Init() {
87 LCD::Init(); 87 LCD::Init();
88 NGLOG_DEBUG(HW, "Initialized OK"); 88 LOG_DEBUG(HW, "Initialized OK");
89} 89}
90 90
91/// Shutdown hardware 91/// Shutdown hardware
92void Shutdown() { 92void Shutdown() {
93 LCD::Shutdown(); 93 LCD::Shutdown();
94 NGLOG_DEBUG(HW, "Shutdown OK"); 94 LOG_DEBUG(HW, "Shutdown OK");
95} 95}
96} // namespace HW 96} // namespace HW
diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp
index e8525efde..0b62174d5 100644
--- a/src/core/hw/lcd.cpp
+++ b/src/core/hw/lcd.cpp
@@ -20,7 +20,7 @@ inline void Read(T& var, const u32 raw_addr) {
20 20
21 // Reads other than u32 are untested, so I'd rather have them abort than silently fail 21 // Reads other than u32 are untested, so I'd rather have them abort than silently fail
22 if (index >= 0x400 || !std::is_same<T, u32>::value) { 22 if (index >= 0x400 || !std::is_same<T, u32>::value) {
23 NGLOG_ERROR(HW_LCD, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr); 23 LOG_ERROR(HW_LCD, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr);
24 return; 24 return;
25 } 25 }
26 26
@@ -34,7 +34,7 @@ inline void Write(u32 addr, const T data) {
34 34
35 // Writes other than u32 are untested, so I'd rather have them abort than silently fail 35 // Writes other than u32 are untested, so I'd rather have them abort than silently fail
36 if (index >= 0x400 || !std::is_same<T, u32>::value) { 36 if (index >= 0x400 || !std::is_same<T, u32>::value) {
37 NGLOG_ERROR(HW_LCD, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr); 37 LOG_ERROR(HW_LCD, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr);
38 return; 38 return;
39 } 39 }
40 40
@@ -56,12 +56,12 @@ template void Write<u8>(u32 addr, const u8 data);
56/// Initialize hardware 56/// Initialize hardware
57void Init() { 57void Init() {
58 memset(&g_regs, 0, sizeof(g_regs)); 58 memset(&g_regs, 0, sizeof(g_regs));
59 NGLOG_DEBUG(HW_LCD, "Initialized OK"); 59 LOG_DEBUG(HW_LCD, "Initialized OK");
60} 60}
61 61
62/// Shutdown hardware 62/// Shutdown hardware
63void Shutdown() { 63void Shutdown() {
64 NGLOG_DEBUG(HW_LCD, "Shutdown OK"); 64 LOG_DEBUG(HW_LCD, "Shutdown OK");
65} 65}
66 66
67} // namespace LCD 67} // namespace LCD
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index b01b2caf6..eb7feb617 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -132,7 +132,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
132 const VAddr load_addr = next_load_addr; 132 const VAddr load_addr = next_load_addr;
133 next_load_addr = AppLoader_NSO::LoadModule(path, load_addr); 133 next_load_addr = AppLoader_NSO::LoadModule(path, load_addr);
134 if (next_load_addr) { 134 if (next_load_addr) {
135 NGLOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); 135 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
136 } else { 136 } else {
137 next_load_addr = load_addr; 137 next_load_addr = load_addr;
138 } 138 }
@@ -163,7 +163,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(
163 std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { 163 std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) {
164 164
165 if (filepath_romfs.empty()) { 165 if (filepath_romfs.empty()) {
166 NGLOG_DEBUG(Loader, "No RomFS available"); 166 LOG_DEBUG(Loader, "No RomFS available");
167 return ResultStatus::ErrorNotUsed; 167 return ResultStatus::ErrorNotUsed;
168 } 168 }
169 169
@@ -176,8 +176,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(
176 offset = 0; 176 offset = 0;
177 size = romfs_file->GetSize(); 177 size = romfs_file->GetSize();
178 178
179 NGLOG_DEBUG(Loader, "RomFS offset: 0x{:016X}", offset); 179 LOG_DEBUG(Loader, "RomFS offset: 0x{:016X}", offset);
180 NGLOG_DEBUG(Loader, "RomFS size: 0x{:016X}", size); 180 LOG_DEBUG(Loader, "RomFS size: 0x{:016X}", size);
181 181
182 // Reset read pointer 182 // Reset read pointer
183 file.Seek(0, SEEK_SET); 183 file.Seek(0, SEEK_SET);
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index e42d3a870..b69e5c6ef 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -273,18 +273,18 @@ const char* ElfReader::GetSectionName(int section) const {
273} 273}
274 274
275SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { 275SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
276 NGLOG_DEBUG(Loader, "String section: {}", header->e_shstrndx); 276 LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx);
277 277
278 // Should we relocate? 278 // Should we relocate?
279 relocate = (header->e_type != ET_EXEC); 279 relocate = (header->e_type != ET_EXEC);
280 280
281 if (relocate) { 281 if (relocate) {
282 NGLOG_DEBUG(Loader, "Relocatable module"); 282 LOG_DEBUG(Loader, "Relocatable module");
283 entryPoint += vaddr; 283 entryPoint += vaddr;
284 } else { 284 } else {
285 NGLOG_DEBUG(Loader, "Prerelocated executable"); 285 LOG_DEBUG(Loader, "Prerelocated executable");
286 } 286 }
287 NGLOG_DEBUG(Loader, "{} segments:", header->e_phnum); 287 LOG_DEBUG(Loader, "{} segments:", header->e_phnum);
288 288
289 // First pass : Get the bits into RAM 289 // First pass : Get the bits into RAM
290 u32 base_addr = relocate ? vaddr : 0; 290 u32 base_addr = relocate ? vaddr : 0;
@@ -304,8 +304,8 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
304 304
305 for (unsigned int i = 0; i < header->e_phnum; ++i) { 305 for (unsigned int i = 0; i < header->e_phnum; ++i) {
306 Elf32_Phdr* p = &segments[i]; 306 Elf32_Phdr* p = &segments[i];
307 NGLOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type, 307 LOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type,
308 p->p_vaddr, p->p_filesz, p->p_memsz); 308 p->p_vaddr, p->p_filesz, p->p_memsz);
309 309
310 if (p->p_type == PT_LOAD) { 310 if (p->p_type == PT_LOAD) {
311 CodeSet::Segment* codeset_segment; 311 CodeSet::Segment* codeset_segment;
@@ -317,16 +317,16 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
317 } else if (permission_flags == (PF_R | PF_W)) { 317 } else if (permission_flags == (PF_R | PF_W)) {
318 codeset_segment = &codeset->data; 318 codeset_segment = &codeset->data;
319 } else { 319 } else {
320 NGLOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, 320 LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i,
321 p->p_flags); 321 p->p_flags);
322 continue; 322 continue;
323 } 323 }
324 324
325 if (codeset_segment->size != 0) { 325 if (codeset_segment->size != 0) {
326 NGLOG_ERROR(Loader, 326 LOG_ERROR(Loader,
327 "ELF has more than one segment of the same type. Skipping extra " 327 "ELF has more than one segment of the same type. Skipping extra "
328 "segment (id {})", 328 "segment (id {})",
329 i); 329 i);
330 continue; 330 continue;
331 } 331 }
332 332
@@ -345,7 +345,7 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
345 codeset->entrypoint = base_addr + header->e_entry; 345 codeset->entrypoint = base_addr + header->e_entry;
346 codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); 346 codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image));
347 347
348 NGLOG_DEBUG(Loader, "Done loading."); 348 LOG_DEBUG(Loader, "Done loading.");
349 349
350 return codeset; 350 return codeset;
351} 351}
diff --git a/src/core/loader/linker.cpp b/src/core/loader/linker.cpp
index c7be5f265..769516b6f 100644
--- a/src/core/loader/linker.cpp
+++ b/src/core/loader/linker.cpp
@@ -84,7 +84,7 @@ void Linker::WriteRelocations(std::vector<u8>& program_image, const std::vector<
84 } 84 }
85 break; 85 break;
86 default: 86 default:
87 NGLOG_CRITICAL(Loader, "Unknown relocation type: {}", static_cast<int>(rela.type)); 87 LOG_CRITICAL(Loader, "Unknown relocation type: {}", static_cast<int>(rela.type));
88 break; 88 break;
89 } 89 }
90 } 90 }
@@ -141,7 +141,7 @@ void Linker::ResolveImports() {
141 if (search != exports.end()) { 141 if (search != exports.end()) {
142 Memory::Write64(import.second.ea, search->second + import.second.addend); 142 Memory::Write64(import.second.ea, search->second + import.second.addend);
143 } else { 143 } else {
144 NGLOG_ERROR(Loader, "Unresolved import: {}", import.first); 144 LOG_ERROR(Loader, "Unresolved import: {}", import.first);
145 } 145 }
146 } 146 }
147} 147}
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 20cc0bac0..8831d8e83 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -43,7 +43,7 @@ FileType IdentifyFile(FileUtil::IOFile& file, const std::string& filepath) {
43FileType IdentifyFile(const std::string& file_name) { 43FileType IdentifyFile(const std::string& file_name) {
44 FileUtil::IOFile file(file_name, "rb"); 44 FileUtil::IOFile file(file_name, "rb");
45 if (!file.IsOpen()) { 45 if (!file.IsOpen()) {
46 NGLOG_ERROR(Loader, "Failed to load file {}", file_name); 46 LOG_ERROR(Loader, "Failed to load file {}", file_name);
47 return FileType::Unknown; 47 return FileType::Unknown;
48 } 48 }
49 49
@@ -126,7 +126,7 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileUtil::IOFile&& file, FileTyp
126std::unique_ptr<AppLoader> GetLoader(const std::string& filename) { 126std::unique_ptr<AppLoader> GetLoader(const std::string& filename) {
127 FileUtil::IOFile file(filename, "rb"); 127 FileUtil::IOFile file(filename, "rb");
128 if (!file.IsOpen()) { 128 if (!file.IsOpen()) {
129 NGLOG_ERROR(Loader, "Failed to load file {}", filename); 129 LOG_ERROR(Loader, "Failed to load file {}", filename);
130 return nullptr; 130 return nullptr;
131 } 131 }
132 132
@@ -137,12 +137,12 @@ std::unique_ptr<AppLoader> GetLoader(const std::string& filename) {
137 FileType filename_type = GuessFromExtension(filename_extension); 137 FileType filename_type = GuessFromExtension(filename_extension);
138 138
139 if (type != filename_type) { 139 if (type != filename_type) {
140 NGLOG_WARNING(Loader, "File {} has a different type than its extension.", filename); 140 LOG_WARNING(Loader, "File {} has a different type than its extension.", filename);
141 if (FileType::Unknown == type) 141 if (FileType::Unknown == type)
142 type = filename_type; 142 type = filename_type;
143 } 143 }
144 144
145 NGLOG_DEBUG(Loader, "Loading file {} as {}...", filename, GetFileTypeString(type)); 145 LOG_DEBUG(Loader, "Loading file {} as {}...", filename, GetFileTypeString(type));
146 146
147 return GetFileLoader(std::move(file), type, filename_filename, filename); 147 return GetFileLoader(std::move(file), type, filename_filename, filename);
148} 148}
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp
index 067945d46..da064f8e3 100644
--- a/src/core/loader/nca.cpp
+++ b/src/core/loader/nca.cpp
@@ -123,7 +123,7 @@ ResultStatus Nca::Load(FileUtil::IOFile&& in_file, std::string in_path) {
123 file.Seek(0, SEEK_SET); 123 file.Seek(0, SEEK_SET);
124 std::array<u8, sizeof(NcaHeader)> header_array{}; 124 std::array<u8, sizeof(NcaHeader)> header_array{};
125 if (sizeof(NcaHeader) != file.ReadBytes(header_array.data(), sizeof(NcaHeader))) 125 if (sizeof(NcaHeader) != file.ReadBytes(header_array.data(), sizeof(NcaHeader)))
126 NGLOG_CRITICAL(Loader, "File reader errored out during header read."); 126 LOG_CRITICAL(Loader, "File reader errored out during header read.");
127 127
128 NcaHeader header{}; 128 NcaHeader header{};
129 std::memcpy(&header, header_array.data(), sizeof(NcaHeader)); 129 std::memcpy(&header, header_array.data(), sizeof(NcaHeader));
@@ -140,7 +140,7 @@ ResultStatus Nca::Load(FileUtil::IOFile&& in_file, std::string in_path) {
140 std::array<u8, sizeof(NcaSectionHeaderBlock)> array{}; 140 std::array<u8, sizeof(NcaSectionHeaderBlock)> array{};
141 if (sizeof(NcaSectionHeaderBlock) != 141 if (sizeof(NcaSectionHeaderBlock) !=
142 file.ReadBytes(array.data(), sizeof(NcaSectionHeaderBlock))) 142 file.ReadBytes(array.data(), sizeof(NcaSectionHeaderBlock)))
143 NGLOG_CRITICAL(Loader, "File reader errored out during header read."); 143 LOG_CRITICAL(Loader, "File reader errored out during header read.");
144 144
145 NcaSectionHeaderBlock block{}; 145 NcaSectionHeaderBlock block{};
146 std::memcpy(&block, array.data(), sizeof(NcaSectionHeaderBlock)); 146 std::memcpy(&block, array.data(), sizeof(NcaSectionHeaderBlock));
@@ -154,7 +154,7 @@ ResultStatus Nca::Load(FileUtil::IOFile&& in_file, std::string in_path) {
154 // Seek back to beginning of this section. 154 // Seek back to beginning of this section.
155 file.Seek(SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE, SEEK_SET); 155 file.Seek(SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE, SEEK_SET);
156 if (sizeof(Pfs0Superblock) != file.ReadBytes(&sb, sizeof(Pfs0Superblock))) 156 if (sizeof(Pfs0Superblock) != file.ReadBytes(&sb, sizeof(Pfs0Superblock)))
157 NGLOG_CRITICAL(Loader, "File reader errored out during header read."); 157 LOG_CRITICAL(Loader, "File reader errored out during header read.");
158 158
159 u64 offset = (static_cast<u64>(header.section_tables[i].media_offset) * 159 u64 offset = (static_cast<u64>(header.section_tables[i].media_offset) *
160 MEDIA_OFFSET_MULTIPLIER) + 160 MEDIA_OFFSET_MULTIPLIER) +
@@ -258,7 +258,7 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
258 const VAddr load_addr = next_load_addr; 258 const VAddr load_addr = next_load_addr;
259 next_load_addr = AppLoader_NSO::LoadModule(module, nca->GetExeFsFile(module), load_addr); 259 next_load_addr = AppLoader_NSO::LoadModule(module, nca->GetExeFsFile(module), load_addr);
260 if (next_load_addr) { 260 if (next_load_addr) {
261 NGLOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); 261 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
262 } else { 262 } else {
263 next_load_addr = load_addr; 263 next_load_addr = load_addr;
264 } 264 }
@@ -283,7 +283,7 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
283ResultStatus AppLoader_NCA::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, 283ResultStatus AppLoader_NCA::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset,
284 u64& size) { 284 u64& size) {
285 if (nca->GetRomFsSize() == 0) { 285 if (nca->GetRomFsSize() == 0) {
286 NGLOG_DEBUG(Loader, "No RomFS available"); 286 LOG_DEBUG(Loader, "No RomFS available");
287 return ResultStatus::ErrorNotUsed; 287 return ResultStatus::ErrorNotUsed;
288 } 288 }
289 289
@@ -292,8 +292,8 @@ ResultStatus AppLoader_NCA::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_f
292 offset = nca->GetRomFsOffset(); 292 offset = nca->GetRomFsOffset();
293 size = nca->GetRomFsSize(); 293 size = nca->GetRomFsSize();
294 294
295 NGLOG_DEBUG(Loader, "RomFS offset: 0x{:016X}", offset); 295 LOG_DEBUG(Loader, "RomFS offset: 0x{:016X}", offset);
296 NGLOG_DEBUG(Loader, "RomFS size: 0x{:016X}", size); 296 LOG_DEBUG(Loader, "RomFS size: 0x{:016X}", size);
297 297
298 return ResultStatus::Success; 298 return ResultStatus::Success;
299} 299}
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 845ed7e90..7f84e4b1b 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -87,7 +87,7 @@ static std::vector<u8> ReadSegment(FileUtil::IOFile& file, const NsoSegmentHeade
87 87
88 file.Seek(header.offset, SEEK_SET); 88 file.Seek(header.offset, SEEK_SET);
89 if (compressed_size != file.ReadBytes(compressed_data.data(), compressed_size)) { 89 if (compressed_size != file.ReadBytes(compressed_data.data(), compressed_size)) {
90 NGLOG_CRITICAL(Loader, "Failed to read {} NSO LZ4 compressed bytes", compressed_size); 90 LOG_CRITICAL(Loader, "Failed to read {} NSO LZ4 compressed bytes", compressed_size);
91 return {}; 91 return {};
92 } 92 }
93 93
@@ -215,7 +215,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
215 215
216 // Load module 216 // Load module
217 LoadModule(filepath, Memory::PROCESS_IMAGE_VADDR); 217 LoadModule(filepath, Memory::PROCESS_IMAGE_VADDR);
218 NGLOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", filepath, Memory::PROCESS_IMAGE_VADDR); 218 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", filepath, Memory::PROCESS_IMAGE_VADDR);
219 219
220 process->svc_access_mask.set(); 220 process->svc_access_mask.set();
221 process->address_mappings = default_address_mappings; 221 process->address_mappings = default_address_mappings;
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index f070dee7d..190ccc25c 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -43,8 +43,8 @@ PageTable* GetCurrentPageTable() {
43} 43}
44 44
45static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, PageType type) { 45static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, PageType type) {
46 NGLOG_DEBUG(HW_Memory, "Mapping {} onto {:016X}-{:016X}", fmt::ptr(memory), base * PAGE_SIZE, 46 LOG_DEBUG(HW_Memory, "Mapping {} onto {:016X}-{:016X}", fmt::ptr(memory), base * PAGE_SIZE,
47 (base + size) * PAGE_SIZE); 47 (base + size) * PAGE_SIZE);
48 48
49 RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, 49 RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE,
50 FlushMode::FlushAndInvalidate); 50 FlushMode::FlushAndInvalidate);
@@ -173,7 +173,7 @@ T Read(const VAddr vaddr) {
173 PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; 173 PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
174 switch (type) { 174 switch (type) {
175 case PageType::Unmapped: 175 case PageType::Unmapped:
176 NGLOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr); 176 LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr);
177 return 0; 177 return 0;
178 case PageType::Memory: 178 case PageType::Memory:
179 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); 179 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
@@ -205,8 +205,8 @@ void Write(const VAddr vaddr, const T data) {
205 PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; 205 PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
206 switch (type) { 206 switch (type) {
207 case PageType::Unmapped: 207 case PageType::Unmapped:
208 NGLOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, 208 LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8,
209 static_cast<u32>(data), vaddr); 209 static_cast<u32>(data), vaddr);
210 return; 210 return;
211 case PageType::Memory: 211 case PageType::Memory:
212 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); 212 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
@@ -259,7 +259,7 @@ u8* GetPointer(const VAddr vaddr) {
259 return GetPointerFromVMA(vaddr); 259 return GetPointerFromVMA(vaddr);
260 } 260 }
261 261
262 NGLOG_ERROR(HW_Memory, "Unknown GetPointer @ 0x{:016X}", vaddr); 262 LOG_ERROR(HW_Memory, "Unknown GetPointer @ 0x{:016X}", vaddr);
263 return nullptr; 263 return nullptr;
264} 264}
265 265
@@ -296,12 +296,12 @@ u8* GetPhysicalPointer(PAddr address) {
296 }); 296 });
297 297
298 if (area == std::end(memory_areas)) { 298 if (area == std::end(memory_areas)) {
299 NGLOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ 0x{:016X}", address); 299 LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ 0x{:016X}", address);
300 return nullptr; 300 return nullptr;
301 } 301 }
302 302
303 if (area->paddr_base == IO_AREA_PADDR) { 303 if (area->paddr_base == IO_AREA_PADDR) {
304 NGLOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:016X}", address); 304 LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:016X}", address);
305 return nullptr; 305 return nullptr;
306 } 306 }
307 307
@@ -348,9 +348,9 @@ void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached)
348 Core::System::GetInstance().GPU().memory_manager->GpuToCpuAddress(gpu_addr); 348 Core::System::GetInstance().GPU().memory_manager->GpuToCpuAddress(gpu_addr);
349 // The GPU <-> CPU virtual memory mapping is not 1:1 349 // The GPU <-> CPU virtual memory mapping is not 1:1
350 if (!maybe_vaddr) { 350 if (!maybe_vaddr) {
351 NGLOG_ERROR(HW_Memory, 351 LOG_ERROR(HW_Memory,
352 "Trying to flush a cached region to an invalid physical address {:016X}", 352 "Trying to flush a cached region to an invalid physical address {:016X}",
353 gpu_addr); 353 gpu_addr);
354 continue; 354 continue;
355 } 355 }
356 VAddr vaddr = *maybe_vaddr; 356 VAddr vaddr = *maybe_vaddr;
@@ -484,9 +484,9 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_
484 484
485 switch (page_table.attributes[page_index]) { 485 switch (page_table.attributes[page_index]) {
486 case PageType::Unmapped: { 486 case PageType::Unmapped: {
487 NGLOG_ERROR(HW_Memory, 487 LOG_ERROR(HW_Memory,
488 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 488 "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
489 current_vaddr, src_addr, size); 489 current_vaddr, src_addr, size);
490 std::memset(dest_buffer, 0, copy_amount); 490 std::memset(dest_buffer, 0, copy_amount);
491 break; 491 break;
492 } 492 }
@@ -548,9 +548,9 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi
548 548
549 switch (page_table.attributes[page_index]) { 549 switch (page_table.attributes[page_index]) {
550 case PageType::Unmapped: { 550 case PageType::Unmapped: {
551 NGLOG_ERROR(HW_Memory, 551 LOG_ERROR(HW_Memory,
552 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 552 "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
553 current_vaddr, dest_addr, size); 553 current_vaddr, dest_addr, size);
554 break; 554 break;
555 } 555 }
556 case PageType::Memory: { 556 case PageType::Memory: {
@@ -596,9 +596,9 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const size
596 596
597 switch (page_table.attributes[page_index]) { 597 switch (page_table.attributes[page_index]) {
598 case PageType::Unmapped: { 598 case PageType::Unmapped: {
599 NGLOG_ERROR(HW_Memory, 599 LOG_ERROR(HW_Memory,
600 "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 600 "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
601 current_vaddr, dest_addr, size); 601 current_vaddr, dest_addr, size);
602 break; 602 break;
603 } 603 }
604 case PageType::Memory: { 604 case PageType::Memory: {
@@ -637,9 +637,9 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
637 637
638 switch (page_table.attributes[page_index]) { 638 switch (page_table.attributes[page_index]) {
639 case PageType::Unmapped: { 639 case PageType::Unmapped: {
640 NGLOG_ERROR(HW_Memory, 640 LOG_ERROR(HW_Memory,
641 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 641 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
642 current_vaddr, src_addr, size); 642 current_vaddr, src_addr, size);
643 ZeroBlock(process, dest_addr, copy_amount); 643 ZeroBlock(process, dest_addr, copy_amount);
644 break; 644 break;
645 } 645 }
@@ -692,7 +692,7 @@ boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) {
692PAddr VirtualToPhysicalAddress(const VAddr addr) { 692PAddr VirtualToPhysicalAddress(const VAddr addr) {
693 auto paddr = TryVirtualToPhysicalAddress(addr); 693 auto paddr = TryVirtualToPhysicalAddress(addr);
694 if (!paddr) { 694 if (!paddr) {
695 NGLOG_ERROR(HW_Memory, "Unknown virtual address @ 0x{:016X}", addr); 695 LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x{:016X}", addr);
696 // To help with debugging, set bit on address so that it's obviously invalid. 696 // To help with debugging, set bit on address so that it's obviously invalid.
697 return addr | 0x80000000; 697 return addr | 0x80000000;
698 } 698 }
diff --git a/src/core/settings.h b/src/core/settings.h
index a7f1e5fa0..7150d9755 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -129,6 +129,7 @@ struct Values {
129 // Renderer 129 // Renderer
130 float resolution_factor; 130 float resolution_factor;
131 bool toggle_framelimit; 131 bool toggle_framelimit;
132 bool use_accurate_framebuffers;
132 133
133 float bg_red; 134 float bg_red;
134 float bg_green; 135 float bg_green;
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index a60aa1143..b9a603df3 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -42,14 +42,14 @@ u64 GetTelemetryId() {
42 if (FileUtil::Exists(filename)) { 42 if (FileUtil::Exists(filename)) {
43 FileUtil::IOFile file(filename, "rb"); 43 FileUtil::IOFile file(filename, "rb");
44 if (!file.IsOpen()) { 44 if (!file.IsOpen()) {
45 NGLOG_ERROR(Core, "failed to open telemetry_id: {}", filename); 45 LOG_ERROR(Core, "failed to open telemetry_id: {}", filename);
46 return {}; 46 return {};
47 } 47 }
48 file.ReadBytes(&telemetry_id, sizeof(u64)); 48 file.ReadBytes(&telemetry_id, sizeof(u64));
49 } else { 49 } else {
50 FileUtil::IOFile file(filename, "wb"); 50 FileUtil::IOFile file(filename, "wb");
51 if (!file.IsOpen()) { 51 if (!file.IsOpen()) {
52 NGLOG_ERROR(Core, "failed to open telemetry_id: {}", filename); 52 LOG_ERROR(Core, "failed to open telemetry_id: {}", filename);
53 return {}; 53 return {};
54 } 54 }
55 telemetry_id = GenerateTelemetryId(); 55 telemetry_id = GenerateTelemetryId();
@@ -65,7 +65,7 @@ u64 RegenerateTelemetryId() {
65 65
66 FileUtil::IOFile file(filename, "wb"); 66 FileUtil::IOFile file(filename, "wb");
67 if (!file.IsOpen()) { 67 if (!file.IsOpen()) {
68 NGLOG_ERROR(Core, "failed to open telemetry_id: {}", filename); 68 LOG_ERROR(Core, "failed to open telemetry_id: {}", filename);
69 return {}; 69 return {};
70 } 70 }
71 file.WriteBytes(&new_telemetry_id, sizeof(u64)); 71 file.WriteBytes(&new_telemetry_id, sizeof(u64));
@@ -161,6 +161,8 @@ TelemetrySession::TelemetrySession() {
161 Settings::values.resolution_factor); 161 Settings::values.resolution_factor);
162 AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit", 162 AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit",
163 Settings::values.toggle_framelimit); 163 Settings::values.toggle_framelimit);
164 AddField(Telemetry::FieldType::UserConfig, "Renderer_UseAccurateFramebuffers",
165 Settings::values.use_accurate_framebuffers);
164 AddField(Telemetry::FieldType::UserConfig, "System_UseDockedMode", 166 AddField(Telemetry::FieldType::UserConfig, "System_UseDockedMode",
165 Settings::values.use_docked_mode); 167 Settings::values.use_docked_mode);
166} 168}
diff --git a/src/core/tracer/recorder.cpp b/src/core/tracer/recorder.cpp
index 2f848c994..af032f0c9 100644
--- a/src/core/tracer/recorder.cpp
+++ b/src/core/tracer/recorder.cpp
@@ -159,7 +159,7 @@ void Recorder::Finish(const std::string& filename) {
159 throw "Failed to write stream element"; 159 throw "Failed to write stream element";
160 } 160 }
161 } catch (const char* str) { 161 } catch (const char* str) {
162 NGLOG_ERROR(HW_GPU, "Writing CiTrace file failed: {}", str); 162 LOG_ERROR(HW_GPU, "Writing CiTrace file failed: {}", str);
163 } 163 }
164} 164}
165 165
diff --git a/src/input_common/sdl/sdl.cpp b/src/input_common/sdl/sdl.cpp
index 231a0f7af..8d117c2d4 100644
--- a/src/input_common/sdl/sdl.cpp
+++ b/src/input_common/sdl/sdl.cpp
@@ -32,7 +32,7 @@ public:
32 explicit SDLJoystick(int joystick_index) 32 explicit SDLJoystick(int joystick_index)
33 : joystick{SDL_JoystickOpen(joystick_index), SDL_JoystickClose} { 33 : joystick{SDL_JoystickOpen(joystick_index), SDL_JoystickClose} {
34 if (!joystick) { 34 if (!joystick) {
35 NGLOG_ERROR(Input, "failed to open joystick {}", joystick_index); 35 LOG_ERROR(Input, "failed to open joystick {}", joystick_index);
36 } 36 }
37 } 37 }
38 38
@@ -204,7 +204,7 @@ public:
204 trigger_if_greater = false; 204 trigger_if_greater = false;
205 } else { 205 } else {
206 trigger_if_greater = true; 206 trigger_if_greater = true;
207 NGLOG_ERROR(Input, "Unknown direction '{}'", direction_name); 207 LOG_ERROR(Input, "Unknown direction '{}'", direction_name);
208 } 208 }
209 return std::make_unique<SDLAxisButton>(GetJoystick(joystick_index), axis, threshold, 209 return std::make_unique<SDLAxisButton>(GetJoystick(joystick_index), axis, threshold,
210 trigger_if_greater); 210 trigger_if_greater);
@@ -235,7 +235,7 @@ public:
235 235
236void Init() { 236void Init() {
237 if (SDL_Init(SDL_INIT_JOYSTICK) < 0) { 237 if (SDL_Init(SDL_INIT_JOYSTICK) < 0) {
238 NGLOG_CRITICAL(Input, "SDL_Init(SDL_INIT_JOYSTICK) failed with: {}", SDL_GetError()); 238 LOG_CRITICAL(Input, "SDL_Init(SDL_INIT_JOYSTICK) failed with: {}", SDL_GetError());
239 } else { 239 } else {
240 using namespace Input; 240 using namespace Input;
241 RegisterFactory<ButtonDevice>("sdl", std::make_shared<SDLButtonFactory>()); 241 RegisterFactory<ButtonDevice>("sdl", std::make_shared<SDLButtonFactory>());
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index cec9cb9f3..31ea3adad 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -29,21 +29,21 @@ enum class BufferMethods {
29}; 29};
30 30
31void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) { 31void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) {
32 NGLOG_WARNING(HW_GPU, 32 LOG_WARNING(HW_GPU,
33 "Processing method {:08X} on subchannel {} value " 33 "Processing method {:08X} on subchannel {} value "
34 "{:08X} remaining params {}", 34 "{:08X} remaining params {}",
35 method, subchannel, value, remaining_params); 35 method, subchannel, value, remaining_params);
36 36
37 if (method == static_cast<u32>(BufferMethods::BindObject)) { 37 if (method == static_cast<u32>(BufferMethods::BindObject)) {
38 // Bind the current subchannel to the desired engine id. 38 // Bind the current subchannel to the desired engine id.
39 NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); 39 LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value);
40 bound_engines[subchannel] = static_cast<EngineID>(value); 40 bound_engines[subchannel] = static_cast<EngineID>(value);
41 return; 41 return;
42 } 42 }
43 43
44 if (method < static_cast<u32>(BufferMethods::CountBufferMethods)) { 44 if (method < static_cast<u32>(BufferMethods::CountBufferMethods)) {
45 // TODO(Subv): Research and implement these methods. 45 // TODO(Subv): Research and implement these methods.
46 NGLOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented"); 46 LOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented");
47 return; 47 return;
48 } 48 }
49 49
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h
index bbba8e380..9382a75e5 100644
--- a/src/video_core/debug_utils/debug_utils.h
+++ b/src/video_core/debug_utils/debug_utils.h
@@ -55,8 +55,10 @@ public:
55 virtual ~BreakPointObserver() { 55 virtual ~BreakPointObserver() {
56 auto context = context_weak.lock(); 56 auto context = context_weak.lock();
57 if (context) { 57 if (context) {
58 std::unique_lock<std::mutex> lock(context->breakpoint_mutex); 58 {
59 context->breakpoint_observers.remove(this); 59 std::unique_lock<std::mutex> lock(context->breakpoint_mutex);
60 context->breakpoint_observers.remove(this);
61 }
60 62
61 // If we are the last observer to be destroyed, tell the debugger context that 63 // If we are the last observer to be destroyed, tell the debugger context that
62 // it is free to continue. In particular, this is required for a proper yuzu 64 // it is free to continue. In particular, this is required for a proper yuzu
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp
index 998b7c843..34053e393 100644
--- a/src/video_core/engines/fermi_2d.cpp
+++ b/src/video_core/engines/fermi_2d.cpp
@@ -26,8 +26,8 @@ void Fermi2D::WriteReg(u32 method, u32 value) {
26} 26}
27 27
28void Fermi2D::HandleSurfaceCopy() { 28void Fermi2D::HandleSurfaceCopy() {
29 NGLOG_WARNING(HW_GPU, "Requested a surface copy with operation {}", 29 LOG_WARNING(HW_GPU, "Requested a surface copy with operation {}",
30 static_cast<u32>(regs.operation)); 30 static_cast<u32>(regs.operation));
31 31
32 const GPUVAddr source = regs.src.Address(); 32 const GPUVAddr source = regs.src.Address();
33 const GPUVAddr dest = regs.dst.Address(); 33 const GPUVAddr dest = regs.dst.Address();
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 93c43c8cb..3bca16364 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -126,6 +126,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
126 DrawArrays(); 126 DrawArrays();
127 break; 127 break;
128 } 128 }
129 case MAXWELL3D_REG_INDEX(clear_buffers): {
130 ProcessClearBuffers();
131 break;
132 }
129 case MAXWELL3D_REG_INDEX(query.query_get): { 133 case MAXWELL3D_REG_INDEX(query.query_get): {
130 ProcessQueryGet(); 134 ProcessQueryGet();
131 break; 135 break;
@@ -207,8 +211,8 @@ void Maxwell3D::ProcessQueryGet() {
207} 211}
208 212
209void Maxwell3D::DrawArrays() { 213void Maxwell3D::DrawArrays() {
210 NGLOG_DEBUG(HW_GPU, "called, topology={}, count={}", 214 LOG_DEBUG(HW_GPU, "called, topology={}, count={}", static_cast<u32>(regs.draw.topology.Value()),
211 static_cast<u32>(regs.draw.topology.Value()), regs.vertex_buffer.count); 215 regs.vertex_buffer.count);
212 ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?"); 216 ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?");
213 217
214 auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); 218 auto debug_context = Core::System::GetInstance().GetGPUDebugContext();
@@ -415,5 +419,13 @@ bool Maxwell3D::IsShaderStageEnabled(Regs::ShaderStage stage) const {
415 UNREACHABLE(); 419 UNREACHABLE();
416} 420}
417 421
422void Maxwell3D::ProcessClearBuffers() {
423 ASSERT(regs.clear_buffers.R == regs.clear_buffers.G &&
424 regs.clear_buffers.R == regs.clear_buffers.B &&
425 regs.clear_buffers.R == regs.clear_buffers.A);
426
427 VideoCore::g_renderer->Rasterizer()->Clear();
428}
429
418} // namespace Engines 430} // namespace Engines
419} // namespace Tegra 431} // namespace Tegra
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 2dc251205..5a7cf0107 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -280,6 +280,46 @@ public:
280 UnsignedInt = 0x2, 280 UnsignedInt = 0x2,
281 }; 281 };
282 282
283 enum class ComparisonOp : u32 {
284 // These values are used by Nouveau and most games, they correspond to the OpenGL token
285 // values for these operations.
286 Never = 0x200,
287 Less = 0x201,
288 Equal = 0x202,
289 LessEqual = 0x203,
290 Greater = 0x204,
291 NotEqual = 0x205,
292 GreaterEqual = 0x206,
293 Always = 0x207,
294
295 // These values are used by some games, they seem to be NV04 values.
296 NeverOld = 1,
297 LessOld = 2,
298 EqualOld = 3,
299 LessEqualOld = 4,
300 GreaterOld = 5,
301 NotEqualOld = 6,
302 GreaterEqualOld = 7,
303 AlwaysOld = 8,
304 };
305
306 struct Cull {
307 enum class FrontFace : u32 {
308 ClockWise = 0x0900,
309 CounterClockWise = 0x0901,
310 };
311
312 enum class CullFace : u32 {
313 Front = 0x0404,
314 Back = 0x0405,
315 FrontAndBack = 0x0408,
316 };
317
318 u32 enabled;
319 FrontFace front_face;
320 CullFace cull_face;
321 };
322
283 struct Blend { 323 struct Blend {
284 enum class Equation : u32 { 324 enum class Equation : u32 {
285 Add = 1, 325 Add = 1,
@@ -321,6 +361,24 @@ public:
321 INSERT_PADDING_WORDS(1); 361 INSERT_PADDING_WORDS(1);
322 }; 362 };
323 363
364 struct RenderTargetConfig {
365 u32 address_high;
366 u32 address_low;
367 u32 width;
368 u32 height;
369 Tegra::RenderTargetFormat format;
370 u32 block_dimensions;
371 u32 array_mode;
372 u32 layer_stride;
373 u32 base_layer;
374 INSERT_PADDING_WORDS(7);
375
376 GPUVAddr Address() const {
377 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
378 address_low);
379 }
380 };
381
324 union { 382 union {
325 struct { 383 struct {
326 INSERT_PADDING_WORDS(0x45); 384 INSERT_PADDING_WORDS(0x45);
@@ -333,23 +391,7 @@ public:
333 391
334 INSERT_PADDING_WORDS(0x1B8); 392 INSERT_PADDING_WORDS(0x1B8);
335 393
336 struct { 394 RenderTargetConfig rt[NumRenderTargets];
337 u32 address_high;
338 u32 address_low;
339 u32 width;
340 u32 height;
341 Tegra::RenderTargetFormat format;
342 u32 block_dimensions;
343 u32 array_mode;
344 u32 layer_stride;
345 u32 base_layer;
346 INSERT_PADDING_WORDS(7);
347
348 GPUVAddr Address() const {
349 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
350 address_low);
351 }
352 } rt[NumRenderTargets];
353 395
354 struct { 396 struct {
355 f32 scale_x; 397 f32 scale_x;
@@ -406,12 +448,17 @@ public:
406 u32 count; 448 u32 count;
407 } vertex_buffer; 449 } vertex_buffer;
408 450
409 INSERT_PADDING_WORDS(0x99); 451 INSERT_PADDING_WORDS(1);
452
453 float clear_color[4];
454 float clear_depth;
455
456 INSERT_PADDING_WORDS(0x93);
410 457
411 struct { 458 struct {
412 u32 address_high; 459 u32 address_high;
413 u32 address_low; 460 u32 address_low;
414 u32 format; 461 Tegra::DepthFormat format;
415 u32 block_dimensions; 462 u32 block_dimensions;
416 u32 layer_stride; 463 u32 layer_stride;
417 464
@@ -433,11 +480,23 @@ public:
433 }; 480 };
434 } rt_control; 481 } rt_control;
435 482
436 INSERT_PADDING_WORDS(0x31); 483 INSERT_PADDING_WORDS(0x2B);
484
485 u32 depth_test_enable;
486
487 INSERT_PADDING_WORDS(0x5);
437 488
438 u32 independent_blend_enable; 489 u32 independent_blend_enable;
439 490
440 INSERT_PADDING_WORDS(0x15); 491 u32 depth_write_enabled;
492
493 INSERT_PADDING_WORDS(0x7);
494
495 u32 d3d_cull_mode;
496
497 ComparisonOp depth_test_func;
498
499 INSERT_PADDING_WORDS(0xB);
441 500
442 struct { 501 struct {
443 u32 separate_alpha; 502 u32 separate_alpha;
@@ -453,7 +512,17 @@ public:
453 u32 enable[NumRenderTargets]; 512 u32 enable[NumRenderTargets];
454 } blend; 513 } blend;
455 514
456 INSERT_PADDING_WORDS(0x77); 515 INSERT_PADDING_WORDS(0xB);
516
517 union {
518 BitField<4, 1, u32> triangle_rast_flip;
519 } screen_y_control;
520
521 INSERT_PADDING_WORDS(0x21);
522
523 u32 vb_element_base;
524
525 INSERT_PADDING_WORDS(0x49);
457 526
458 struct { 527 struct {
459 u32 tsc_address_high; 528 u32 tsc_address_high;
@@ -479,7 +548,12 @@ public:
479 } 548 }
480 } tic; 549 } tic;
481 550
482 INSERT_PADDING_WORDS(0x22); 551 INSERT_PADDING_WORDS(0x21);
552
553 union {
554 BitField<2, 1, u32> coord_origin;
555 BitField<3, 10, u32> enable;
556 } point_coord_replace;
483 557
484 struct { 558 struct {
485 u32 code_address_high; 559 u32 code_address_high;
@@ -534,7 +608,27 @@ public:
534 } 608 }
535 } index_array; 609 } index_array;
536 610
537 INSERT_PADDING_WORDS(0xC7); 611 INSERT_PADDING_WORDS(0x7);
612
613 INSERT_PADDING_WORDS(0x46);
614
615 Cull cull;
616
617 INSERT_PADDING_WORDS(0x2B);
618
619 union {
620 u32 raw;
621 BitField<0, 1, u32> Z;
622 BitField<1, 1, u32> S;
623 BitField<2, 1, u32> R;
624 BitField<3, 1, u32> G;
625 BitField<4, 1, u32> B;
626 BitField<5, 1, u32> A;
627 BitField<6, 4, u32> RT;
628 BitField<10, 11, u32> layer;
629 } clear_buffers;
630
631 INSERT_PADDING_WORDS(0x4B);
538 632
539 struct { 633 struct {
540 u32 query_address_high; 634 u32 query_address_high;
@@ -716,6 +810,9 @@ private:
716 /// Handles writes to the macro uploading registers. 810 /// Handles writes to the macro uploading registers.
717 void ProcessMacroUpload(u32 data); 811 void ProcessMacroUpload(u32 data);
718 812
813 /// Handles a write to the CLEAR_BUFFERS register.
814 void ProcessClearBuffers();
815
719 /// Handles a write to the QUERY_GET register. 816 /// Handles a write to the QUERY_GET register.
720 void ProcessQueryGet(); 817 void ProcessQueryGet();
721 818
@@ -738,16 +835,27 @@ ASSERT_REG_POSITION(rt, 0x200);
738ASSERT_REG_POSITION(viewport_transform[0], 0x280); 835ASSERT_REG_POSITION(viewport_transform[0], 0x280);
739ASSERT_REG_POSITION(viewport, 0x300); 836ASSERT_REG_POSITION(viewport, 0x300);
740ASSERT_REG_POSITION(vertex_buffer, 0x35D); 837ASSERT_REG_POSITION(vertex_buffer, 0x35D);
838ASSERT_REG_POSITION(clear_color[0], 0x360);
839ASSERT_REG_POSITION(clear_depth, 0x364);
741ASSERT_REG_POSITION(zeta, 0x3F8); 840ASSERT_REG_POSITION(zeta, 0x3F8);
742ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458); 841ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458);
743ASSERT_REG_POSITION(rt_control, 0x487); 842ASSERT_REG_POSITION(rt_control, 0x487);
843ASSERT_REG_POSITION(depth_test_enable, 0x4B3);
744ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); 844ASSERT_REG_POSITION(independent_blend_enable, 0x4B9);
845ASSERT_REG_POSITION(depth_write_enabled, 0x4BA);
846ASSERT_REG_POSITION(d3d_cull_mode, 0x4C2);
847ASSERT_REG_POSITION(depth_test_func, 0x4C3);
745ASSERT_REG_POSITION(blend, 0x4CF); 848ASSERT_REG_POSITION(blend, 0x4CF);
849ASSERT_REG_POSITION(screen_y_control, 0x4EB);
850ASSERT_REG_POSITION(vb_element_base, 0x50D);
746ASSERT_REG_POSITION(tsc, 0x557); 851ASSERT_REG_POSITION(tsc, 0x557);
747ASSERT_REG_POSITION(tic, 0x55D); 852ASSERT_REG_POSITION(tic, 0x55D);
853ASSERT_REG_POSITION(point_coord_replace, 0x581);
748ASSERT_REG_POSITION(code_address, 0x582); 854ASSERT_REG_POSITION(code_address, 0x582);
749ASSERT_REG_POSITION(draw, 0x585); 855ASSERT_REG_POSITION(draw, 0x585);
750ASSERT_REG_POSITION(index_array, 0x5F2); 856ASSERT_REG_POSITION(index_array, 0x5F2);
857ASSERT_REG_POSITION(cull, 0x646);
858ASSERT_REG_POSITION(clear_buffers, 0x674);
751ASSERT_REG_POSITION(query, 0x6C0); 859ASSERT_REG_POSITION(query, 0x6C0);
752ASSERT_REG_POSITION(vertex_array[0], 0x700); 860ASSERT_REG_POSITION(vertex_array[0], 0x700);
753ASSERT_REG_POSITION(independent_blend, 0x780); 861ASSERT_REG_POSITION(independent_blend, 0x780);
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index 442138988..6e740713f 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -31,7 +31,7 @@ void MaxwellDMA::WriteReg(u32 method, u32 value) {
31} 31}
32 32
33void MaxwellDMA::HandleCopy() { 33void MaxwellDMA::HandleCopy() {
34 NGLOG_WARNING(HW_GPU, "Requested a DMA copy"); 34 LOG_WARNING(HW_GPU, "Requested a DMA copy");
35 35
36 const GPUVAddr source = regs.src_address.Address(); 36 const GPUVAddr source = regs.src_address.Address();
37 const GPUVAddr dest = regs.dst_address.Address(); 37 const GPUVAddr dest = regs.dst_address.Address();
@@ -49,7 +49,11 @@ void MaxwellDMA::HandleCopy() {
49 ASSERT(regs.src_params.pos_y == 0); 49 ASSERT(regs.src_params.pos_y == 0);
50 ASSERT(regs.dst_params.pos_x == 0); 50 ASSERT(regs.dst_params.pos_x == 0);
51 ASSERT(regs.dst_params.pos_y == 0); 51 ASSERT(regs.dst_params.pos_y == 0);
52 ASSERT(regs.exec.is_dst_linear != regs.exec.is_src_linear); 52
53 if (regs.exec.is_dst_linear == regs.exec.is_src_linear) {
54 Memory::CopyBlock(dest_cpu, source_cpu, regs.x_count * regs.y_count);
55 return;
56 }
53 57
54 u8* src_buffer = Memory::GetPointer(source_cpu); 58 u8* src_buffer = Memory::GetPointer(source_cpu);
55 u8* dst_buffer = Memory::GetPointer(dest_cpu); 59 u8* dst_buffer = Memory::GetPointer(dest_cpu);
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index cb4db0679..2bc1782ad 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -142,6 +142,7 @@ enum class PredCondition : u64 {
142 GreaterThan = 4, 142 GreaterThan = 4,
143 NotEqual = 5, 143 NotEqual = 5,
144 GreaterEqual = 6, 144 GreaterEqual = 6,
145 NotEqualWithNan = 13,
145 // TODO(Subv): Other condition types 146 // TODO(Subv): Other condition types
146}; 147};
147 148
@@ -165,7 +166,7 @@ enum class SubOp : u64 {
165 Lg2 = 0x3, 166 Lg2 = 0x3,
166 Rcp = 0x4, 167 Rcp = 0x4,
167 Rsq = 0x5, 168 Rsq = 0x5,
168 Min = 0x8, 169 Sqrt = 0x8,
169}; 170};
170 171
171enum class F2iRoundingOp : u64 { 172enum class F2iRoundingOp : u64 {
@@ -193,6 +194,13 @@ enum class UniformType : u64 {
193 Double = 5, 194 Double = 5,
194}; 195};
195 196
197enum class IMinMaxExchange : u64 {
198 None = 0,
199 XLo = 1,
200 XMed = 2,
201 XHi = 3,
202};
203
196union Instruction { 204union Instruction {
197 Instruction& operator=(const Instruction& instr) { 205 Instruction& operator=(const Instruction& instr) {
198 value = instr.value; 206 value = instr.value;
@@ -209,7 +217,7 @@ union Instruction {
209 } pred; 217 } pred;
210 BitField<19, 1, u64> negate_pred; 218 BitField<19, 1, u64> negate_pred;
211 BitField<20, 8, Register> gpr20; 219 BitField<20, 8, Register> gpr20;
212 BitField<20, 7, SubOp> sub_op; 220 BitField<20, 4, SubOp> sub_op;
213 BitField<28, 8, Register> gpr28; 221 BitField<28, 8, Register> gpr28;
214 BitField<39, 8, Register> gpr39; 222 BitField<39, 8, Register> gpr39;
215 BitField<48, 16, u64> opcode; 223 BitField<48, 16, u64> opcode;
@@ -278,6 +286,13 @@ union Instruction {
278 } alu_integer; 286 } alu_integer;
279 287
280 union { 288 union {
289 BitField<39, 3, u64> pred;
290 BitField<42, 1, u64> negate_pred;
291 BitField<43, 2, IMinMaxExchange> exchange;
292 BitField<48, 1, u64> is_signed;
293 } imnmx;
294
295 union {
281 BitField<54, 1, u64> saturate; 296 BitField<54, 1, u64> saturate;
282 BitField<56, 1, u64> negate_a; 297 BitField<56, 1, u64> negate_a;
283 } iadd32i; 298 } iadd32i;
@@ -328,6 +343,19 @@ union Instruction {
328 } isetp; 343 } isetp;
329 344
330 union { 345 union {
346 BitField<0, 3, u64> pred0;
347 BitField<3, 3, u64> pred3;
348 BitField<12, 3, u64> pred12;
349 BitField<15, 1, u64> neg_pred12;
350 BitField<24, 2, PredOperation> cond;
351 BitField<29, 3, u64> pred29;
352 BitField<32, 1, u64> neg_pred29;
353 BitField<39, 3, u64> pred39;
354 BitField<42, 1, u64> neg_pred39;
355 BitField<45, 2, PredOperation> op;
356 } psetp;
357
358 union {
331 BitField<39, 3, u64> pred39; 359 BitField<39, 3, u64> pred39;
332 BitField<42, 1, u64> neg_pred; 360 BitField<42, 1, u64> neg_pred;
333 BitField<43, 1, u64> neg_a; 361 BitField<43, 1, u64> neg_a;
@@ -437,6 +465,8 @@ public:
437 enum class Id { 465 enum class Id {
438 KIL, 466 KIL,
439 SSY, 467 SSY,
468 SYNC,
469 DEPBAR,
440 BFE_C, 470 BFE_C,
441 BFE_R, 471 BFE_R,
442 BFE_IMM, 472 BFE_IMM,
@@ -533,6 +563,7 @@ public:
533 Shift, 563 Shift,
534 Ffma, 564 Ffma,
535 Flow, 565 Flow,
566 Synch,
536 Memory, 567 Memory,
537 FloatSet, 568 FloatSet,
538 FloatSetPredicate, 569 FloatSetPredicate,
@@ -637,10 +668,12 @@ private:
637 INST("111000110011----", Id::KIL, Type::Flow, "KIL"), 668 INST("111000110011----", Id::KIL, Type::Flow, "KIL"),
638 INST("111000101001----", Id::SSY, Type::Flow, "SSY"), 669 INST("111000101001----", Id::SSY, Type::Flow, "SSY"),
639 INST("111000100100----", Id::BRA, Type::Flow, "BRA"), 670 INST("111000100100----", Id::BRA, Type::Flow, "BRA"),
671 INST("1111000011110---", Id::DEPBAR, Type::Synch, "DEPBAR"),
672 INST("1111000011111---", Id::SYNC, Type::Synch, "SYNC"),
640 INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"), 673 INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"),
641 INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"), 674 INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"),
642 INST("1110111111110---", Id::ST_A, Type::Memory, "ST_A"), 675 INST("1110111111110---", Id::ST_A, Type::Memory, "ST_A"),
643 INST("1100000000111---", Id::TEX, Type::Memory, "TEX"), 676 INST("110000----111---", Id::TEX, Type::Memory, "TEX"),
644 INST("1101111101001---", Id::TEXQ, Type::Memory, "TEXQ"), 677 INST("1101111101001---", Id::TEXQ, Type::Memory, "TEXQ"),
645 INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"), 678 INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"),
646 INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"), 679 INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"),
@@ -681,9 +714,9 @@ private:
681 INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"), 714 INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"),
682 INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"), 715 INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"),
683 INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), 716 INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"),
684 INST("0100110000100---", Id::IMNMX_C, Type::Arithmetic, "FMNMX_IMM"), 717 INST("0100110000100---", Id::IMNMX_C, Type::ArithmeticInteger, "IMNMX_C"),
685 INST("0101110000100---", Id::IMNMX_R, Type::Arithmetic, "FMNMX_IMM"), 718 INST("0101110000100---", Id::IMNMX_R, Type::ArithmeticInteger, "IMNMX_R"),
686 INST("0011100-00100---", Id::IMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), 719 INST("0011100-00100---", Id::IMNMX_IMM, Type::ArithmeticInteger, "IMNMX_IMM"),
687 INST("0100110000000---", Id::BFE_C, Type::Bfe, "BFE_C"), 720 INST("0100110000000---", Id::BFE_C, Type::Bfe, "BFE_C"),
688 INST("0101110000000---", Id::BFE_R, Type::Bfe, "BFE_R"), 721 INST("0101110000000---", Id::BFE_R, Type::Bfe, "BFE_R"),
689 INST("0011100-00000---", Id::BFE_IMM, Type::Bfe, "BFE_IMM"), 722 INST("0011100-00000---", Id::BFE_IMM, Type::Bfe, "BFE_IMM"),
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 7b4e9b842..cc5ca656e 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -16,6 +16,7 @@ namespace Tegra {
16enum class RenderTargetFormat : u32 { 16enum class RenderTargetFormat : u32 {
17 NONE = 0x0, 17 NONE = 0x0,
18 RGBA32_FLOAT = 0xC0, 18 RGBA32_FLOAT = 0xC0,
19 RGBA32_UINT = 0xC2,
19 RGBA16_FLOAT = 0xCA, 20 RGBA16_FLOAT = 0xCA,
20 RGB10_A2_UNORM = 0xD1, 21 RGB10_A2_UNORM = 0xD1,
21 RGBA8_UNORM = 0xD5, 22 RGBA8_UNORM = 0xD5,
@@ -23,6 +24,15 @@ enum class RenderTargetFormat : u32 {
23 R11G11B10_FLOAT = 0xE0, 24 R11G11B10_FLOAT = 0xE0,
24}; 25};
25 26
27enum class DepthFormat : u32 {
28 Z32_FLOAT = 0xA,
29 Z16_UNORM = 0x13,
30 S8_Z24_UNORM = 0x14,
31 Z24_X8_UNORM = 0x15,
32 Z24_S8_UNORM = 0x16,
33 Z24_C8_UNORM = 0x18,
34};
35
26/// Returns the number of bytes per pixel of each rendertarget format. 36/// Returns the number of bytes per pixel of each rendertarget format.
27u32 RenderTargetBytesPerPixel(RenderTargetFormat format); 37u32 RenderTargetBytesPerPixel(RenderTargetFormat format);
28 38
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index 5cefce9fc..2f814a184 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -100,9 +100,9 @@ boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
100 100
101boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { 101boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) {
102 VAddr base_addr = PageSlot(gpu_addr); 102 VAddr base_addr = PageSlot(gpu_addr);
103 ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped));
104 103
105 if (base_addr == static_cast<u64>(PageStatus::Allocated)) { 104 if (base_addr == static_cast<u64>(PageStatus::Allocated) ||
105 base_addr == static_cast<u64>(PageStatus::Unmapped)) {
106 return {}; 106 return {};
107 } 107 }
108 108
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index f0e48a802..499e84b89 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -19,6 +19,9 @@ public:
19 /// Draw the current batch of vertex arrays 19 /// Draw the current batch of vertex arrays
20 virtual void DrawArrays() = 0; 20 virtual void DrawArrays() = 0;
21 21
22 /// Clear the current framebuffer
23 virtual void Clear() = 0;
24
22 /// Notify rasterizer that the specified Maxwell register has been changed 25 /// Notify rasterizer that the specified Maxwell register has been changed
23 virtual void NotifyMaxwellRegisterChanged(u32 method) = 0; 26 virtual void NotifyMaxwellRegisterChanged(u32 method) = 0;
24 27
@@ -51,9 +54,8 @@ public:
51 } 54 }
52 55
53 /// Attempt to use a faster method to display the framebuffer to screen 56 /// Attempt to use a faster method to display the framebuffer to screen
54 virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& framebuffer, 57 virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
55 VAddr framebuffer_addr, u32 pixel_stride, 58 u32 pixel_stride, ScreenInfo& screen_info) {
56 ScreenInfo& screen_info) {
57 return false; 59 return false;
58 } 60 }
59 61
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 3ba20f978..ea138d402 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -112,7 +112,7 @@ RasterizerOpenGL::RasterizerOpenGL() {
112 112
113 glEnable(GL_BLEND); 113 glEnable(GL_BLEND);
114 114
115 NGLOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!"); 115 LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!");
116} 116}
117 117
118RasterizerOpenGL::~RasterizerOpenGL() { 118RasterizerOpenGL::~RasterizerOpenGL() {
@@ -146,7 +146,6 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
146 u64 size = end - start + 1; 146 u64 size = end - start + 1;
147 147
148 // Copy vertex array data 148 // Copy vertex array data
149 res_cache.FlushRegion(start, size, nullptr);
150 Memory::ReadBlock(*memory_manager->GpuToCpuAddress(start), array_ptr, size); 149 Memory::ReadBlock(*memory_manager->GpuToCpuAddress(start), array_ptr, size);
151 150
152 // Bind the vertex array to the buffer at the current offset. 151 // Bind the vertex array to the buffer at the current offset.
@@ -166,9 +165,9 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
166 // assume every shader uses them all. 165 // assume every shader uses them all.
167 for (unsigned index = 0; index < 16; ++index) { 166 for (unsigned index = 0; index < 16; ++index) {
168 auto& attrib = regs.vertex_attrib_format[index]; 167 auto& attrib = regs.vertex_attrib_format[index];
169 NGLOG_DEBUG(HW_GPU, "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}", 168 LOG_DEBUG(HW_GPU, "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}",
170 index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(), 169 index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(),
171 attrib.offset.Value(), attrib.IsNormalized()); 170 attrib.offset.Value(), attrib.IsNormalized());
172 171
173 auto& buffer = regs.vertex_array[attrib.buffer]; 172 auto& buffer = regs.vertex_array[attrib.buffer];
174 ASSERT(buffer.IsEnabled()); 173 ASSERT(buffer.IsEnabled());
@@ -197,8 +196,8 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) {
197 ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!"); 196 ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!");
198 197
199 // Next available bindpoints to use when uploading the const buffers and textures to the GLSL 198 // Next available bindpoints to use when uploading the const buffers and textures to the GLSL
200 // shaders. 199 // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points.
201 u32 current_constbuffer_bindpoint = 0; 200 u32 current_constbuffer_bindpoint = uniform_buffers.size();
202 u32 current_texture_bindpoint = 0; 201 u32 current_texture_bindpoint = 0;
203 202
204 for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) { 203 for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) {
@@ -252,8 +251,8 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) {
252 break; 251 break;
253 } 252 }
254 default: 253 default:
255 NGLOG_CRITICAL(HW_GPU, "Unimplemented shader index={}, enable={}, offset=0x{:08X}", 254 LOG_CRITICAL(HW_GPU, "Unimplemented shader index={}, enable={}, offset=0x{:08X}", index,
256 index, shader_config.enable.Value(), shader_config.offset); 255 shader_config.enable.Value(), shader_config.offset);
257 UNREACHABLE(); 256 UNREACHABLE();
258 } 257 }
259 258
@@ -298,17 +297,16 @@ bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) {
298 return true; 297 return true;
299} 298}
300 299
301void RasterizerOpenGL::DrawArrays() { 300std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb,
302 if (accelerate_draw == AccelDraw::Disabled) 301 bool using_depth_fb) {
303 return;
304
305 MICROPROFILE_SCOPE(OpenGL_Drawing);
306 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; 302 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
307 303
308 // TODO(bunnei): Implement these 304 // Sync the depth test state before configuring the framebuffer surfaces.
305 SyncDepthTestState();
306
307 // TODO(bunnei): Implement this
309 const bool has_stencil = false; 308 const bool has_stencil = false;
310 const bool using_color_fb = true; 309
311 const bool using_depth_fb = false;
312 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; 310 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
313 311
314 const bool write_color_fb = 312 const bool write_color_fb =
@@ -325,35 +323,21 @@ void RasterizerOpenGL::DrawArrays() {
325 std::tie(color_surface, depth_surface, surfaces_rect) = 323 std::tie(color_surface, depth_surface, surfaces_rect) =
326 res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect); 324 res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect);
327 325
328 const u16 res_scale = color_surface != nullptr
329 ? color_surface->res_scale
330 : (depth_surface == nullptr ? 1u : depth_surface->res_scale);
331
332 MathUtil::Rectangle<u32> draw_rect{ 326 MathUtil::Rectangle<u32> draw_rect{
327 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left,
328 surfaces_rect.left, surfaces_rect.right)), // Left
329 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.top,
330 surfaces_rect.bottom, surfaces_rect.top)), // Top
331 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.right,
332 surfaces_rect.left, surfaces_rect.right)), // Right
333 static_cast<u32>( 333 static_cast<u32>(
334 std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left * res_scale, 334 std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.bottom,
335 surfaces_rect.left, surfaces_rect.right)), // Left 335 surfaces_rect.bottom, surfaces_rect.top))}; // Bottom
336 static_cast<u32>(
337 std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.top * res_scale,
338 surfaces_rect.bottom, surfaces_rect.top)), // Top
339 static_cast<u32>(
340 std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.right * res_scale,
341 surfaces_rect.left, surfaces_rect.right)), // Right
342 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) +
343 viewport_rect.bottom * res_scale,
344 surfaces_rect.bottom, surfaces_rect.top))}; // Bottom
345 336
346 // Bind the framebuffer surfaces 337 // Bind the framebuffer surfaces
347 BindFramebufferSurfaces(color_surface, depth_surface, has_stencil); 338 BindFramebufferSurfaces(color_surface, depth_surface, has_stencil);
348 339
349 // Sync the viewport 340 SyncViewport(surfaces_rect);
350 SyncViewport(surfaces_rect, res_scale);
351
352 // Sync the blend state registers
353 SyncBlendState();
354
355 // TODO(bunnei): Sync framebuffer_scale uniform here
356 // TODO(bunnei): Sync scissorbox uniform(s) here
357 341
358 // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable 342 // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable
359 // scissor test to prevent drawing outside of the framebuffer region 343 // scissor test to prevent drawing outside of the framebuffer region
@@ -364,6 +348,66 @@ void RasterizerOpenGL::DrawArrays() {
364 state.scissor.height = draw_rect.GetHeight(); 348 state.scissor.height = draw_rect.GetHeight();
365 state.Apply(); 349 state.Apply();
366 350
351 // Only return the surface to be marked as dirty if writing to it is enabled.
352 return std::make_pair(write_color_fb ? color_surface : nullptr,
353 write_depth_fb ? depth_surface : nullptr);
354}
355
356void RasterizerOpenGL::Clear() {
357 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
358
359 bool use_color_fb = false;
360 bool use_depth_fb = false;
361
362 GLbitfield clear_mask = 0;
363 if (regs.clear_buffers.R && regs.clear_buffers.G && regs.clear_buffers.B &&
364 regs.clear_buffers.A) {
365 clear_mask |= GL_COLOR_BUFFER_BIT;
366 use_color_fb = true;
367 }
368 if (regs.clear_buffers.Z) {
369 clear_mask |= GL_DEPTH_BUFFER_BIT;
370 use_depth_fb = true;
371 }
372
373 if (clear_mask == 0)
374 return;
375
376 auto [dirty_color_surface, dirty_depth_surface] =
377 ConfigureFramebuffers(use_color_fb, use_depth_fb);
378
379 // TODO(Subv): Support clearing only partial colors.
380 glClearColor(regs.clear_color[0], regs.clear_color[1], regs.clear_color[2],
381 regs.clear_color[3]);
382 glClearDepth(regs.clear_depth);
383
384 glClear(clear_mask);
385
386 // Mark framebuffer surfaces as dirty
387 if (dirty_color_surface != nullptr) {
388 res_cache.MarkSurfaceAsDirty(dirty_color_surface);
389 }
390 if (dirty_depth_surface != nullptr) {
391 res_cache.MarkSurfaceAsDirty(dirty_depth_surface);
392 }
393}
394
395void RasterizerOpenGL::DrawArrays() {
396 if (accelerate_draw == AccelDraw::Disabled)
397 return;
398
399 MICROPROFILE_SCOPE(OpenGL_Drawing);
400 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
401
402 auto [dirty_color_surface, dirty_depth_surface] =
403 ConfigureFramebuffers(true, regs.zeta.Address() != 0);
404
405 SyncBlendState();
406 SyncCullMode();
407
408 // TODO(bunnei): Sync framebuffer_scale uniform here
409 // TODO(bunnei): Sync scissorbox uniform(s) here
410
367 // Draw the vertex batch 411 // Draw the vertex batch
368 const bool is_indexed = accelerate_draw == AccelDraw::Indexed; 412 const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
369 const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; 413 const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()};
@@ -420,14 +464,16 @@ void RasterizerOpenGL::DrawArrays() {
420 464
421 const GLenum primitive_mode{MaxwellToGL::PrimitiveTopology(regs.draw.topology)}; 465 const GLenum primitive_mode{MaxwellToGL::PrimitiveTopology(regs.draw.topology)};
422 if (is_indexed) { 466 if (is_indexed) {
423 const GLint index_min{static_cast<GLint>(regs.index_array.first)}; 467 const GLint base_vertex{static_cast<GLint>(regs.vb_element_base)};
424 const GLint index_max{static_cast<GLint>(regs.index_array.first + regs.index_array.count)}; 468
425 glDrawRangeElementsBaseVertex(primitive_mode, index_min, index_max, regs.index_array.count, 469 // Adjust the index buffer offset so it points to the first desired index.
426 MaxwellToGL::IndexFormat(regs.index_array.format), 470 index_buffer_offset += regs.index_array.first * regs.index_array.FormatSizeInBytes();
427 reinterpret_cast<const void*>(index_buffer_offset), 471
428 -index_min); 472 glDrawElementsBaseVertex(primitive_mode, regs.index_array.count,
473 MaxwellToGL::IndexFormat(regs.index_array.format),
474 reinterpret_cast<const void*>(index_buffer_offset), base_vertex);
429 } else { 475 } else {
430 glDrawArrays(primitive_mode, 0, regs.vertex_buffer.count); 476 glDrawArrays(primitive_mode, regs.vertex_buffer.first, regs.vertex_buffer.count);
431 } 477 }
432 478
433 // Disable scissor test 479 // Disable scissor test
@@ -437,24 +483,16 @@ void RasterizerOpenGL::DrawArrays() {
437 483
438 // Unbind textures for potential future use as framebuffer attachments 484 // Unbind textures for potential future use as framebuffer attachments
439 for (auto& texture_unit : state.texture_units) { 485 for (auto& texture_unit : state.texture_units) {
440 texture_unit.texture_2d = 0; 486 texture_unit.Unbind();
441 } 487 }
442 state.Apply(); 488 state.Apply();
443 489
444 // Mark framebuffer surfaces as dirty 490 // Mark framebuffer surfaces as dirty
445 MathUtil::Rectangle<u32> draw_rect_unscaled{ 491 if (dirty_color_surface != nullptr) {
446 draw_rect.left / res_scale, draw_rect.top / res_scale, draw_rect.right / res_scale, 492 res_cache.MarkSurfaceAsDirty(dirty_color_surface);
447 draw_rect.bottom / res_scale};
448
449 if (color_surface != nullptr && write_color_fb) {
450 auto interval = color_surface->GetSubRectInterval(draw_rect_unscaled);
451 res_cache.InvalidateRegion(boost::icl::first(interval), boost::icl::length(interval),
452 color_surface);
453 } 493 }
454 if (depth_surface != nullptr && write_depth_fb) { 494 if (dirty_depth_surface != nullptr) {
455 auto interval = depth_surface->GetSubRectInterval(draw_rect_unscaled); 495 res_cache.MarkSurfaceAsDirty(dirty_depth_surface);
456 res_cache.InvalidateRegion(boost::icl::first(interval), boost::icl::length(interval),
457 depth_surface);
458 } 496 }
459} 497}
460 498
@@ -462,7 +500,7 @@ void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 method) {}
462 500
463void RasterizerOpenGL::FlushAll() { 501void RasterizerOpenGL::FlushAll() {
464 MICROPROFILE_SCOPE(OpenGL_CacheManagement); 502 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
465 res_cache.FlushAll(); 503 res_cache.FlushRegion(0, Kernel::VMManager::MAX_ADDRESS);
466} 504}
467 505
468void RasterizerOpenGL::FlushRegion(Tegra::GPUVAddr addr, u64 size) { 506void RasterizerOpenGL::FlushRegion(Tegra::GPUVAddr addr, u64 size) {
@@ -472,13 +510,13 @@ void RasterizerOpenGL::FlushRegion(Tegra::GPUVAddr addr, u64 size) {
472 510
473void RasterizerOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, u64 size) { 511void RasterizerOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, u64 size) {
474 MICROPROFILE_SCOPE(OpenGL_CacheManagement); 512 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
475 res_cache.InvalidateRegion(addr, size, nullptr); 513 res_cache.InvalidateRegion(addr, size);
476} 514}
477 515
478void RasterizerOpenGL::FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) { 516void RasterizerOpenGL::FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) {
479 MICROPROFILE_SCOPE(OpenGL_CacheManagement); 517 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
480 res_cache.FlushRegion(addr, size); 518 res_cache.FlushRegion(addr, size);
481 res_cache.InvalidateRegion(addr, size, nullptr); 519 res_cache.InvalidateRegion(addr, size);
482} 520}
483 521
484bool RasterizerOpenGL::AccelerateDisplayTransfer(const void* config) { 522bool RasterizerOpenGL::AccelerateDisplayTransfer(const void* config) {
@@ -497,45 +535,28 @@ bool RasterizerOpenGL::AccelerateFill(const void* config) {
497 return true; 535 return true;
498} 536}
499 537
500bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebuffer, 538bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
501 VAddr framebuffer_addr, u32 pixel_stride, 539 VAddr framebuffer_addr, u32 pixel_stride,
502 ScreenInfo& screen_info) { 540 ScreenInfo& screen_info) {
503 if (framebuffer_addr == 0) { 541 if (!framebuffer_addr) {
504 return false; 542 return {};
505 } 543 }
544
506 MICROPROFILE_SCOPE(OpenGL_CacheManagement); 545 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
507 546
508 SurfaceParams src_params; 547 const auto& surface{res_cache.TryFindFramebufferSurface(framebuffer_addr)};
509 src_params.cpu_addr = framebuffer_addr; 548 if (!surface) {
510 src_params.addr = res_cache.TryFindFramebufferGpuAddress(framebuffer_addr).get_value_or(0); 549 return {};
511 src_params.width = std::min(framebuffer.width, pixel_stride);
512 src_params.height = framebuffer.height;
513 src_params.stride = pixel_stride;
514 src_params.is_tiled = true;
515 src_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight;
516 src_params.pixel_format =
517 SurfaceParams::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format);
518 src_params.component_type =
519 SurfaceParams::ComponentTypeFromGPUPixelFormat(framebuffer.pixel_format);
520 src_params.UpdateParams();
521
522 MathUtil::Rectangle<u32> src_rect;
523 Surface src_surface;
524 std::tie(src_surface, src_rect) =
525 res_cache.GetSurfaceSubRect(src_params, ScaleMatch::Ignore, true);
526
527 if (src_surface == nullptr) {
528 return false;
529 } 550 }
530 551
531 u32 scaled_width = src_surface->GetScaledWidth(); 552 // Verify that the cached surface is the same size and format as the requested framebuffer
532 u32 scaled_height = src_surface->GetScaledHeight(); 553 const auto& params{surface->GetSurfaceParams()};
533 554 const auto& pixel_format{SurfaceParams::PixelFormatFromGPUPixelFormat(config.pixel_format)};
534 screen_info.display_texcoords = MathUtil::Rectangle<float>( 555 ASSERT_MSG(params.width == config.width, "Framebuffer width is different");
535 (float)src_rect.bottom / (float)scaled_height, (float)src_rect.left / (float)scaled_width, 556 ASSERT_MSG(params.height == config.height, "Framebuffer height is different");
536 (float)src_rect.top / (float)scaled_height, (float)src_rect.right / (float)scaled_width); 557 ASSERT_MSG(params.pixel_format == pixel_format, "Framebuffer pixel_format is different");
537 558
538 screen_info.display_texture = src_surface->texture.handle; 559 screen_info.display_texture = surface->Texture().handle;
539 560
540 return true; 561 return true;
541} 562}
@@ -608,27 +629,39 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr
608 629
609 boost::optional<VAddr> addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); 630 boost::optional<VAddr> addr = gpu.memory_manager->GpuToCpuAddress(buffer.address);
610 631
611 std::vector<u8> data; 632 size_t size = 0;
633
612 if (used_buffer.IsIndirect()) { 634 if (used_buffer.IsIndirect()) {
613 // Buffer is accessed indirectly, so upload the entire thing 635 // Buffer is accessed indirectly, so upload the entire thing
614 data.resize(buffer.size * sizeof(float)); 636 size = buffer.size * sizeof(float);
637
638 if (size > MaxConstbufferSize) {
639 LOG_ERROR(HW_GPU, "indirect constbuffer size {} exceeds maximum {}", size,
640 MaxConstbufferSize);
641 size = MaxConstbufferSize;
642 }
615 } else { 643 } else {
616 // Buffer is accessed directly, upload just what we use 644 // Buffer is accessed directly, upload just what we use
617 data.resize(used_buffer.GetSize() * sizeof(float)); 645 size = used_buffer.GetSize() * sizeof(float);
618 } 646 }
619 647
648 // Align the actual size so it ends up being a multiple of vec4 to meet the OpenGL std140
649 // UBO alignment requirements.
650 size = Common::AlignUp(size, sizeof(GLvec4));
651 ASSERT_MSG(size <= MaxConstbufferSize, "Constbuffer too big");
652
653 std::vector<u8> data(size);
620 Memory::ReadBlock(*addr, data.data(), data.size()); 654 Memory::ReadBlock(*addr, data.data(), data.size());
621 655
622 glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo); 656 glBindBuffer(GL_UNIFORM_BUFFER, buffer_draw_state.ssbo);
623 glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); 657 glBufferData(GL_UNIFORM_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW);
624 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 658 glBindBuffer(GL_UNIFORM_BUFFER, 0);
625 659
626 // Now configure the bindpoint of the buffer inside the shader 660 // Now configure the bindpoint of the buffer inside the shader
627 std::string buffer_name = used_buffer.GetName(); 661 std::string buffer_name = used_buffer.GetName();
628 GLuint index = 662 GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, buffer_name.c_str());
629 glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, buffer_name.c_str());
630 if (index != -1) 663 if (index != -1)
631 glShaderStorageBlockBinding(program, index, buffer_draw_state.bindpoint); 664 glUniformBlockBinding(program, index, buffer_draw_state.bindpoint);
632 } 665 }
633 666
634 state.Apply(); 667 state.Apply();
@@ -653,16 +686,23 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, GLuint program,
653 686
654 // Bind the uniform to the sampler. 687 // Bind the uniform to the sampler.
655 GLint uniform = glGetUniformLocation(program, entry.GetName().c_str()); 688 GLint uniform = glGetUniformLocation(program, entry.GetName().c_str());
656 ASSERT(uniform != -1); 689 if (uniform == -1) {
690 continue;
691 }
692
657 glProgramUniform1i(program, uniform, current_bindpoint); 693 glProgramUniform1i(program, uniform, current_bindpoint);
658 694
659 const auto texture = maxwell3d.GetStageTexture(entry.GetStage(), entry.GetOffset()); 695 const auto texture = maxwell3d.GetStageTexture(entry.GetStage(), entry.GetOffset());
660 ASSERT(texture.enabled); 696
697 if (!texture.enabled) {
698 state.texture_units[current_bindpoint].texture_2d = 0;
699 continue;
700 }
661 701
662 texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); 702 texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc);
663 Surface surface = res_cache.GetTextureSurface(texture); 703 Surface surface = res_cache.GetTextureSurface(texture);
664 if (surface != nullptr) { 704 if (surface != nullptr) {
665 state.texture_units[current_bindpoint].texture_2d = surface->texture.handle; 705 state.texture_units[current_bindpoint].texture_2d = surface->Texture().handle;
666 state.texture_units[current_bindpoint].swizzle.r = 706 state.texture_units[current_bindpoint].swizzle.r =
667 MaxwellToGL::SwizzleSource(texture.tic.x_source); 707 MaxwellToGL::SwizzleSource(texture.tic.x_source);
668 state.texture_units[current_bindpoint].swizzle.g = 708 state.texture_units[current_bindpoint].swizzle.g =
@@ -688,16 +728,16 @@ void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface,
688 state.Apply(); 728 state.Apply();
689 729
690 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 730 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
691 color_surface != nullptr ? color_surface->texture.handle : 0, 0); 731 color_surface != nullptr ? color_surface->Texture().handle : 0, 0);
692 if (depth_surface != nullptr) { 732 if (depth_surface != nullptr) {
693 if (has_stencil) { 733 if (has_stencil) {
694 // attach both depth and stencil 734 // attach both depth and stencil
695 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 735 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
696 depth_surface->texture.handle, 0); 736 depth_surface->Texture().handle, 0);
697 } else { 737 } else {
698 // attach depth 738 // attach depth
699 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 739 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
700 depth_surface->texture.handle, 0); 740 depth_surface->Texture().handle, 0);
701 // clear stencil attachment 741 // clear stencil attachment
702 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); 742 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
703 } 743 }
@@ -708,14 +748,14 @@ void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface,
708 } 748 }
709} 749}
710 750
711void RasterizerOpenGL::SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale) { 751void RasterizerOpenGL::SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect) {
712 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; 752 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
713 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; 753 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
714 754
715 state.viewport.x = static_cast<GLint>(surfaces_rect.left) + viewport_rect.left * res_scale; 755 state.viewport.x = static_cast<GLint>(surfaces_rect.left) + viewport_rect.left;
716 state.viewport.y = static_cast<GLint>(surfaces_rect.bottom) + viewport_rect.bottom * res_scale; 756 state.viewport.y = static_cast<GLint>(surfaces_rect.bottom) + viewport_rect.bottom;
717 state.viewport.width = static_cast<GLsizei>(viewport_rect.GetWidth() * res_scale); 757 state.viewport.width = static_cast<GLsizei>(viewport_rect.GetWidth());
718 state.viewport.height = static_cast<GLsizei>(viewport_rect.GetHeight() * res_scale); 758 state.viewport.height = static_cast<GLsizei>(viewport_rect.GetHeight());
719} 759}
720 760
721void RasterizerOpenGL::SyncClipEnabled() { 761void RasterizerOpenGL::SyncClipEnabled() {
@@ -727,7 +767,27 @@ void RasterizerOpenGL::SyncClipCoef() {
727} 767}
728 768
729void RasterizerOpenGL::SyncCullMode() { 769void RasterizerOpenGL::SyncCullMode() {
730 UNREACHABLE(); 770 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
771
772 state.cull.enabled = regs.cull.enabled != 0;
773
774 if (state.cull.enabled) {
775 state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face);
776 state.cull.mode = MaxwellToGL::CullFace(regs.cull.cull_face);
777
778 const bool flip_triangles{regs.screen_y_control.triangle_rast_flip == 0 ||
779 regs.viewport_transform[0].scale_y < 0.0f};
780
781 // If the GPU is configured to flip the rasterized triangles, then we need to flip the
782 // notion of front and back. Note: We flip the triangles when the value of the register is 0
783 // because OpenGL already does it for us.
784 if (flip_triangles) {
785 if (state.cull.front_face == GL_CCW)
786 state.cull.front_face = GL_CW;
787 else if (state.cull.front_face == GL_CW)
788 state.cull.front_face = GL_CCW;
789 }
790 }
731} 791}
732 792
733void RasterizerOpenGL::SyncDepthScale() { 793void RasterizerOpenGL::SyncDepthScale() {
@@ -738,6 +798,18 @@ void RasterizerOpenGL::SyncDepthOffset() {
738 UNREACHABLE(); 798 UNREACHABLE();
739} 799}
740 800
801void RasterizerOpenGL::SyncDepthTestState() {
802 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
803
804 state.depth.test_enabled = regs.depth_test_enable != 0;
805 state.depth.write_mask = regs.depth_write_enabled ? GL_TRUE : GL_FALSE;
806
807 if (!state.depth.test_enabled)
808 return;
809
810 state.depth.test_func = MaxwellToGL::ComparisonOp(regs.depth_test_func);
811}
812
741void RasterizerOpenGL::SyncBlendState() { 813void RasterizerOpenGL::SyncBlendState() {
742 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; 814 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
743 815
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index b7c8cf843..c406142e4 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -7,6 +7,7 @@
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include <memory> 9#include <memory>
10#include <utility>
10#include <vector> 11#include <vector>
11#include <glad/glad.h> 12#include <glad/glad.h>
12#include "common/common_types.h" 13#include "common/common_types.h"
@@ -28,6 +29,7 @@ public:
28 ~RasterizerOpenGL() override; 29 ~RasterizerOpenGL() override;
29 30
30 void DrawArrays() override; 31 void DrawArrays() override;
32 void Clear() override;
31 void NotifyMaxwellRegisterChanged(u32 method) override; 33 void NotifyMaxwellRegisterChanged(u32 method) override;
32 void FlushAll() override; 34 void FlushAll() override;
33 void FlushRegion(Tegra::GPUVAddr addr, u64 size) override; 35 void FlushRegion(Tegra::GPUVAddr addr, u64 size) override;
@@ -54,6 +56,11 @@ public:
54 OGLShader shader; 56 OGLShader shader;
55 }; 57 };
56 58
59 /// Maximum supported size that a constbuffer can have in bytes.
60 static constexpr size_t MaxConstbufferSize = 0x10000;
61 static_assert(MaxConstbufferSize % sizeof(GLvec4) == 0,
62 "The maximum size of a constbuffer must be a multiple of the size of GLvec4");
63
57private: 64private:
58 class SamplerInfo { 65 class SamplerInfo {
59 public: 66 public:
@@ -76,6 +83,10 @@ private:
76 u32 border_color_a; 83 u32 border_color_a;
77 }; 84 };
78 85
86 /// Configures the color and depth framebuffer states and returns the dirty <Color, Depth>
87 /// surfaces if writing was enabled.
88 std::pair<Surface, Surface> ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb);
89
79 /// Binds the framebuffer color and depth surface 90 /// Binds the framebuffer color and depth surface
80 void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface, 91 void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface,
81 bool has_stencil); 92 bool has_stencil);
@@ -104,7 +115,7 @@ private:
104 u32 current_unit, const std::vector<GLShader::SamplerEntry>& entries); 115 u32 current_unit, const std::vector<GLShader::SamplerEntry>& entries);
105 116
106 /// Syncs the viewport to match the guest state 117 /// Syncs the viewport to match the guest state
107 void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale); 118 void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect);
108 119
109 /// Syncs the clip enabled status to match the guest state 120 /// Syncs the clip enabled status to match the guest state
110 void SyncClipEnabled(); 121 void SyncClipEnabled();
@@ -121,6 +132,9 @@ private:
121 /// Syncs the depth offset to match the guest state 132 /// Syncs the depth offset to match the guest state
122 void SyncDepthOffset(); 133 void SyncDepthOffset();
123 134
135 /// Syncs the depth test state to match the guest state
136 void SyncDepthTestState();
137
124 /// Syncs the blend state to match the guest state 138 /// Syncs the blend state to match the guest state
125 void SyncBlendState(); 139 void SyncBlendState();
126 140
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 61d670dcb..323ff7408 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -1,37 +1,23 @@
1// Copyright 2015 Citra Emulator Project 1// Copyright 2018 yuzu Emulator Project
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 <algorithm> 5#include <algorithm>
6#include <atomic>
7#include <cstring>
8#include <iterator>
9#include <memory>
10#include <utility>
11#include <vector>
12#include <boost/optional.hpp>
13#include <boost/range/iterator_range.hpp>
14#include <glad/glad.h> 6#include <glad/glad.h>
7
15#include "common/alignment.h" 8#include "common/alignment.h"
16#include "common/bit_field.h" 9#include "common/assert.h"
17#include "common/color.h"
18#include "common/logging/log.h"
19#include "common/math_util.h"
20#include "common/microprofile.h" 10#include "common/microprofile.h"
21#include "common/scope_exit.h" 11#include "common/scope_exit.h"
22#include "core/core.h" 12#include "core/core.h"
23#include "core/frontend/emu_window.h"
24#include "core/hle/kernel/process.h" 13#include "core/hle/kernel/process.h"
25#include "core/hle/kernel/vm_manager.h"
26#include "core/memory.h" 14#include "core/memory.h"
27#include "core/settings.h" 15#include "core/settings.h"
28#include "video_core/engines/maxwell_3d.h" 16#include "video_core/engines/maxwell_3d.h"
29#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 17#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
30#include "video_core/renderer_opengl/gl_state.h"
31#include "video_core/textures/astc.h" 18#include "video_core/textures/astc.h"
32#include "video_core/textures/decoders.h" 19#include "video_core/textures/decoders.h"
33#include "video_core/utils.h" 20#include "video_core/utils.h"
34#include "video_core/video_core.h"
35 21
36using SurfaceType = SurfaceParams::SurfaceType; 22using SurfaceType = SurfaceParams::SurfaceType;
37using PixelFormat = SurfaceParams::PixelFormat; 23using PixelFormat = SurfaceParams::PixelFormat;
@@ -41,113 +27,178 @@ struct FormatTuple {
41 GLint internal_format; 27 GLint internal_format;
42 GLenum format; 28 GLenum format;
43 GLenum type; 29 GLenum type;
30 ComponentType component_type;
44 bool compressed; 31 bool compressed;
45}; 32};
46 33
34/*static*/ SurfaceParams SurfaceParams::CreateForTexture(
35 const Tegra::Texture::FullTextureInfo& config) {
36
37 SurfaceParams params{};
38 params.addr = config.tic.Address();
39 params.is_tiled = config.tic.IsTiled();
40 params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0,
41 params.pixel_format = PixelFormatFromTextureFormat(config.tic.format);
42 params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value());
43 params.type = GetFormatType(params.pixel_format);
44 params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format));
45 params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format));
46 params.unaligned_height = config.tic.Height();
47 params.size_in_bytes = params.SizeInBytes();
48 return params;
49}
50
51/*static*/ SurfaceParams SurfaceParams::CreateForFramebuffer(
52 const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config) {
53
54 SurfaceParams params{};
55 params.addr = config.Address();
56 params.is_tiled = true;
57 params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight;
58 params.pixel_format = PixelFormatFromRenderTargetFormat(config.format);
59 params.component_type = ComponentTypeFromRenderTarget(config.format);
60 params.type = GetFormatType(params.pixel_format);
61 params.width = config.width;
62 params.height = config.height;
63 params.unaligned_height = config.height;
64 params.size_in_bytes = params.SizeInBytes();
65 return params;
66}
67
68/*static*/ SurfaceParams SurfaceParams::CreateForDepthBuffer(
69 const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config, Tegra::GPUVAddr zeta_address,
70 Tegra::DepthFormat format) {
71
72 SurfaceParams params{};
73 params.addr = zeta_address;
74 params.is_tiled = true;
75 params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight;
76 params.pixel_format = PixelFormatFromDepthFormat(format);
77 params.component_type = ComponentTypeFromDepthFormat(format);
78 params.type = GetFormatType(params.pixel_format);
79 params.size_in_bytes = params.SizeInBytes();
80 params.width = config.width;
81 params.height = config.height;
82 params.unaligned_height = config.height;
83 params.size_in_bytes = params.SizeInBytes();
84 return params;
85}
86
47static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ 87static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{
48 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8 88 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8
49 {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, false}, // B5G6R5 89 {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, ComponentType::UNorm, false}, // B5G6R5
50 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false}, // A2B10G10R10 90 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, ComponentType::UNorm,
51 {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, false}, // A1B5G5R5 91 false}, // A2B10G10R10
52 {GL_R8, GL_RED, GL_UNSIGNED_BYTE, false}, // R8 92 {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ComponentType::UNorm, false}, // A1B5G5R5
53 {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, false}, // RGBA16F 93 {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // R8
54 {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, false}, // R11FG11FB10F 94 {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, ComponentType::Float, false}, // RGBA16F
55 {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT1 95 {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, ComponentType::Float,
56 {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23 96 false}, // R11FG11FB10F
57 {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45 97 {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RGBA32UI
58 {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, true}, // DXN1 98 {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm,
59 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_4X4 99 true}, // DXT1
100 {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm,
101 true}, // DXT23
102 {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm,
103 true}, // DXT45
104 {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // DXN1
105 {GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm,
106 true}, // BC7U
107 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4
108
109 // DepthStencil formats
110 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm,
111 false}, // Z24S8
112 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm,
113 false}, // S8Z24
114 {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, ComponentType::Float, false}, // Z32F
60}}; 115}};
61 116
62static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { 117static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) {
63 const SurfaceType type = SurfaceParams::GetFormatType(pixel_format); 118 ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size());
64 if (type == SurfaceType::ColorTexture) { 119 auto& format = tex_format_tuples[static_cast<unsigned int>(pixel_format)];
65 ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size()); 120 ASSERT(component_type == format.component_type);
66 // For now only UNORM components are supported, or either R11FG11FB10F or RGBA16F which are
67 // type FLOAT
68 ASSERT(component_type == ComponentType::UNorm || pixel_format == PixelFormat::RGBA16F ||
69 pixel_format == PixelFormat::R11FG11FB10F);
70 return tex_format_tuples[static_cast<unsigned int>(pixel_format)];
71 } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) {
72 // TODO(Subv): Implement depth formats
73 ASSERT_MSG(false, "Unimplemented");
74 }
75 121
76 UNREACHABLE(); 122 return format;
77 return {};
78} 123}
79 124
80template <typename Map, typename Interval> 125VAddr SurfaceParams::GetCpuAddr() const {
81constexpr auto RangeFromInterval(Map& map, const Interval& interval) { 126 const auto& gpu = Core::System::GetInstance().GPU();
82 return boost::make_iterator_range(map.equal_range(interval)); 127 return *gpu.memory_manager->GpuToCpuAddress(addr);
83} 128}
84 129
85static u16 GetResolutionScaleFactor() { 130static bool IsPixelFormatASTC(PixelFormat format) {
86 return static_cast<u16>(!Settings::values.resolution_factor 131 switch (format) {
87 ? VideoCore::g_emu_window->GetFramebufferLayout().GetScalingRatio() 132 case PixelFormat::ASTC_2D_4X4:
88 : Settings::values.resolution_factor); 133 return true;
134 default:
135 return false;
136 }
89} 137}
90 138
91static void ConvertASTCToRGBA8(std::vector<u8>& data, PixelFormat format, u32 width, u32 height) { 139static std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
92 u32 block_width{};
93 u32 block_height{};
94
95 switch (format) { 140 switch (format) {
96 case PixelFormat::ASTC_2D_4X4: 141 case PixelFormat::ASTC_2D_4X4:
97 block_width = 4; 142 return {4, 4};
98 block_height = 4;
99 break;
100 default: 143 default:
101 NGLOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format)); 144 LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format));
102 UNREACHABLE(); 145 UNREACHABLE();
103 } 146 }
147}
104 148
105 data = Tegra::Texture::ASTC::Decompress(data, width, height, block_width, block_height); 149MathUtil::Rectangle<u32> SurfaceParams::GetRect() const {
150 u32 actual_height{unaligned_height};
151 if (IsPixelFormatASTC(pixel_format)) {
152 // ASTC formats must stop at the ATSC block size boundary
153 actual_height = Common::AlignDown(actual_height, GetASTCBlockSize(pixel_format).second);
154 }
155 return {0, actual_height, width, 0};
106} 156}
107 157
108template <bool morton_to_gl, PixelFormat format> 158template <bool morton_to_gl, PixelFormat format>
109void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::GPUVAddr base, 159void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::GPUVAddr addr) {
110 Tegra::GPUVAddr start, Tegra::GPUVAddr end) {
111 constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / CHAR_BIT; 160 constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / CHAR_BIT;
112 constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); 161 constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format);
113 const auto& gpu = Core::System::GetInstance().GPU(); 162 const auto& gpu = Core::System::GetInstance().GPU();
114 163
115 if (morton_to_gl) { 164 if (morton_to_gl) {
116 auto data = Tegra::Texture::UnswizzleTexture( 165 if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) {
117 *gpu.memory_manager->GpuToCpuAddress(base), 166 auto data = Tegra::Texture::UnswizzleTexture(
118 SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); 167 *gpu.memory_manager->GpuToCpuAddress(addr),
119 168 SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height);
120 if (SurfaceParams::IsFormatASTC(format)) { 169 std::memcpy(gl_buffer, data.data(), data.size());
121 // ASTC formats are converted to RGBA8 in software, as most PC GPUs do not support this 170 } else {
122 ConvertASTCToRGBA8(data, format, stride, height); 171 auto data = Tegra::Texture::UnswizzleDepthTexture(
172 *gpu.memory_manager->GpuToCpuAddress(addr),
173 SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height);
174 std::memcpy(gl_buffer, data.data(), data.size());
123 } 175 }
124
125 std::memcpy(gl_buffer, data.data(), data.size());
126 } else { 176 } else {
127 // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check 177 // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should
128 // the configuration for this and perform more generic un/swizzle 178 // check the configuration for this and perform more generic un/swizzle
129 NGLOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); 179 LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!");
130 VideoCore::MortonCopyPixels128( 180 VideoCore::MortonCopyPixels128(
131 stride, height, bytes_per_pixel, gl_bytes_per_pixel, 181 stride, height, bytes_per_pixel, gl_bytes_per_pixel,
132 Memory::GetPointer(*gpu.memory_manager->GpuToCpuAddress(base)), gl_buffer, 182 Memory::GetPointer(*gpu.memory_manager->GpuToCpuAddress(addr)), gl_buffer,
133 morton_to_gl); 183 morton_to_gl);
134 } 184 }
135} 185}
136 186
137static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr, Tegra::GPUVAddr, 187static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
138 Tegra::GPUVAddr),
139 SurfaceParams::MaxPixelFormat> 188 SurfaceParams::MaxPixelFormat>
140 morton_to_gl_fns = { 189 morton_to_gl_fns = {
141 MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>, 190 MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>,
142 MortonCopy<true, PixelFormat::A2B10G10R10>, MortonCopy<true, PixelFormat::A1B5G5R5>, 191 MortonCopy<true, PixelFormat::A2B10G10R10>, MortonCopy<true, PixelFormat::A1B5G5R5>,
143 MortonCopy<true, PixelFormat::R8>, MortonCopy<true, PixelFormat::RGBA16F>, 192 MortonCopy<true, PixelFormat::R8>, MortonCopy<true, PixelFormat::RGBA16F>,
144 MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::DXT1>, 193 MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::RGBA32UI>,
145 MortonCopy<true, PixelFormat::DXT23>, MortonCopy<true, PixelFormat::DXT45>, 194 MortonCopy<true, PixelFormat::DXT1>, MortonCopy<true, PixelFormat::DXT23>,
146 MortonCopy<true, PixelFormat::DXN1>, MortonCopy<true, PixelFormat::ASTC_2D_4X4>, 195 MortonCopy<true, PixelFormat::DXT45>, MortonCopy<true, PixelFormat::DXN1>,
196 MortonCopy<true, PixelFormat::BC7U>, MortonCopy<true, PixelFormat::ASTC_2D_4X4>,
197 MortonCopy<true, PixelFormat::Z24S8>, MortonCopy<true, PixelFormat::S8Z24>,
198 MortonCopy<true, PixelFormat::Z32F>,
147}; 199};
148 200
149static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr, Tegra::GPUVAddr, 201static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr),
150 Tegra::GPUVAddr),
151 SurfaceParams::MaxPixelFormat> 202 SurfaceParams::MaxPixelFormat>
152 gl_to_morton_fns = { 203 gl_to_morton_fns = {
153 MortonCopy<false, PixelFormat::ABGR8>, 204 MortonCopy<false, PixelFormat::ABGR8>,
@@ -157,12 +208,17 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr, Tegra:
157 MortonCopy<false, PixelFormat::R8>, 208 MortonCopy<false, PixelFormat::R8>,
158 MortonCopy<false, PixelFormat::RGBA16F>, 209 MortonCopy<false, PixelFormat::RGBA16F>,
159 MortonCopy<false, PixelFormat::R11FG11FB10F>, 210 MortonCopy<false, PixelFormat::R11FG11FB10F>,
160 // TODO(Subv): Swizzling the DXT1/DXT23/DXT45/DXN1 formats is not yet supported 211 MortonCopy<false, PixelFormat::RGBA32UI>,
212 // TODO(Subv): Swizzling the DXT1/DXT23/DXT45/DXN1/BC7U formats is not yet supported
213 nullptr,
161 nullptr, 214 nullptr,
162 nullptr, 215 nullptr,
163 nullptr, 216 nullptr,
164 nullptr, 217 nullptr,
165 MortonCopy<false, PixelFormat::ABGR8>, 218 MortonCopy<false, PixelFormat::ABGR8>,
219 MortonCopy<false, PixelFormat::Z24S8>,
220 MortonCopy<false, PixelFormat::S8Z24>,
221 MortonCopy<false, PixelFormat::Z32F>,
166}; 222};
167 223
168// Allocate an uninitialized texture of appropriate size and format for the surface 224// Allocate an uninitialized texture of appropriate size and format for the surface
@@ -192,374 +248,144 @@ static void AllocateSurfaceTexture(GLuint texture, const FormatTuple& format_tup
192 cur_state.Apply(); 248 cur_state.Apply();
193} 249}
194 250
195static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect, GLuint dst_tex, 251CachedSurface::CachedSurface(const SurfaceParams& params) : params(params) {
196 const MathUtil::Rectangle<u32>& dst_rect, SurfaceType type, 252 texture.Create();
197 GLuint read_fb_handle, GLuint draw_fb_handle) { 253 const auto& rect{params.GetRect()};
198 254 AllocateSurfaceTexture(texture.handle,
199 glCopyImageSubData(src_tex, GL_TEXTURE_2D, 0, src_rect.left, src_rect.bottom, 0, dst_tex, 255 GetFormatTuple(params.pixel_format, params.component_type),
200 GL_TEXTURE_2D, 0, dst_rect.left, dst_rect.bottom, 0, src_rect.GetWidth(), 256 rect.GetWidth(), rect.GetHeight());
201 src_rect.GetHeight(), 0); 257}
202 return true; 258
203} 259static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) {
204 260 union S8Z24 {
205static bool FillSurface(const Surface& surface, const u8* fill_data, 261 BitField<0, 24, u32> z24;
206 const MathUtil::Rectangle<u32>& fill_rect, GLuint draw_fb_handle) { 262 BitField<24, 8, u32> s8;
207 UNREACHABLE(); 263 };
208 return {}; 264 static_assert(sizeof(S8Z24) == 4, "S8Z24 is incorrect size");
209} 265
210 266 union Z24S8 {
211SurfaceParams SurfaceParams::FromInterval(SurfaceInterval interval) const { 267 BitField<0, 8, u32> s8;
212 SurfaceParams params = *this; 268 BitField<8, 24, u32> z24;
213 const u32 tiled_size = is_tiled ? 8 : 1; 269 };
214 const u64 stride_tiled_bytes = BytesInPixels(stride * tiled_size); 270 static_assert(sizeof(Z24S8) == 4, "Z24S8 is incorrect size");
215 Tegra::GPUVAddr aligned_start = 271
216 addr + Common::AlignDown(boost::icl::first(interval) - addr, stride_tiled_bytes); 272 S8Z24 input_pixel{};
217 Tegra::GPUVAddr aligned_end = 273 Z24S8 output_pixel{};
218 addr + Common::AlignUp(boost::icl::last_next(interval) - addr, stride_tiled_bytes); 274 for (size_t y = 0; y < height; ++y) {
219 275 for (size_t x = 0; x < width; ++x) {
220 if (aligned_end - aligned_start > stride_tiled_bytes) { 276 const size_t offset{y * width + x};
221 params.addr = aligned_start; 277 std::memcpy(&input_pixel, &data[offset], sizeof(S8Z24));
222 params.height = static_cast<u32>((aligned_end - aligned_start) / BytesInPixels(stride)); 278 output_pixel.s8.Assign(input_pixel.s8);
223 } else { 279 output_pixel.z24.Assign(input_pixel.z24);
224 // 1 row 280 std::memcpy(&data[offset], &output_pixel, sizeof(Z24S8));
225 ASSERT(aligned_end - aligned_start == stride_tiled_bytes);
226 const u64 tiled_alignment = BytesInPixels(is_tiled ? 8 * 8 : 1);
227 aligned_start =
228 addr + Common::AlignDown(boost::icl::first(interval) - addr, tiled_alignment);
229 aligned_end =
230 addr + Common::AlignUp(boost::icl::last_next(interval) - addr, tiled_alignment);
231 params.addr = aligned_start;
232 params.width = static_cast<u32>(PixelsInBytes(aligned_end - aligned_start) / tiled_size);
233 params.stride = params.width;
234 params.height = tiled_size;
235 }
236 params.UpdateParams();
237
238 return params;
239}
240
241SurfaceInterval SurfaceParams::GetSubRectInterval(MathUtil::Rectangle<u32> unscaled_rect) const {
242 if (unscaled_rect.GetHeight() == 0 || unscaled_rect.GetWidth() == 0) {
243 return {};
244 }
245
246 if (is_tiled) {
247 unscaled_rect.left = Common::AlignDown(unscaled_rect.left, 8) * 8;
248 unscaled_rect.bottom = Common::AlignDown(unscaled_rect.bottom, 8) / 8;
249 unscaled_rect.right = Common::AlignUp(unscaled_rect.right, 8) * 8;
250 unscaled_rect.top = Common::AlignUp(unscaled_rect.top, 8) / 8;
251 }
252
253 const u32 stride_tiled = !is_tiled ? stride : stride * 8;
254
255 const u32 pixel_offset =
256 stride_tiled * (!is_tiled ? unscaled_rect.bottom : (height / 8) - unscaled_rect.top) +
257 unscaled_rect.left;
258
259 const u32 pixels = (unscaled_rect.GetHeight() - 1) * stride_tiled + unscaled_rect.GetWidth();
260
261 return {addr + BytesInPixels(pixel_offset), addr + BytesInPixels(pixel_offset + pixels)};
262}
263
264MathUtil::Rectangle<u32> SurfaceParams::GetSubRect(const SurfaceParams& sub_surface) const {
265 const u32 begin_pixel_index = static_cast<u32>(PixelsInBytes(sub_surface.addr - addr));
266
267 if (is_tiled) {
268 const int x0 = (begin_pixel_index % (stride * 8)) / 8;
269 const int y0 = (begin_pixel_index / (stride * 8)) * 8;
270 // Top to bottom
271 return MathUtil::Rectangle<u32>(x0, height - y0, x0 + sub_surface.width,
272 height - (y0 + sub_surface.height));
273 }
274
275 const int x0 = begin_pixel_index % stride;
276 const int y0 = begin_pixel_index / stride;
277 // Bottom to top
278 return MathUtil::Rectangle<u32>(x0, y0 + sub_surface.height, x0 + sub_surface.width, y0);
279}
280
281MathUtil::Rectangle<u32> SurfaceParams::GetScaledSubRect(const SurfaceParams& sub_surface) const {
282 auto rect = GetSubRect(sub_surface);
283 rect.left = rect.left * res_scale;
284 rect.right = rect.right * res_scale;
285 rect.top = rect.top * res_scale;
286 rect.bottom = rect.bottom * res_scale;
287 return rect;
288}
289
290bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const {
291 return std::tie(other_surface.addr, other_surface.width, other_surface.height,
292 other_surface.stride, other_surface.block_height, other_surface.pixel_format,
293 other_surface.component_type,
294 other_surface.is_tiled) == std::tie(addr, width, height, stride, block_height,
295 pixel_format, component_type, is_tiled) &&
296 pixel_format != PixelFormat::Invalid;
297}
298
299bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const {
300 return sub_surface.addr >= addr && sub_surface.end <= end &&
301 sub_surface.pixel_format == pixel_format && pixel_format != PixelFormat::Invalid &&
302 sub_surface.is_tiled == is_tiled && sub_surface.block_height == block_height &&
303 sub_surface.component_type == component_type &&
304 (sub_surface.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0 &&
305 (sub_surface.stride == stride || sub_surface.height <= (is_tiled ? 8u : 1u)) &&
306 GetSubRect(sub_surface).left + sub_surface.width <= stride;
307}
308
309bool SurfaceParams::CanExpand(const SurfaceParams& expanded_surface) const {
310 return pixel_format != PixelFormat::Invalid && pixel_format == expanded_surface.pixel_format &&
311 addr <= expanded_surface.end && expanded_surface.addr <= end &&
312 is_tiled == expanded_surface.is_tiled && block_height == expanded_surface.block_height &&
313 component_type == expanded_surface.component_type && stride == expanded_surface.stride &&
314 (std::max(expanded_surface.addr, addr) - std::min(expanded_surface.addr, addr)) %
315 BytesInPixels(stride * (is_tiled ? 8 : 1)) ==
316 0;
317}
318
319bool SurfaceParams::CanTexCopy(const SurfaceParams& texcopy_params) const {
320 if (pixel_format == PixelFormat::Invalid || addr > texcopy_params.addr ||
321 end < texcopy_params.end) {
322 return false;
323 }
324 if (texcopy_params.block_height != block_height ||
325 texcopy_params.component_type != component_type)
326 return false;
327
328 if (texcopy_params.width != texcopy_params.stride) {
329 const u32 tile_stride = static_cast<u32>(BytesInPixels(stride * (is_tiled ? 8 : 1)));
330 return (texcopy_params.addr - addr) % BytesInPixels(is_tiled ? 64 : 1) == 0 &&
331 texcopy_params.width % BytesInPixels(is_tiled ? 64 : 1) == 0 &&
332 (texcopy_params.height == 1 || texcopy_params.stride == tile_stride) &&
333 ((texcopy_params.addr - addr) % tile_stride) + texcopy_params.width <= tile_stride;
334 }
335 return FromInterval(texcopy_params.GetInterval()).GetInterval() == texcopy_params.GetInterval();
336}
337
338VAddr SurfaceParams::GetCpuAddr() const {
339 // When this function is used, only cpu_addr or (GPU) addr should be set, not both
340 ASSERT(!(cpu_addr && addr));
341 const auto& gpu = Core::System::GetInstance().GPU();
342 return cpu_addr.get_value_or(*gpu.memory_manager->GpuToCpuAddress(addr));
343}
344
345bool CachedSurface::CanFill(const SurfaceParams& dest_surface,
346 SurfaceInterval fill_interval) const {
347 if (type == SurfaceType::Fill && IsRegionValid(fill_interval) &&
348 boost::icl::first(fill_interval) >= addr &&
349 boost::icl::last_next(fill_interval) <= end && // dest_surface is within our fill range
350 dest_surface.FromInterval(fill_interval).GetInterval() ==
351 fill_interval) { // make sure interval is a rectangle in dest surface
352 if (fill_size * CHAR_BIT != dest_surface.GetFormatBpp()) {
353 // Check if bits repeat for our fill_size
354 const u32 dest_bytes_per_pixel = std::max(dest_surface.GetFormatBpp() / CHAR_BIT, 1u);
355 std::vector<u8> fill_test(fill_size * dest_bytes_per_pixel);
356
357 for (u32 i = 0; i < dest_bytes_per_pixel; ++i)
358 std::memcpy(&fill_test[i * fill_size], &fill_data[0], fill_size);
359
360 for (u32 i = 0; i < fill_size; ++i)
361 if (std::memcmp(&fill_test[dest_bytes_per_pixel * i], &fill_test[0],
362 dest_bytes_per_pixel) != 0)
363 return false;
364
365 if (dest_surface.GetFormatBpp() == 4 && (fill_test[0] & 0xF) != (fill_test[0] >> 4))
366 return false;
367 } 281 }
368 return true;
369 } 282 }
370 return false;
371} 283}
372 284/**
373bool CachedSurface::CanCopy(const SurfaceParams& dest_surface, 285 * Helper function to perform software conversion (as needed) when loading a buffer from Switch
374 SurfaceInterval copy_interval) const { 286 * memory. This is for Maxwell pixel formats that cannot be represented as-is in OpenGL or with
375 SurfaceParams subrect_params = dest_surface.FromInterval(copy_interval); 287 * typical desktop GPUs.
376 ASSERT(subrect_params.GetInterval() == copy_interval); 288 */
377 if (CanSubRect(subrect_params)) 289static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelFormat pixel_format,
378 return true; 290 u32 width, u32 height) {
379 291 switch (pixel_format) {
380 if (CanFill(dest_surface, copy_interval)) 292 case PixelFormat::ASTC_2D_4X4: {
381 return true; 293 // Convert ASTC pixel formats to RGBA8, as most desktop GPUs do not support ASTC.
382 294 u32 block_width{};
383 return false; 295 u32 block_height{};
384} 296 std::tie(block_width, block_height) = GetASTCBlockSize(pixel_format);
385 297 data = Tegra::Texture::ASTC::Decompress(data, width, height, block_width, block_height);
386SurfaceInterval SurfaceParams::GetCopyableInterval(const Surface& src_surface) const { 298 break;
387 SurfaceInterval result{}; 299 }
388 const auto valid_regions = 300 case PixelFormat::S8Z24:
389 SurfaceRegions(GetInterval() & src_surface->GetInterval()) - src_surface->invalid_regions; 301 // Convert the S8Z24 depth format to Z24S8, as OpenGL does not support S8Z24.
390 for (auto& valid_interval : valid_regions) { 302 ConvertS8Z24ToZ24S8(data, width, height);
391 const SurfaceInterval aligned_interval{ 303 break;
392 addr + Common::AlignUp(boost::icl::first(valid_interval) - addr,
393 BytesInPixels(is_tiled ? 8 * 8 : 1)),
394 addr + Common::AlignDown(boost::icl::last_next(valid_interval) - addr,
395 BytesInPixels(is_tiled ? 8 * 8 : 1))};
396
397 if (BytesInPixels(is_tiled ? 8 * 8 : 1) > boost::icl::length(valid_interval) ||
398 boost::icl::length(aligned_interval) == 0) {
399 continue;
400 }
401
402 // Get the rectangle within aligned_interval
403 const u32 stride_bytes = static_cast<u32>(BytesInPixels(stride)) * (is_tiled ? 8 : 1);
404 SurfaceInterval rect_interval{
405 addr + Common::AlignUp(boost::icl::first(aligned_interval) - addr, stride_bytes),
406 addr + Common::AlignDown(boost::icl::last_next(aligned_interval) - addr, stride_bytes),
407 };
408 if (boost::icl::first(rect_interval) > boost::icl::last_next(rect_interval)) {
409 // 1 row
410 rect_interval = aligned_interval;
411 } else if (boost::icl::length(rect_interval) == 0) {
412 // 2 rows that do not make a rectangle, return the larger one
413 const SurfaceInterval row1{boost::icl::first(aligned_interval),
414 boost::icl::first(rect_interval)};
415 const SurfaceInterval row2{boost::icl::first(rect_interval),
416 boost::icl::last_next(aligned_interval)};
417 rect_interval = (boost::icl::length(row1) > boost::icl::length(row2)) ? row1 : row2;
418 }
419
420 if (boost::icl::length(rect_interval) > boost::icl::length(result)) {
421 result = rect_interval;
422 }
423 } 304 }
424 return result;
425} 305}
426 306
427void RasterizerCacheOpenGL::CopySurface(const Surface& src_surface, const Surface& dst_surface, 307/**
428 SurfaceInterval copy_interval) { 308 * Helper function to perform software conversion (as needed) when flushing a buffer to Switch
429 SurfaceParams subrect_params = dst_surface->FromInterval(copy_interval); 309 * memory. This is for Maxwell pixel formats that cannot be represented as-is in OpenGL or with
430 ASSERT(subrect_params.GetInterval() == copy_interval); 310 * typical desktop GPUs.
431 311 */
432 ASSERT(src_surface != dst_surface); 312static void ConvertFormatAsNeeded_FlushGLBuffer(std::vector<u8>& /*data*/, PixelFormat pixel_format,
433 313 u32 /*width*/, u32 /*height*/) {
434 // This is only called when CanCopy is true, no need to run checks here 314 switch (pixel_format) {
435 if (src_surface->type == SurfaceType::Fill) { 315 case PixelFormat::ASTC_2D_4X4:
436 // FillSurface needs a 4 bytes buffer 316 case PixelFormat::S8Z24:
437 const u64 fill_offset = 317 LOG_CRITICAL(Render_OpenGL, "Unimplemented pixel_format={}",
438 (boost::icl::first(copy_interval) - src_surface->addr) % src_surface->fill_size; 318 static_cast<u32>(pixel_format));
439 std::array<u8, 4> fill_buffer; 319 UNREACHABLE();
440 320 break;
441 u64 fill_buff_pos = fill_offset;
442 for (int i : {0, 1, 2, 3})
443 fill_buffer[i] = src_surface->fill_data[fill_buff_pos++ % src_surface->fill_size];
444
445 FillSurface(dst_surface, &fill_buffer[0], dst_surface->GetScaledSubRect(subrect_params),
446 draw_framebuffer.handle);
447 return;
448 }
449 if (src_surface->CanSubRect(subrect_params)) {
450 BlitTextures(src_surface->texture.handle, src_surface->GetScaledSubRect(subrect_params),
451 dst_surface->texture.handle, dst_surface->GetScaledSubRect(subrect_params),
452 src_surface->type, read_framebuffer.handle, draw_framebuffer.handle);
453 return;
454 } 321 }
455 UNREACHABLE();
456} 322}
457 323
458MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); 324MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192));
459void CachedSurface::LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr load_end) { 325void CachedSurface::LoadGLBuffer() {
460 ASSERT(type != SurfaceType::Fill); 326 ASSERT(params.type != SurfaceType::Fill);
461 327
462 u8* const texture_src_data = Memory::GetPointer(GetCpuAddr()); 328 u8* const texture_src_data = Memory::GetPointer(params.GetCpuAddr());
463 if (texture_src_data == nullptr)
464 return;
465 329
466 if (gl_buffer == nullptr) { 330 ASSERT(texture_src_data);
467 gl_buffer_size = GetActualWidth() * GetActualHeight() * GetGLBytesPerPixel(pixel_format);
468 gl_buffer.reset(new u8[gl_buffer_size]);
469 }
470 331
471 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); 332 gl_buffer.resize(params.width * params.height * GetGLBytesPerPixel(params.pixel_format));
472 333
473 ASSERT(load_start >= addr && load_end <= end); 334 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad);
474 const u64 start_offset = load_start - addr;
475 335
476 if (!is_tiled) { 336 if (!params.is_tiled) {
477 const u32 bytes_per_pixel{GetFormatBpp() >> 3}; 337 const u32 bytes_per_pixel{params.GetFormatBpp() >> 3};
478 338
479 std::memcpy(&gl_buffer[start_offset], texture_src_data + start_offset, 339 std::memcpy(gl_buffer.data(), texture_src_data,
480 bytes_per_pixel * width * height); 340 bytes_per_pixel * params.width * params.height);
481 } else { 341 } else {
482 morton_to_gl_fns[static_cast<size_t>(pixel_format)](GetActualWidth(), block_height, 342 morton_to_gl_fns[static_cast<size_t>(params.pixel_format)](
483 GetActualHeight(), &gl_buffer[0], addr, 343 params.width, params.block_height, params.height, gl_buffer.data(), params.addr);
484 load_start, load_end);
485 } 344 }
345
346 ConvertFormatAsNeeded_LoadGLBuffer(gl_buffer, params.pixel_format, params.width, params.height);
486} 347}
487 348
488MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64)); 349MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64));
489void CachedSurface::FlushGLBuffer(Tegra::GPUVAddr flush_start, Tegra::GPUVAddr flush_end) { 350void CachedSurface::FlushGLBuffer() {
490 u8* const dst_buffer = Memory::GetPointer(GetCpuAddr()); 351 u8* const dst_buffer = Memory::GetPointer(params.GetCpuAddr());
491 if (dst_buffer == nullptr)
492 return;
493
494 ASSERT(gl_buffer_size == width * height * GetGLBytesPerPixel(pixel_format));
495 352
496 // TODO: Should probably be done in ::Memory:: and check for other regions too 353 ASSERT(dst_buffer);
497 // same as loadglbuffer() 354 ASSERT(gl_buffer.size() ==
498 if (flush_start < Memory::VRAM_VADDR_END && flush_end > Memory::VRAM_VADDR_END) 355 params.width * params.height * GetGLBytesPerPixel(params.pixel_format));
499 flush_end = Memory::VRAM_VADDR_END;
500
501 if (flush_start < Memory::VRAM_VADDR && flush_end > Memory::VRAM_VADDR)
502 flush_start = Memory::VRAM_VADDR;
503 356
504 MICROPROFILE_SCOPE(OpenGL_SurfaceFlush); 357 MICROPROFILE_SCOPE(OpenGL_SurfaceFlush);
505 358
506 ASSERT(flush_start >= addr && flush_end <= end); 359 ConvertFormatAsNeeded_FlushGLBuffer(gl_buffer, params.pixel_format, params.width,
507 const u64 start_offset = flush_start - addr; 360 params.height);
508 const u64 end_offset = flush_end - addr;
509
510 if (type == SurfaceType::Fill) {
511 const u64 coarse_start_offset = start_offset - (start_offset % fill_size);
512 const u64 backup_bytes = start_offset % fill_size;
513 std::array<u8, 4> backup_data;
514 if (backup_bytes)
515 std::memcpy(&backup_data[0], &dst_buffer[coarse_start_offset], backup_bytes);
516 361
517 for (u64 offset = coarse_start_offset; offset < end_offset; offset += fill_size) { 362 if (!params.is_tiled) {
518 std::memcpy(&dst_buffer[offset], &fill_data[0], 363 std::memcpy(dst_buffer, gl_buffer.data(), params.size_in_bytes);
519 std::min(fill_size, end_offset - offset));
520 }
521
522 if (backup_bytes)
523 std::memcpy(&dst_buffer[coarse_start_offset], &backup_data[0], backup_bytes);
524 } else if (!is_tiled) {
525 std::memcpy(dst_buffer + start_offset, &gl_buffer[start_offset], flush_end - flush_start);
526 } else { 364 } else {
527 gl_to_morton_fns[static_cast<size_t>(pixel_format)]( 365 gl_to_morton_fns[static_cast<size_t>(params.pixel_format)](
528 stride, block_height, height, &gl_buffer[0], addr, flush_start, flush_end); 366 params.width, params.block_height, params.height, gl_buffer.data(), params.addr);
529 } 367 }
530} 368}
531 369
532MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); 370MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192));
533void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, 371void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) {
534 GLuint draw_fb_handle) { 372 if (params.type == SurfaceType::Fill)
535 if (type == SurfaceType::Fill)
536 return; 373 return;
537 374
538 MICROPROFILE_SCOPE(OpenGL_TextureUL); 375 MICROPROFILE_SCOPE(OpenGL_TextureUL);
539 376
540 ASSERT(gl_buffer_size == 377 ASSERT(gl_buffer.size() ==
541 GetActualWidth() * GetActualHeight() * GetGLBytesPerPixel(pixel_format)); 378 params.width * params.height * GetGLBytesPerPixel(params.pixel_format));
379
380 const auto& rect{params.GetRect()};
542 381
543 // Load data from memory to the surface 382 // Load data from memory to the surface
544 GLint x0 = static_cast<GLint>(rect.left); 383 GLint x0 = static_cast<GLint>(rect.left);
545 GLint y0 = static_cast<GLint>(rect.bottom); 384 GLint y0 = static_cast<GLint>(rect.bottom);
546 size_t buffer_offset = (y0 * stride + x0) * GetGLBytesPerPixel(pixel_format); 385 size_t buffer_offset = (y0 * params.width + x0) * GetGLBytesPerPixel(params.pixel_format);
547 386
548 const FormatTuple& tuple = GetFormatTuple(pixel_format, component_type); 387 const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type);
549 GLuint target_tex = texture.handle; 388 GLuint target_tex = texture.handle;
550
551 // If not 1x scale, create 1x texture that we will blit from to replace texture subrect in
552 // surface
553 OGLTexture unscaled_tex;
554 if (res_scale != 1) {
555 x0 = 0;
556 y0 = 0;
557
558 unscaled_tex.Create();
559 AllocateSurfaceTexture(unscaled_tex.handle, tuple, rect.GetWidth(), rect.GetHeight());
560 target_tex = unscaled_tex.handle;
561 }
562
563 OpenGLState cur_state = OpenGLState::GetCurState(); 389 OpenGLState cur_state = OpenGLState::GetCurState();
564 390
565 GLuint old_tex = cur_state.texture_units[0].texture_2d; 391 GLuint old_tex = cur_state.texture_units[0].texture_2d;
@@ -567,15 +393,15 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint
567 cur_state.Apply(); 393 cur_state.Apply();
568 394
569 // Ensure no bad interactions with GL_UNPACK_ALIGNMENT 395 // Ensure no bad interactions with GL_UNPACK_ALIGNMENT
570 ASSERT(stride * GetGLBytesPerPixel(pixel_format) % 4 == 0); 396 ASSERT(params.width * GetGLBytesPerPixel(params.pixel_format) % 4 == 0);
571 glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(stride)); 397 glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(params.width));
572 398
573 glActiveTexture(GL_TEXTURE0); 399 glActiveTexture(GL_TEXTURE0);
574 if (tuple.compressed) { 400 if (tuple.compressed) {
575 glCompressedTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, 401 glCompressedTexImage2D(
576 static_cast<GLsizei>(rect.GetWidth() * GetCompresssionFactor()), 402 GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width),
577 static_cast<GLsizei>(rect.GetHeight() * GetCompresssionFactor()), 0, 403 static_cast<GLsizei>(params.height), 0, static_cast<GLsizei>(params.size_in_bytes),
578 static_cast<GLsizei>(size), &gl_buffer[buffer_offset]); 404 &gl_buffer[buffer_offset]);
579 } else { 405 } else {
580 glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()), 406 glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
581 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, 407 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
@@ -586,827 +412,250 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint
586 412
587 cur_state.texture_units[0].texture_2d = old_tex; 413 cur_state.texture_units[0].texture_2d = old_tex;
588 cur_state.Apply(); 414 cur_state.Apply();
589
590 if (res_scale != 1) {
591 auto scaled_rect = rect;
592 scaled_rect.left *= res_scale;
593 scaled_rect.top *= res_scale;
594 scaled_rect.right *= res_scale;
595 scaled_rect.bottom *= res_scale;
596
597 BlitTextures(unscaled_tex.handle, {0, rect.GetHeight(), rect.GetWidth(), 0}, texture.handle,
598 scaled_rect, type, read_fb_handle, draw_fb_handle);
599 }
600} 415}
601 416
602MICROPROFILE_DEFINE(OpenGL_TextureDL, "OpenGL", "Texture Download", MP_RGB(128, 192, 64)); 417MICROPROFILE_DEFINE(OpenGL_TextureDL, "OpenGL", "Texture Download", MP_RGB(128, 192, 64));
603void CachedSurface::DownloadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, 418void CachedSurface::DownloadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) {
604 GLuint draw_fb_handle) { 419 if (params.type == SurfaceType::Fill)
605 if (type == SurfaceType::Fill)
606 return; 420 return;
607 421
608 MICROPROFILE_SCOPE(OpenGL_TextureDL); 422 MICROPROFILE_SCOPE(OpenGL_TextureDL);
609 423
610 if (gl_buffer == nullptr) { 424 gl_buffer.resize(params.width * params.height * GetGLBytesPerPixel(params.pixel_format));
611 gl_buffer_size = width * height * GetGLBytesPerPixel(pixel_format);
612 gl_buffer.reset(new u8[gl_buffer_size]);
613 }
614 425
615 OpenGLState state = OpenGLState::GetCurState(); 426 OpenGLState state = OpenGLState::GetCurState();
616 OpenGLState prev_state = state; 427 OpenGLState prev_state = state;
617 SCOPE_EXIT({ prev_state.Apply(); }); 428 SCOPE_EXIT({ prev_state.Apply(); });
618 429
619 const FormatTuple& tuple = GetFormatTuple(pixel_format, component_type); 430 const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type);
620 431
621 // Ensure no bad interactions with GL_PACK_ALIGNMENT 432 // Ensure no bad interactions with GL_PACK_ALIGNMENT
622 ASSERT(stride * GetGLBytesPerPixel(pixel_format) % 4 == 0); 433 ASSERT(params.width * GetGLBytesPerPixel(params.pixel_format) % 4 == 0);
623 glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(stride)); 434 glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(params.width));
624 size_t buffer_offset = (rect.bottom * stride + rect.left) * GetGLBytesPerPixel(pixel_format);
625
626 // If not 1x scale, blit scaled texture to a new 1x texture and use that to flush
627 if (res_scale != 1) {
628 auto scaled_rect = rect;
629 scaled_rect.left *= res_scale;
630 scaled_rect.top *= res_scale;
631 scaled_rect.right *= res_scale;
632 scaled_rect.bottom *= res_scale;
633
634 OGLTexture unscaled_tex;
635 unscaled_tex.Create();
636
637 MathUtil::Rectangle<u32> unscaled_tex_rect{0, rect.GetHeight(), rect.GetWidth(), 0};
638 AllocateSurfaceTexture(unscaled_tex.handle, tuple, rect.GetWidth(), rect.GetHeight());
639 BlitTextures(texture.handle, scaled_rect, unscaled_tex.handle, unscaled_tex_rect, type,
640 read_fb_handle, draw_fb_handle);
641
642 state.texture_units[0].texture_2d = unscaled_tex.handle;
643 state.Apply();
644
645 glActiveTexture(GL_TEXTURE0);
646 glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, &gl_buffer[buffer_offset]);
647 } else {
648 state.ResetTexture(texture.handle);
649 state.draw.read_framebuffer = read_fb_handle;
650 state.Apply();
651
652 if (type == SurfaceType::ColorTexture) {
653 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
654 texture.handle, 0);
655 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
656 0, 0);
657 } else if (type == SurfaceType::Depth) {
658 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
659 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
660 texture.handle, 0);
661 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
662 } else {
663 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
664 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
665 texture.handle, 0);
666 }
667 glReadPixels(static_cast<GLint>(rect.left), static_cast<GLint>(rect.bottom),
668 static_cast<GLsizei>(rect.GetWidth()), static_cast<GLsizei>(rect.GetHeight()),
669 tuple.format, tuple.type, &gl_buffer[buffer_offset]);
670 }
671
672 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
673}
674 435
675enum class MatchFlags { 436 const auto& rect{params.GetRect()};
676 None = 0, 437 size_t buffer_offset =
677 Invalid = 1, // Flag that can be applied to other match types, invalid matches require 438 (rect.bottom * params.width + rect.left) * GetGLBytesPerPixel(params.pixel_format);
678 // validation before they can be used
679 Exact = 1 << 1, // Surfaces perfectly match
680 SubRect = 1 << 2, // Surface encompasses params
681 Copy = 1 << 3, // Surface we can copy from
682 Expand = 1 << 4, // Surface that can expand params
683 TexCopy = 1 << 5 // Surface that will match a display transfer "texture copy" parameters
684};
685
686constexpr MatchFlags operator|(MatchFlags lhs, MatchFlags rhs) {
687 return static_cast<MatchFlags>(static_cast<int>(lhs) | static_cast<int>(rhs));
688}
689 439
690constexpr MatchFlags operator&(MatchFlags lhs, MatchFlags rhs) { 440 state.UnbindTexture(texture.handle);
691 return static_cast<MatchFlags>(static_cast<int>(lhs) & static_cast<int>(rhs)); 441 state.draw.read_framebuffer = read_fb_handle;
692} 442 state.Apply();
693 443
694/// Get the best surface match (and its match type) for the given flags 444 if (params.type == SurfaceType::ColorTexture) {
695template <MatchFlags find_flags> 445 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
696Surface FindMatch(const SurfaceCache& surface_cache, const SurfaceParams& params, 446 texture.handle, 0);
697 ScaleMatch match_scale_type, 447 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
698 boost::optional<SurfaceInterval> validate_interval = boost::none) { 448 0);
699 Surface match_surface = nullptr; 449 } else if (params.type == SurfaceType::Depth) {
700 bool match_valid = false; 450 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
701 u32 match_scale = 0; 451 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
702 SurfaceInterval match_interval{}; 452 texture.handle, 0);
703 453 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
704 for (auto& pair : RangeFromInterval(surface_cache, params.GetInterval())) { 454 } else {
705 for (auto& surface : pair.second) { 455 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
706 bool res_scale_matched = match_scale_type == ScaleMatch::Exact 456 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
707 ? (params.res_scale == surface->res_scale) 457 texture.handle, 0);
708 : (params.res_scale <= surface->res_scale);
709 // validity will be checked in GetCopyableInterval
710 bool is_valid =
711 (find_flags & MatchFlags::Copy) != MatchFlags::None
712 ? true
713 : surface->IsRegionValid(validate_interval.value_or(params.GetInterval()));
714
715 if ((find_flags & MatchFlags::Invalid) == MatchFlags::None && !is_valid)
716 continue;
717
718 auto IsMatch_Helper = [&](auto check_type, auto match_fn) {
719 if ((find_flags & check_type) == MatchFlags::None)
720 return;
721
722 bool matched;
723 SurfaceInterval surface_interval;
724 std::tie(matched, surface_interval) = match_fn();
725 if (!matched)
726 return;
727
728 if (!res_scale_matched && match_scale_type != ScaleMatch::Ignore &&
729 surface->type != SurfaceType::Fill)
730 return;
731
732 // Found a match, update only if this is better than the previous one
733 auto UpdateMatch = [&] {
734 match_surface = surface;
735 match_valid = is_valid;
736 match_scale = surface->res_scale;
737 match_interval = surface_interval;
738 };
739
740 if (surface->res_scale > match_scale) {
741 UpdateMatch();
742 return;
743 } else if (surface->res_scale < match_scale) {
744 return;
745 }
746
747 if (is_valid && !match_valid) {
748 UpdateMatch();
749 return;
750 } else if (is_valid != match_valid) {
751 return;
752 }
753
754 if (boost::icl::length(surface_interval) > boost::icl::length(match_interval)) {
755 UpdateMatch();
756 }
757 };
758 IsMatch_Helper(std::integral_constant<MatchFlags, MatchFlags::Exact>{}, [&] {
759 return std::make_pair(surface->ExactMatch(params), surface->GetInterval());
760 });
761 IsMatch_Helper(std::integral_constant<MatchFlags, MatchFlags::SubRect>{}, [&] {
762 return std::make_pair(surface->CanSubRect(params), surface->GetInterval());
763 });
764 IsMatch_Helper(std::integral_constant<MatchFlags, MatchFlags::Copy>{}, [&] {
765 auto copy_interval =
766 params.FromInterval(*validate_interval).GetCopyableInterval(surface);
767 bool matched = boost::icl::length(copy_interval & *validate_interval) != 0 &&
768 surface->CanCopy(params, copy_interval);
769 return std::make_pair(matched, copy_interval);
770 });
771 IsMatch_Helper(std::integral_constant<MatchFlags, MatchFlags::Expand>{}, [&] {
772 return std::make_pair(surface->CanExpand(params), surface->GetInterval());
773 });
774 IsMatch_Helper(std::integral_constant<MatchFlags, MatchFlags::TexCopy>{}, [&] {
775 return std::make_pair(surface->CanTexCopy(params), surface->GetInterval());
776 });
777 }
778 } 458 }
779 return match_surface; 459 glReadPixels(static_cast<GLint>(rect.left), static_cast<GLint>(rect.bottom),
460 static_cast<GLsizei>(rect.GetWidth()), static_cast<GLsizei>(rect.GetHeight()),
461 tuple.format, tuple.type, &gl_buffer[buffer_offset]);
462
463 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
780} 464}
781 465
782RasterizerCacheOpenGL::RasterizerCacheOpenGL() { 466RasterizerCacheOpenGL::RasterizerCacheOpenGL() {
783 read_framebuffer.Create(); 467 read_framebuffer.Create();
784 draw_framebuffer.Create(); 468 draw_framebuffer.Create();
785
786 attributeless_vao.Create();
787
788 d24s8_abgr_buffer.Create();
789 d24s8_abgr_buffer_size = 0;
790
791 const char* vs_source = R"(
792#version 330 core
793const vec2 vertices[4] = vec2[4](vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 1.0), vec2(1.0, 1.0));
794void main() {
795 gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0);
796}
797)";
798 const char* fs_source = R"(
799#version 330 core
800
801uniform samplerBuffer tbo;
802uniform vec2 tbo_size;
803uniform vec4 viewport;
804
805out vec4 color;
806
807void main() {
808 vec2 tbo_coord = (gl_FragCoord.xy - viewport.xy) * tbo_size / viewport.zw;
809 int tbo_offset = int(tbo_coord.y) * int(tbo_size.x) + int(tbo_coord.x);
810 color = texelFetch(tbo, tbo_offset).rabg;
811}
812)";
813 d24s8_abgr_shader.CreateFromSource(vs_source, nullptr, fs_source);
814
815 OpenGLState state = OpenGLState::GetCurState();
816 GLuint old_program = state.draw.shader_program;
817 state.draw.shader_program = d24s8_abgr_shader.handle;
818 state.Apply();
819
820 GLint tbo_u_id = glGetUniformLocation(d24s8_abgr_shader.handle, "tbo");
821 ASSERT(tbo_u_id != -1);
822 glUniform1i(tbo_u_id, 0);
823
824 state.draw.shader_program = old_program;
825 state.Apply();
826
827 d24s8_abgr_tbo_size_u_id = glGetUniformLocation(d24s8_abgr_shader.handle, "tbo_size");
828 ASSERT(d24s8_abgr_tbo_size_u_id != -1);
829 d24s8_abgr_viewport_u_id = glGetUniformLocation(d24s8_abgr_shader.handle, "viewport");
830 ASSERT(d24s8_abgr_viewport_u_id != -1);
831} 469}
832 470
833RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { 471RasterizerCacheOpenGL::~RasterizerCacheOpenGL() {
834 FlushAll(); 472 while (!surface_cache.empty()) {
835 while (!surface_cache.empty()) 473 UnregisterSurface(surface_cache.begin()->second);
836 UnregisterSurface(*surface_cache.begin()->second.begin());
837}
838
839bool RasterizerCacheOpenGL::BlitSurfaces(const Surface& src_surface,
840 const MathUtil::Rectangle<u32>& src_rect,
841 const Surface& dst_surface,
842 const MathUtil::Rectangle<u32>& dst_rect) {
843 if (!SurfaceParams::CheckFormatsBlittable(src_surface->pixel_format, dst_surface->pixel_format))
844 return false;
845
846 return BlitTextures(src_surface->texture.handle, src_rect, dst_surface->texture.handle,
847 dst_rect, src_surface->type, read_framebuffer.handle,
848 draw_framebuffer.handle);
849}
850
851void RasterizerCacheOpenGL::ConvertD24S8toABGR(GLuint src_tex,
852 const MathUtil::Rectangle<u32>& src_rect,
853 GLuint dst_tex,
854 const MathUtil::Rectangle<u32>& dst_rect) {
855 OpenGLState prev_state = OpenGLState::GetCurState();
856 SCOPE_EXIT({ prev_state.Apply(); });
857
858 OpenGLState state;
859 state.draw.read_framebuffer = read_framebuffer.handle;
860 state.draw.draw_framebuffer = draw_framebuffer.handle;
861 state.Apply();
862
863 glBindBuffer(GL_PIXEL_PACK_BUFFER, d24s8_abgr_buffer.handle);
864
865 GLsizeiptr target_pbo_size = src_rect.GetWidth() * src_rect.GetHeight() * 4;
866 if (target_pbo_size > d24s8_abgr_buffer_size) {
867 d24s8_abgr_buffer_size = target_pbo_size * 2;
868 glBufferData(GL_PIXEL_PACK_BUFFER, d24s8_abgr_buffer_size, nullptr, GL_STREAM_COPY);
869 } 474 }
870
871 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
872 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, src_tex,
873 0);
874 glReadPixels(static_cast<GLint>(src_rect.left), static_cast<GLint>(src_rect.bottom),
875 static_cast<GLsizei>(src_rect.GetWidth()),
876 static_cast<GLsizei>(src_rect.GetHeight()), GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
877 0);
878
879 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
880
881 // PBO now contains src_tex in RABG format
882 state.draw.shader_program = d24s8_abgr_shader.handle;
883 state.draw.vertex_array = attributeless_vao.handle;
884 state.viewport.x = static_cast<GLint>(dst_rect.left);
885 state.viewport.y = static_cast<GLint>(dst_rect.bottom);
886 state.viewport.width = static_cast<GLsizei>(dst_rect.GetWidth());
887 state.viewport.height = static_cast<GLsizei>(dst_rect.GetHeight());
888 state.Apply();
889
890 OGLTexture tbo;
891 tbo.Create();
892 glActiveTexture(GL_TEXTURE0);
893 glBindTexture(GL_TEXTURE_BUFFER, tbo.handle);
894 glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA8, d24s8_abgr_buffer.handle);
895
896 glUniform2f(d24s8_abgr_tbo_size_u_id, static_cast<GLfloat>(src_rect.GetWidth()),
897 static_cast<GLfloat>(src_rect.GetHeight()));
898 glUniform4f(d24s8_abgr_viewport_u_id, static_cast<GLfloat>(state.viewport.x),
899 static_cast<GLfloat>(state.viewport.y), static_cast<GLfloat>(state.viewport.width),
900 static_cast<GLfloat>(state.viewport.height));
901
902 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex, 0);
903 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
904 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
905
906 glBindTexture(GL_TEXTURE_BUFFER, 0);
907}
908
909Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale,
910 bool load_if_create) {
911 if (params.addr == 0 || params.height * params.width == 0) {
912 return nullptr;
913 }
914 // Use GetSurfaceSubRect instead
915 ASSERT(params.width == params.stride);
916
917 // Check for an exact match in existing surfaces
918 Surface surface =
919 FindMatch<MatchFlags::Exact | MatchFlags::Invalid>(surface_cache, params, match_res_scale);
920
921 if (surface == nullptr) {
922 u16 target_res_scale = params.res_scale;
923 if (match_res_scale != ScaleMatch::Exact) {
924 // This surface may have a subrect of another surface with a higher res_scale, find it
925 // to adjust our params
926 SurfaceParams find_params = params;
927 Surface expandable = FindMatch<MatchFlags::Expand | MatchFlags::Invalid>(
928 surface_cache, find_params, match_res_scale);
929 if (expandable != nullptr && expandable->res_scale > target_res_scale) {
930 target_res_scale = expandable->res_scale;
931 }
932 }
933 SurfaceParams new_params = params;
934 new_params.res_scale = target_res_scale;
935 surface = CreateSurface(new_params);
936 RegisterSurface(surface);
937 }
938
939 if (load_if_create) {
940 ValidateSurface(surface, params.addr, params.size);
941 }
942
943 return surface;
944}
945
946boost::optional<Tegra::GPUVAddr> RasterizerCacheOpenGL::TryFindFramebufferGpuAddress(
947 VAddr cpu_addr) const {
948 // Tries to find the GPU address of a framebuffer based on the CPU address. This is because
949 // final output framebuffers are specified by CPU address, but internally our GPU cache uses GPU
950 // addresses. We iterate through all cached framebuffers, and compare their starting CPU address
951 // to the one provided. This is obviously not great, and won't work if the framebuffer overlaps
952 // surfaces.
953
954 std::vector<Tegra::GPUVAddr> gpu_addresses;
955 for (const auto& pair : surface_cache) {
956 for (const auto& surface : pair.second) {
957 const VAddr surface_cpu_addr = surface->GetCpuAddr();
958 if (cpu_addr >= surface_cpu_addr && cpu_addr < (surface_cpu_addr + surface->size)) {
959 ASSERT_MSG(cpu_addr == surface_cpu_addr, "overlapping surfaces are unsupported");
960 gpu_addresses.push_back(surface->addr);
961 }
962 }
963 }
964
965 if (gpu_addresses.empty()) {
966 return {};
967 }
968
969 ASSERT_MSG(gpu_addresses.size() == 1, ">1 surface is unsupported");
970 return gpu_addresses[0];
971}
972
973SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams& params,
974 ScaleMatch match_res_scale,
975 bool load_if_create) {
976 if (params.addr == 0 || params.height * params.width == 0) {
977 return std::make_tuple(nullptr, MathUtil::Rectangle<u32>{});
978 }
979
980 // Attempt to find encompassing surface
981 Surface surface = FindMatch<MatchFlags::SubRect | MatchFlags::Invalid>(surface_cache, params,
982 match_res_scale);
983
984 // Check if FindMatch failed because of res scaling
985 // If that's the case create a new surface with
986 // the dimensions of the lower res_scale surface
987 // to suggest it should not be used again
988 if (surface == nullptr && match_res_scale != ScaleMatch::Ignore) {
989 surface = FindMatch<MatchFlags::SubRect | MatchFlags::Invalid>(surface_cache, params,
990 ScaleMatch::Ignore);
991 if (surface != nullptr) {
992 ASSERT(surface->res_scale < params.res_scale);
993 SurfaceParams new_params = *surface;
994 new_params.res_scale = params.res_scale;
995
996 surface = CreateSurface(new_params);
997 RegisterSurface(surface);
998 }
999 }
1000
1001 SurfaceParams aligned_params = params;
1002 if (params.is_tiled) {
1003 aligned_params.height = Common::AlignUp(params.height, 8);
1004 aligned_params.width = Common::AlignUp(params.width, 8);
1005 aligned_params.stride = Common::AlignUp(params.stride, 8);
1006 aligned_params.UpdateParams();
1007 }
1008
1009 // Check for a surface we can expand before creating a new one
1010 if (surface == nullptr) {
1011 surface = FindMatch<MatchFlags::Expand | MatchFlags::Invalid>(surface_cache, aligned_params,
1012 match_res_scale);
1013 if (surface != nullptr) {
1014 aligned_params.width = aligned_params.stride;
1015 aligned_params.UpdateParams();
1016
1017 SurfaceParams new_params = *surface;
1018 new_params.addr = std::min(aligned_params.addr, surface->addr);
1019 new_params.end = std::max(aligned_params.end, surface->end);
1020 new_params.size = new_params.end - new_params.addr;
1021 new_params.height = static_cast<u32>(
1022 new_params.size / aligned_params.BytesInPixels(aligned_params.stride));
1023 ASSERT(new_params.size % aligned_params.BytesInPixels(aligned_params.stride) == 0);
1024
1025 Surface new_surface = CreateSurface(new_params);
1026 DuplicateSurface(surface, new_surface);
1027
1028 // Delete the expanded surface, this can't be done safely yet
1029 // because it may still be in use
1030 remove_surfaces.emplace(surface);
1031
1032 surface = new_surface;
1033 RegisterSurface(new_surface);
1034 }
1035 }
1036
1037 // No subrect found - create and return a new surface
1038 if (surface == nullptr) {
1039 SurfaceParams new_params = aligned_params;
1040 // Can't have gaps in a surface
1041 new_params.width = aligned_params.stride;
1042 new_params.UpdateParams();
1043 // GetSurface will create the new surface and possibly adjust res_scale if necessary
1044 surface = GetSurface(new_params, match_res_scale, load_if_create);
1045 } else if (load_if_create) {
1046 ValidateSurface(surface, aligned_params.addr, aligned_params.size);
1047 }
1048
1049 return std::make_tuple(surface, surface->GetScaledSubRect(params));
1050} 475}
1051 476
1052Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) { 477Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) {
1053 auto& gpu = Core::System::GetInstance().GPU(); 478 return GetSurface(SurfaceParams::CreateForTexture(config));
1054
1055 SurfaceParams params;
1056 params.addr = config.tic.Address();
1057 params.is_tiled = config.tic.IsTiled();
1058 params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format);
1059
1060 params.width = Common::AlignUp(config.tic.Width(), params.GetCompresssionFactor()) /
1061 params.GetCompresssionFactor();
1062 params.height = Common::AlignUp(config.tic.Height(), params.GetCompresssionFactor()) /
1063 params.GetCompresssionFactor();
1064
1065 // TODO(Subv): Different types per component are not supported.
1066 ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() &&
1067 config.tic.r_type.Value() == config.tic.b_type.Value() &&
1068 config.tic.r_type.Value() == config.tic.a_type.Value());
1069
1070 params.component_type = SurfaceParams::ComponentTypeFromTexture(config.tic.r_type.Value());
1071
1072 if (config.tic.IsTiled()) {
1073 params.block_height = config.tic.BlockHeight();
1074
1075 // TODO(bunnei): The below align up is a hack. This is here because some compressed textures
1076 // are not a multiple of their own compression factor, and so this accounts for that. This
1077 // could potentially result in an extra row of 4px being decoded if a texture is not a
1078 // multiple of 4.
1079 params.width = Common::AlignUp(params.width, 4);
1080 params.height = Common::AlignUp(params.height, 4);
1081 } else {
1082 // Use the texture-provided stride value if the texture isn't tiled.
1083 params.stride = static_cast<u32>(params.PixelsInBytes(config.tic.Pitch()));
1084 }
1085
1086 params.UpdateParams();
1087
1088 return GetSurface(params, ScaleMatch::Ignore, true);
1089} 479}
1090 480
1091SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( 481SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
1092 bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) { 482 bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) {
1093 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; 483 const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
1094 const auto& config = regs.rt[0];
1095 484
1096 // TODO(bunnei): This is hard corded to use just the first render buffer 485 // TODO(bunnei): This is hard corded to use just the first render buffer
1097 NGLOG_WARNING(Render_OpenGL, "hard-coded for render target 0!"); 486 LOG_WARNING(Render_OpenGL, "hard-coded for render target 0!");
1098
1099 // update resolution_scale_factor and reset cache if changed
1100 // TODO (bunnei): This code was ported as-is from Citra, and is technically not thread-safe. We
1101 // need to fix this before making the renderer multi-threaded.
1102 static u16 resolution_scale_factor = GetResolutionScaleFactor();
1103 if (resolution_scale_factor != GetResolutionScaleFactor()) {
1104 resolution_scale_factor = GetResolutionScaleFactor();
1105 FlushAll();
1106 while (!surface_cache.empty())
1107 UnregisterSurface(*surface_cache.begin()->second.begin());
1108 }
1109
1110 MathUtil::Rectangle<u32> viewport_clamped{
1111 static_cast<u32>(std::clamp(viewport.left, 0, static_cast<s32>(config.width))),
1112 static_cast<u32>(std::clamp(viewport.top, 0, static_cast<s32>(config.height))),
1113 static_cast<u32>(std::clamp(viewport.right, 0, static_cast<s32>(config.width))),
1114 static_cast<u32>(std::clamp(viewport.bottom, 0, static_cast<s32>(config.height)))};
1115 487
1116 // get color and depth surfaces 488 // get color and depth surfaces
1117 SurfaceParams color_params; 489 SurfaceParams color_params{};
1118 color_params.is_tiled = true; 490 SurfaceParams depth_params{};
1119 color_params.res_scale = resolution_scale_factor; 491
1120 color_params.width = config.width; 492 if (using_color_fb) {
1121 color_params.height = config.height; 493 color_params = SurfaceParams::CreateForFramebuffer(regs.rt[0]);
1122 // TODO(Subv): Can framebuffers use a different block height? 494 }
1123 color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; 495
1124 SurfaceParams depth_params = color_params; 496 if (using_depth_fb) {
1125 497 depth_params =
1126 color_params.addr = config.Address(); 498 SurfaceParams::CreateForDepthBuffer(regs.rt[0], regs.zeta.Address(), regs.zeta.format);
1127 color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format);
1128 color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format);
1129 color_params.UpdateParams();
1130
1131 ASSERT_MSG(!using_depth_fb, "depth buffer is unimplemented");
1132 // depth_params.addr = config.GetDepthBufferPhysicalAddress();
1133 // depth_params.pixel_format = SurfaceParams::PixelFormatFromDepthFormat(config.depth_format);
1134 // depth_params.UpdateParams();
1135
1136 auto color_vp_interval = color_params.GetSubRectInterval(viewport_clamped);
1137 auto depth_vp_interval = depth_params.GetSubRectInterval(viewport_clamped);
1138
1139 // Make sure that framebuffers don't overlap if both color and depth are being used
1140 if (using_color_fb && using_depth_fb &&
1141 boost::icl::length(color_vp_interval & depth_vp_interval)) {
1142 NGLOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; "
1143 "overlapping framebuffers not supported!");
1144 using_depth_fb = false;
1145 } 499 }
1146 500
1147 MathUtil::Rectangle<u32> color_rect{}; 501 MathUtil::Rectangle<u32> color_rect{};
1148 Surface color_surface = nullptr; 502 Surface color_surface;
1149 if (using_color_fb) 503 if (using_color_fb) {
1150 std::tie(color_surface, color_rect) = 504 color_surface = GetSurface(color_params);
1151 GetSurfaceSubRect(color_params, ScaleMatch::Exact, false); 505 if (color_surface) {
506 color_rect = color_surface->GetSurfaceParams().GetRect();
507 }
508 }
1152 509
1153 MathUtil::Rectangle<u32> depth_rect{}; 510 MathUtil::Rectangle<u32> depth_rect{};
1154 Surface depth_surface = nullptr; 511 Surface depth_surface;
1155 if (using_depth_fb) 512 if (using_depth_fb) {
1156 std::tie(depth_surface, depth_rect) = 513 depth_surface = GetSurface(depth_params);
1157 GetSurfaceSubRect(depth_params, ScaleMatch::Exact, false); 514 if (depth_surface) {
515 depth_rect = depth_surface->GetSurfaceParams().GetRect();
516 }
517 }
1158 518
1159 MathUtil::Rectangle<u32> fb_rect{}; 519 MathUtil::Rectangle<u32> fb_rect{};
1160 if (color_surface != nullptr && depth_surface != nullptr) { 520 if (color_surface && depth_surface) {
1161 fb_rect = color_rect; 521 fb_rect = color_rect;
1162 // Color and Depth surfaces must have the same dimensions and offsets 522 // Color and Depth surfaces must have the same dimensions and offsets
1163 if (color_rect.bottom != depth_rect.bottom || color_rect.top != depth_rect.top || 523 if (color_rect.bottom != depth_rect.bottom || color_rect.top != depth_rect.top ||
1164 color_rect.left != depth_rect.left || color_rect.right != depth_rect.right) { 524 color_rect.left != depth_rect.left || color_rect.right != depth_rect.right) {
1165 color_surface = GetSurface(color_params, ScaleMatch::Exact, false); 525 color_surface = GetSurface(color_params);
1166 depth_surface = GetSurface(depth_params, ScaleMatch::Exact, false); 526 depth_surface = GetSurface(depth_params);
1167 fb_rect = color_surface->GetScaledRect(); 527 fb_rect = color_surface->GetSurfaceParams().GetRect();
1168 } 528 }
1169 } else if (color_surface != nullptr) { 529 } else if (color_surface) {
1170 fb_rect = color_rect; 530 fb_rect = color_rect;
1171 } else if (depth_surface != nullptr) { 531 } else if (depth_surface) {
1172 fb_rect = depth_rect; 532 fb_rect = depth_rect;
1173 } 533 }
1174 534
1175 if (color_surface != nullptr) {
1176 ValidateSurface(color_surface, boost::icl::first(color_vp_interval),
1177 boost::icl::length(color_vp_interval));
1178 }
1179 if (depth_surface != nullptr) {
1180 ValidateSurface(depth_surface, boost::icl::first(depth_vp_interval),
1181 boost::icl::length(depth_vp_interval));
1182 }
1183
1184 return std::make_tuple(color_surface, depth_surface, fb_rect); 535 return std::make_tuple(color_surface, depth_surface, fb_rect);
1185} 536}
1186 537
1187Surface RasterizerCacheOpenGL::GetFillSurface(const void* config) { 538void RasterizerCacheOpenGL::LoadSurface(const Surface& surface) {
1188 UNREACHABLE(); 539 surface->LoadGLBuffer();
1189 return {}; 540 surface->UploadGLTexture(read_framebuffer.handle, draw_framebuffer.handle);
1190} 541}
1191 542
1192SurfaceRect_Tuple RasterizerCacheOpenGL::GetTexCopySurface(const SurfaceParams& params) { 543void RasterizerCacheOpenGL::MarkSurfaceAsDirty(const Surface& surface) {
1193 MathUtil::Rectangle<u32> rect{}; 544 if (Settings::values.use_accurate_framebuffers) {
545 // If enabled, always flush dirty surfaces
546 surface->DownloadGLTexture(read_framebuffer.handle, draw_framebuffer.handle);
547 surface->FlushGLBuffer();
548 } else {
549 // Otherwise, don't mark surfaces that we write to as cached, because the resulting loads
550 // and flushes are very slow and do not seem to improve accuracy
551 const auto& params{surface->GetSurfaceParams()};
552 Memory::RasterizerMarkRegionCached(params.addr, params.size_in_bytes, false);
553 }
554}
1194 555
1195 Surface match_surface = FindMatch<MatchFlags::TexCopy | MatchFlags::Invalid>( 556Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) {
1196 surface_cache, params, ScaleMatch::Ignore); 557 if (params.addr == 0 || params.height * params.width == 0) {
558 return {};
559 }
1197 560
1198 if (match_surface != nullptr) { 561 const auto& gpu = Core::System::GetInstance().GPU();
1199 ValidateSurface(match_surface, params.addr, params.size); 562 // Don't try to create any entries in the cache if the address of the texture is invalid.
563 if (gpu.memory_manager->GpuToCpuAddress(params.addr) == boost::none)
564 return {};
1200 565
1201 SurfaceParams match_subrect; 566 // Check for an exact match in existing surfaces
1202 if (params.width != params.stride) { 567 const auto& surface_key{SurfaceKey::Create(params)};
1203 const u32 tiled_size = match_surface->is_tiled ? 8 : 1; 568 const auto& search{surface_cache.find(surface_key)};
1204 match_subrect = params; 569 Surface surface;
1205 match_subrect.width = 570 if (search != surface_cache.end()) {
1206 static_cast<u32>(match_surface->PixelsInBytes(params.width) / tiled_size); 571 surface = search->second;
1207 match_subrect.stride = 572 if (Settings::values.use_accurate_framebuffers) {
1208 static_cast<u32>(match_surface->PixelsInBytes(params.stride) / tiled_size); 573 // Reload the surface from Switch memory
1209 match_subrect.height *= tiled_size; 574 LoadSurface(surface);
1210 } else {
1211 match_subrect = match_surface->FromInterval(params.GetInterval());
1212 ASSERT(match_subrect.GetInterval() == params.GetInterval());
1213 } 575 }
1214 576 } else {
1215 rect = match_surface->GetScaledSubRect(match_subrect); 577 surface = std::make_shared<CachedSurface>(params);
578 RegisterSurface(surface);
579 LoadSurface(surface);
1216 } 580 }
1217 581
1218 return std::make_tuple(match_surface, rect); 582 return surface;
1219} 583}
1220 584
1221void RasterizerCacheOpenGL::DuplicateSurface(const Surface& src_surface, 585Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr cpu_addr) const {
1222 const Surface& dest_surface) { 586 // Tries to find the GPU address of a framebuffer based on the CPU address. This is because
1223 ASSERT(dest_surface->addr <= src_surface->addr && dest_surface->end >= src_surface->end); 587 // final output framebuffers are specified by CPU address, but internally our GPU cache uses
1224 588 // GPU addresses. We iterate through all cached framebuffers, and compare their starting CPU
1225 BlitSurfaces(src_surface, src_surface->GetScaledRect(), dest_surface, 589 // address to the one provided. This is obviously not great, and won't work if the
1226 dest_surface->GetScaledSubRect(*src_surface)); 590 // framebuffer overlaps surfaces.
1227 591
1228 dest_surface->invalid_regions -= src_surface->GetInterval(); 592 std::vector<Surface> surfaces;
1229 dest_surface->invalid_regions += src_surface->invalid_regions; 593 for (const auto& surface : surface_cache) {
1230 594 const auto& params = surface.second->GetSurfaceParams();
1231 SurfaceRegions regions; 595 const VAddr surface_cpu_addr = params.GetCpuAddr();
1232 for (auto& pair : RangeFromInterval(dirty_regions, src_surface->GetInterval())) { 596 if (cpu_addr >= surface_cpu_addr && cpu_addr < (surface_cpu_addr + params.size_in_bytes)) {
1233 if (pair.second == src_surface) { 597 ASSERT_MSG(cpu_addr == surface_cpu_addr, "overlapping surfaces are unsupported");
1234 regions += pair.first; 598 surfaces.push_back(surface.second);
1235 } 599 }
1236 } 600 }
1237 for (auto& interval : regions) {
1238 dirty_regions.set({interval, dest_surface});
1239 }
1240}
1241 601
1242void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, Tegra::GPUVAddr addr, 602 if (surfaces.empty()) {
1243 u64 size) { 603 return {};
1244 if (size == 0)
1245 return;
1246
1247 const SurfaceInterval validate_interval(addr, addr + size);
1248
1249 if (surface->type == SurfaceType::Fill) {
1250 // Sanity check, fill surfaces will always be valid when used
1251 ASSERT(surface->IsRegionValid(validate_interval));
1252 return;
1253 } 604 }
1254 605
1255 while (true) { 606 ASSERT_MSG(surfaces.size() == 1, ">1 surface is unsupported");
1256 const auto it = surface->invalid_regions.find(validate_interval);
1257 if (it == surface->invalid_regions.end())
1258 break;
1259
1260 const auto interval = *it & validate_interval;
1261 // Look for a valid surface to copy from
1262 SurfaceParams params = *surface;
1263
1264 Surface copy_surface =
1265 FindMatch<MatchFlags::Copy>(surface_cache, params, ScaleMatch::Ignore, interval);
1266 if (copy_surface != nullptr) {
1267 SurfaceInterval copy_interval = params.GetCopyableInterval(copy_surface);
1268 CopySurface(copy_surface, surface, copy_interval);
1269 surface->invalid_regions.erase(copy_interval);
1270 continue;
1271 }
1272 607
1273 // Load data from Switch memory 608 return surfaces[0];
1274 FlushRegion(params.addr, params.size);
1275 surface->LoadGLBuffer(params.addr, params.end);
1276 surface->UploadGLTexture(surface->GetSubRect(params), read_framebuffer.handle,
1277 draw_framebuffer.handle);
1278 surface->invalid_regions.erase(params.GetInterval());
1279 }
1280} 609}
1281 610
1282void RasterizerCacheOpenGL::FlushRegion(Tegra::GPUVAddr addr, u64 size, Surface flush_surface) { 611void RasterizerCacheOpenGL::FlushRegion(Tegra::GPUVAddr /*addr*/, size_t /*size*/) {
1283 if (size == 0) 612 // TODO(bunnei): This is unused in the current implementation of the rasterizer cache. We should
1284 return; 613 // probably implement this in the future, but for now, the `use_accurate_framebufers` setting
1285 614 // can be used to always flush.
1286 const SurfaceInterval flush_interval(addr, addr + size); 615}
1287 SurfaceRegions flushed_intervals;
1288
1289 for (auto& pair : RangeFromInterval(dirty_regions, flush_interval)) {
1290 // small sizes imply that this most likely comes from the cpu, flush the entire region
1291 // the point is to avoid thousands of small writes every frame if the cpu decides to access
1292 // that region, anything higher than 8 you're guaranteed it comes from a service
1293 const auto interval = size <= 8 ? pair.first : pair.first & flush_interval;
1294 auto& surface = pair.second;
1295
1296 if (flush_surface != nullptr && surface != flush_surface)
1297 continue;
1298 616
1299 // Sanity check, this surface is the last one that marked this region dirty 617void RasterizerCacheOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, size_t size) {
1300 ASSERT(surface->IsRegionValid(interval)); 618 for (const auto& pair : surface_cache) {
619 const auto& surface{pair.second};
620 const auto& params{surface->GetSurfaceParams()};
1301 621
1302 if (surface->type != SurfaceType::Fill) { 622 if (params.IsOverlappingRegion(addr, size)) {
1303 SurfaceParams params = surface->FromInterval(interval); 623 UnregisterSurface(surface);
1304 surface->DownloadGLTexture(surface->GetSubRect(params), read_framebuffer.handle,
1305 draw_framebuffer.handle);
1306 } 624 }
1307 surface->FlushGLBuffer(boost::icl::first(interval), boost::icl::last_next(interval));
1308 flushed_intervals += interval;
1309 } 625 }
1310 // Reset dirty regions
1311 dirty_regions -= flushed_intervals;
1312} 626}
1313 627
1314void RasterizerCacheOpenGL::FlushAll() { 628void RasterizerCacheOpenGL::RegisterSurface(const Surface& surface) {
1315 FlushRegion(0, Kernel::VMManager::MAX_ADDRESS); 629 const auto& params{surface->GetSurfaceParams()};
1316} 630 const auto& surface_key{SurfaceKey::Create(params)};
631 const auto& search{surface_cache.find(surface_key)};
1317 632
1318void RasterizerCacheOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, u64 size, 633 if (search != surface_cache.end()) {
1319 const Surface& region_owner) { 634 // Registered already
1320 if (size == 0)
1321 return; 635 return;
1322
1323 const SurfaceInterval invalid_interval(addr, addr + size);
1324
1325 if (region_owner != nullptr) {
1326 ASSERT(addr >= region_owner->addr && addr + size <= region_owner->end);
1327 // Surfaces can't have a gap
1328 ASSERT(region_owner->width == region_owner->stride);
1329 region_owner->invalid_regions.erase(invalid_interval);
1330 }
1331
1332 for (auto& pair : RangeFromInterval(surface_cache, invalid_interval)) {
1333 for (auto& cached_surface : pair.second) {
1334 if (cached_surface == region_owner)
1335 continue;
1336
1337 // If cpu is invalidating this region we want to remove it
1338 // to (likely) mark the memory pages as uncached
1339 if (region_owner == nullptr && size <= 8) {
1340 FlushRegion(cached_surface->addr, cached_surface->size, cached_surface);
1341 remove_surfaces.emplace(cached_surface);
1342 continue;
1343 }
1344
1345 const auto interval = cached_surface->GetInterval() & invalid_interval;
1346 cached_surface->invalid_regions.insert(interval);
1347
1348 // Remove only "empty" fill surfaces to avoid destroying and recreating OGL textures
1349 if (cached_surface->type == SurfaceType::Fill &&
1350 cached_surface->IsSurfaceFullyInvalid()) {
1351 remove_surfaces.emplace(cached_surface);
1352 }
1353 }
1354 } 636 }
1355 637
1356 if (region_owner != nullptr) 638 surface_cache[surface_key] = surface;
1357 dirty_regions.set({invalid_interval, region_owner}); 639 UpdatePagesCachedCount(params.addr, params.size_in_bytes, 1);
1358 else
1359 dirty_regions.erase(invalid_interval);
1360
1361 for (auto& remove_surface : remove_surfaces) {
1362 if (remove_surface == region_owner) {
1363 Surface expanded_surface = FindMatch<MatchFlags::SubRect | MatchFlags::Invalid>(
1364 surface_cache, *region_owner, ScaleMatch::Ignore);
1365 ASSERT(expanded_surface);
1366
1367 if ((region_owner->invalid_regions - expanded_surface->invalid_regions).empty()) {
1368 DuplicateSurface(region_owner, expanded_surface);
1369 } else {
1370 continue;
1371 }
1372 }
1373 UnregisterSurface(remove_surface);
1374 }
1375
1376 remove_surfaces.clear();
1377} 640}
1378 641
1379Surface RasterizerCacheOpenGL::CreateSurface(const SurfaceParams& params) { 642void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) {
1380 Surface surface = std::make_shared<CachedSurface>(); 643 const auto& params{surface->GetSurfaceParams()};
1381 static_cast<SurfaceParams&>(*surface) = params; 644 const auto& surface_key{SurfaceKey::Create(params)};
1382 645 const auto& search{surface_cache.find(surface_key)};
1383 surface->texture.Create();
1384
1385 surface->gl_buffer_size = 0;
1386 surface->invalid_regions.insert(surface->GetInterval());
1387 AllocateSurfaceTexture(surface->texture.handle,
1388 GetFormatTuple(surface->pixel_format, surface->component_type),
1389 surface->GetScaledWidth(), surface->GetScaledHeight());
1390
1391 return surface;
1392}
1393 646
1394void RasterizerCacheOpenGL::RegisterSurface(const Surface& surface) { 647 if (search == surface_cache.end()) {
1395 if (surface->registered) { 648 // Unregistered already
1396 return; 649 return;
1397 } 650 }
1398 surface->registered = true; 651
1399 surface_cache.add({surface->GetInterval(), SurfaceSet{surface}}); 652 UpdatePagesCachedCount(params.addr, params.size_in_bytes, -1);
1400 UpdatePagesCachedCount(surface->addr, surface->size, 1); 653 surface_cache.erase(search);
1401} 654}
1402 655
1403void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) { 656template <typename Map, typename Interval>
1404 if (!surface->registered) { 657constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
1405 return; 658 return boost::make_iterator_range(map.equal_range(interval));
1406 }
1407 surface->registered = false;
1408 UpdatePagesCachedCount(surface->addr, surface->size, -1);
1409 surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}});
1410} 659}
1411 660
1412void RasterizerCacheOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) { 661void RasterizerCacheOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 9da945e19..1bedae992 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -1,57 +1,26 @@
1// Copyright 2015 Citra Emulator Project 1// Copyright 2018 yuzu Emulator Project
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#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <map>
8#include <memory> 9#include <memory>
9#include <set> 10#include <vector>
10#include <tuple>
11#ifdef __GNUC__
12#pragma GCC diagnostic push
13#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
14#endif
15#include <boost/icl/interval_map.hpp> 11#include <boost/icl/interval_map.hpp>
16#include <boost/icl/interval_set.hpp>
17#ifdef __GNUC__
18#pragma GCC diagnostic pop
19#endif
20#include <boost/optional.hpp>
21#include <glad/glad.h>
22#include "common/assert.h"
23#include "common/common_funcs.h"
24#include "common/common_types.h" 12#include "common/common_types.h"
13#include "common/hash.h"
25#include "common/math_util.h" 14#include "common/math_util.h"
26#include "video_core/gpu.h" 15#include "video_core/engines/maxwell_3d.h"
27#include "video_core/memory_manager.h"
28#include "video_core/renderer_opengl/gl_resource_manager.h" 16#include "video_core/renderer_opengl/gl_resource_manager.h"
29#include "video_core/textures/texture.h" 17#include "video_core/textures/texture.h"
30 18
31struct CachedSurface; 19class CachedSurface;
32using Surface = std::shared_ptr<CachedSurface>; 20using Surface = std::shared_ptr<CachedSurface>;
33using SurfaceSet = std::set<Surface>;
34
35using SurfaceRegions = boost::icl::interval_set<Tegra::GPUVAddr>;
36using SurfaceMap = boost::icl::interval_map<Tegra::GPUVAddr, Surface>;
37using SurfaceCache = boost::icl::interval_map<Tegra::GPUVAddr, SurfaceSet>;
38
39using SurfaceInterval = SurfaceCache::interval_type;
40static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval_type>() &&
41 std::is_same<SurfaceMap::interval_type, SurfaceCache::interval_type>(),
42 "incorrect interval types");
43
44using SurfaceRect_Tuple = std::tuple<Surface, MathUtil::Rectangle<u32>>;
45using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, MathUtil::Rectangle<u32>>; 21using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, MathUtil::Rectangle<u32>>;
46
47using PageMap = boost::icl::interval_map<u64, int>; 22using PageMap = boost::icl::interval_map<u64, int>;
48 23
49enum class ScaleMatch {
50 Exact, // only accept same res scale
51 Upscale, // only allow higher scale than params
52 Ignore // accept every scaled res
53};
54
55struct SurfaceParams { 24struct SurfaceParams {
56 enum class PixelFormat { 25 enum class PixelFormat {
57 ABGR8 = 0, 26 ABGR8 = 0,
@@ -61,13 +30,24 @@ struct SurfaceParams {
61 R8 = 4, 30 R8 = 4,
62 RGBA16F = 5, 31 RGBA16F = 5,
63 R11FG11FB10F = 6, 32 R11FG11FB10F = 6,
64 DXT1 = 7, 33 RGBA32UI = 7,
65 DXT23 = 8, 34 DXT1 = 8,
66 DXT45 = 9, 35 DXT23 = 9,
67 DXN1 = 10, // This is also known as BC4 36 DXT45 = 10,
68 ASTC_2D_4X4 = 11, 37 DXN1 = 11, // This is also known as BC4
38 BC7U = 12,
39 ASTC_2D_4X4 = 13,
40
41 MaxColorFormat,
69 42
70 Max, 43 // DepthStencil formats
44 Z24S8 = 14,
45 S8Z24 = 15,
46 Z32F = 16,
47
48 MaxDepthStencilFormat,
49
50 Max = MaxDepthStencilFormat,
71 Invalid = 255, 51 Invalid = 255,
72 }; 52 };
73 53
@@ -93,10 +73,10 @@ struct SurfaceParams {
93 /** 73 /**
94 * Gets the compression factor for the specified PixelFormat. This applies to just the 74 * Gets the compression factor for the specified PixelFormat. This applies to just the
95 * "compressed width" and "compressed height", not the overall compression factor of a 75 * "compressed width" and "compressed height", not the overall compression factor of a
96 * compressed image. This is used for maintaining proper surface sizes for compressed texture 76 * compressed image. This is used for maintaining proper surface sizes for compressed
97 * formats. 77 * texture formats.
98 */ 78 */
99 static constexpr u32 GetCompresssionFactor(PixelFormat format) { 79 static constexpr u32 GetCompressionFactor(PixelFormat format) {
100 if (format == PixelFormat::Invalid) 80 if (format == PixelFormat::Invalid)
101 return 0; 81 return 0;
102 82
@@ -108,19 +88,21 @@ struct SurfaceParams {
108 1, // R8 88 1, // R8
109 1, // RGBA16F 89 1, // RGBA16F
110 1, // R11FG11FB10F 90 1, // R11FG11FB10F
91 1, // RGBA32UI
111 4, // DXT1 92 4, // DXT1
112 4, // DXT23 93 4, // DXT23
113 4, // DXT45 94 4, // DXT45
114 4, // DXN1 95 4, // DXN1
115 1, // ASTC_2D_4X4 96 4, // BC7U
97 4, // ASTC_2D_4X4
98 1, // Z24S8
99 1, // S8Z24
100 1, // Z32F
116 }}; 101 }};
117 102
118 ASSERT(static_cast<size_t>(format) < compression_factor_table.size()); 103 ASSERT(static_cast<size_t>(format) < compression_factor_table.size());
119 return compression_factor_table[static_cast<size_t>(format)]; 104 return compression_factor_table[static_cast<size_t>(format)];
120 } 105 }
121 u32 GetCompresssionFactor() const {
122 return GetCompresssionFactor(pixel_format);
123 }
124 106
125 static constexpr u32 GetFormatBpp(PixelFormat format) { 107 static constexpr u32 GetFormatBpp(PixelFormat format) {
126 if (format == PixelFormat::Invalid) 108 if (format == PixelFormat::Invalid)
@@ -134,11 +116,16 @@ struct SurfaceParams {
134 8, // R8 116 8, // R8
135 64, // RGBA16F 117 64, // RGBA16F
136 32, // R11FG11FB10F 118 32, // R11FG11FB10F
119 128, // RGBA32UI
137 64, // DXT1 120 64, // DXT1
138 128, // DXT23 121 128, // DXT23
139 128, // DXT45 122 128, // DXT45
140 64, // DXN1 123 64, // DXN1
124 128, // BC7U
141 32, // ASTC_2D_4X4 125 32, // ASTC_2D_4X4
126 32, // Z24S8
127 32, // S8Z24
128 32, // Z32F
142 }}; 129 }};
143 130
144 ASSERT(static_cast<size_t>(format) < bpp_table.size()); 131 ASSERT(static_cast<size_t>(format) < bpp_table.size());
@@ -148,6 +135,20 @@ struct SurfaceParams {
148 return GetFormatBpp(pixel_format); 135 return GetFormatBpp(pixel_format);
149 } 136 }
150 137
138 static PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) {
139 switch (format) {
140 case Tegra::DepthFormat::S8_Z24_UNORM:
141 return PixelFormat::S8Z24;
142 case Tegra::DepthFormat::Z24_S8_UNORM:
143 return PixelFormat::Z24S8;
144 case Tegra::DepthFormat::Z32_FLOAT:
145 return PixelFormat::Z32F;
146 default:
147 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
148 UNREACHABLE();
149 }
150 }
151
151 static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { 152 static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) {
152 switch (format) { 153 switch (format) {
153 case Tegra::RenderTargetFormat::RGBA8_UNORM: 154 case Tegra::RenderTargetFormat::RGBA8_UNORM:
@@ -159,27 +160,10 @@ struct SurfaceParams {
159 return PixelFormat::RGBA16F; 160 return PixelFormat::RGBA16F;
160 case Tegra::RenderTargetFormat::R11G11B10_FLOAT: 161 case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
161 return PixelFormat::R11FG11FB10F; 162 return PixelFormat::R11FG11FB10F;
163 case Tegra::RenderTargetFormat::RGBA32_UINT:
164 return PixelFormat::RGBA32UI;
162 default: 165 default:
163 NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); 166 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
164 UNREACHABLE();
165 }
166 }
167
168 static bool IsFormatASTC(PixelFormat format) {
169 switch (format) {
170 case PixelFormat::ASTC_2D_4X4:
171 return true;
172 default:
173 return false;
174 }
175 }
176
177 static PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) {
178 switch (format) {
179 case Tegra::FramebufferConfig::PixelFormat::ABGR8:
180 return PixelFormat::ABGR8;
181 default:
182 NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
183 UNREACHABLE(); 167 UNREACHABLE();
184 } 168 }
185 } 169 }
@@ -201,6 +185,8 @@ struct SurfaceParams {
201 return PixelFormat::RGBA16F; 185 return PixelFormat::RGBA16F;
202 case Tegra::Texture::TextureFormat::BF10GF11RF11: 186 case Tegra::Texture::TextureFormat::BF10GF11RF11:
203 return PixelFormat::R11FG11FB10F; 187 return PixelFormat::R11FG11FB10F;
188 case Tegra::Texture::TextureFormat::R32_G32_B32_A32:
189 return PixelFormat::RGBA32UI;
204 case Tegra::Texture::TextureFormat::DXT1: 190 case Tegra::Texture::TextureFormat::DXT1:
205 return PixelFormat::DXT1; 191 return PixelFormat::DXT1;
206 case Tegra::Texture::TextureFormat::DXT23: 192 case Tegra::Texture::TextureFormat::DXT23:
@@ -209,10 +195,12 @@ struct SurfaceParams {
209 return PixelFormat::DXT45; 195 return PixelFormat::DXT45;
210 case Tegra::Texture::TextureFormat::DXN1: 196 case Tegra::Texture::TextureFormat::DXN1:
211 return PixelFormat::DXN1; 197 return PixelFormat::DXN1;
198 case Tegra::Texture::TextureFormat::BC7U:
199 return PixelFormat::BC7U;
212 case Tegra::Texture::TextureFormat::ASTC_2D_4X4: 200 case Tegra::Texture::TextureFormat::ASTC_2D_4X4:
213 return PixelFormat::ASTC_2D_4X4; 201 return PixelFormat::ASTC_2D_4X4;
214 default: 202 default:
215 NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); 203 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
216 UNREACHABLE(); 204 UNREACHABLE();
217 } 205 }
218 } 206 }
@@ -234,6 +222,8 @@ struct SurfaceParams {
234 return Tegra::Texture::TextureFormat::R16_G16_B16_A16; 222 return Tegra::Texture::TextureFormat::R16_G16_B16_A16;
235 case PixelFormat::R11FG11FB10F: 223 case PixelFormat::R11FG11FB10F:
236 return Tegra::Texture::TextureFormat::BF10GF11RF11; 224 return Tegra::Texture::TextureFormat::BF10GF11RF11;
225 case PixelFormat::RGBA32UI:
226 return Tegra::Texture::TextureFormat::R32_G32_B32_A32;
237 case PixelFormat::DXT1: 227 case PixelFormat::DXT1:
238 return Tegra::Texture::TextureFormat::DXT1; 228 return Tegra::Texture::TextureFormat::DXT1;
239 case PixelFormat::DXT23: 229 case PixelFormat::DXT23:
@@ -242,6 +232,8 @@ struct SurfaceParams {
242 return Tegra::Texture::TextureFormat::DXT45; 232 return Tegra::Texture::TextureFormat::DXT45;
243 case PixelFormat::DXN1: 233 case PixelFormat::DXN1:
244 return Tegra::Texture::TextureFormat::DXN1; 234 return Tegra::Texture::TextureFormat::DXN1;
235 case PixelFormat::BC7U:
236 return Tegra::Texture::TextureFormat::BC7U;
245 case PixelFormat::ASTC_2D_4X4: 237 case PixelFormat::ASTC_2D_4X4:
246 return Tegra::Texture::TextureFormat::ASTC_2D_4X4; 238 return Tegra::Texture::TextureFormat::ASTC_2D_4X4;
247 default: 239 default:
@@ -249,13 +241,26 @@ struct SurfaceParams {
249 } 241 }
250 } 242 }
251 243
244 static Tegra::DepthFormat DepthFormatFromPixelFormat(PixelFormat format) {
245 switch (format) {
246 case PixelFormat::S8Z24:
247 return Tegra::DepthFormat::S8_Z24_UNORM;
248 case PixelFormat::Z24S8:
249 return Tegra::DepthFormat::Z24_S8_UNORM;
250 case PixelFormat::Z32F:
251 return Tegra::DepthFormat::Z32_FLOAT;
252 default:
253 UNREACHABLE();
254 }
255 }
256
252 static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { 257 static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) {
253 // TODO(Subv): Implement more component types 258 // TODO(Subv): Implement more component types
254 switch (type) { 259 switch (type) {
255 case Tegra::Texture::ComponentType::UNORM: 260 case Tegra::Texture::ComponentType::UNORM:
256 return ComponentType::UNorm; 261 return ComponentType::UNorm;
257 default: 262 default:
258 NGLOG_CRITICAL(HW_GPU, "Unimplemented component type={}", static_cast<u32>(type)); 263 LOG_CRITICAL(HW_GPU, "Unimplemented component type={}", static_cast<u32>(type));
259 UNREACHABLE(); 264 UNREACHABLE();
260 } 265 }
261 } 266 }
@@ -270,215 +275,153 @@ struct SurfaceParams {
270 case Tegra::RenderTargetFormat::RGBA16_FLOAT: 275 case Tegra::RenderTargetFormat::RGBA16_FLOAT:
271 case Tegra::RenderTargetFormat::R11G11B10_FLOAT: 276 case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
272 return ComponentType::Float; 277 return ComponentType::Float;
278 case Tegra::RenderTargetFormat::RGBA32_UINT:
279 return ComponentType::UInt;
273 default: 280 default:
274 NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); 281 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
275 UNREACHABLE(); 282 UNREACHABLE();
276 } 283 }
277 } 284 }
278 285
279 static ComponentType ComponentTypeFromGPUPixelFormat( 286 static PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) {
280 Tegra::FramebufferConfig::PixelFormat format) {
281 switch (format) { 287 switch (format) {
282 case Tegra::FramebufferConfig::PixelFormat::ABGR8: 288 case Tegra::FramebufferConfig::PixelFormat::ABGR8:
283 return ComponentType::UNorm; 289 return PixelFormat::ABGR8;
284 default: 290 default:
285 NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); 291 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
286 UNREACHABLE(); 292 UNREACHABLE();
287 } 293 }
288 } 294 }
289 295
290 static bool CheckFormatsBlittable(PixelFormat pixel_format_a, PixelFormat pixel_format_b) { 296 static ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format) {
291 SurfaceType a_type = GetFormatType(pixel_format_a); 297 switch (format) {
292 SurfaceType b_type = GetFormatType(pixel_format_b); 298 case Tegra::DepthFormat::S8_Z24_UNORM:
293 299 case Tegra::DepthFormat::Z24_S8_UNORM:
294 if (a_type == SurfaceType::ColorTexture && b_type == SurfaceType::ColorTexture) { 300 return ComponentType::UNorm;
295 return true; 301 case Tegra::DepthFormat::Z32_FLOAT:
296 } 302 return ComponentType::Float;
297 303 default:
298 if (a_type == SurfaceType::Depth && b_type == SurfaceType::Depth) { 304 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
299 return true; 305 UNREACHABLE();
300 }
301
302 if (a_type == SurfaceType::DepthStencil && b_type == SurfaceType::DepthStencil) {
303 return true;
304 } 306 }
305
306 return false;
307 } 307 }
308 308
309 static SurfaceType GetFormatType(PixelFormat pixel_format) { 309 static SurfaceType GetFormatType(PixelFormat pixel_format) {
310 if (static_cast<size_t>(pixel_format) < MaxPixelFormat) { 310 if (static_cast<size_t>(pixel_format) < static_cast<size_t>(PixelFormat::MaxColorFormat)) {
311 return SurfaceType::ColorTexture; 311 return SurfaceType::ColorTexture;
312 } 312 }
313 313
314 if (static_cast<size_t>(pixel_format) <
315 static_cast<size_t>(PixelFormat::MaxDepthStencilFormat)) {
316 return SurfaceType::DepthStencil;
317 }
318
314 // TODO(Subv): Implement the other formats 319 // TODO(Subv): Implement the other formats
315 ASSERT(false); 320 ASSERT(false);
316 321
317 return SurfaceType::Invalid; 322 return SurfaceType::Invalid;
318 } 323 }
319 324
320 /// Update the params "size", "end" and "type" from the already set "addr", "width", "height" 325 /// Returns the rectangle corresponding to this surface
321 /// and "pixel_format" 326 MathUtil::Rectangle<u32> GetRect() const;
322 void UpdateParams() {
323 if (stride == 0) {
324 stride = width;
325 }
326 type = GetFormatType(pixel_format);
327 size = !is_tiled ? BytesInPixels(stride * (height - 1) + width)
328 : BytesInPixels(stride * 8 * (height / 8 - 1) + width * 8);
329 end = addr + size;
330 }
331 327
332 SurfaceInterval GetInterval() const { 328 /// Returns the size of this surface in bytes, adjusted for compression
333 return SurfaceInterval::right_open(addr, end); 329 size_t SizeInBytes() const {
330 const u32 compression_factor{GetCompressionFactor(pixel_format)};
331 ASSERT(width % compression_factor == 0);
332 ASSERT(height % compression_factor == 0);
333 return (width / compression_factor) * (height / compression_factor) *
334 GetFormatBpp(pixel_format) / CHAR_BIT;
334 } 335 }
335 336
336 // Returns the outer rectangle containing "interval" 337 /// Returns the CPU virtual address for this surface
337 SurfaceParams FromInterval(SurfaceInterval interval) const; 338 VAddr GetCpuAddr() const;
338
339 SurfaceInterval GetSubRectInterval(MathUtil::Rectangle<u32> unscaled_rect) const;
340
341 // Returns the region of the biggest valid rectange within interval
342 SurfaceInterval GetCopyableInterval(const Surface& src_surface) const;
343
344 /**
345 * Gets the actual width (in pixels) of the surface. This is provided because `width` is used
346 * for tracking the surface region in memory, which may be compressed for certain formats. In
347 * this scenario, `width` is actually the compressed width.
348 */
349 u32 GetActualWidth() const {
350 return width * GetCompresssionFactor();
351 }
352
353 /**
354 * Gets the actual height (in pixels) of the surface. This is provided because `height` is used
355 * for tracking the surface region in memory, which may be compressed for certain formats. In
356 * this scenario, `height` is actually the compressed height.
357 */
358 u32 GetActualHeight() const {
359 return height * GetCompresssionFactor();
360 }
361
362 u32 GetScaledWidth() const {
363 return width * res_scale;
364 }
365
366 u32 GetScaledHeight() const {
367 return height * res_scale;
368 }
369 339
370 MathUtil::Rectangle<u32> GetRect() const { 340 /// Returns true if the specified region overlaps with this surface's region in Switch memory
371 return {0, height, width, 0}; 341 bool IsOverlappingRegion(Tegra::GPUVAddr region_addr, size_t region_size) const {
342 return addr <= (region_addr + region_size) && region_addr <= (addr + size_in_bytes);
372 } 343 }
373 344
374 MathUtil::Rectangle<u32> GetScaledRect() const { 345 /// Creates SurfaceParams from a texture configuration
375 return {0, GetScaledHeight(), GetScaledWidth(), 0}; 346 static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config);
376 } 347
348 /// Creates SurfaceParams from a framebuffer configuration
349 static SurfaceParams CreateForFramebuffer(
350 const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config);
351
352 /// Creates SurfaceParams for a depth buffer configuration
353 static SurfaceParams CreateForDepthBuffer(
354 const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config,
355 Tegra::GPUVAddr zeta_address, Tegra::DepthFormat format);
356
357 Tegra::GPUVAddr addr;
358 bool is_tiled;
359 u32 block_height;
360 PixelFormat pixel_format;
361 ComponentType component_type;
362 SurfaceType type;
363 u32 width;
364 u32 height;
365 u32 unaligned_height;
366 size_t size_in_bytes;
367};
377 368
378 u64 PixelsInBytes(u64 size) const { 369/// Hashable variation of SurfaceParams, used for a key in the surface cache
379 return size * CHAR_BIT / GetFormatBpp(pixel_format); 370struct SurfaceKey : Common::HashableStruct<SurfaceParams> {
371 static SurfaceKey Create(const SurfaceParams& params) {
372 SurfaceKey res;
373 res.state = params;
374 return res;
380 } 375 }
376};
381 377
382 u64 BytesInPixels(u64 pixels) const { 378namespace std {
383 return pixels * GetFormatBpp(pixel_format) / CHAR_BIT; 379template <>
380struct hash<SurfaceKey> {
381 size_t operator()(const SurfaceKey& k) const {
382 return k.Hash();
384 } 383 }
385
386 VAddr GetCpuAddr() const;
387
388 bool ExactMatch(const SurfaceParams& other_surface) const;
389 bool CanSubRect(const SurfaceParams& sub_surface) const;
390 bool CanExpand(const SurfaceParams& expanded_surface) const;
391 bool CanTexCopy(const SurfaceParams& texcopy_params) const;
392
393 MathUtil::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const;
394 MathUtil::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const;
395
396 Tegra::GPUVAddr addr = 0;
397 Tegra::GPUVAddr end = 0;
398 boost::optional<VAddr> cpu_addr;
399 u64 size = 0;
400
401 u32 width = 0;
402 u32 height = 0;
403 u32 stride = 0;
404 u32 block_height = 0;
405 u16 res_scale = 1;
406
407 bool is_tiled = false;
408 PixelFormat pixel_format = PixelFormat::Invalid;
409 SurfaceType type = SurfaceType::Invalid;
410 ComponentType component_type = ComponentType::Invalid;
411}; 384};
385} // namespace std
412 386
413struct CachedSurface : SurfaceParams { 387class CachedSurface final {
414 bool CanFill(const SurfaceParams& dest_surface, SurfaceInterval fill_interval) const; 388public:
415 bool CanCopy(const SurfaceParams& dest_surface, SurfaceInterval copy_interval) const; 389 CachedSurface(const SurfaceParams& params);
416
417 bool IsRegionValid(SurfaceInterval interval) const {
418 return (invalid_regions.find(interval) == invalid_regions.end());
419 }
420 390
421 bool IsSurfaceFullyInvalid() const { 391 const OGLTexture& Texture() const {
422 return (invalid_regions & GetInterval()) == SurfaceRegions(GetInterval()); 392 return texture;
423 } 393 }
424 394
425 bool registered = false; 395 static constexpr unsigned int GetGLBytesPerPixel(SurfaceParams::PixelFormat format) {
426 SurfaceRegions invalid_regions; 396 if (format == SurfaceParams::PixelFormat::Invalid)
427
428 u64 fill_size = 0; /// Number of bytes to read from fill_data
429 std::array<u8, 4> fill_data;
430
431 OGLTexture texture;
432
433 static constexpr unsigned int GetGLBytesPerPixel(PixelFormat format) {
434 if (format == PixelFormat::Invalid)
435 return 0; 397 return 0;
436 398
437 return SurfaceParams::GetFormatBpp(format) / CHAR_BIT; 399 return SurfaceParams::GetFormatBpp(format) / CHAR_BIT;
438 } 400 }
439 401
440 std::unique_ptr<u8[]> gl_buffer; 402 const SurfaceParams& GetSurfaceParams() const {
441 size_t gl_buffer_size = 0; 403 return params;
404 }
442 405
443 // Read/Write data in Switch memory to/from gl_buffer 406 // Read/Write data in Switch memory to/from gl_buffer
444 void LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr load_end); 407 void LoadGLBuffer();
445 void FlushGLBuffer(Tegra::GPUVAddr flush_start, Tegra::GPUVAddr flush_end); 408 void FlushGLBuffer();
446 409
447 // Upload/Download data in gl_buffer in/to this surface's texture 410 // Upload/Download data in gl_buffer in/to this surface's texture
448 void UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, 411 void UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle);
449 GLuint draw_fb_handle); 412 void DownloadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle);
450 void DownloadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, 413
451 GLuint draw_fb_handle); 414private:
415 OGLTexture texture;
416 std::vector<u8> gl_buffer;
417 SurfaceParams params;
452}; 418};
453 419
454class RasterizerCacheOpenGL : NonCopyable { 420class RasterizerCacheOpenGL final : NonCopyable {
455public: 421public:
456 RasterizerCacheOpenGL(); 422 RasterizerCacheOpenGL();
457 ~RasterizerCacheOpenGL(); 423 ~RasterizerCacheOpenGL();
458 424
459 /// Blit one surface's texture to another
460 bool BlitSurfaces(const Surface& src_surface, const MathUtil::Rectangle<u32>& src_rect,
461 const Surface& dst_surface, const MathUtil::Rectangle<u32>& dst_rect);
462
463 void ConvertD24S8toABGR(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect,
464 GLuint dst_tex, const MathUtil::Rectangle<u32>& dst_rect);
465
466 /// Copy one surface's region to another
467 void CopySurface(const Surface& src_surface, const Surface& dst_surface,
468 SurfaceInterval copy_interval);
469
470 /// Load a texture from Switch memory to OpenGL and cache it (if not already cached)
471 Surface GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale,
472 bool load_if_create);
473
474 /// Tries to find a framebuffer GPU address based on the provided CPU address
475 boost::optional<Tegra::GPUVAddr> TryFindFramebufferGpuAddress(VAddr cpu_addr) const;
476
477 /// Attempt to find a subrect (resolution scaled) of a surface, otherwise loads a texture from
478 /// Switch memory to OpenGL and caches it (if not already cached)
479 SurfaceRect_Tuple GetSurfaceSubRect(const SurfaceParams& params, ScaleMatch match_res_scale,
480 bool load_if_create);
481
482 /// Get a surface based on the texture configuration 425 /// Get a surface based on the texture configuration
483 Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config); 426 Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config);
484 427
@@ -486,29 +429,21 @@ public:
486 SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb, 429 SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb,
487 const MathUtil::Rectangle<s32>& viewport); 430 const MathUtil::Rectangle<s32>& viewport);
488 431
489 /// Get a surface that matches the fill config 432 /// Marks the specified surface as "dirty", in that it is out of sync with Switch memory
490 Surface GetFillSurface(const void* config); 433 void MarkSurfaceAsDirty(const Surface& surface);
491 434
492 /// Get a surface that matches a "texture copy" display transfer config 435 /// Tries to find a framebuffer GPU address based on the provided CPU address
493 SurfaceRect_Tuple GetTexCopySurface(const SurfaceParams& params); 436 Surface TryFindFramebufferSurface(VAddr cpu_addr) const;
494 437
495 /// Write any cached resources overlapping the region back to memory (if dirty) 438 /// Write any cached resources overlapping the region back to memory (if dirty)
496 void FlushRegion(Tegra::GPUVAddr addr, u64 size, Surface flush_surface = nullptr); 439 void FlushRegion(Tegra::GPUVAddr addr, size_t size);
497
498 /// Mark region as being invalidated by region_owner (nullptr if Switch memory)
499 void InvalidateRegion(Tegra::GPUVAddr addr, u64 size, const Surface& region_owner);
500 440
501 /// Flush all cached resources tracked by this cache manager 441 /// Mark the specified region as being invalidated
502 void FlushAll(); 442 void InvalidateRegion(Tegra::GPUVAddr addr, size_t size);
503 443
504private: 444private:
505 void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface); 445 void LoadSurface(const Surface& surface);
506 446 Surface GetSurface(const SurfaceParams& params);
507 /// Update surface's texture for given region when necessary
508 void ValidateSurface(const Surface& surface, Tegra::GPUVAddr addr, u64 size);
509
510 /// Create a new surface
511 Surface CreateSurface(const SurfaceParams& params);
512 447
513 /// Register surface into the cache 448 /// Register surface into the cache
514 void RegisterSurface(const Surface& surface); 449 void RegisterSurface(const Surface& surface);
@@ -519,18 +454,9 @@ private:
519 /// Increase/decrease the number of surface in pages touching the specified region 454 /// Increase/decrease the number of surface in pages touching the specified region
520 void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta); 455 void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta);
521 456
522 SurfaceCache surface_cache; 457 std::unordered_map<SurfaceKey, Surface> surface_cache;
523 PageMap cached_pages; 458 PageMap cached_pages;
524 SurfaceMap dirty_regions;
525 SurfaceSet remove_surfaces;
526 459
527 OGLFramebuffer read_framebuffer; 460 OGLFramebuffer read_framebuffer;
528 OGLFramebuffer draw_framebuffer; 461 OGLFramebuffer draw_framebuffer;
529
530 OGLVertexArray attributeless_vao;
531 OGLBuffer d24s8_abgr_buffer;
532 GLsizeiptr d24s8_abgr_buffer_size;
533 OGLProgram d24s8_abgr_shader;
534 GLint d24s8_abgr_tbo_size_u_id;
535 GLint d24s8_abgr_viewport_u_id;
536}; 462};
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h
index 93f9172e7..0fed93ca5 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.h
+++ b/src/video_core/renderer_opengl/gl_resource_manager.h
@@ -38,7 +38,7 @@ public:
38 if (handle == 0) 38 if (handle == 0)
39 return; 39 return;
40 glDeleteTextures(1, &handle); 40 glDeleteTextures(1, &handle);
41 OpenGLState::GetCurState().ResetTexture(handle).Apply(); 41 OpenGLState::GetCurState().UnbindTexture(handle).Apply();
42 handle = 0; 42 handle = 0;
43 } 43 }
44 44
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 65fed77ef..5914077e8 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -9,6 +9,7 @@
9#include "common/assert.h" 9#include "common/assert.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "video_core/engines/shader_bytecode.h" 11#include "video_core/engines/shader_bytecode.h"
12#include "video_core/renderer_opengl/gl_rasterizer.h"
12#include "video_core/renderer_opengl/gl_shader_decompiler.h" 13#include "video_core/renderer_opengl/gl_shader_decompiler.h"
13 14
14namespace GLShader { 15namespace GLShader {
@@ -282,7 +283,7 @@ public:
282 // Default - do nothing 283 // Default - do nothing
283 return value; 284 return value;
284 default: 285 default:
285 NGLOG_CRITICAL(HW_GPU, "Unimplemented conversion size {}", static_cast<u32>(size)); 286 LOG_CRITICAL(HW_GPU, "Unimplemented conversion size {}", static_cast<u32>(size));
286 UNREACHABLE(); 287 UNREACHABLE();
287 } 288 }
288 } 289 }
@@ -397,7 +398,8 @@ public:
397 /// Generates code representing a uniform (C buffer) register, interpreted as the input type. 398 /// Generates code representing a uniform (C buffer) register, interpreted as the input type.
398 std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) { 399 std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) {
399 declr_const_buffers[index].MarkAsUsed(index, offset, stage); 400 declr_const_buffers[index].MarkAsUsed(index, offset, stage);
400 std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset) + ']'; 401 std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" +
402 std::to_string(offset % 4) + ']';
401 403
402 if (type == GLSLRegister::Type::Float) { 404 if (type == GLSLRegister::Type::Float) {
403 return value; 405 return value;
@@ -411,8 +413,12 @@ public:
411 std::string GetUniformIndirect(u64 index, s64 offset, const Register& index_reg, 413 std::string GetUniformIndirect(u64 index, s64 offset, const Register& index_reg,
412 GLSLRegister::Type type) { 414 GLSLRegister::Type type) {
413 declr_const_buffers[index].MarkAsUsedIndirect(index, stage); 415 declr_const_buffers[index].MarkAsUsedIndirect(index, stage);
414 std::string value = 'c' + std::to_string(index) + "[(floatBitsToInt(" + 416
415 GetRegister(index_reg, 0) + ") + " + std::to_string(offset) + ") / 4]"; 417 std::string final_offset = "((floatBitsToInt(" + GetRegister(index_reg, 0) + ") + " +
418 std::to_string(offset) + ") / 4)";
419
420 std::string value =
421 'c' + std::to_string(index) + '[' + final_offset + " / 4][" + final_offset + " % 4]";
416 422
417 if (type == GLSLRegister::Type::Float) { 423 if (type == GLSLRegister::Type::Float) {
418 return value; 424 return value;
@@ -454,9 +460,10 @@ public:
454 460
455 unsigned const_buffer_layout = 0; 461 unsigned const_buffer_layout = 0;
456 for (const auto& entry : GetConstBuffersDeclarations()) { 462 for (const auto& entry : GetConstBuffersDeclarations()) {
457 declarations.AddLine("layout(std430) buffer " + entry.GetName()); 463 declarations.AddLine("layout(std140) uniform " + entry.GetName());
458 declarations.AddLine('{'); 464 declarations.AddLine('{');
459 declarations.AddLine(" float c" + std::to_string(entry.GetIndex()) + "[];"); 465 declarations.AddLine(" vec4 c" + std::to_string(entry.GetIndex()) +
466 "[MAX_CONSTBUFFER_ELEMENTS];");
460 declarations.AddLine("};"); 467 declarations.AddLine("};");
461 declarations.AddNewLine(); 468 declarations.AddNewLine();
462 ++const_buffer_layout; 469 ++const_buffer_layout;
@@ -574,7 +581,7 @@ private:
574 return "input_attribute_" + std::to_string(index); 581 return "input_attribute_" + std::to_string(index);
575 } 582 }
576 583
577 NGLOG_CRITICAL(HW_GPU, "Unhandled input attribute: {}", index); 584 LOG_CRITICAL(HW_GPU, "Unhandled input attribute: {}", index);
578 UNREACHABLE(); 585 UNREACHABLE();
579 } 586 }
580 } 587 }
@@ -592,7 +599,7 @@ private:
592 return "output_attribute_" + std::to_string(index); 599 return "output_attribute_" + std::to_string(index);
593 } 600 }
594 601
595 NGLOG_CRITICAL(HW_GPU, "Unhandled output attribute: {}", index); 602 LOG_CRITICAL(HW_GPU, "Unhandled output attribute: {}", index);
596 UNREACHABLE(); 603 UNREACHABLE();
597 } 604 }
598 } 605 }
@@ -712,21 +719,31 @@ private:
712 /** 719 /**
713 * Returns the comparison string to use to compare two values in the 'set' family of 720 * Returns the comparison string to use to compare two values in the 'set' family of
714 * instructions. 721 * instructions.
715 * @params condition The condition used in the 'set'-family instruction. 722 * @param condition The condition used in the 'set'-family instruction.
723 * @param op_a First operand to use for the comparison.
724 * @param op_b Second operand to use for the comparison.
716 * @returns String corresponding to the GLSL operator that matches the desired comparison. 725 * @returns String corresponding to the GLSL operator that matches the desired comparison.
717 */ 726 */
718 std::string GetPredicateComparison(Tegra::Shader::PredCondition condition) const { 727 std::string GetPredicateComparison(Tegra::Shader::PredCondition condition,
728 const std::string& op_a, const std::string& op_b) const {
719 using Tegra::Shader::PredCondition; 729 using Tegra::Shader::PredCondition;
720 static const std::unordered_map<PredCondition, const char*> PredicateComparisonStrings = { 730 static const std::unordered_map<PredCondition, const char*> PredicateComparisonStrings = {
721 {PredCondition::LessThan, "<"}, {PredCondition::Equal, "=="}, 731 {PredCondition::LessThan, "<"}, {PredCondition::Equal, "=="},
722 {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"}, 732 {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"},
723 {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="}, 733 {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="},
734 {PredCondition::NotEqualWithNan, "!="},
724 }; 735 };
725 736
726 auto comparison = PredicateComparisonStrings.find(condition); 737 const auto& comparison{PredicateComparisonStrings.find(condition)};
727 ASSERT_MSG(comparison != PredicateComparisonStrings.end(), 738 ASSERT_MSG(comparison != PredicateComparisonStrings.end(),
728 "Unknown predicate comparison operation"); 739 "Unknown predicate comparison operation");
729 return comparison->second; 740
741 std::string predicate{'(' + op_a + ") " + comparison->second + " (" + op_b + ')'};
742 if (condition == PredCondition::NotEqualWithNan) {
743 predicate += " || isnan(" + op_a + ") || isnan(" + op_b + ')';
744 }
745
746 return predicate;
730 } 747 }
731 748
732 /** 749 /**
@@ -780,7 +797,7 @@ private:
780 break; 797 break;
781 } 798 }
782 default: 799 default:
783 NGLOG_CRITICAL(HW_GPU, "Unimplemented logic operation: {}", static_cast<u32>(logic_op)); 800 LOG_CRITICAL(HW_GPU, "Unimplemented logic operation: {}", static_cast<u32>(logic_op));
784 UNREACHABLE(); 801 UNREACHABLE();
785 } 802 }
786 } 803 }
@@ -802,8 +819,9 @@ private:
802 819
803 // Decoding failure 820 // Decoding failure
804 if (!opcode) { 821 if (!opcode) {
805 NGLOG_CRITICAL(HW_GPU, "Unhandled instruction: {0:x}", instr.value); 822 LOG_CRITICAL(HW_GPU, "Unhandled instruction: {0:x}", instr.value);
806 UNREACHABLE(); 823 UNREACHABLE();
824 return offset + 1;
807 } 825 }
808 826
809 shader.AddLine("// " + std::to_string(offset) + ": " + opcode->GetName()); 827 shader.AddLine("// " + std::to_string(offset) + ": " + opcode->GetName());
@@ -899,13 +917,13 @@ private:
899 regs.SetRegisterToFloat(instr.gpr0, 0, "inversesqrt(" + op_a + ')', 1, 1, 917 regs.SetRegisterToFloat(instr.gpr0, 0, "inversesqrt(" + op_a + ')', 1, 1,
900 instr.alu.saturate_d); 918 instr.alu.saturate_d);
901 break; 919 break;
902 case SubOp::Min: 920 case SubOp::Sqrt:
903 regs.SetRegisterToFloat(instr.gpr0, 0, "min(" + op_a + "," + op_b + ')', 1, 1, 921 regs.SetRegisterToFloat(instr.gpr0, 0, "sqrt(" + op_a + ')', 1, 1,
904 instr.alu.saturate_d); 922 instr.alu.saturate_d);
905 break; 923 break;
906 default: 924 default:
907 NGLOG_CRITICAL(HW_GPU, "Unhandled MUFU sub op: {0:x}", 925 LOG_CRITICAL(HW_GPU, "Unhandled MUFU sub op: {0:x}",
908 static_cast<unsigned>(instr.sub_op.Value())); 926 static_cast<unsigned>(instr.sub_op.Value()));
909 UNREACHABLE(); 927 UNREACHABLE();
910 } 928 }
911 break; 929 break;
@@ -928,11 +946,11 @@ private:
928 // Currently RRO is only implemented as a register move. 946 // Currently RRO is only implemented as a register move.
929 // Usage of `abs_b` and `negate_b` here should also be correct. 947 // Usage of `abs_b` and `negate_b` here should also be correct.
930 regs.SetRegisterToFloat(instr.gpr0, 0, op_b, 1, 1); 948 regs.SetRegisterToFloat(instr.gpr0, 0, op_b, 1, 1);
931 NGLOG_WARNING(HW_GPU, "RRO instruction is incomplete"); 949 LOG_WARNING(HW_GPU, "RRO instruction is incomplete");
932 break; 950 break;
933 } 951 }
934 default: { 952 default: {
935 NGLOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {}", opcode->GetName()); 953 LOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {}", opcode->GetName());
936 UNREACHABLE(); 954 UNREACHABLE();
937 } 955 }
938 } 956 }
@@ -971,7 +989,7 @@ private:
971 break; 989 break;
972 } 990 }
973 default: { 991 default: {
974 NGLOG_CRITICAL(HW_GPU, "Unhandled BFE instruction: {}", opcode->GetName()); 992 LOG_CRITICAL(HW_GPU, "Unhandled BFE instruction: {}", opcode->GetName());
975 UNREACHABLE(); 993 UNREACHABLE();
976 } 994 }
977 } 995 }
@@ -1014,7 +1032,7 @@ private:
1014 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1); 1032 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1);
1015 break; 1033 break;
1016 default: { 1034 default: {
1017 NGLOG_CRITICAL(HW_GPU, "Unhandled shift instruction: {}", opcode->GetName()); 1035 LOG_CRITICAL(HW_GPU, "Unhandled shift instruction: {}", opcode->GetName());
1018 UNREACHABLE(); 1036 UNREACHABLE();
1019 } 1037 }
1020 } 1038 }
@@ -1044,8 +1062,8 @@ private:
1044 break; 1062 break;
1045 } 1063 }
1046 default: { 1064 default: {
1047 NGLOG_CRITICAL(HW_GPU, "Unhandled ArithmeticIntegerImmediate instruction: {}", 1065 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticIntegerImmediate instruction: {}",
1048 opcode->GetName()); 1066 opcode->GetName());
1049 UNREACHABLE(); 1067 UNREACHABLE();
1050 } 1068 }
1051 } 1069 }
@@ -1109,9 +1127,23 @@ private:
1109 WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b); 1127 WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b);
1110 break; 1128 break;
1111 } 1129 }
1130 case OpCode::Id::IMNMX_C:
1131 case OpCode::Id::IMNMX_R:
1132 case OpCode::Id::IMNMX_IMM: {
1133 ASSERT_MSG(instr.imnmx.exchange == Tegra::Shader::IMinMaxExchange::None,
1134 "Unimplemented");
1135 std::string condition =
1136 GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0);
1137 std::string parameters = op_a + ',' + op_b;
1138 regs.SetRegisterToInteger(instr.gpr0, instr.imnmx.is_signed, 0,
1139 '(' + condition + ") ? min(" + parameters + ") : max(" +
1140 parameters + ')',
1141 1, 1);
1142 break;
1143 }
1112 default: { 1144 default: {
1113 NGLOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", 1145 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}",
1114 opcode->GetName()); 1146 opcode->GetName());
1115 UNREACHABLE(); 1147 UNREACHABLE();
1116 } 1148 }
1117 } 1149 }
@@ -1147,7 +1179,7 @@ private:
1147 break; 1179 break;
1148 } 1180 }
1149 default: { 1181 default: {
1150 NGLOG_CRITICAL(HW_GPU, "Unhandled FFMA instruction: {}", opcode->GetName()); 1182 LOG_CRITICAL(HW_GPU, "Unhandled FFMA instruction: {}", opcode->GetName());
1151 UNREACHABLE(); 1183 UNREACHABLE();
1152 } 1184 }
1153 } 1185 }
@@ -1195,6 +1227,9 @@ private:
1195 switch (instr.conversion.f2f.rounding) { 1227 switch (instr.conversion.f2f.rounding) {
1196 case Tegra::Shader::F2fRoundingOp::None: 1228 case Tegra::Shader::F2fRoundingOp::None:
1197 break; 1229 break;
1230 case Tegra::Shader::F2fRoundingOp::Round:
1231 op_a = "roundEven(" + op_a + ')';
1232 break;
1198 case Tegra::Shader::F2fRoundingOp::Floor: 1233 case Tegra::Shader::F2fRoundingOp::Floor:
1199 op_a = "floor(" + op_a + ')'; 1234 op_a = "floor(" + op_a + ')';
1200 break; 1235 break;
@@ -1205,8 +1240,8 @@ private:
1205 op_a = "trunc(" + op_a + ')'; 1240 op_a = "trunc(" + op_a + ')';
1206 break; 1241 break;
1207 default: 1242 default:
1208 NGLOG_CRITICAL(HW_GPU, "Unimplemented f2f rounding mode {}", 1243 LOG_CRITICAL(HW_GPU, "Unimplemented f2f rounding mode {}",
1209 static_cast<u32>(instr.conversion.f2f.rounding.Value())); 1244 static_cast<u32>(instr.conversion.f2f.rounding.Value()));
1210 UNREACHABLE(); 1245 UNREACHABLE();
1211 break; 1246 break;
1212 } 1247 }
@@ -1239,8 +1274,8 @@ private:
1239 op_a = "trunc(" + op_a + ')'; 1274 op_a = "trunc(" + op_a + ')';
1240 break; 1275 break;
1241 default: 1276 default:
1242 NGLOG_CRITICAL(HW_GPU, "Unimplemented f2i rounding mode {}", 1277 LOG_CRITICAL(HW_GPU, "Unimplemented f2i rounding mode {}",
1243 static_cast<u32>(instr.conversion.f2i.rounding.Value())); 1278 static_cast<u32>(instr.conversion.f2i.rounding.Value()));
1244 UNREACHABLE(); 1279 UNREACHABLE();
1245 break; 1280 break;
1246 } 1281 }
@@ -1256,7 +1291,7 @@ private:
1256 break; 1291 break;
1257 } 1292 }
1258 default: { 1293 default: {
1259 NGLOG_CRITICAL(HW_GPU, "Unhandled conversion instruction: {}", opcode->GetName()); 1294 LOG_CRITICAL(HW_GPU, "Unhandled conversion instruction: {}", opcode->GetName());
1260 UNREACHABLE(); 1295 UNREACHABLE();
1261 } 1296 }
1262 } 1297 }
@@ -1291,8 +1326,8 @@ private:
1291 break; 1326 break;
1292 1327
1293 default: 1328 default:
1294 NGLOG_CRITICAL(HW_GPU, "Unhandled type: {}", 1329 LOG_CRITICAL(HW_GPU, "Unhandled type: {}",
1295 static_cast<unsigned>(instr.ld_c.type.Value())); 1330 static_cast<unsigned>(instr.ld_c.type.Value()));
1296 UNREACHABLE(); 1331 UNREACHABLE();
1297 } 1332 }
1298 break; 1333 break;
@@ -1365,7 +1400,7 @@ private:
1365 break; 1400 break;
1366 } 1401 }
1367 default: { 1402 default: {
1368 NGLOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName()); 1403 LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName());
1369 UNREACHABLE(); 1404 UNREACHABLE();
1370 } 1405 }
1371 } 1406 }
@@ -1407,10 +1442,9 @@ private:
1407 std::string second_pred = 1442 std::string second_pred =
1408 GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); 1443 GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0);
1409 1444
1410 std::string comparator = GetPredicateComparison(instr.fsetp.cond);
1411 std::string combiner = GetPredicateCombiner(instr.fsetp.op); 1445 std::string combiner = GetPredicateCombiner(instr.fsetp.op);
1412 1446
1413 std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')'; 1447 std::string predicate = GetPredicateComparison(instr.fsetp.cond, op_a, op_b);
1414 // Set the primary predicate to the result of Predicate OP SecondPredicate 1448 // Set the primary predicate to the result of Predicate OP SecondPredicate
1415 SetPredicate(instr.fsetp.pred3, 1449 SetPredicate(instr.fsetp.pred3,
1416 '(' + predicate + ") " + combiner + " (" + second_pred + ')'); 1450 '(' + predicate + ") " + combiner + " (" + second_pred + ')');
@@ -1445,10 +1479,9 @@ private:
1445 std::string second_pred = 1479 std::string second_pred =
1446 GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0); 1480 GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0);
1447 1481
1448 std::string comparator = GetPredicateComparison(instr.isetp.cond);
1449 std::string combiner = GetPredicateCombiner(instr.isetp.op); 1482 std::string combiner = GetPredicateCombiner(instr.isetp.op);
1450 1483
1451 std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')'; 1484 std::string predicate = GetPredicateComparison(instr.isetp.cond, op_a, op_b);
1452 // Set the primary predicate to the result of Predicate OP SecondPredicate 1485 // Set the primary predicate to the result of Predicate OP SecondPredicate
1453 SetPredicate(instr.isetp.pred3, 1486 SetPredicate(instr.isetp.pred3,
1454 '(' + predicate + ") " + combiner + " (" + second_pred + ')'); 1487 '(' + predicate + ") " + combiner + " (" + second_pred + ')');
@@ -1461,6 +1494,36 @@ private:
1461 } 1494 }
1462 break; 1495 break;
1463 } 1496 }
1497 case OpCode::Type::PredicateSetPredicate: {
1498 std::string op_a =
1499 GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0);
1500 std::string op_b =
1501 GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0);
1502
1503 using Tegra::Shader::Pred;
1504 // We can't use the constant predicate as destination.
1505 ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
1506
1507 std::string second_pred =
1508 GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0);
1509
1510 std::string combiner = GetPredicateCombiner(instr.psetp.op);
1511
1512 std::string predicate =
1513 '(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')';
1514
1515 // Set the primary predicate to the result of Predicate OP SecondPredicate
1516 SetPredicate(instr.psetp.pred3,
1517 '(' + predicate + ") " + combiner + " (" + second_pred + ')');
1518
1519 if (instr.psetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
1520 // Set the secondary predicate to the result of !Predicate OP SecondPredicate,
1521 // if enabled
1522 SetPredicate(instr.psetp.pred0,
1523 "!(" + predicate + ") " + combiner + " (" + second_pred + ')');
1524 }
1525 break;
1526 }
1464 case OpCode::Type::FloatSet: { 1527 case OpCode::Type::FloatSet: {
1465 std::string op_a = instr.fset.neg_a ? "-" : ""; 1528 std::string op_a = instr.fset.neg_a ? "-" : "";
1466 op_a += regs.GetRegisterAsFloat(instr.gpr8); 1529 op_a += regs.GetRegisterAsFloat(instr.gpr8);
@@ -1495,11 +1558,10 @@ private:
1495 std::string second_pred = 1558 std::string second_pred =
1496 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); 1559 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0);
1497 1560
1498 std::string comparator = GetPredicateComparison(instr.fset.cond);
1499 std::string combiner = GetPredicateCombiner(instr.fset.op); 1561 std::string combiner = GetPredicateCombiner(instr.fset.op);
1500 1562
1501 std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " + 1563 std::string predicate = "((" + GetPredicateComparison(instr.fset.cond, op_a, op_b) +
1502 combiner + " (" + second_pred + "))"; 1564 ") " + combiner + " (" + second_pred + "))";
1503 1565
1504 if (instr.fset.bf) { 1566 if (instr.fset.bf) {
1505 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); 1567 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1);
@@ -1530,11 +1592,10 @@ private:
1530 std::string second_pred = 1592 std::string second_pred =
1531 GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); 1593 GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0);
1532 1594
1533 std::string comparator = GetPredicateComparison(instr.iset.cond);
1534 std::string combiner = GetPredicateCombiner(instr.iset.op); 1595 std::string combiner = GetPredicateCombiner(instr.iset.op);
1535 1596
1536 std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " + 1597 std::string predicate = "((" + GetPredicateComparison(instr.iset.cond, op_a, op_b) +
1537 combiner + " (" + second_pred + "))"; 1598 ") " + combiner + " (" + second_pred + "))";
1538 1599
1539 if (instr.iset.bf) { 1600 if (instr.iset.bf) {
1540 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); 1601 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1);
@@ -1585,8 +1646,15 @@ private:
1585 // can ignore this when generating GLSL code. 1646 // can ignore this when generating GLSL code.
1586 break; 1647 break;
1587 } 1648 }
1649 case OpCode::Id::DEPBAR:
1650 case OpCode::Id::SYNC: {
1651 // TODO(Subv): Find out if we actually have to care about these instructions or if
1652 // the GLSL compiler takes care of that for us.
1653 LOG_WARNING(HW_GPU, "DEPBAR/SYNC instruction is stubbed");
1654 break;
1655 }
1588 default: { 1656 default: {
1589 NGLOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", opcode->GetName()); 1657 LOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", opcode->GetName());
1590 UNREACHABLE(); 1658 UNREACHABLE();
1591 } 1659 }
1592 } 1660 }
@@ -1713,7 +1781,10 @@ private:
1713}; // namespace Decompiler 1781}; // namespace Decompiler
1714 1782
1715std::string GetCommonDeclarations() { 1783std::string GetCommonDeclarations() {
1716 return "bool exec_shader();"; 1784 std::string declarations = "bool exec_shader();\n";
1785 declarations += "#define MAX_CONSTBUFFER_ELEMENTS " +
1786 std::to_string(RasterizerOpenGL::MaxConstbufferSize / (sizeof(GLvec4)));
1787 return declarations;
1717} 1788}
1718 1789
1719boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset, 1790boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset,
@@ -1723,7 +1794,7 @@ boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code,
1723 GLSLGenerator generator(subroutines, program_code, main_offset, stage); 1794 GLSLGenerator generator(subroutines, program_code, main_offset, stage);
1724 return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; 1795 return ProgramResult{generator.GetShaderCode(), generator.GetEntries()};
1725 } catch (const DecompileFail& exception) { 1796 } catch (const DecompileFail& exception) {
1726 NGLOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what()); 1797 LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what());
1727 } 1798 }
1728 return boost::none; 1799 return boost::none;
1729} 1800}
diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp
index 8568fface..3c087d638 100644
--- a/src/video_core/renderer_opengl/gl_shader_util.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_util.cpp
@@ -27,7 +27,7 @@ GLuint LoadShader(const char* source, GLenum type) {
27 } 27 }
28 GLuint shader_id = glCreateShader(type); 28 GLuint shader_id = glCreateShader(type);
29 glShaderSource(shader_id, 1, &source, nullptr); 29 glShaderSource(shader_id, 1, &source, nullptr);
30 NGLOG_DEBUG(Render_OpenGL, "Compiling {} shader...", debug_type); 30 LOG_DEBUG(Render_OpenGL, "Compiling {} shader...", debug_type);
31 glCompileShader(shader_id); 31 glCompileShader(shader_id);
32 32
33 GLint result = GL_FALSE; 33 GLint result = GL_FALSE;
@@ -39,9 +39,9 @@ GLuint LoadShader(const char* source, GLenum type) {
39 std::string shader_error(info_log_length, ' '); 39 std::string shader_error(info_log_length, ' ');
40 glGetShaderInfoLog(shader_id, info_log_length, nullptr, &shader_error[0]); 40 glGetShaderInfoLog(shader_id, info_log_length, nullptr, &shader_error[0]);
41 if (result == GL_TRUE) { 41 if (result == GL_TRUE) {
42 NGLOG_DEBUG(Render_OpenGL, "{}", shader_error); 42 LOG_DEBUG(Render_OpenGL, "{}", shader_error);
43 } else { 43 } else {
44 NGLOG_ERROR(Render_OpenGL, "Error compiling {} shader:\n{}", debug_type, shader_error); 44 LOG_ERROR(Render_OpenGL, "Error compiling {} shader:\n{}", debug_type, shader_error);
45 } 45 }
46 } 46 }
47 return shader_id; 47 return shader_id;
diff --git a/src/video_core/renderer_opengl/gl_shader_util.h b/src/video_core/renderer_opengl/gl_shader_util.h
index 2036a06a9..0e4d782e2 100644
--- a/src/video_core/renderer_opengl/gl_shader_util.h
+++ b/src/video_core/renderer_opengl/gl_shader_util.h
@@ -29,7 +29,7 @@ void LogShaderSource(T... shaders) {
29 29
30 std::string source(source_length, ' '); 30 std::string source(source_length, ' ');
31 glGetShaderSource(shader, source_length, nullptr, &source[0]); 31 glGetShaderSource(shader, source_length, nullptr, &source[0]);
32 NGLOG_INFO(Render_OpenGL, "Shader source {}", source); 32 LOG_INFO(Render_OpenGL, "Shader source {}", source);
33 } 33 }
34} 34}
35 35
@@ -49,7 +49,7 @@ GLuint LoadShader(const char* source, GLenum type);
49template <typename... T> 49template <typename... T>
50GLuint LoadProgram(bool separable_program, T... shaders) { 50GLuint LoadProgram(bool separable_program, T... shaders) {
51 // Link the program 51 // Link the program
52 NGLOG_DEBUG(Render_OpenGL, "Linking program..."); 52 LOG_DEBUG(Render_OpenGL, "Linking program...");
53 53
54 GLuint program_id = glCreateProgram(); 54 GLuint program_id = glCreateProgram();
55 55
@@ -71,9 +71,9 @@ GLuint LoadProgram(bool separable_program, T... shaders) {
71 std::string program_error(info_log_length, ' '); 71 std::string program_error(info_log_length, ' ');
72 glGetProgramInfoLog(program_id, info_log_length, nullptr, &program_error[0]); 72 glGetProgramInfoLog(program_id, info_log_length, nullptr, &program_error[0]);
73 if (result == GL_TRUE) { 73 if (result == GL_TRUE) {
74 NGLOG_DEBUG(Render_OpenGL, "{}", program_error); 74 LOG_DEBUG(Render_OpenGL, "{}", program_error);
75 } else { 75 } else {
76 NGLOG_ERROR(Render_OpenGL, "Error linking shader:\n{}", program_error); 76 LOG_ERROR(Render_OpenGL, "Error linking shader:\n{}", program_error);
77 } 77 }
78 } 78 }
79 79
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 1f1e48425..2e8a422a8 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -48,24 +48,9 @@ OpenGLState::OpenGLState() {
48 logic_op = GL_COPY; 48 logic_op = GL_COPY;
49 49
50 for (auto& texture_unit : texture_units) { 50 for (auto& texture_unit : texture_units) {
51 texture_unit.texture_2d = 0; 51 texture_unit.Reset();
52 texture_unit.sampler = 0;
53 texture_unit.swizzle.r = GL_RED;
54 texture_unit.swizzle.g = GL_GREEN;
55 texture_unit.swizzle.b = GL_BLUE;
56 texture_unit.swizzle.a = GL_ALPHA;
57 } 52 }
58 53
59 lighting_lut.texture_buffer = 0;
60
61 fog_lut.texture_buffer = 0;
62
63 proctex_lut.texture_buffer = 0;
64 proctex_diff_lut.texture_buffer = 0;
65 proctex_color_map.texture_buffer = 0;
66 proctex_alpha_map.texture_buffer = 0;
67 proctex_noise_lut.texture_buffer = 0;
68
69 draw.read_framebuffer = 0; 54 draw.read_framebuffer = 0;
70 draw.draw_framebuffer = 0; 55 draw.draw_framebuffer = 0;
71 draw.vertex_array = 0; 56 draw.vertex_array = 0;
@@ -223,54 +208,12 @@ void OpenGLState::Apply() const {
223 if (current.enabled != new_state.enabled || current.bindpoint != new_state.bindpoint || 208 if (current.enabled != new_state.enabled || current.bindpoint != new_state.bindpoint ||
224 current.ssbo != new_state.ssbo) { 209 current.ssbo != new_state.ssbo) {
225 if (new_state.enabled) { 210 if (new_state.enabled) {
226 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, new_state.bindpoint, new_state.ssbo); 211 glBindBufferBase(GL_UNIFORM_BUFFER, new_state.bindpoint, new_state.ssbo);
227 } 212 }
228 } 213 }
229 } 214 }
230 } 215 }
231 216
232 // Lighting LUTs
233 if (lighting_lut.texture_buffer != cur_state.lighting_lut.texture_buffer) {
234 glActiveTexture(TextureUnits::LightingLUT.Enum());
235 glBindTexture(GL_TEXTURE_BUFFER, lighting_lut.texture_buffer);
236 }
237
238 // Fog LUT
239 if (fog_lut.texture_buffer != cur_state.fog_lut.texture_buffer) {
240 glActiveTexture(TextureUnits::FogLUT.Enum());
241 glBindTexture(GL_TEXTURE_BUFFER, fog_lut.texture_buffer);
242 }
243
244 // ProcTex Noise LUT
245 if (proctex_noise_lut.texture_buffer != cur_state.proctex_noise_lut.texture_buffer) {
246 glActiveTexture(TextureUnits::ProcTexNoiseLUT.Enum());
247 glBindTexture(GL_TEXTURE_BUFFER, proctex_noise_lut.texture_buffer);
248 }
249
250 // ProcTex Color Map
251 if (proctex_color_map.texture_buffer != cur_state.proctex_color_map.texture_buffer) {
252 glActiveTexture(TextureUnits::ProcTexColorMap.Enum());
253 glBindTexture(GL_TEXTURE_BUFFER, proctex_color_map.texture_buffer);
254 }
255
256 // ProcTex Alpha Map
257 if (proctex_alpha_map.texture_buffer != cur_state.proctex_alpha_map.texture_buffer) {
258 glActiveTexture(TextureUnits::ProcTexAlphaMap.Enum());
259 glBindTexture(GL_TEXTURE_BUFFER, proctex_alpha_map.texture_buffer);
260 }
261
262 // ProcTex LUT
263 if (proctex_lut.texture_buffer != cur_state.proctex_lut.texture_buffer) {
264 glActiveTexture(TextureUnits::ProcTexLUT.Enum());
265 glBindTexture(GL_TEXTURE_BUFFER, proctex_lut.texture_buffer);
266 }
267
268 // ProcTex Diff LUT
269 if (proctex_diff_lut.texture_buffer != cur_state.proctex_diff_lut.texture_buffer) {
270 glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum());
271 glBindTexture(GL_TEXTURE_BUFFER, proctex_diff_lut.texture_buffer);
272 }
273
274 // Framebuffer 217 // Framebuffer
275 if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { 218 if (draw.read_framebuffer != cur_state.draw.read_framebuffer) {
276 glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); 219 glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
@@ -338,26 +281,12 @@ void OpenGLState::Apply() const {
338 cur_state = *this; 281 cur_state = *this;
339} 282}
340 283
341OpenGLState& OpenGLState::ResetTexture(GLuint handle) { 284OpenGLState& OpenGLState::UnbindTexture(GLuint handle) {
342 for (auto& unit : texture_units) { 285 for (auto& unit : texture_units) {
343 if (unit.texture_2d == handle) { 286 if (unit.texture_2d == handle) {
344 unit.texture_2d = 0; 287 unit.Unbind();
345 } 288 }
346 } 289 }
347 if (lighting_lut.texture_buffer == handle)
348 lighting_lut.texture_buffer = 0;
349 if (fog_lut.texture_buffer == handle)
350 fog_lut.texture_buffer = 0;
351 if (proctex_noise_lut.texture_buffer == handle)
352 proctex_noise_lut.texture_buffer = 0;
353 if (proctex_color_map.texture_buffer == handle)
354 proctex_color_map.texture_buffer = 0;
355 if (proctex_alpha_map.texture_buffer == handle)
356 proctex_alpha_map.texture_buffer = 0;
357 if (proctex_lut.texture_buffer == handle)
358 proctex_lut.texture_buffer = 0;
359 if (proctex_diff_lut.texture_buffer == handle)
360 proctex_diff_lut.texture_buffer = 0;
361 return *this; 290 return *this;
362} 291}
363 292
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 839e50e93..3398d7c04 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -91,35 +91,20 @@ public:
91 GLint b; // GL_TEXTURE_SWIZZLE_B 91 GLint b; // GL_TEXTURE_SWIZZLE_B
92 GLint a; // GL_TEXTURE_SWIZZLE_A 92 GLint a; // GL_TEXTURE_SWIZZLE_A
93 } swizzle; 93 } swizzle;
94 } texture_units[32];
95
96 struct {
97 GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER
98 } lighting_lut;
99
100 struct {
101 GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER
102 } fog_lut;
103
104 struct {
105 GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER
106 } proctex_noise_lut;
107 94
108 struct { 95 void Unbind() {
109 GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER 96 texture_2d = 0;
110 } proctex_color_map; 97 swizzle.r = GL_RED;
111 98 swizzle.g = GL_GREEN;
112 struct { 99 swizzle.b = GL_BLUE;
113 GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER 100 swizzle.a = GL_ALPHA;
114 } proctex_alpha_map; 101 }
115 102
116 struct { 103 void Reset() {
117 GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER 104 Unbind();
118 } proctex_lut; 105 sampler = 0;
119 106 }
120 struct { 107 } texture_units[32];
121 GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER
122 } proctex_diff_lut;
123 108
124 struct { 109 struct {
125 GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING 110 GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING
@@ -165,7 +150,7 @@ public:
165 void Apply() const; 150 void Apply() const;
166 151
167 /// Resets any references to the given resource 152 /// Resets any references to the given resource
168 OpenGLState& ResetTexture(GLuint handle); 153 OpenGLState& UnbindTexture(GLuint handle);
169 OpenGLState& ResetSampler(GLuint handle); 154 OpenGLState& ResetSampler(GLuint handle);
170 OpenGLState& ResetProgram(GLuint handle); 155 OpenGLState& ResetProgram(GLuint handle);
171 OpenGLState& ResetPipeline(GLuint handle); 156 OpenGLState& ResetPipeline(GLuint handle);
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 2155fb019..e19c3b280 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -29,9 +29,13 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) {
29 switch (attrib.size) { 29 switch (attrib.size) {
30 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 30 case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
31 return GL_UNSIGNED_BYTE; 31 return GL_UNSIGNED_BYTE;
32 case Maxwell::VertexAttribute::Size::Size_16_16:
33 return GL_UNSIGNED_SHORT;
34 case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
35 return GL_UNSIGNED_INT_2_10_10_10_REV;
32 } 36 }
33 37
34 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented vertex size={}", attrib.SizeString()); 38 LOG_CRITICAL(Render_OpenGL, "Unimplemented vertex size={}", attrib.SizeString());
35 UNREACHABLE(); 39 UNREACHABLE();
36 return {}; 40 return {};
37 } 41 }
@@ -41,9 +45,13 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) {
41 switch (attrib.size) { 45 switch (attrib.size) {
42 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 46 case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
43 return GL_BYTE; 47 return GL_BYTE;
48 case Maxwell::VertexAttribute::Size::Size_16_16:
49 return GL_SHORT;
50 case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
51 return GL_INT_2_10_10_10_REV;
44 } 52 }
45 53
46 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented vertex size={}", attrib.SizeString()); 54 LOG_CRITICAL(Render_OpenGL, "Unimplemented vertex size={}", attrib.SizeString());
47 UNREACHABLE(); 55 UNREACHABLE();
48 return {}; 56 return {};
49 } 57 }
@@ -52,7 +60,7 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) {
52 return GL_FLOAT; 60 return GL_FLOAT;
53 } 61 }
54 62
55 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented vertex type={}", attrib.TypeString()); 63 LOG_CRITICAL(Render_OpenGL, "Unimplemented vertex type={}", attrib.TypeString());
56 UNREACHABLE(); 64 UNREACHABLE();
57 return {}; 65 return {};
58} 66}
@@ -66,7 +74,7 @@ inline GLenum IndexFormat(Maxwell::IndexFormat index_format) {
66 case Maxwell::IndexFormat::UnsignedInt: 74 case Maxwell::IndexFormat::UnsignedInt:
67 return GL_UNSIGNED_INT; 75 return GL_UNSIGNED_INT;
68 } 76 }
69 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented index_format={}", static_cast<u32>(index_format)); 77 LOG_CRITICAL(Render_OpenGL, "Unimplemented index_format={}", static_cast<u32>(index_format));
70 UNREACHABLE(); 78 UNREACHABLE();
71 return {}; 79 return {};
72} 80}
@@ -78,7 +86,7 @@ inline GLenum PrimitiveTopology(Maxwell::PrimitiveTopology topology) {
78 case Maxwell::PrimitiveTopology::TriangleStrip: 86 case Maxwell::PrimitiveTopology::TriangleStrip:
79 return GL_TRIANGLE_STRIP; 87 return GL_TRIANGLE_STRIP;
80 } 88 }
81 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented topology={}", static_cast<u32>(topology)); 89 LOG_CRITICAL(Render_OpenGL, "Unimplemented topology={}", static_cast<u32>(topology));
82 UNREACHABLE(); 90 UNREACHABLE();
83 return {}; 91 return {};
84} 92}
@@ -90,8 +98,8 @@ inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode) {
90 case Tegra::Texture::TextureFilter::Nearest: 98 case Tegra::Texture::TextureFilter::Nearest:
91 return GL_NEAREST; 99 return GL_NEAREST;
92 } 100 }
93 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented texture filter mode={}", 101 LOG_CRITICAL(Render_OpenGL, "Unimplemented texture filter mode={}",
94 static_cast<u32>(filter_mode)); 102 static_cast<u32>(filter_mode));
95 UNREACHABLE(); 103 UNREACHABLE();
96 return {}; 104 return {};
97} 105}
@@ -110,8 +118,7 @@ inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) {
110 // manually mix them. However the shader part of this is not yet implemented. 118 // manually mix them. However the shader part of this is not yet implemented.
111 return GL_CLAMP_TO_BORDER; 119 return GL_CLAMP_TO_BORDER;
112 } 120 }
113 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented texture wrap mode={}", 121 LOG_CRITICAL(Render_OpenGL, "Unimplemented texture wrap mode={}", static_cast<u32>(wrap_mode));
114 static_cast<u32>(wrap_mode));
115 UNREACHABLE(); 122 UNREACHABLE();
116 return {}; 123 return {};
117} 124}
@@ -129,7 +136,7 @@ inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
129 case Maxwell::Blend::Equation::Max: 136 case Maxwell::Blend::Equation::Max:
130 return GL_MAX; 137 return GL_MAX;
131 } 138 }
132 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented blend equation={}", static_cast<u32>(equation)); 139 LOG_CRITICAL(Render_OpenGL, "Unimplemented blend equation={}", static_cast<u32>(equation));
133 UNREACHABLE(); 140 UNREACHABLE();
134 return {}; 141 return {};
135} 142}
@@ -175,7 +182,7 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
175 case Maxwell::Blend::Factor::OneMinusConstantAlpha: 182 case Maxwell::Blend::Factor::OneMinusConstantAlpha:
176 return GL_ONE_MINUS_CONSTANT_ALPHA; 183 return GL_ONE_MINUS_CONSTANT_ALPHA;
177 } 184 }
178 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented blend factor={}", static_cast<u32>(factor)); 185 LOG_CRITICAL(Render_OpenGL, "Unimplemented blend factor={}", static_cast<u32>(factor));
179 UNREACHABLE(); 186 UNREACHABLE();
180 return {}; 187 return {};
181} 188}
@@ -196,7 +203,65 @@ inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) {
196 case Tegra::Texture::SwizzleSource::OneFloat: 203 case Tegra::Texture::SwizzleSource::OneFloat:
197 return GL_ONE; 204 return GL_ONE;
198 } 205 }
199 NGLOG_CRITICAL(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source)); 206 LOG_CRITICAL(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source));
207 UNREACHABLE();
208 return {};
209}
210
211inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
212 switch (comparison) {
213 case Maxwell::ComparisonOp::Never:
214 case Maxwell::ComparisonOp::NeverOld:
215 return GL_NEVER;
216 case Maxwell::ComparisonOp::Less:
217 case Maxwell::ComparisonOp::LessOld:
218 return GL_LESS;
219 case Maxwell::ComparisonOp::Equal:
220 case Maxwell::ComparisonOp::EqualOld:
221 return GL_EQUAL;
222 case Maxwell::ComparisonOp::LessEqual:
223 case Maxwell::ComparisonOp::LessEqualOld:
224 return GL_LEQUAL;
225 case Maxwell::ComparisonOp::Greater:
226 case Maxwell::ComparisonOp::GreaterOld:
227 return GL_GREATER;
228 case Maxwell::ComparisonOp::NotEqual:
229 case Maxwell::ComparisonOp::NotEqualOld:
230 return GL_NOTEQUAL;
231 case Maxwell::ComparisonOp::GreaterEqual:
232 case Maxwell::ComparisonOp::GreaterEqualOld:
233 return GL_GEQUAL;
234 case Maxwell::ComparisonOp::Always:
235 case Maxwell::ComparisonOp::AlwaysOld:
236 return GL_ALWAYS;
237 }
238 LOG_CRITICAL(Render_OpenGL, "Unimplemented comparison op={}", static_cast<u32>(comparison));
239 UNREACHABLE();
240 return {};
241}
242
243inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) {
244 switch (front_face) {
245 case Maxwell::Cull::FrontFace::ClockWise:
246 return GL_CW;
247 case Maxwell::Cull::FrontFace::CounterClockWise:
248 return GL_CCW;
249 }
250 LOG_CRITICAL(Render_OpenGL, "Unimplemented front face cull={}", static_cast<u32>(front_face));
251 UNREACHABLE();
252 return {};
253}
254
255inline GLenum CullFace(Maxwell::Cull::CullFace cull_face) {
256 switch (cull_face) {
257 case Maxwell::Cull::CullFace::Front:
258 return GL_FRONT;
259 case Maxwell::Cull::CullFace::Back:
260 return GL_BACK;
261 case Maxwell::Cull::CullFace::FrontAndBack:
262 return GL_FRONT_AND_BACK;
263 }
264 LOG_CRITICAL(Render_OpenGL, "Unimplemented cull face={}", static_cast<u32>(cull_face));
200 UNREACHABLE(); 265 UNREACHABLE();
201 return {}; 266 return {};
202} 267}
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index f33766bfd..00841e937 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -150,7 +150,6 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
150 screen_info)) { 150 screen_info)) {
151 // Reset the screen info's display texture to its own permanent texture 151 // Reset the screen info's display texture to its own permanent texture
152 screen_info.display_texture = screen_info.texture.resource.handle; 152 screen_info.display_texture = screen_info.texture.resource.handle;
153 screen_info.display_texcoords = MathUtil::Rectangle<float>(0.f, 0.f, 1.f, 1.f);
154 153
155 Memory::RasterizerFlushVirtualRegion(framebuffer_addr, size_in_bytes, 154 Memory::RasterizerFlushVirtualRegion(framebuffer_addr, size_in_bytes,
156 Memory::FlushMode::Flush); 155 Memory::FlushMode::Flush);
@@ -302,8 +301,8 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
302 right = texcoords.left; 301 right = texcoords.left;
303 } else { 302 } else {
304 // Other transformations are unsupported 303 // Other transformations are unsupported
305 NGLOG_CRITICAL(Render_OpenGL, "Unsupported framebuffer_transform_flags={}", 304 LOG_CRITICAL(Render_OpenGL, "Unsupported framebuffer_transform_flags={}",
306 static_cast<u32>(framebuffer_transform_flags)); 305 static_cast<u32>(framebuffer_transform_flags));
307 UNIMPLEMENTED(); 306 UNIMPLEMENTED();
308 } 307 }
309 } 308 }
@@ -405,14 +404,14 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum
405 404
406 switch (severity) { 405 switch (severity) {
407 case GL_DEBUG_SEVERITY_HIGH: 406 case GL_DEBUG_SEVERITY_HIGH:
408 NGLOG_ERROR(Render_OpenGL, format, str_source, str_type, id, message); 407 LOG_ERROR(Render_OpenGL, format, str_source, str_type, id, message);
409 break; 408 break;
410 case GL_DEBUG_SEVERITY_MEDIUM: 409 case GL_DEBUG_SEVERITY_MEDIUM:
411 NGLOG_WARNING(Render_OpenGL, format, str_source, str_type, id, message); 410 LOG_WARNING(Render_OpenGL, format, str_source, str_type, id, message);
412 break; 411 break;
413 case GL_DEBUG_SEVERITY_NOTIFICATION: 412 case GL_DEBUG_SEVERITY_NOTIFICATION:
414 case GL_DEBUG_SEVERITY_LOW: 413 case GL_DEBUG_SEVERITY_LOW:
415 NGLOG_DEBUG(Render_OpenGL, format, str_source, str_type, id, message); 414 LOG_DEBUG(Render_OpenGL, format, str_source, str_type, id, message);
416 break; 415 break;
417 } 416 }
418} 417}
@@ -430,9 +429,9 @@ bool RendererOpenGL::Init() {
430 const char* gpu_vendor{reinterpret_cast<char const*>(glGetString(GL_VENDOR))}; 429 const char* gpu_vendor{reinterpret_cast<char const*>(glGetString(GL_VENDOR))};
431 const char* gpu_model{reinterpret_cast<char const*>(glGetString(GL_RENDERER))}; 430 const char* gpu_model{reinterpret_cast<char const*>(glGetString(GL_RENDERER))};
432 431
433 NGLOG_INFO(Render_OpenGL, "GL_VERSION: {}", gl_version); 432 LOG_INFO(Render_OpenGL, "GL_VERSION: {}", gl_version);
434 NGLOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor); 433 LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor);
435 NGLOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model); 434 LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model);
436 435
437 Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Vendor", gpu_vendor); 436 Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Vendor", gpu_vendor);
438 Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Model", gpu_model); 437 Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Model", gpu_model);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 2cc6d9a00..21f0d298c 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -27,7 +27,7 @@ struct TextureInfo {
27/// Structure used for storing information about the display target for the Switch screen 27/// Structure used for storing information about the display target for the Switch screen
28struct ScreenInfo { 28struct ScreenInfo {
29 GLuint display_texture; 29 GLuint display_texture;
30 MathUtil::Rectangle<float> display_texcoords; 30 const MathUtil::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f};
31 TextureInfo texture; 31 TextureInfo texture;
32}; 32};
33 33
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 0db4367f1..b3937b2fe 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -5,6 +5,7 @@
5#include <cstring> 5#include <cstring>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/memory.h" 7#include "core/memory.h"
8#include "video_core/gpu.h"
8#include "video_core/textures/decoders.h" 9#include "video_core/textures/decoders.h"
9#include "video_core/textures/texture.h" 10#include "video_core/textures/texture.h"
10 11
@@ -51,6 +52,7 @@ u32 BytesPerPixel(TextureFormat format) {
51 return 8; 52 return 8;
52 case TextureFormat::DXT23: 53 case TextureFormat::DXT23:
53 case TextureFormat::DXT45: 54 case TextureFormat::DXT45:
55 case TextureFormat::BC7U:
54 // In this case a 'pixel' actually refers to a 4x4 tile. 56 // In this case a 'pixel' actually refers to a 4x4 tile.
55 return 16; 57 return 16;
56 case TextureFormat::ASTC_2D_4X4: 58 case TextureFormat::ASTC_2D_4X4:
@@ -65,6 +67,20 @@ u32 BytesPerPixel(TextureFormat format) {
65 return 1; 67 return 1;
66 case TextureFormat::R16_G16_B16_A16: 68 case TextureFormat::R16_G16_B16_A16:
67 return 8; 69 return 8;
70 case TextureFormat::R32_G32_B32_A32:
71 return 16;
72 default:
73 UNIMPLEMENTED_MSG("Format not implemented");
74 break;
75 }
76}
77
78static u32 DepthBytesPerPixel(DepthFormat format) {
79 switch (format) {
80 case DepthFormat::S8_Z24_UNORM:
81 case DepthFormat::Z24_S8_UNORM:
82 case DepthFormat::Z32_FLOAT:
83 return 4;
68 default: 84 default:
69 UNIMPLEMENTED_MSG("Format not implemented"); 85 UNIMPLEMENTED_MSG("Format not implemented");
70 break; 86 break;
@@ -83,6 +99,7 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width,
83 case TextureFormat::DXT23: 99 case TextureFormat::DXT23:
84 case TextureFormat::DXT45: 100 case TextureFormat::DXT45:
85 case TextureFormat::DXN1: 101 case TextureFormat::DXN1:
102 case TextureFormat::BC7U:
86 // In the DXT and DXN formats, each 4x4 tile is swizzled instead of just individual pixel 103 // In the DXT and DXN formats, each 4x4 tile is swizzled instead of just individual pixel
87 // values. 104 // values.
88 CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data, 105 CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data,
@@ -94,6 +111,7 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width,
94 case TextureFormat::B5G6R5: 111 case TextureFormat::B5G6R5:
95 case TextureFormat::R8: 112 case TextureFormat::R8:
96 case TextureFormat::R16_G16_B16_A16: 113 case TextureFormat::R16_G16_B16_A16:
114 case TextureFormat::R32_G32_B32_A32:
97 case TextureFormat::BF10GF11RF11: 115 case TextureFormat::BF10GF11RF11:
98 case TextureFormat::ASTC_2D_4X4: 116 case TextureFormat::ASTC_2D_4X4:
99 CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, 117 CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
@@ -107,6 +125,28 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width,
107 return unswizzled_data; 125 return unswizzled_data;
108} 126}
109 127
128std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height,
129 u32 block_height) {
130 u8* data = Memory::GetPointer(address);
131 u32 bytes_per_pixel = DepthBytesPerPixel(format);
132
133 std::vector<u8> unswizzled_data(width * height * bytes_per_pixel);
134
135 switch (format) {
136 case DepthFormat::S8_Z24_UNORM:
137 case DepthFormat::Z24_S8_UNORM:
138 case DepthFormat::Z32_FLOAT:
139 CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
140 unswizzled_data.data(), true, block_height);
141 break;
142 default:
143 UNIMPLEMENTED_MSG("Format not implemented");
144 break;
145 }
146
147 return unswizzled_data;
148}
149
110std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width, 150std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width,
111 u32 height) { 151 u32 height) {
112 std::vector<u8> rgba_data; 152 std::vector<u8> rgba_data;
@@ -117,6 +157,7 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
117 case TextureFormat::DXT23: 157 case TextureFormat::DXT23:
118 case TextureFormat::DXT45: 158 case TextureFormat::DXT45:
119 case TextureFormat::DXN1: 159 case TextureFormat::DXN1:
160 case TextureFormat::BC7U:
120 case TextureFormat::ASTC_2D_4X4: 161 case TextureFormat::ASTC_2D_4X4:
121 case TextureFormat::A8R8G8B8: 162 case TextureFormat::A8R8G8B8:
122 case TextureFormat::A2B10G10R10: 163 case TextureFormat::A2B10G10R10:
@@ -124,6 +165,7 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
124 case TextureFormat::B5G6R5: 165 case TextureFormat::B5G6R5:
125 case TextureFormat::R8: 166 case TextureFormat::R8:
126 case TextureFormat::BF10GF11RF11: 167 case TextureFormat::BF10GF11RF11:
168 case TextureFormat::R32_G32_B32_A32:
127 // TODO(Subv): For the time being just forward the same data without any decoding. 169 // TODO(Subv): For the time being just forward the same data without any decoding.
128 rgba_data = texture_data; 170 rgba_data = texture_data;
129 break; 171 break;
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h
index 2562c4b06..2b088c077 100644
--- a/src/video_core/textures/decoders.h
+++ b/src/video_core/textures/decoders.h
@@ -17,6 +17,12 @@ namespace Texture {
17std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, 17std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
18 u32 block_height = TICEntry::DefaultBlockHeight); 18 u32 block_height = TICEntry::DefaultBlockHeight);
19 19
20/**
21 * Unswizzles a swizzled depth texture without changing its format.
22 */
23std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height,
24 u32 block_height = TICEntry::DefaultBlockHeight);
25
20/// Copies texture data from a buffer and performs swizzling/unswizzling as necessary. 26/// Copies texture data from a buffer and performs swizzling/unswizzling as necessary.
21void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, 27void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel,
22 u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height); 28 u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height);
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index 89dc8ed1e..289140f31 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -24,9 +24,9 @@ bool Init(EmuWindow* emu_window) {
24 g_renderer = std::make_unique<RendererOpenGL>(); 24 g_renderer = std::make_unique<RendererOpenGL>();
25 g_renderer->SetWindow(g_emu_window); 25 g_renderer->SetWindow(g_emu_window);
26 if (g_renderer->Init()) { 26 if (g_renderer->Init()) {
27 NGLOG_DEBUG(Render, "initialized OK"); 27 LOG_DEBUG(Render, "initialized OK");
28 } else { 28 } else {
29 NGLOG_CRITICAL(Render, "initialization failed !"); 29 LOG_CRITICAL(Render, "initialization failed !");
30 return false; 30 return false;
31 } 31 }
32 return true; 32 return true;
@@ -36,7 +36,7 @@ bool Init(EmuWindow* emu_window) {
36void Shutdown() { 36void Shutdown() {
37 g_renderer.reset(); 37 g_renderer.reset();
38 38
39 NGLOG_DEBUG(Render, "shutdown OK"); 39 LOG_DEBUG(Render, "shutdown OK");
40} 40}
41 41
42} // namespace VideoCore 42} // namespace VideoCore
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index c662570d2..7de919a8e 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -30,6 +30,8 @@ add_executable(yuzu
30 debugger/graphics/graphics_breakpoints_p.h 30 debugger/graphics/graphics_breakpoints_p.h
31 debugger/graphics/graphics_surface.cpp 31 debugger/graphics/graphics_surface.cpp
32 debugger/graphics/graphics_surface.h 32 debugger/graphics/graphics_surface.h
33 debugger/console.cpp
34 debugger/console.h
33 debugger/profiler.cpp 35 debugger/profiler.cpp
34 debugger/profiler.h 36 debugger/profiler.h
35 debugger/wait_tree.cpp 37 debugger/wait_tree.cpp
@@ -81,6 +83,14 @@ if (APPLE)
81 target_sources(yuzu PRIVATE ${MACOSX_ICON}) 83 target_sources(yuzu PRIVATE ${MACOSX_ICON})
82 set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE TRUE) 84 set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE TRUE)
83 set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) 85 set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
86elseif(WIN32)
87 # compile as a win32 gui application instead of a console application
88 target_link_libraries(yuzu PRIVATE Qt5::WinMain)
89 if(MSVC)
90 set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
91 elseif(MINGW)
92 set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "-mwindows")
93 endif()
84endif() 94endif()
85 95
86create_target_directory_groups(yuzu) 96create_target_directory_groups(yuzu)
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 5c17cd0d9..833085559 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -127,13 +127,14 @@ void GRenderWindow::moveContext() {
127} 127}
128 128
129void GRenderWindow::SwapBuffers() { 129void GRenderWindow::SwapBuffers() {
130#if !defined(QT_NO_DEBUG) 130 // In our multi-threaded QGLWidget use case we shouldn't need to call `makeCurrent`,
131 // Qt debug runtime prints a bogus warning on the console if you haven't called makeCurrent 131 // since we never call `doneCurrent` in this thread.
132 // since the last time you called swapBuffers. This presumably means something if you're using 132 // However:
133 // QGLWidget the "regular" way, but in our multi-threaded use case is harmless since we never 133 // - The Qt debug runtime prints a bogus warning on the console if `makeCurrent` wasn't called
134 // call doneCurrent in this thread. 134 // since the last time `swapBuffers` was executed;
135 // - On macOS, if `makeCurrent` isn't called explicitely, resizing the buffer breaks.
135 child->makeCurrent(); 136 child->makeCurrent();
136#endif 137
137 child->swapBuffers(); 138 child->swapBuffers();
138} 139}
139 140
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 8316db708..a32134fbe 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -84,6 +84,8 @@ void Config::ReadValues() {
84 qt_config->beginGroup("Renderer"); 84 qt_config->beginGroup("Renderer");
85 Settings::values.resolution_factor = qt_config->value("resolution_factor", 1.0).toFloat(); 85 Settings::values.resolution_factor = qt_config->value("resolution_factor", 1.0).toFloat();
86 Settings::values.toggle_framelimit = qt_config->value("toggle_framelimit", true).toBool(); 86 Settings::values.toggle_framelimit = qt_config->value("toggle_framelimit", true).toBool();
87 Settings::values.use_accurate_framebuffers =
88 qt_config->value("use_accurate_framebuffers", false).toBool();
87 89
88 Settings::values.bg_red = qt_config->value("bg_red", 0.0).toFloat(); 90 Settings::values.bg_red = qt_config->value("bg_red", 0.0).toFloat();
89 Settings::values.bg_green = qt_config->value("bg_green", 0.0).toFloat(); 91 Settings::values.bg_green = qt_config->value("bg_green", 0.0).toFloat();
@@ -158,6 +160,7 @@ void Config::ReadValues() {
158 UISettings::values.confirm_before_closing = qt_config->value("confirmClose", true).toBool(); 160 UISettings::values.confirm_before_closing = qt_config->value("confirmClose", true).toBool();
159 UISettings::values.first_start = qt_config->value("firstStart", true).toBool(); 161 UISettings::values.first_start = qt_config->value("firstStart", true).toBool();
160 UISettings::values.callout_flags = qt_config->value("calloutFlags", 0).toUInt(); 162 UISettings::values.callout_flags = qt_config->value("calloutFlags", 0).toUInt();
163 UISettings::values.show_console = qt_config->value("showConsole", false).toBool();
161 164
162 qt_config->endGroup(); 165 qt_config->endGroup();
163} 166}
@@ -184,6 +187,7 @@ void Config::SaveValues() {
184 qt_config->beginGroup("Renderer"); 187 qt_config->beginGroup("Renderer");
185 qt_config->setValue("resolution_factor", (double)Settings::values.resolution_factor); 188 qt_config->setValue("resolution_factor", (double)Settings::values.resolution_factor);
186 qt_config->setValue("toggle_framelimit", Settings::values.toggle_framelimit); 189 qt_config->setValue("toggle_framelimit", Settings::values.toggle_framelimit);
190 qt_config->setValue("use_accurate_framebuffers", Settings::values.use_accurate_framebuffers);
187 191
188 // Cast to double because Qt's written float values are not human-readable 192 // Cast to double because Qt's written float values are not human-readable
189 qt_config->setValue("bg_red", (double)Settings::values.bg_red); 193 qt_config->setValue("bg_red", (double)Settings::values.bg_red);
@@ -243,7 +247,7 @@ void Config::SaveValues() {
243 qt_config->setValue("confirmClose", UISettings::values.confirm_before_closing); 247 qt_config->setValue("confirmClose", UISettings::values.confirm_before_closing);
244 qt_config->setValue("firstStart", UISettings::values.first_start); 248 qt_config->setValue("firstStart", UISettings::values.first_start);
245 qt_config->setValue("calloutFlags", UISettings::values.callout_flags); 249 qt_config->setValue("calloutFlags", UISettings::values.callout_flags);
246 250 qt_config->setValue("showConsole", UISettings::values.show_console);
247 qt_config->endGroup(); 251 qt_config->endGroup();
248} 252}
249 253
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index a45edd510..241db4ae3 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -2,13 +2,26 @@
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 <QDesktopServices>
6#include <QUrl>
7#include "common/file_util.h"
8#include "common/logging/backend.h"
9#include "common/logging/filter.h"
10#include "common/logging/log.h"
11#include "core/core.h"
5#include "core/settings.h" 12#include "core/settings.h"
6#include "ui_configure_debug.h" 13#include "ui_configure_debug.h"
7#include "yuzu/configuration/configure_debug.h" 14#include "yuzu/configuration/configure_debug.h"
15#include "yuzu/debugger/console.h"
16#include "yuzu/ui_settings.h"
8 17
9ConfigureDebug::ConfigureDebug(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureDebug) { 18ConfigureDebug::ConfigureDebug(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureDebug) {
10 ui->setupUi(this); 19 ui->setupUi(this);
11 this->setConfiguration(); 20 this->setConfiguration();
21 connect(ui->open_log_button, &QPushButton::pressed, []() {
22 QString path = QString::fromStdString(FileUtil::GetUserPath(D_LOGS_IDX));
23 QDesktopServices::openUrl(QUrl::fromLocalFile(path));
24 });
12} 25}
13 26
14ConfigureDebug::~ConfigureDebug() {} 27ConfigureDebug::~ConfigureDebug() {}
@@ -17,10 +30,19 @@ void ConfigureDebug::setConfiguration() {
17 ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub); 30 ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub);
18 ui->gdbport_spinbox->setEnabled(Settings::values.use_gdbstub); 31 ui->gdbport_spinbox->setEnabled(Settings::values.use_gdbstub);
19 ui->gdbport_spinbox->setValue(Settings::values.gdbstub_port); 32 ui->gdbport_spinbox->setValue(Settings::values.gdbstub_port);
33 ui->toggle_console->setEnabled(!Core::System::GetInstance().IsPoweredOn());
34 ui->toggle_console->setChecked(UISettings::values.show_console);
35 ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter));
20} 36}
21 37
22void ConfigureDebug::applyConfiguration() { 38void ConfigureDebug::applyConfiguration() {
23 Settings::values.use_gdbstub = ui->toggle_gdbstub->isChecked(); 39 Settings::values.use_gdbstub = ui->toggle_gdbstub->isChecked();
24 Settings::values.gdbstub_port = ui->gdbport_spinbox->value(); 40 Settings::values.gdbstub_port = ui->gdbport_spinbox->value();
41 UISettings::values.show_console = ui->toggle_console->isChecked();
42 Settings::values.log_filter = ui->log_filter_edit->text().toStdString();
43 Debugger::ToggleConsole();
44 Log::Filter filter;
45 filter.ParseFilterString(Settings::values.log_filter);
46 Log::SetGlobalFilter(filter);
25 Settings::Apply(); 47 Settings::Apply();
26} 48}
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index a10bea2f4..118e91cf1 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -73,6 +73,47 @@
73 </layout> 73 </layout>
74 </item> 74 </item>
75 <item> 75 <item>
76 <widget class="QGroupBox" name="groupBox_2">
77 <property name="title">
78 <string>Logging</string>
79 </property>
80 <layout class="QVBoxLayout" name="verticalLayout">
81 <item>
82 <layout class="QHBoxLayout" name="horizontalLayout">
83 <item>
84 <widget class="QLabel" name="label">
85 <property name="text">
86 <string>Global Log Filter</string>
87 </property>
88 </widget>
89 </item>
90 <item>
91 <widget class="QLineEdit" name="log_filter_edit"/>
92 </item>
93 </layout>
94 </item>
95 <item>
96 <layout class="QHBoxLayout" name="horizontalLayout_2">
97 <item>
98 <widget class="QCheckBox" name="toggle_console">
99 <property name="text">
100 <string>Show Log Console (Windows Only)</string>
101 </property>
102 </widget>
103 </item>
104 <item>
105 <widget class="QPushButton" name="open_log_button">
106 <property name="text">
107 <string>Open Log Location</string>
108 </property>
109 </widget>
110 </item>
111 </layout>
112 </item>
113 </layout>
114 </widget>
115 </item>
116 <item>
76 <spacer name="verticalSpacer"> 117 <spacer name="verticalSpacer">
77 <property name="orientation"> 118 <property name="orientation">
78 <enum>Qt::Vertical</enum> 119 <enum>Qt::Vertical</enum>
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 47b9b6e95..7664880d5 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -59,11 +59,13 @@ void ConfigureGraphics::setConfiguration() {
59 ui->resolution_factor_combobox->setCurrentIndex( 59 ui->resolution_factor_combobox->setCurrentIndex(
60 static_cast<int>(FromResolutionFactor(Settings::values.resolution_factor))); 60 static_cast<int>(FromResolutionFactor(Settings::values.resolution_factor)));
61 ui->toggle_framelimit->setChecked(Settings::values.toggle_framelimit); 61 ui->toggle_framelimit->setChecked(Settings::values.toggle_framelimit);
62 ui->use_accurate_framebuffers->setChecked(Settings::values.use_accurate_framebuffers);
62} 63}
63 64
64void ConfigureGraphics::applyConfiguration() { 65void ConfigureGraphics::applyConfiguration() {
65 Settings::values.resolution_factor = 66 Settings::values.resolution_factor =
66 ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex())); 67 ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex()));
67 Settings::values.toggle_framelimit = ui->toggle_framelimit->isChecked(); 68 Settings::values.toggle_framelimit = ui->toggle_framelimit->isChecked();
69 Settings::values.use_accurate_framebuffers = ui->use_accurate_framebuffers->isChecked();
68 Settings::Apply(); 70 Settings::Apply();
69} 71}
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui
index 366931a9a..7d092df03 100644
--- a/src/yuzu/configuration/configure_graphics.ui
+++ b/src/yuzu/configuration/configure_graphics.ui
@@ -30,6 +30,13 @@
30 </widget> 30 </widget>
31 </item> 31 </item>
32 <item> 32 <item>
33 <widget class="QCheckBox" name="use_accurate_framebuffers">
34 <property name="text">
35 <string>Use accurate framebuffers (slow)</string>
36 </property>
37 </widget>
38 </item>
39 <item>
33 <layout class="QHBoxLayout" name="horizontalLayout"> 40 <layout class="QHBoxLayout" name="horizontalLayout">
34 <item> 41 <item>
35 <widget class="QLabel" name="label"> 42 <widget class="QLabel" name="label">
diff --git a/src/yuzu/debugger/console.cpp b/src/yuzu/debugger/console.cpp
new file mode 100644
index 000000000..e3d2d975f
--- /dev/null
+++ b/src/yuzu/debugger/console.cpp
@@ -0,0 +1,45 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#ifdef _WIN32
6#include <windows.h>
7
8#include <wincon.h>
9#endif
10
11#include "common/logging/backend.h"
12#include "yuzu/debugger/console.h"
13#include "yuzu/ui_settings.h"
14
15namespace Debugger {
16void ToggleConsole() {
17#if defined(_WIN32) && !defined(_DEBUG)
18 FILE* temp;
19 if (UISettings::values.show_console) {
20 if (AllocConsole()) {
21 // The first parameter for freopen_s is a out parameter, so we can just ignore it
22 freopen_s(&temp, "CONIN$", "r", stdin);
23 freopen_s(&temp, "CONOUT$", "w", stdout);
24 freopen_s(&temp, "CONOUT$", "w", stderr);
25 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
26 }
27 } else {
28 if (FreeConsole()) {
29 // In order to close the console, we have to also detach the streams on it.
30 // Just redirect them to NUL if there is no console window
31 Log::RemoveBackend(Log::ColorConsoleBackend::Name());
32 freopen_s(&temp, "NUL", "r", stdin);
33 freopen_s(&temp, "NUL", "w", stdout);
34 freopen_s(&temp, "NUL", "w", stderr);
35 }
36 }
37#else
38 if (UISettings::values.show_console) {
39 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
40 } else {
41 Log::RemoveBackend(Log::ColorConsoleBackend::Name());
42 }
43#endif
44}
45} // namespace Debugger
diff --git a/src/yuzu/debugger/console.h b/src/yuzu/debugger/console.h
new file mode 100644
index 000000000..d1990c496
--- /dev/null
+++ b/src/yuzu/debugger/console.h
@@ -0,0 +1,14 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Debugger {
8
9/**
10 * Uses the WINAPI to hide or show the stderr console. This function is a placeholder until we can
11 * get a real qt logging window which would work for all platforms.
12 */
13void ToggleConsole();
14} // namespace Debugger \ No newline at end of file
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index 55dce6d47..5a708dc73 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -325,8 +325,7 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
325void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) { 325void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
326 if (!FileUtil::Exists(dir_path.toStdString()) || 326 if (!FileUtil::Exists(dir_path.toStdString()) ||
327 !FileUtil::IsDirectory(dir_path.toStdString())) { 327 !FileUtil::IsDirectory(dir_path.toStdString())) {
328 NGLOG_ERROR(Frontend, "Could not find game list folder at {}", 328 LOG_ERROR(Frontend, "Could not find game list folder at {}", dir_path.toLocal8Bit().data());
329 dir_path.toLocal8Bit().data());
330 search_field->setFilterResult(0, 0); 329 search_field->setFilterResult(0, 0);
331 return; 330 return;
332 } 331 }
@@ -388,7 +387,7 @@ static QString FormatGameName(const std::string& physical_name) {
388 387
389void GameList::RefreshGameDirectory() { 388void GameList::RefreshGameDirectory() {
390 if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) { 389 if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) {
391 NGLOG_INFO(Frontend, "Change detected in the games directory. Reloading game list."); 390 LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
392 search_field->clear(); 391 search_field->clear();
393 PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); 392 PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
394 } 393 }
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 97be548d7..05a8ae6d2 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -31,6 +31,7 @@
31#include "yuzu/bootmanager.h" 31#include "yuzu/bootmanager.h"
32#include "yuzu/configuration/config.h" 32#include "yuzu/configuration/config.h"
33#include "yuzu/configuration/configure_dialog.h" 33#include "yuzu/configuration/configure_dialog.h"
34#include "yuzu/debugger/console.h"
34#include "yuzu/debugger/graphics/graphics_breakpoints.h" 35#include "yuzu/debugger/graphics/graphics_breakpoints.h"
35#include "yuzu/debugger/graphics/graphics_surface.h" 36#include "yuzu/debugger/graphics/graphics_surface.h"
36#include "yuzu/debugger/profiler.h" 37#include "yuzu/debugger/profiler.h"
@@ -261,6 +262,7 @@ void GMainWindow::RestoreUIState() {
261 262
262 ui.action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar); 263 ui.action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar);
263 statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked()); 264 statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked());
265 Debugger::ToggleConsole();
264} 266}
265 267
266void GMainWindow::ConnectWidgetEvents() { 268void GMainWindow::ConnectWidgetEvents() {
@@ -334,13 +336,11 @@ bool GMainWindow::SupportsRequiredGLExtensions() {
334 unsupported_ext.append("ARB_program_interface_query"); 336 unsupported_ext.append("ARB_program_interface_query");
335 if (!GLAD_GL_ARB_separate_shader_objects) 337 if (!GLAD_GL_ARB_separate_shader_objects)
336 unsupported_ext.append("ARB_separate_shader_objects"); 338 unsupported_ext.append("ARB_separate_shader_objects");
337 if (!GLAD_GL_ARB_shader_storage_buffer_object)
338 unsupported_ext.append("ARB_shader_storage_buffer_object");
339 if (!GLAD_GL_ARB_vertex_attrib_binding) 339 if (!GLAD_GL_ARB_vertex_attrib_binding)
340 unsupported_ext.append("ARB_vertex_attrib_binding"); 340 unsupported_ext.append("ARB_vertex_attrib_binding");
341 341
342 for (const QString& ext : unsupported_ext) 342 for (const QString& ext : unsupported_ext)
343 NGLOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext.toStdString()); 343 LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext.toStdString());
344 344
345 return unsupported_ext.empty(); 345 return unsupported_ext.empty();
346} 346}
@@ -377,17 +377,17 @@ bool GMainWindow::LoadROM(const QString& filename) {
377 if (result != Core::System::ResultStatus::Success) { 377 if (result != Core::System::ResultStatus::Success) {
378 switch (result) { 378 switch (result) {
379 case Core::System::ResultStatus::ErrorGetLoader: 379 case Core::System::ResultStatus::ErrorGetLoader:
380 NGLOG_CRITICAL(Frontend, "Failed to obtain loader for {}!", filename.toStdString()); 380 LOG_CRITICAL(Frontend, "Failed to obtain loader for {}!", filename.toStdString());
381 QMessageBox::critical(this, tr("Error while loading ROM!"), 381 QMessageBox::critical(this, tr("Error while loading ROM!"),
382 tr("The ROM format is not supported.")); 382 tr("The ROM format is not supported."));
383 break; 383 break;
384 case Core::System::ResultStatus::ErrorUnsupportedArch: 384 case Core::System::ResultStatus::ErrorUnsupportedArch:
385 NGLOG_CRITICAL(Frontend, "Unsupported architecture detected!", filename.toStdString()); 385 LOG_CRITICAL(Frontend, "Unsupported architecture detected!", filename.toStdString());
386 QMessageBox::critical(this, tr("Error while loading ROM!"), 386 QMessageBox::critical(this, tr("Error while loading ROM!"),
387 tr("The ROM uses currently unusable 32-bit architecture")); 387 tr("The ROM uses currently unusable 32-bit architecture"));
388 break; 388 break;
389 case Core::System::ResultStatus::ErrorSystemMode: 389 case Core::System::ResultStatus::ErrorSystemMode:
390 NGLOG_CRITICAL(Frontend, "Failed to load ROM!"); 390 LOG_CRITICAL(Frontend, "Failed to load ROM!");
391 QMessageBox::critical(this, tr("Error while loading ROM!"), 391 QMessageBox::critical(this, tr("Error while loading ROM!"),
392 tr("Could not determine the system mode.")); 392 tr("Could not determine the system mode."));
393 break; 393 break;
@@ -437,7 +437,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
437} 437}
438 438
439void GMainWindow::BootGame(const QString& filename) { 439void GMainWindow::BootGame(const QString& filename) {
440 NGLOG_INFO(Frontend, "yuzu starting..."); 440 LOG_INFO(Frontend, "yuzu starting...");
441 StoreRecentFile(filename); // Put the filename on top of the list 441 StoreRecentFile(filename); // Put the filename on top of the list
442 442
443 if (!LoadROM(filename)) 443 if (!LoadROM(filename))
@@ -884,7 +884,7 @@ void GMainWindow::UpdateUITheme() {
884 QString theme_uri(":" + UISettings::values.theme + "/style.qss"); 884 QString theme_uri(":" + UISettings::values.theme + "/style.qss");
885 QFile f(theme_uri); 885 QFile f(theme_uri);
886 if (!f.exists()) { 886 if (!f.exists()) {
887 NGLOG_ERROR(Frontend, "Unable to set style, stylesheet file not found"); 887 LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found");
888 } else { 888 } else {
889 f.open(QFile::ReadOnly | QFile::Text); 889 f.open(QFile::ReadOnly | QFile::Text);
890 QTextStream ts(&f); 890 QTextStream ts(&f);
@@ -908,8 +908,7 @@ void GMainWindow::UpdateUITheme() {
908#endif 908#endif
909 909
910int main(int argc, char* argv[]) { 910int main(int argc, char* argv[]) {
911 Log::Filter log_filter(Log::Level::Info); 911 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
912 Log::SetFilter(&log_filter);
913 912
914 MicroProfileOnThreadCreate("Frontend"); 913 MicroProfileOnThreadCreate("Frontend");
915 SCOPE_EXIT({ MicroProfileShutdown(); }); 914 SCOPE_EXIT({ MicroProfileShutdown(); });
@@ -927,7 +926,12 @@ int main(int argc, char* argv[]) {
927 926
928 GMainWindow main_window; 927 GMainWindow main_window;
929 // After settings have been loaded by GMainWindow, apply the filter 928 // After settings have been loaded by GMainWindow, apply the filter
929 Log::Filter log_filter;
930 log_filter.ParseFilterString(Settings::values.log_filter); 930 log_filter.ParseFilterString(Settings::values.log_filter);
931 Log::SetGlobalFilter(log_filter);
932 FileUtil::CreateFullPath(FileUtil::GetUserPath(D_LOGS_IDX));
933 Log::AddBackend(
934 std::make_unique<Log::FileBackend>(FileUtil::GetUserPath(D_LOGS_IDX) + LOG_FILE));
931 935
932 main_window.show(); 936 main_window.show();
933 return app.exec(); 937 return app.exec();
diff --git a/src/yuzu/ui_settings.h b/src/yuzu/ui_settings.h
index 8e215a002..2286c2559 100644
--- a/src/yuzu/ui_settings.h
+++ b/src/yuzu/ui_settings.h
@@ -51,6 +51,9 @@ struct Values {
51 std::vector<Shortcut> shortcuts; 51 std::vector<Shortcut> shortcuts;
52 52
53 uint32_t callout_flags; 53 uint32_t callout_flags;
54
55 // logging
56 bool show_console;
54}; 57};
55 58
56extern Values values; 59extern Values values;
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index ee6e4d658..3a311b69f 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -27,17 +27,17 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) {
27 const char* location = this->sdl2_config_loc.c_str(); 27 const char* location = this->sdl2_config_loc.c_str();
28 if (sdl2_config->ParseError() < 0) { 28 if (sdl2_config->ParseError() < 0) {
29 if (retry) { 29 if (retry) {
30 NGLOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", location); 30 LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", location);
31 FileUtil::CreateFullPath(location); 31 FileUtil::CreateFullPath(location);
32 FileUtil::WriteStringToFile(true, default_contents, location); 32 FileUtil::WriteStringToFile(true, default_contents, location);
33 sdl2_config = std::make_unique<INIReader>(location); // Reopen file 33 sdl2_config = std::make_unique<INIReader>(location); // Reopen file
34 34
35 return LoadINI(default_contents, false); 35 return LoadINI(default_contents, false);
36 } 36 }
37 NGLOG_ERROR(Config, "Failed."); 37 LOG_ERROR(Config, "Failed.");
38 return false; 38 return false;
39 } 39 }
40 NGLOG_INFO(Config, "Successfully loaded {}", location); 40 LOG_INFO(Config, "Successfully loaded {}", location);
41 return true; 41 return true;
42} 42}
43 43
@@ -98,6 +98,8 @@ void Config::ReadValues() {
98 (float)sdl2_config->GetReal("Renderer", "resolution_factor", 1.0); 98 (float)sdl2_config->GetReal("Renderer", "resolution_factor", 1.0);
99 Settings::values.toggle_framelimit = 99 Settings::values.toggle_framelimit =
100 sdl2_config->GetBoolean("Renderer", "toggle_framelimit", true); 100 sdl2_config->GetBoolean("Renderer", "toggle_framelimit", true);
101 Settings::values.use_accurate_framebuffers =
102 sdl2_config->GetBoolean("Renderer", "use_accurate_framebuffers", false);
101 103
102 Settings::values.bg_red = (float)sdl2_config->GetReal("Renderer", "bg_red", 0.0); 104 Settings::values.bg_red = (float)sdl2_config->GetReal("Renderer", "bg_red", 0.0);
103 Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0); 105 Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0);
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 1c438c3f5..71d2e040f 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -102,6 +102,10 @@ resolution_factor =
102# 0 (default): Off, 1: On 102# 0 (default): Off, 1: On
103use_vsync = 103use_vsync =
104 104
105# Whether to use accurate framebuffers
106# 0 (default): Off (fast), 1 : On (slow)
107use_accurate_framebuffers =
108
105# The clear color for the renderer. What shows up on the sides of the bottom screen. 109# The clear color for the renderer. What shows up on the sides of the bottom screen.
106# Must be in range of 0.0-1.0. Defaults to 1.0 for all. 110# Must be in range of 0.0-1.0. Defaults to 1.0 for all.
107bg_red = 111bg_red =
@@ -162,7 +166,7 @@ use_virtual_sd =
162# 1 (default): Yes, 0: No 166# 1 (default): Yes, 0: No
163use_docked_mode = 167use_docked_mode =
164 168
165# The system region that Citra will use during emulation 169# The system region that yuzu will use during emulation
166# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan 170# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
167region_value = 171region_value =
168 172
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index cfd8eb7e6..e6f0bbe8f 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -62,19 +62,19 @@ void EmuWindow_SDL2::Fullscreen() {
62 return; 62 return;
63 } 63 }
64 64
65 NGLOG_ERROR(Frontend, "Fullscreening failed: {}", SDL_GetError()); 65 LOG_ERROR(Frontend, "Fullscreening failed: {}", SDL_GetError());
66 66
67 // Try a different fullscreening method 67 // Try a different fullscreening method
68 NGLOG_INFO(Frontend, "Attempting to use borderless fullscreen..."); 68 LOG_INFO(Frontend, "Attempting to use borderless fullscreen...");
69 if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) { 69 if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) {
70 return; 70 return;
71 } 71 }
72 72
73 NGLOG_ERROR(Frontend, "Borderless fullscreening failed: {}", SDL_GetError()); 73 LOG_ERROR(Frontend, "Borderless fullscreening failed: {}", SDL_GetError());
74 74
75 // Fallback algorithm: Maximise window. 75 // Fallback algorithm: Maximise window.
76 // Works on all systems (unless something is seriously wrong), so no fallback for this one. 76 // Works on all systems (unless something is seriously wrong), so no fallback for this one.
77 NGLOG_INFO(Frontend, "Falling back on a maximised window..."); 77 LOG_INFO(Frontend, "Falling back on a maximised window...");
78 SDL_MaximizeWindow(render_window); 78 SDL_MaximizeWindow(render_window);
79} 79}
80 80
@@ -91,7 +91,7 @@ bool EmuWindow_SDL2::SupportsRequiredGLExtensions() {
91 unsupported_ext.push_back("ARB_vertex_attrib_binding"); 91 unsupported_ext.push_back("ARB_vertex_attrib_binding");
92 92
93 for (const std::string& ext : unsupported_ext) 93 for (const std::string& ext : unsupported_ext)
94 NGLOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext); 94 LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext);
95 95
96 return unsupported_ext.empty(); 96 return unsupported_ext.empty();
97} 97}
@@ -103,7 +103,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) {
103 103
104 // Initialize the window 104 // Initialize the window
105 if (SDL_Init(SDL_INIT_VIDEO) < 0) { 105 if (SDL_Init(SDL_INIT_VIDEO) < 0) {
106 NGLOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); 106 LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting...");
107 exit(1); 107 exit(1);
108 } 108 }
109 109
@@ -126,7 +126,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) {
126 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); 126 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
127 127
128 if (render_window == nullptr) { 128 if (render_window == nullptr) {
129 NGLOG_CRITICAL(Frontend, "Failed to create SDL2 window! Exiting..."); 129 LOG_CRITICAL(Frontend, "Failed to create SDL2 window! Exiting...");
130 exit(1); 130 exit(1);
131 } 131 }
132 132
@@ -137,17 +137,17 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) {
137 gl_context = SDL_GL_CreateContext(render_window); 137 gl_context = SDL_GL_CreateContext(render_window);
138 138
139 if (gl_context == nullptr) { 139 if (gl_context == nullptr) {
140 NGLOG_CRITICAL(Frontend, "Failed to create SDL2 GL context! Exiting..."); 140 LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context! Exiting...");
141 exit(1); 141 exit(1);
142 } 142 }
143 143
144 if (!gladLoadGLLoader(static_cast<GLADloadproc>(SDL_GL_GetProcAddress))) { 144 if (!gladLoadGLLoader(static_cast<GLADloadproc>(SDL_GL_GetProcAddress))) {
145 NGLOG_CRITICAL(Frontend, "Failed to initialize GL functions! Exiting..."); 145 LOG_CRITICAL(Frontend, "Failed to initialize GL functions! Exiting...");
146 exit(1); 146 exit(1);
147 } 147 }
148 148
149 if (!SupportsRequiredGLExtensions()) { 149 if (!SupportsRequiredGLExtensions()) {
150 NGLOG_CRITICAL(Frontend, "GPU does not support all required OpenGL extensions! Exiting..."); 150 LOG_CRITICAL(Frontend, "GPU does not support all required OpenGL extensions! Exiting...");
151 exit(1); 151 exit(1);
152 } 152 }
153 153
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 95e568b7b..8ddd202d8 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -7,6 +7,7 @@
7#include <string> 7#include <string>
8#include <thread> 8#include <thread>
9 9
10#include "common/common_paths.h"
10#include "common/logging/backend.h" 11#include "common/logging/backend.h"
11#include "common/logging/filter.h" 12#include "common/logging/filter.h"
12#include "common/logging/log.h" 13#include "common/logging/log.h"
@@ -69,7 +70,7 @@ int main(int argc, char** argv) {
69 auto argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w); 70 auto argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w);
70 71
71 if (argv_w == nullptr) { 72 if (argv_w == nullptr) {
72 NGLOG_CRITICAL(Frontend, "Failed to get command line arguments"); 73 LOG_CRITICAL(Frontend, "Failed to get command line arguments");
73 return -1; 74 return -1;
74 } 75 }
75#endif 76#endif
@@ -102,7 +103,7 @@ int main(int argc, char** argv) {
102 break; 103 break;
103 case 'f': 104 case 'f':
104 fullscreen = true; 105 fullscreen = true;
105 NGLOG_INFO(Frontend, "Starting in fullscreen mode..."); 106 LOG_INFO(Frontend, "Starting in fullscreen mode...");
106 break; 107 break;
107 case 'h': 108 case 'h':
108 PrintHelp(argv[0]); 109 PrintHelp(argv[0]);
@@ -126,13 +127,18 @@ int main(int argc, char** argv) {
126#endif 127#endif
127 128
128 Log::Filter log_filter(Log::Level::Debug); 129 Log::Filter log_filter(Log::Level::Debug);
129 Log::SetFilter(&log_filter); 130 Log::SetGlobalFilter(log_filter);
131
132 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
133 FileUtil::CreateFullPath(FileUtil::GetUserPath(D_LOGS_IDX));
134 Log::AddBackend(
135 std::make_unique<Log::FileBackend>(FileUtil::GetUserPath(D_LOGS_IDX) + LOG_FILE));
130 136
131 MicroProfileOnThreadCreate("EmuThread"); 137 MicroProfileOnThreadCreate("EmuThread");
132 SCOPE_EXIT({ MicroProfileShutdown(); }); 138 SCOPE_EXIT({ MicroProfileShutdown(); });
133 139
134 if (filepath.empty()) { 140 if (filepath.empty()) {
135 NGLOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); 141 LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
136 return -1; 142 return -1;
137 } 143 }
138 144
@@ -153,28 +159,28 @@ int main(int argc, char** argv) {
153 159
154 switch (load_result) { 160 switch (load_result) {
155 case Core::System::ResultStatus::ErrorGetLoader: 161 case Core::System::ResultStatus::ErrorGetLoader:
156 NGLOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filepath.c_str()); 162 LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filepath.c_str());
157 return -1; 163 return -1;
158 case Core::System::ResultStatus::ErrorLoader: 164 case Core::System::ResultStatus::ErrorLoader:
159 NGLOG_CRITICAL(Frontend, "Failed to load ROM!"); 165 LOG_CRITICAL(Frontend, "Failed to load ROM!");
160 return -1; 166 return -1;
161 case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: 167 case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted:
162 NGLOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before " 168 LOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before "
163 "being used with yuzu. \n\n For more information on dumping and " 169 "being used with yuzu. \n\n For more information on dumping and "
164 "decrypting games, please refer to: " 170 "decrypting games, please refer to: "
165 "https://yuzu-emu.org/wiki/dumping-game-cartridges/"); 171 "https://yuzu-emu.org/wiki/dumping-game-cartridges/");
166 return -1; 172 return -1;
167 case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: 173 case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat:
168 NGLOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); 174 LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported.");
169 return -1; 175 return -1;
170 case Core::System::ResultStatus::ErrorNotInitialized: 176 case Core::System::ResultStatus::ErrorNotInitialized:
171 NGLOG_CRITICAL(Frontend, "CPUCore not initialized"); 177 LOG_CRITICAL(Frontend, "CPUCore not initialized");
172 return -1; 178 return -1;
173 case Core::System::ResultStatus::ErrorSystemMode: 179 case Core::System::ResultStatus::ErrorSystemMode:
174 NGLOG_CRITICAL(Frontend, "Failed to determine system mode!"); 180 LOG_CRITICAL(Frontend, "Failed to determine system mode!");
175 return -1; 181 return -1;
176 case Core::System::ResultStatus::ErrorVideoCore: 182 case Core::System::ResultStatus::ErrorVideoCore:
177 NGLOG_CRITICAL(Frontend, "VideoCore not initialized"); 183 LOG_CRITICAL(Frontend, "VideoCore not initialized");
178 return -1; 184 return -1;
179 case Core::System::ResultStatus::Success: 185 case Core::System::ResultStatus::Success:
180 break; // Expected case 186 break; // Expected case