summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra/citra.cpp14
-rw-r--r--src/citra/emu_window/emu_window_sdl2.cpp4
-rw-r--r--src/citra_qt/debugger/graphics_vertex_shader.cpp12
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/core/CMakeLists.txt6
-rw-r--r--src/core/hle/service/ndm/ndm.cpp47
-rw-r--r--src/core/hle/service/ndm/ndm.h52
-rw-r--r--src/core/hle/service/ndm/ndm_u.cpp (renamed from src/core/hle/service/ndm_u.cpp)23
-rw-r--r--src/core/hle/service/ndm/ndm_u.h (renamed from src/core/hle/service/ndm_u.h)15
-rw-r--r--src/core/hle/service/service.cpp5
-rw-r--r--src/video_core/shader/shader.cpp16
-rw-r--r--src/video_core/shader/shader_interpreter.cpp7
-rw-r--r--src/video_core/shader/shader_jit_x64.cpp68
-rw-r--r--src/video_core/shader/shader_jit_x64.h5
15 files changed, 204 insertions, 72 deletions
diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp
index 415b98a05..40e40f192 100644
--- a/src/citra/citra.cpp
+++ b/src/citra/citra.cpp
@@ -19,6 +19,8 @@
19#include "common/logging/log.h" 19#include "common/logging/log.h"
20#include "common/logging/backend.h" 20#include "common/logging/backend.h"
21#include "common/logging/filter.h" 21#include "common/logging/filter.h"
22#include "common/make_unique.h"
23#include "common/scope_exit.h"
22 24
23#include "core/settings.h" 25#include "core/settings.h"
24#include "core/system.h" 26#include "core/system.h"
@@ -64,6 +66,7 @@ int main(int argc, char **argv) {
64 Log::SetFilter(&log_filter); 66 Log::SetFilter(&log_filter);
65 67
66 MicroProfileOnThreadCreate("EmuThread"); 68 MicroProfileOnThreadCreate("EmuThread");
69 SCOPE_EXIT({ MicroProfileShutdown(); });
67 70
68 if (boot_filename.empty()) { 71 if (boot_filename.empty()) {
69 LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); 72 LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
@@ -76,12 +79,13 @@ int main(int argc, char **argv) {
76 GDBStub::ToggleServer(Settings::values.use_gdbstub); 79 GDBStub::ToggleServer(Settings::values.use_gdbstub);
77 GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port)); 80 GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port));
78 81
79 EmuWindow_SDL2* emu_window = new EmuWindow_SDL2; 82 std::unique_ptr<EmuWindow_SDL2> emu_window = Common::make_unique<EmuWindow_SDL2>();
80 83
81 VideoCore::g_hw_renderer_enabled = Settings::values.use_hw_renderer; 84 VideoCore::g_hw_renderer_enabled = Settings::values.use_hw_renderer;
82 VideoCore::g_shader_jit_enabled = Settings::values.use_shader_jit; 85 VideoCore::g_shader_jit_enabled = Settings::values.use_shader_jit;
83 86
84 System::Init(emu_window); 87 System::Init(emu_window.get());
88 SCOPE_EXIT({ System::Shutdown(); });
85 89
86 Loader::ResultStatus load_result = Loader::LoadFile(boot_filename); 90 Loader::ResultStatus load_result = Loader::LoadFile(boot_filename);
87 if (Loader::ResultStatus::Success != load_result) { 91 if (Loader::ResultStatus::Success != load_result) {
@@ -93,11 +97,5 @@ int main(int argc, char **argv) {
93 Core::RunLoop(); 97 Core::RunLoop();
94 } 98 }
95 99
96 System::Shutdown();
97
98 delete emu_window;
99
100 MicroProfileShutdown();
101
102 return 0; 100 return 0;
103} 101}
diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp
index 1fed82e78..924189f4c 100644
--- a/src/citra/emu_window/emu_window_sdl2.cpp
+++ b/src/citra/emu_window/emu_window_sdl2.cpp
@@ -73,6 +73,10 @@ EmuWindow_SDL2::EmuWindow_SDL2() {
73 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); 73 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
74 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 74 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
75 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 75 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
76 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
77 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
78 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
79 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
76 80
77 std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); 81 std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc);
78 render_window = SDL_CreateWindow(window_title.c_str(), 82 render_window = SDL_CreateWindow(window_title.c_str(),
diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics_vertex_shader.cpp
index 4b676f1b1..d648d4640 100644
--- a/src/citra_qt/debugger/graphics_vertex_shader.cpp
+++ b/src/citra_qt/debugger/graphics_vertex_shader.cpp
@@ -179,9 +179,17 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con
179 AlignToColumn(kOutputColumnWidth); 179 AlignToColumn(kOutputColumnWidth);
180 print_input(output, src1, swizzle.negate_src1, SelectorToString(swizzle.src1_selector)); 180 print_input(output, src1, swizzle.negate_src1, SelectorToString(swizzle.src1_selector));
181 AlignToColumn(kInputOperandColumnWidth); 181 AlignToColumn(kInputOperandColumnWidth);
182 print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector)); 182 if (src_is_inverted) {
183 print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector));
184 } else {
185 print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector), true, instr.mad.AddressRegisterName());
186 }
183 AlignToColumn(kInputOperandColumnWidth); 187 AlignToColumn(kInputOperandColumnWidth);
184 print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector)); 188 if (src_is_inverted) {
189 print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector), true, instr.mad.AddressRegisterName());
190 } else {
191 print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector));
192 }
185 AlignToColumn(kInputOperandColumnWidth); 193 AlignToColumn(kInputOperandColumnWidth);
186 break; 194 break;
187 } 195 }
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 54291429a..4c86151ab 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -42,6 +42,7 @@ namespace Log {
42 SUB(Service, AM) \ 42 SUB(Service, AM) \
43 SUB(Service, PTM) \ 43 SUB(Service, PTM) \
44 SUB(Service, LDR) \ 44 SUB(Service, LDR) \
45 SUB(Service, NDM) \
45 SUB(Service, NIM) \ 46 SUB(Service, NIM) \
46 SUB(Service, NWM) \ 47 SUB(Service, NWM) \
47 SUB(Service, CAM) \ 48 SUB(Service, CAM) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 4b01805ae..e4c39c308 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -57,6 +57,7 @@ enum class Class : ClassType {
57 Service_AM, ///< The AM (Application manager) service 57 Service_AM, ///< The AM (Application manager) service
58 Service_PTM, ///< The PTM (Power status & misc.) service 58 Service_PTM, ///< The PTM (Power status & misc.) service
59 Service_LDR, ///< The LDR (3ds dll loader) service 59 Service_LDR, ///< The LDR (3ds dll loader) service
60 Service_NDM, ///< The NDM (Network daemon manager) service
60 Service_NIM, ///< The NIM (Network interface manager) service 61 Service_NIM, ///< The NIM (Network interface manager) service
61 Service_NWM, ///< The NWM (Network wlan manager) service 62 Service_NWM, ///< The NWM (Network wlan manager) service
62 Service_CAM, ///< The CAM (Camera) service 63 Service_CAM, ///< The CAM (Camera) service
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 35b61dada..3473e2f5b 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -87,7 +87,8 @@ set(SRCS
87 hle/service/ir/ir_user.cpp 87 hle/service/ir/ir_user.cpp
88 hle/service/ldr_ro.cpp 88 hle/service/ldr_ro.cpp
89 hle/service/mic_u.cpp 89 hle/service/mic_u.cpp
90 hle/service/ndm_u.cpp 90 hle/service/ndm/ndm.cpp
91 hle/service/ndm/ndm_u.cpp
91 hle/service/news/news.cpp 92 hle/service/news/news.cpp
92 hle/service/news/news_s.cpp 93 hle/service/news/news_s.cpp
93 hle/service/news/news_u.cpp 94 hle/service/news/news_u.cpp
@@ -218,7 +219,8 @@ set(HEADERS
218 hle/service/ir/ir_user.h 219 hle/service/ir/ir_user.h
219 hle/service/ldr_ro.h 220 hle/service/ldr_ro.h
220 hle/service/mic_u.h 221 hle/service/mic_u.h
221 hle/service/ndm_u.h 222 hle/service/ndm/ndm.h
223 hle/service/ndm/ndm_u.h
222 hle/service/news/news.h 224 hle/service/news/news.h
223 hle/service/news/news_s.h 225 hle/service/news/news_s.h
224 hle/service/news/news_u.h 226 hle/service/news/news_u.h
diff --git a/src/core/hle/service/ndm/ndm.cpp b/src/core/hle/service/ndm/ndm.cpp
new file mode 100644
index 000000000..47076a7b8
--- /dev/null
+++ b/src/core/hle/service/ndm/ndm.cpp
@@ -0,0 +1,47 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/common_types.h"
6#include "common/logging/log.h"
7#include "core/hle/service/service.h"
8#include "core/hle/service/ndm/ndm.h"
9#include "core/hle/service/ndm/ndm_u.h"
10
11namespace Service {
12namespace NDM {
13
14void SuspendDaemons(Service::Interface* self) {
15 u32* cmd_buff = Kernel::GetCommandBuffer();
16
17 LOG_WARNING(Service_NDM, "(STUBBED) bit_mask=0x%08X ", cmd_buff[1]);
18
19 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
20}
21
22void ResumeDaemons(Service::Interface* self) {
23 u32* cmd_buff = Kernel::GetCommandBuffer();
24
25 LOG_WARNING(Service_NDM, "(STUBBED) bit_mask=0x%08X ", cmd_buff[1]);
26
27 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
28}
29
30void OverrideDefaultDaemons(Service::Interface* self) {
31 u32* cmd_buff = Kernel::GetCommandBuffer();
32
33 LOG_WARNING(Service_NDM, "(STUBBED) bit_mask=0x%08X ", cmd_buff[1]);
34
35 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
36}
37
38void Init() {
39 AddService(new NDM_U_Interface);
40}
41
42void Shutdown() {
43
44}
45
46}// namespace NDM
47}// namespace Service
diff --git a/src/core/hle/service/ndm/ndm.h b/src/core/hle/service/ndm/ndm.h
new file mode 100644
index 000000000..734730f8c
--- /dev/null
+++ b/src/core/hle/service/ndm/ndm.h
@@ -0,0 +1,52 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9namespace Service {
10
11class Interface;
12
13namespace NDM {
14
15/**
16 * SuspendDaemons
17 * Inputs:
18 * 0 : Command header (0x00020082)
19 * 1 : Daemon bit mask
20 * Outputs:
21 * 1 : Result, 0 on success, otherwise error code
22 */
23void SuspendDaemons(Service::Interface* self);
24
25/**
26 * ResumeDaemons
27 * Inputs:
28 * 0 : Command header (0x00020082)
29 * 1 : Daemon bit mask
30 * Outputs:
31 * 1 : Result, 0 on success, otherwise error code
32 */
33void ResumeDaemons(Service::Interface* self);
34
35/**
36 * OverrideDefaultDaemons
37 * Inputs:
38 * 0 : Command header (0x00020082)
39 * 1 : Daemon bit mask
40 * Outputs:
41 * 1 : Result, 0 on success, otherwise error code
42 */
43void OverrideDefaultDaemons(Service::Interface* self);
44
45/// Initialize NDM service
46void Init();
47
48/// Shutdown NDM service
49void Shutdown();
50
51}// namespace NDM
52}// namespace Service
diff --git a/src/core/hle/service/ndm_u.cpp b/src/core/hle/service/ndm/ndm_u.cpp
index 8fdf1ef90..bf95cc7aa 100644
--- a/src/core/hle/service/ndm_u.cpp
+++ b/src/core/hle/service/ndm/ndm_u.cpp
@@ -2,12 +2,11 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/service/ndm_u.h" 5#include "core/hle/service/ndm/ndm.h"
6#include "core/hle/service/ndm/ndm_u.h"
6 7
7//////////////////////////////////////////////////////////////////////////////////////////////////// 8namespace Service {
8// Namespace NDM_U 9namespace NDM {
9
10namespace NDM_U {
11 10
12const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010042, nullptr, "EnterExclusiveState"}, 12 {0x00010042, nullptr, "EnterExclusiveState"},
@@ -15,8 +14,8 @@ const Interface::FunctionInfo FunctionTable[] = {
15 {0x00030000, nullptr, "QueryExclusiveMode"}, 14 {0x00030000, nullptr, "QueryExclusiveMode"},
16 {0x00040002, nullptr, "LockState"}, 15 {0x00040002, nullptr, "LockState"},
17 {0x00050002, nullptr, "UnlockState"}, 16 {0x00050002, nullptr, "UnlockState"},
18 {0x00060040, nullptr, "SuspendDaemons"}, 17 {0x00060040, SuspendDaemons, "SuspendDaemons"},
19 {0x00070040, nullptr, "ResumeDaemons"}, 18 {0x00070040, ResumeDaemons, "ResumeDaemons"},
20 {0x00080040, nullptr, "DisableWifiUsage"}, 19 {0x00080040, nullptr, "DisableWifiUsage"},
21 {0x00090000, nullptr, "EnableWifiUsage"}, 20 {0x00090000, nullptr, "EnableWifiUsage"},
22 {0x000A0000, nullptr, "GetCurrentState"}, 21 {0x000A0000, nullptr, "GetCurrentState"},
@@ -29,17 +28,15 @@ const Interface::FunctionInfo FunctionTable[] = {
29 {0x00110000, nullptr, "GetScanInterval"}, 28 {0x00110000, nullptr, "GetScanInterval"},
30 {0x00120040, nullptr, "SetRetryInterval"}, 29 {0x00120040, nullptr, "SetRetryInterval"},
31 {0x00130000, nullptr, "GetRetryInterval"}, 30 {0x00130000, nullptr, "GetRetryInterval"},
32 {0x00140040, nullptr, "OverrideDefaultDaemons"}, 31 {0x00140040, OverrideDefaultDaemons, "OverrideDefaultDaemons"},
33 {0x00150000, nullptr, "ResetDefaultDaemons"}, 32 {0x00150000, nullptr, "ResetDefaultDaemons"},
34 {0x00160000, nullptr, "GetDefaultDaemons"}, 33 {0x00160000, nullptr, "GetDefaultDaemons"},
35 {0x00170000, nullptr, "ClearHalfAwakeMacFilter"}, 34 {0x00170000, nullptr, "ClearHalfAwakeMacFilter"},
36}; 35};
37 36
38//////////////////////////////////////////////////////////////////////////////////////////////////// 37NDM_U_Interface::NDM_U_Interface() {
39// Interface class
40
41Interface::Interface() {
42 Register(FunctionTable); 38 Register(FunctionTable);
43} 39}
44 40
45} // namespace 41} // namespace NDM
42} // namespace Service
diff --git a/src/core/hle/service/ndm_u.h b/src/core/hle/service/ndm/ndm_u.h
index 51c4b3902..d567abc84 100644
--- a/src/core/hle/service/ndm_u.h
+++ b/src/core/hle/service/ndm/ndm_u.h
@@ -6,20 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace NDM 10namespace NDM {
11 11
12// No idea what this is 12class NDM_U_Interface : public Service::Interface {
13
14namespace NDM_U {
15
16class Interface : public Service::Interface {
17public: 13public:
18 Interface(); 14 NDM_U_Interface();
19 15
20 std::string GetPortName() const override { 16 std::string GetPortName() const override {
21 return "ndm:u"; 17 return "ndm:u";
22 } 18 }
23}; 19};
24 20
25} // namespace 21} // namespace NDM
22} // namespace Service
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 0de0b13a3..35b648409 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -16,7 +16,6 @@
16#include "core/hle/service/http_c.h" 16#include "core/hle/service/http_c.h"
17#include "core/hle/service/ldr_ro.h" 17#include "core/hle/service/ldr_ro.h"
18#include "core/hle/service/mic_u.h" 18#include "core/hle/service/mic_u.h"
19#include "core/hle/service/ndm_u.h"
20#include "core/hle/service/ns_s.h" 19#include "core/hle/service/ns_s.h"
21#include "core/hle/service/nwm_uds.h" 20#include "core/hle/service/nwm_uds.h"
22#include "core/hle/service/pm_app.h" 21#include "core/hle/service/pm_app.h"
@@ -35,6 +34,7 @@
35#include "core/hle/service/cfg/cfg.h" 34#include "core/hle/service/cfg/cfg.h"
36#include "core/hle/service/hid/hid.h" 35#include "core/hle/service/hid/hid.h"
37#include "core/hle/service/ir/ir.h" 36#include "core/hle/service/ir/ir.h"
37#include "core/hle/service/ndm/ndm.h"
38#include "core/hle/service/news/news.h" 38#include "core/hle/service/news/news.h"
39#include "core/hle/service/nim/nim.h" 39#include "core/hle/service/nim/nim.h"
40#include "core/hle/service/ptm/ptm.h" 40#include "core/hle/service/ptm/ptm.h"
@@ -114,6 +114,7 @@ void Init() {
114 Service::HID::Init(); 114 Service::HID::Init();
115 Service::IR::Init(); 115 Service::IR::Init();
116 Service::NEWS::Init(); 116 Service::NEWS::Init();
117 Service::NDM::Init();
117 Service::NIM::Init(); 118 Service::NIM::Init();
118 Service::PTM::Init(); 119 Service::PTM::Init();
119 120
@@ -126,7 +127,6 @@ void Init() {
126 AddService(new HTTP_C::Interface); 127 AddService(new HTTP_C::Interface);
127 AddService(new LDR_RO::Interface); 128 AddService(new LDR_RO::Interface);
128 AddService(new MIC_U::Interface); 129 AddService(new MIC_U::Interface);
129 AddService(new NDM_U::Interface);
130 AddService(new NS_S::Interface); 130 AddService(new NS_S::Interface);
131 AddService(new NWM_UDS::Interface); 131 AddService(new NWM_UDS::Interface);
132 AddService(new PM_APP::Interface); 132 AddService(new PM_APP::Interface);
@@ -141,6 +141,7 @@ void Init() {
141void Shutdown() { 141void Shutdown() {
142 142
143 Service::PTM::Shutdown(); 143 Service::PTM::Shutdown();
144 Service::NDM::Shutdown();
144 Service::NIM::Shutdown(); 145 Service::NIM::Shutdown();
145 Service::NEWS::Shutdown(); 146 Service::NEWS::Shutdown();
146 Service::IR::Shutdown(); 147 Service::IR::Shutdown();
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 5e8930476..509558fc0 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -32,6 +32,12 @@ namespace Shader {
32static std::unordered_map<u64, CompiledShader*> shader_map; 32static std::unordered_map<u64, CompiledShader*> shader_map;
33static JitCompiler jit; 33static JitCompiler jit;
34static CompiledShader* jit_shader; 34static CompiledShader* jit_shader;
35
36static void ClearCache() {
37 shader_map.clear();
38 jit.Clear();
39 LOG_INFO(HW_GPU, "Shader JIT cache cleared");
40}
35#endif // ARCHITECTURE_x86_64 41#endif // ARCHITECTURE_x86_64
36 42
37void Setup(UnitState<false>& state) { 43void Setup(UnitState<false>& state) {
@@ -45,6 +51,12 @@ void Setup(UnitState<false>& state) {
45 if (iter != shader_map.end()) { 51 if (iter != shader_map.end()) {
46 jit_shader = iter->second; 52 jit_shader = iter->second;
47 } else { 53 } else {
54 // Check if remaining JIT code space is enough for at least one more (massive) shader
55 if (jit.GetSpaceLeft() < jit_shader_size) {
56 // If not, clear the cache of all previously compiled shaders
57 ClearCache();
58 }
59
48 jit_shader = jit.Compile(); 60 jit_shader = jit.Compile();
49 shader_map.emplace(cache_key, jit_shader); 61 shader_map.emplace(cache_key, jit_shader);
50 } 62 }
@@ -54,7 +66,7 @@ void Setup(UnitState<false>& state) {
54 66
55void Shutdown() { 67void Shutdown() {
56#ifdef ARCHITECTURE_x86_64 68#ifdef ARCHITECTURE_x86_64
57 shader_map.clear(); 69 ClearCache();
58#endif // ARCHITECTURE_x86_64 70#endif // ARCHITECTURE_x86_64
59} 71}
60 72
@@ -135,7 +147,7 @@ OutputVertex Run(UnitState<false>& state, const InputVertex& input, int num_attr
135 std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f)); 147 std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f));
136 } 148 }
137 149
138 LOG_TRACE(Render_Software, "Output vertex: pos(%.2f, %.2f, %.2f, %.2f), quat(%.2f, %.2f, %.2f, %.2f), " 150 LOG_TRACE(HW_GPU, "Output vertex: pos(%.2f, %.2f, %.2f, %.2f), quat(%.2f, %.2f, %.2f, %.2f), "
139 "col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f), view(%.2f, %.2f, %.2f)", 151 "col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f), view(%.2f, %.2f, %.2f)",
140 ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(), 152 ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(),
141 ret.quat.x.ToFloat32(), ret.quat.y.ToFloat32(), ret.quat.z.ToFloat32(), ret.quat.w.ToFloat32(), 153 ret.quat.x.ToFloat32(), ret.quat.y.ToFloat32(), ret.quat.z.ToFloat32(), ret.quat.w.ToFloat32(),
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp
index 79fcc56b9..295a2466b 100644
--- a/src/video_core/shader/shader_interpreter.cpp
+++ b/src/video_core/shader/shader_interpreter.cpp
@@ -413,9 +413,12 @@ void RunInterpreter(UnitState<Debug>& state) {
413 413
414 bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI); 414 bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI);
415 415
416 const int address_offset = (instr.mad.address_register_index == 0)
417 ? 0 : state.address_registers[instr.mad.address_register_index - 1];
418
416 const float24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted)); 419 const float24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted));
417 const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted)); 420 const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) + (!is_inverted * address_offset));
418 const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted)); 421 const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) + ( is_inverted * address_offset));
419 422
420 const bool negate_src1 = ((bool)swizzle.negate_src1 != false); 423 const bool negate_src1 = ((bool)swizzle.negate_src1 != false);
421 const bool negate_src2 = ((bool)swizzle.negate_src2 != false); 424 const bool negate_src2 = ((bool)swizzle.negate_src2 != false);
diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp
index 5083d7e54..dffe051ef 100644
--- a/src/video_core/shader/shader_jit_x64.cpp
+++ b/src/video_core/shader/shader_jit_x64.cpp
@@ -160,40 +160,41 @@ void JitCompiler::Compile_SwizzleSrc(Instruction instr, unsigned src_num, Source
160 ASSERT_MSG(src_offset == src_offset_disp, "Source register offset too large for int type"); 160 ASSERT_MSG(src_offset == src_offset_disp, "Source register offset too large for int type");
161 161
162 unsigned operand_desc_id; 162 unsigned operand_desc_id;
163
164 const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed));
165
166 unsigned address_register_index;
167 unsigned offset_src;
168
163 if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD || 169 if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD ||
164 instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI) { 170 instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI) {
165 // The MAD and MADI instructions do not use the address offset registers, so loading the
166 // source is a bit simpler here
167
168 operand_desc_id = instr.mad.operand_desc_id; 171 operand_desc_id = instr.mad.operand_desc_id;
169 172 offset_src = is_inverted ? 3 : 2;
170 // Load the source 173 address_register_index = instr.mad.address_register_index;
171 MOVAPS(dest, MDisp(src_ptr, src_offset_disp));
172 } else { 174 } else {
173 operand_desc_id = instr.common.operand_desc_id; 175 operand_desc_id = instr.common.operand_desc_id;
176 offset_src = is_inverted ? 2 : 1;
177 address_register_index = instr.common.address_register_index;
178 }
174 179
175 const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); 180 if (src_num == offset_src && address_register_index != 0) {
176 unsigned offset_src = is_inverted ? 2 : 1; 181 switch (address_register_index) {
177 182 case 1: // address offset 1
178 if (src_num == offset_src && instr.common.address_register_index != 0) { 183 MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, SCALE_1, src_offset_disp));
179 switch (instr.common.address_register_index) { 184 break;
180 case 1: // address offset 1 185 case 2: // address offset 2
181 MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, SCALE_1, src_offset_disp)); 186 MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, SCALE_1, src_offset_disp));
182 break; 187 break;
183 case 2: // address offset 2 188 case 3: // address offset 3
184 MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, SCALE_1, src_offset_disp)); 189 MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, SCALE_1, src_offset_disp));
185 break; 190 break;
186 case 3: // address offset 3 191 default:
187 MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, SCALE_1, src_offset_disp)); 192 UNREACHABLE();
188 break; 193 break;
189 default:
190 UNREACHABLE();
191 break;
192 }
193 } else {
194 // Load the source
195 MOVAPS(dest, MDisp(src_ptr, src_offset_disp));
196 } 194 }
195 } else {
196 // Load the source
197 MOVAPS(dest, MDisp(src_ptr, src_offset_disp));
197 } 198 }
198 199
199 SwizzlePattern swiz = { g_state.vs.swizzle_data[operand_desc_id] }; 200 SwizzlePattern swiz = { g_state.vs.swizzle_data[operand_desc_id] };
@@ -644,7 +645,8 @@ void JitCompiler::Compile_MAD(Instruction instr) {
644} 645}
645 646
646void JitCompiler::Compile_IF(Instruction instr) { 647void JitCompiler::Compile_IF(Instruction instr) {
647 ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards if-statements not supported"); 648 ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards if-statements (%d -> %d) not supported",
649 *offset_ptr, instr.flow_control.dest_offset.Value());
648 650
649 // Evaluate the "IF" condition 651 // Evaluate the "IF" condition
650 if (instr.opcode.Value() == OpCode::Id::IFU) { 652 if (instr.opcode.Value() == OpCode::Id::IFU) {
@@ -675,7 +677,8 @@ void JitCompiler::Compile_IF(Instruction instr) {
675} 677}
676 678
677void JitCompiler::Compile_LOOP(Instruction instr) { 679void JitCompiler::Compile_LOOP(Instruction instr) {
678 ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards loops not supported"); 680 ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards loops (%d -> %d) not supported",
681 *offset_ptr, instr.flow_control.dest_offset.Value());
679 ASSERT_MSG(!looping, "Nested loops not supported"); 682 ASSERT_MSG(!looping, "Nested loops not supported");
680 683
681 looping = true; 684 looping = true;
@@ -703,7 +706,8 @@ void JitCompiler::Compile_LOOP(Instruction instr) {
703} 706}
704 707
705void JitCompiler::Compile_JMP(Instruction instr) { 708void JitCompiler::Compile_JMP(Instruction instr) {
706 ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards jumps not supported"); 709 ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards jumps (%d -> %d) not supported",
710 *offset_ptr, instr.flow_control.dest_offset.Value());
707 711
708 if (instr.opcode.Value() == OpCode::Id::JMPC) 712 if (instr.opcode.Value() == OpCode::Id::JMPC)
709 Compile_EvaluateCondition(instr); 713 Compile_EvaluateCondition(instr);
@@ -747,7 +751,7 @@ void JitCompiler::Compile_NextInstr(unsigned* offset) {
747 } else { 751 } else {
748 // Unhandled instruction 752 // Unhandled instruction
749 LOG_CRITICAL(HW_GPU, "Unhandled instruction: 0x%02x (0x%08x)", 753 LOG_CRITICAL(HW_GPU, "Unhandled instruction: 0x%02x (0x%08x)",
750 instr.opcode.Value().EffectiveOpCode(), instr.hex); 754 instr.opcode.Value().EffectiveOpCode(), instr.hex);
751 } 755 }
752} 756}
753 757
@@ -786,7 +790,7 @@ CompiledShader* JitCompiler::Compile() {
786} 790}
787 791
788JitCompiler::JitCompiler() { 792JitCompiler::JitCompiler() {
789 AllocCodeSpace(1024 * 1024 * 4); 793 AllocCodeSpace(jit_cache_size);
790} 794}
791 795
792void JitCompiler::Clear() { 796void JitCompiler::Clear() {
diff --git a/src/video_core/shader/shader_jit_x64.h b/src/video_core/shader/shader_jit_x64.h
index 5ad2d9606..5357c964b 100644
--- a/src/video_core/shader/shader_jit_x64.h
+++ b/src/video_core/shader/shader_jit_x64.h
@@ -19,6 +19,11 @@ namespace Pica {
19 19
20namespace Shader { 20namespace Shader {
21 21
22/// Memory needed to be available to compile the next shader (otherwise, clear the cache)
23constexpr size_t jit_shader_size = 1024 * 512;
24/// Memory allocated for the JIT code space cache
25constexpr size_t jit_cache_size = 1024 * 1024 * 8;
26
22using CompiledShader = void(void* registers); 27using CompiledShader = void(void* registers);
23 28
24/** 29/**