diff options
| -rw-r--r-- | src/common/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/common/bit_cast.h | 22 | ||||
| -rw-r--r-- | src/common/logging/backend.cpp | 1 | ||||
| -rw-r--r-- | src/common/logging/log.h | 1 | ||||
| -rw-r--r-- | src/common/virtual_buffer.h | 7 | ||||
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/hle/service/olsc/olsc.cpp | 69 | ||||
| -rw-r--r-- | src/core/hle/service/olsc/olsc.h | 16 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 2 | ||||
| -rw-r--r-- | src/input_common/gcadapter/gc_poller.cpp | 4 | ||||
| -rw-r--r-- | src/input_common/sdl/sdl_impl.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 265 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 8 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 2 |
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 | |||
| 10 | namespace Common { | ||
| 11 | |||
| 12 | template <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> | ||
| 16 | BitCast(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 | |||
| 11 | namespace Service::OLSC { | ||
| 12 | |||
| 13 | class OLSC final : public ServiceFramework<OLSC> { | ||
| 14 | public: | ||
| 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 | |||
| 45 | private: | ||
| 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 | |||
| 65 | void 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 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::OLSC { | ||
| 12 | |||
| 13 | /// Registers all SSL services with the specified service manager. | ||
| 14 | void 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 | ||
| 127 | void 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 | |||
| 144 | u32 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 | |||
| 158 | void 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 | |||
| 169 | void 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 | |||
| 127 | void Maxwell3D::CallMacroMethod(u32 method, const std::vector<u32>& parameters) { | 233 | void 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 | ||
| 298 | void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, | 278 | void 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: | |||
| 1461 | private: | 1461 | private: |
| 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; |