summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/bit_cast.h22
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/common/virtual_buffer.h7
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/service/olsc/olsc.cpp69
-rw-r--r--src/core/hle/service/olsc/olsc.h16
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/input_common/gcadapter/gc_poller.cpp4
-rw-r--r--src/input_common/sdl/sdl_impl.cpp3
-rw-r--r--src/video_core/engines/maxwell_3d.cpp265
-rw-r--r--src/video_core/engines/maxwell_3d.h8
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp2
14 files changed, 246 insertions, 157 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 207c7a0a6..d20e6c3b5 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -102,6 +102,7 @@ add_library(common STATIC
102 atomic_ops.h 102 atomic_ops.h
103 detached_tasks.cpp 103 detached_tasks.cpp
104 detached_tasks.h 104 detached_tasks.h
105 bit_cast.h
105 bit_field.h 106 bit_field.h
106 bit_util.h 107 bit_util.h
107 cityhash.cpp 108 cityhash.cpp
diff --git a/src/common/bit_cast.h b/src/common/bit_cast.h
new file mode 100644
index 000000000..a32a063d1
--- /dev/null
+++ b/src/common/bit_cast.h
@@ -0,0 +1,22 @@
1// Copyright 2020 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 <cstring>
8#include <type_traits>
9
10namespace Common {
11
12template <typename To, typename From>
13[[nodiscard]] std::enable_if_t<sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> &&
14 std::is_trivially_copyable_v<To>,
15 To>
16BitCast(const From& src) noexcept {
17 To dst;
18 std::memcpy(&dst, &src, sizeof(To));
19 return dst;
20}
21
22} // namespace Common
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 90dfa22ca..7859344b9 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -222,6 +222,7 @@ void DebuggerBackend::Write(const Entry& entry) {
222 SUB(Service, NPNS) \ 222 SUB(Service, NPNS) \
223 SUB(Service, NS) \ 223 SUB(Service, NS) \
224 SUB(Service, NVDRV) \ 224 SUB(Service, NVDRV) \
225 SUB(Service, OLSC) \
225 SUB(Service, PCIE) \ 226 SUB(Service, PCIE) \
226 SUB(Service, PCTL) \ 227 SUB(Service, PCTL) \
227 SUB(Service, PCV) \ 228 SUB(Service, PCV) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 13a4f1e30..835894918 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -95,6 +95,7 @@ enum class Class : ClassType {
95 Service_NPNS, ///< The NPNS service 95 Service_NPNS, ///< The NPNS service
96 Service_NS, ///< The NS services 96 Service_NS, ///< The NS services
97 Service_NVDRV, ///< The NVDRV (Nvidia driver) service 97 Service_NVDRV, ///< The NVDRV (Nvidia driver) service
98 Service_OLSC, ///< The OLSC service
98 Service_PCIE, ///< The PCIe service 99 Service_PCIE, ///< The PCIe service
99 Service_PCTL, ///< The PCTL (Parental control) service 100 Service_PCTL, ///< The PCTL (Parental control) service
100 Service_PCV, ///< The PCV service 101 Service_PCV, ///< The PCV service
diff --git a/src/common/virtual_buffer.h b/src/common/virtual_buffer.h
index 078e61c77..91d430036 100644
--- a/src/common/virtual_buffer.h
+++ b/src/common/virtual_buffer.h
@@ -43,9 +43,14 @@ public:
43 } 43 }
44 44
45 void resize(std::size_t count) { 45 void resize(std::size_t count) {
46 const auto new_size = count * sizeof(T);
47 if (new_size == alloc_size) {
48 return;
49 }
50
46 FreeMemoryPages(base_ptr, alloc_size); 51 FreeMemoryPages(base_ptr, alloc_size);
47 52
48 alloc_size = count * sizeof(T); 53 alloc_size = new_size;
49 base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size)); 54 base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
50 } 55 }
51 56
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index a1d8dcfa5..e370fd225 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -458,6 +458,8 @@ add_library(core STATIC
458 hle/service/nvflinger/buffer_queue.h 458 hle/service/nvflinger/buffer_queue.h
459 hle/service/nvflinger/nvflinger.cpp 459 hle/service/nvflinger/nvflinger.cpp
460 hle/service/nvflinger/nvflinger.h 460 hle/service/nvflinger/nvflinger.h
461 hle/service/olsc/olsc.cpp
462 hle/service/olsc/olsc.h
461 hle/service/pcie/pcie.cpp 463 hle/service/pcie/pcie.cpp
462 hle/service/pcie/pcie.h 464 hle/service/pcie/pcie.h
463 hle/service/pctl/module.cpp 465 hle/service/pctl/module.cpp
diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp
new file mode 100644
index 000000000..aad4ca706
--- /dev/null
+++ b/src/core/hle/service/olsc/olsc.cpp
@@ -0,0 +1,69 @@
1// Copyright 2020 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/kernel/hle_ipc.h"
7#include "core/hle/service/olsc/olsc.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10
11namespace Service::OLSC {
12
13class OLSC final : public ServiceFramework<OLSC> {
14public:
15 explicit OLSC() : ServiceFramework{"olsc:u"} {
16 // clang-format off
17 static const FunctionInfo functions[] = {
18 {0, &OLSC::Initialize, "Initialize"},
19 {10, nullptr, "VerifySaveDataBackupLicenseAsync"},
20 {13, nullptr, "GetSaveDataBackupSetting"},
21 {14, &OLSC::SetSaveDataBackupSettingEnabled, "SetSaveDataBackupSettingEnabled"},
22 {15, nullptr, "SetCustomData"},
23 {16, nullptr, "DeleteSaveDataBackupSetting"},
24 {18, nullptr, "GetSaveDataBackupInfoCache"},
25 {19, nullptr, "UpdateSaveDataBackupInfoCacheAsync"},
26 {22, nullptr, "DeleteSaveDataBackupAsync"},
27 {25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"},
28 {26, nullptr, "DownloadSaveDataBackupAsync"},
29 {9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"},
30 {9013, nullptr, "GetSaveDataBackupSettingForDebug"},
31 {9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"},
32 {9015, nullptr, "SetCustomDataForDebug"},
33 {9016, nullptr, "DeleteSaveDataBackupSettingForDebug"},
34 {9018, nullptr, "GetSaveDataBackupInfoCacheForDebug"},
35 {9019, nullptr, "UpdateSaveDataBackupInfoCacheAsyncForDebug"},
36 {9022, nullptr, "DeleteSaveDataBackupAsyncForDebug"},
37 {9025, nullptr, "ListDownloadableSaveDataBackupInfoAsyncForDebug"},
38 {9026, nullptr, "DownloadSaveDataBackupAsyncForDebug"},
39 };
40 // clang-format on
41
42 RegisterHandlers(functions);
43 }
44
45private:
46 void Initialize(Kernel::HLERequestContext& ctx) {
47 LOG_WARNING(Service_OLSC, "(STUBBED) called");
48
49 initialized = true;
50
51 IPC::ResponseBuilder rb{ctx, 2};
52 rb.Push(RESULT_SUCCESS);
53 }
54
55 void SetSaveDataBackupSettingEnabled(Kernel::HLERequestContext& ctx) {
56 LOG_WARNING(Service_OLSC, "(STUBBED) called");
57
58 IPC::ResponseBuilder rb{ctx, 2};
59 rb.Push(RESULT_SUCCESS);
60 }
61
62 bool initialized{};
63};
64
65void InstallInterfaces(SM::ServiceManager& service_manager) {
66 std::make_shared<OLSC>()->InstallAsService(service_manager);
67}
68
69} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc.h b/src/core/hle/service/olsc/olsc.h
new file mode 100644
index 000000000..edee4376b
--- /dev/null
+++ b/src/core/hle/service/olsc/olsc.h
@@ -0,0 +1,16 @@
1// Copyright 2020 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::OLSC {
12
13/// Registers all SSL services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& service_manager);
15
16} // namespace Service::OLSC
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index ba9159ee0..fbfda2d5b 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -51,6 +51,7 @@
51#include "core/hle/service/ns/ns.h" 51#include "core/hle/service/ns/ns.h"
52#include "core/hle/service/nvdrv/nvdrv.h" 52#include "core/hle/service/nvdrv/nvdrv.h"
53#include "core/hle/service/nvflinger/nvflinger.h" 53#include "core/hle/service/nvflinger/nvflinger.h"
54#include "core/hle/service/olsc/olsc.h"
54#include "core/hle/service/pcie/pcie.h" 55#include "core/hle/service/pcie/pcie.h"
55#include "core/hle/service/pctl/module.h" 56#include "core/hle/service/pctl/module.h"
56#include "core/hle/service/pcv/pcv.h" 57#include "core/hle/service/pcv/pcv.h"
@@ -231,6 +232,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) {
231 NPNS::InstallInterfaces(*sm); 232 NPNS::InstallInterfaces(*sm);
232 NS::InstallInterfaces(*sm, system); 233 NS::InstallInterfaces(*sm, system);
233 Nvidia::InstallInterfaces(*sm, *nv_flinger, system); 234 Nvidia::InstallInterfaces(*sm, *nv_flinger, system);
235 OLSC::InstallInterfaces(*sm);
234 PCIe::InstallInterfaces(*sm); 236 PCIe::InstallInterfaces(*sm);
235 PCTL::InstallInterfaces(*sm); 237 PCTL::InstallInterfaces(*sm);
236 PCV::InstallInterfaces(*sm); 238 PCV::InstallInterfaces(*sm);
diff --git a/src/input_common/gcadapter/gc_poller.cpp b/src/input_common/gcadapter/gc_poller.cpp
index fe57c13a5..d95574bb5 100644
--- a/src/input_common/gcadapter/gc_poller.cpp
+++ b/src/input_common/gcadapter/gc_poller.cpp
@@ -302,8 +302,8 @@ public:
302 302
303 bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override { 303 bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override {
304 const auto mean_amplitude = (amp_low + amp_high) * 0.5f; 304 const auto mean_amplitude = (amp_low + amp_high) * 0.5f;
305 const auto processed_amplitude = static_cast<u8>( 305 const auto processed_amplitude =
306 pow(mean_amplitude, 0.5f) * (3.0f - 2.0f * pow(mean_amplitude, 0.15f)) * 0x8); 306 static_cast<u8>((mean_amplitude + std::pow(mean_amplitude, 0.3f)) * 0.5f * 0x8);
307 307
308 return gcadapter->RumblePlay(port, processed_amplitude); 308 return gcadapter->RumblePlay(port, processed_amplitude);
309 } 309 }
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index 8c48bb861..c395d96cf 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -402,8 +402,7 @@ public:
402 402
403 bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override { 403 bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override {
404 const auto process_amplitude = [](f32 amplitude) { 404 const auto process_amplitude = [](f32 amplitude) {
405 return static_cast<u16>(std::pow(amplitude, 0.5f) * 405 return static_cast<u16>((amplitude + std::pow(amplitude, 0.3f)) * 0.5f * 0xFFFF);
406 (3.0f - 2.0f * std::pow(amplitude, 0.15f)) * 0xFFFF);
407 }; 406 };
408 407
409 const auto processed_amp_low = process_amplitude(amp_low); 408 const auto processed_amp_low = process_amplitude(amp_low);
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 57ebc785f..6287df633 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -124,6 +124,112 @@ void Maxwell3D::InitializeRegisterDefaults() {
124 mme_inline[MAXWELL3D_REG_INDEX(index_array.count)] = true; 124 mme_inline[MAXWELL3D_REG_INDEX(index_array.count)] = true;
125} 125}
126 126
127void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) {
128 if (executing_macro == 0) {
129 // A macro call must begin by writing the macro method's register, not its argument.
130 ASSERT_MSG((method % 2) == 0,
131 "Can't start macro execution by writing to the ARGS register");
132 executing_macro = method;
133 }
134
135 macro_params.insert(macro_params.end(), base_start, base_start + amount);
136
137 // Call the macro when there are no more parameters in the command buffer
138 if (is_last_call) {
139 CallMacroMethod(executing_macro, macro_params);
140 macro_params.clear();
141 }
142}
143
144u32 Maxwell3D::ProcessShadowRam(u32 method, u32 argument) {
145 // Keep track of the register value in shadow_state when requested.
146 const auto control = shadow_state.shadow_ram_control;
147 if (control == Regs::ShadowRamControl::Track ||
148 control == Regs::ShadowRamControl::TrackWithFilter) {
149 shadow_state.reg_array[method] = argument;
150 return argument;
151 }
152 if (control == Regs::ShadowRamControl::Replay) {
153 return shadow_state.reg_array[method];
154 }
155 return argument;
156}
157
158void Maxwell3D::ProcessDirtyRegisters(u32 method, u32 argument) {
159 if (regs.reg_array[method] == argument) {
160 return;
161 }
162 regs.reg_array[method] = argument;
163
164 for (const auto& table : dirty.tables) {
165 dirty.flags[table[method]] = true;
166 }
167}
168
169void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argument,
170 bool is_last_call) {
171 switch (method) {
172 case MAXWELL3D_REG_INDEX(wait_for_idle):
173 return rasterizer->WaitForIdle();
174 case MAXWELL3D_REG_INDEX(shadow_ram_control):
175 shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(nonshadow_argument);
176 return;
177 case MAXWELL3D_REG_INDEX(macros.data):
178 return macro_engine->AddCode(regs.macros.upload_address, argument);
179 case MAXWELL3D_REG_INDEX(macros.bind):
180 return ProcessMacroBind(argument);
181 case MAXWELL3D_REG_INDEX(firmware[4]):
182 return ProcessFirmwareCall4();
183 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]):
184 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]):
185 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]):
186 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[3]):
187 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[4]):
188 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[5]):
189 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[6]):
190 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[7]):
191 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[8]):
192 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[9]):
193 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[10]):
194 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[11]):
195 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]):
196 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]):
197 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]):
198 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]):
199 return StartCBData(method);
200 case MAXWELL3D_REG_INDEX(cb_bind[0]):
201 return ProcessCBBind(0);
202 case MAXWELL3D_REG_INDEX(cb_bind[1]):
203 return ProcessCBBind(1);
204 case MAXWELL3D_REG_INDEX(cb_bind[2]):
205 return ProcessCBBind(2);
206 case MAXWELL3D_REG_INDEX(cb_bind[3]):
207 return ProcessCBBind(3);
208 case MAXWELL3D_REG_INDEX(cb_bind[4]):
209 return ProcessCBBind(4);
210 case MAXWELL3D_REG_INDEX(draw.vertex_end_gl):
211 return DrawArrays();
212 case MAXWELL3D_REG_INDEX(clear_buffers):
213 return ProcessClearBuffers();
214 case MAXWELL3D_REG_INDEX(query.query_get):
215 return ProcessQueryGet();
216 case MAXWELL3D_REG_INDEX(condition.mode):
217 return ProcessQueryCondition();
218 case MAXWELL3D_REG_INDEX(counter_reset):
219 return ProcessCounterReset();
220 case MAXWELL3D_REG_INDEX(sync_info):
221 return ProcessSyncPoint();
222 case MAXWELL3D_REG_INDEX(exec_upload):
223 return upload_state.ProcessExec(regs.exec_upload.linear != 0);
224 case MAXWELL3D_REG_INDEX(data_upload):
225 upload_state.ProcessData(argument, is_last_call);
226 if (is_last_call) {
227 OnMemoryWrite();
228 }
229 return;
230 }
231}
232
127void Maxwell3D::CallMacroMethod(u32 method, const std::vector<u32>& parameters) { 233void Maxwell3D::CallMacroMethod(u32 method, const std::vector<u32>& parameters) {
128 // Reset the current macro. 234 // Reset the current macro.
129 executing_macro = 0; 235 executing_macro = 0;
@@ -157,142 +263,16 @@ void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) {
157 // Methods after 0xE00 are special, they're actually triggers for some microcode that was 263 // Methods after 0xE00 are special, they're actually triggers for some microcode that was
158 // uploaded to the GPU during initialization. 264 // uploaded to the GPU during initialization.
159 if (method >= MacroRegistersStart) { 265 if (method >= MacroRegistersStart) {
160 // We're trying to execute a macro 266 ProcessMacro(method, &method_argument, 1, is_last_call);
161 if (executing_macro == 0) {
162 // A macro call must begin by writing the macro method's register, not its argument.
163 ASSERT_MSG((method % 2) == 0,
164 "Can't start macro execution by writing to the ARGS register");
165 executing_macro = method;
166 }
167
168 macro_params.push_back(method_argument);
169
170 // Call the macro when there are no more parameters in the command buffer
171 if (is_last_call) {
172 CallMacroMethod(executing_macro, macro_params);
173 macro_params.clear();
174 }
175 return; 267 return;
176 } 268 }
177 269
178 ASSERT_MSG(method < Regs::NUM_REGS, 270 ASSERT_MSG(method < Regs::NUM_REGS,
179 "Invalid Maxwell3D register, increase the size of the Regs structure"); 271 "Invalid Maxwell3D register, increase the size of the Regs structure");
180 272
181 u32 arg = method_argument; 273 const u32 argument = ProcessShadowRam(method, method_argument);
182 // Keep track of the register value in shadow_state when requested. 274 ProcessDirtyRegisters(method, argument);
183 if (shadow_state.shadow_ram_control == Regs::ShadowRamControl::Track || 275 ProcessMethodCall(method, argument, method_argument, is_last_call);
184 shadow_state.shadow_ram_control == Regs::ShadowRamControl::TrackWithFilter) {
185 shadow_state.reg_array[method] = arg;
186 } else if (shadow_state.shadow_ram_control == Regs::ShadowRamControl::Replay) {
187 arg = shadow_state.reg_array[method];
188 }
189
190 if (regs.reg_array[method] != arg) {
191 regs.reg_array[method] = arg;
192
193 for (const auto& table : dirty.tables) {
194 dirty.flags[table[method]] = true;
195 }
196 }
197
198 switch (method) {
199 case MAXWELL3D_REG_INDEX(wait_for_idle): {
200 rasterizer->WaitForIdle();
201 break;
202 }
203 case MAXWELL3D_REG_INDEX(shadow_ram_control): {
204 shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(method_argument);
205 break;
206 }
207 case MAXWELL3D_REG_INDEX(macros.data): {
208 macro_engine->AddCode(regs.macros.upload_address, arg);
209 break;
210 }
211 case MAXWELL3D_REG_INDEX(macros.bind): {
212 ProcessMacroBind(arg);
213 break;
214 }
215 case MAXWELL3D_REG_INDEX(firmware[4]): {
216 ProcessFirmwareCall4();
217 break;
218 }
219 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]):
220 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]):
221 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]):
222 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[3]):
223 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[4]):
224 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[5]):
225 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[6]):
226 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[7]):
227 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[8]):
228 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[9]):
229 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[10]):
230 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[11]):
231 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]):
232 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]):
233 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]):
234 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): {
235 StartCBData(method);
236 break;
237 }
238 case MAXWELL3D_REG_INDEX(cb_bind[0]): {
239 ProcessCBBind(0);
240 break;
241 }
242 case MAXWELL3D_REG_INDEX(cb_bind[1]): {
243 ProcessCBBind(1);
244 break;
245 }
246 case MAXWELL3D_REG_INDEX(cb_bind[2]): {
247 ProcessCBBind(2);
248 break;
249 }
250 case MAXWELL3D_REG_INDEX(cb_bind[3]): {
251 ProcessCBBind(3);
252 break;
253 }
254 case MAXWELL3D_REG_INDEX(cb_bind[4]): {
255 ProcessCBBind(4);
256 break;
257 }
258 case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): {
259 DrawArrays();
260 break;
261 }
262 case MAXWELL3D_REG_INDEX(clear_buffers): {
263 ProcessClearBuffers();
264 break;
265 }
266 case MAXWELL3D_REG_INDEX(query.query_get): {
267 ProcessQueryGet();
268 break;
269 }
270 case MAXWELL3D_REG_INDEX(condition.mode): {
271 ProcessQueryCondition();
272 break;
273 }
274 case MAXWELL3D_REG_INDEX(counter_reset): {
275 ProcessCounterReset();
276 break;
277 }
278 case MAXWELL3D_REG_INDEX(sync_info): {
279 ProcessSyncPoint();
280 break;
281 }
282 case MAXWELL3D_REG_INDEX(exec_upload): {
283 upload_state.ProcessExec(regs.exec_upload.linear != 0);
284 break;
285 }
286 case MAXWELL3D_REG_INDEX(data_upload): {
287 upload_state.ProcessData(arg, is_last_call);
288 if (is_last_call) {
289 OnMemoryWrite();
290 }
291 break;
292 }
293 default:
294 break;
295 }
296} 276}
297 277
298void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, 278void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
@@ -300,23 +280,7 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
300 // Methods after 0xE00 are special, they're actually triggers for some microcode that was 280 // Methods after 0xE00 are special, they're actually triggers for some microcode that was
301 // uploaded to the GPU during initialization. 281 // uploaded to the GPU during initialization.
302 if (method >= MacroRegistersStart) { 282 if (method >= MacroRegistersStart) {
303 // We're trying to execute a macro 283 ProcessMacro(method, base_start, amount, amount == methods_pending);
304 if (executing_macro == 0) {
305 // A macro call must begin by writing the macro method's register, not its argument.
306 ASSERT_MSG((method % 2) == 0,
307 "Can't start macro execution by writing to the ARGS register");
308 executing_macro = method;
309 }
310
311 for (std::size_t i = 0; i < amount; i++) {
312 macro_params.push_back(base_start[i]);
313 }
314
315 // Call the macro when there are no more parameters in the command buffer
316 if (amount == methods_pending) {
317 CallMacroMethod(executing_macro, macro_params);
318 macro_params.clear();
319 }
320 return; 284 return;
321 } 285 }
322 switch (method) { 286 switch (method) {
@@ -335,15 +299,14 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
335 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]): 299 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]):
336 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]): 300 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]):
337 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]): 301 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]):
338 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): { 302 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]):
339 ProcessCBMultiData(method, base_start, amount); 303 ProcessCBMultiData(method, base_start, amount);
340 break; 304 break;
341 } 305 default:
342 default: {
343 for (std::size_t i = 0; i < amount; i++) { 306 for (std::size_t i = 0; i < amount; i++) {
344 CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1); 307 CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
345 } 308 }
346 } 309 break;
347 } 310 }
348} 311}
349 312
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index bc289c55d..1cbe8fe67 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1461,6 +1461,14 @@ public:
1461private: 1461private:
1462 void InitializeRegisterDefaults(); 1462 void InitializeRegisterDefaults();
1463 1463
1464 void ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call);
1465
1466 u32 ProcessShadowRam(u32 method, u32 argument);
1467
1468 void ProcessDirtyRegisters(u32 method, u32 argument);
1469
1470 void ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argument, bool is_last_call);
1471
1464 Core::System& system; 1472 Core::System& system;
1465 MemoryManager& memory_manager; 1473 MemoryManager& memory_manager;
1466 1474
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 72640f5e7..56ab32a35 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -1137,7 +1137,7 @@ void ConfigureInputPlayer::CreateProfile() {
1137 return; 1137 return;
1138 } 1138 }
1139 1139
1140 if (!profiles->IsProfileNameValid(profile_name.toStdString())) { 1140 if (!InputProfiles::IsProfileNameValid(profile_name.toStdString())) {
1141 QMessageBox::critical(this, tr("Create Input Profile"), 1141 QMessageBox::critical(this, tr("Create Input Profile"),
1142 tr("The given profile name is not valid!")); 1142 tr("The given profile name is not valid!"));
1143 return; 1143 return;