diff options
Diffstat (limited to 'src')
112 files changed, 1428 insertions, 418 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 63dd9febf..19d16147d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt | |||
| @@ -24,6 +24,7 @@ if (MSVC) | |||
| 24 | # /W3 - Level 3 warnings | 24 | # /W3 - Level 3 warnings |
| 25 | # /MP - Multi-threaded compilation | 25 | # /MP - Multi-threaded compilation |
| 26 | # /Zi - Output debugging information | 26 | # /Zi - Output debugging information |
| 27 | # /Zm - Specifies the precompiled header memory allocation limit | ||
| 27 | # /Zo - Enhanced debug info for optimized builds | 28 | # /Zo - Enhanced debug info for optimized builds |
| 28 | # /permissive- - Enables stricter C++ standards conformance checks | 29 | # /permissive- - Enables stricter C++ standards conformance checks |
| 29 | # /EHsc - C++-only exception handling semantics | 30 | # /EHsc - C++-only exception handling semantics |
| @@ -36,6 +37,7 @@ if (MSVC) | |||
| 36 | add_compile_options( | 37 | add_compile_options( |
| 37 | /MP | 38 | /MP |
| 38 | /Zi | 39 | /Zi |
| 40 | /Zm200 | ||
| 39 | /Zo | 41 | /Zo |
| 40 | /permissive- | 42 | /permissive- |
| 41 | /EHsc | 43 | /EHsc |
diff --git a/src/audio_core/delay_line.cpp b/src/audio_core/delay_line.cpp index f4e4dd8d2..2793ed8db 100644 --- a/src/audio_core/delay_line.cpp +++ b/src/audio_core/delay_line.cpp | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 1 | #include <cstring> | 5 | #include <cstring> |
| 2 | #include "audio_core/delay_line.h" | 6 | #include "audio_core/delay_line.h" |
| 3 | 7 | ||
diff --git a/src/audio_core/delay_line.h b/src/audio_core/delay_line.h index cafddd432..84f11bc52 100644 --- a/src/audio_core/delay_line.h +++ b/src/audio_core/delay_line.h | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 1 | #pragma once | 5 | #pragma once |
| 2 | 6 | ||
| 3 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index b44a44949..28949fe5e 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 1 | #ifdef _WIN32 | 5 | #ifdef _WIN32 |
| 2 | 6 | ||
| 3 | #include <iterator> | 7 | #include <iterator> |
diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 42744c994..b898a652c 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp | |||
| @@ -114,6 +114,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { | |||
| 114 | SUB(Service, NGCT) \ | 114 | SUB(Service, NGCT) \ |
| 115 | SUB(Service, NIFM) \ | 115 | SUB(Service, NIFM) \ |
| 116 | SUB(Service, NIM) \ | 116 | SUB(Service, NIM) \ |
| 117 | SUB(Service, NOTIF) \ | ||
| 117 | SUB(Service, NPNS) \ | 118 | SUB(Service, NPNS) \ |
| 118 | SUB(Service, NS) \ | 119 | SUB(Service, NS) \ |
| 119 | SUB(Service, NVDRV) \ | 120 | SUB(Service, NVDRV) \ |
diff --git a/src/common/logging/types.h b/src/common/logging/types.h index 2d21fc483..9ed0c7ad6 100644 --- a/src/common/logging/types.h +++ b/src/common/logging/types.h | |||
| @@ -82,6 +82,7 @@ enum class Class : u8 { | |||
| 82 | Service_NGCT, ///< The NGCT (No Good Content for Terra) service | 82 | Service_NGCT, ///< The NGCT (No Good Content for Terra) service |
| 83 | Service_NIFM, ///< The NIFM (Network interface) service | 83 | Service_NIFM, ///< The NIFM (Network interface) service |
| 84 | Service_NIM, ///< The NIM service | 84 | Service_NIM, ///< The NIM service |
| 85 | Service_NOTIF, ///< The NOTIF (Notification) service | ||
| 85 | Service_NPNS, ///< The NPNS service | 86 | Service_NPNS, ///< The NPNS service |
| 86 | Service_NS, ///< The NS services | 87 | Service_NS, ///< The NS services |
| 87 | Service_NVDRV, ///< The NVDRV (Nvidia driver) service | 88 | Service_NVDRV, ///< The NVDRV (Nvidia driver) service |
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index 28f834443..82ee2c8a1 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp | |||
| @@ -15,26 +15,26 @@ | |||
| 15 | namespace Common { | 15 | namespace Common { |
| 16 | 16 | ||
| 17 | u64 EstimateRDTSCFrequency() { | 17 | u64 EstimateRDTSCFrequency() { |
| 18 | const auto milli_10 = std::chrono::milliseconds{10}; | 18 | // Discard the first result measuring the rdtsc. |
| 19 | // get current time | ||
| 20 | _mm_mfence(); | 19 | _mm_mfence(); |
| 21 | const u64 tscStart = __rdtsc(); | 20 | __rdtsc(); |
| 22 | const auto startTime = std::chrono::steady_clock::now(); | 21 | std::this_thread::sleep_for(std::chrono::milliseconds{1}); |
| 23 | // wait roughly 3 seconds | 22 | _mm_mfence(); |
| 24 | while (true) { | 23 | __rdtsc(); |
| 25 | auto milli = std::chrono::duration_cast<std::chrono::milliseconds>( | 24 | |
| 26 | std::chrono::steady_clock::now() - startTime); | 25 | // Get the current time. |
| 27 | if (milli.count() >= 3000) | 26 | const auto start_time = std::chrono::steady_clock::now(); |
| 28 | break; | 27 | _mm_mfence(); |
| 29 | std::this_thread::sleep_for(milli_10); | 28 | const u64 tsc_start = __rdtsc(); |
| 30 | } | 29 | // Wait for 200 milliseconds. |
| 31 | const auto endTime = std::chrono::steady_clock::now(); | 30 | std::this_thread::sleep_for(std::chrono::milliseconds{200}); |
| 31 | const auto end_time = std::chrono::steady_clock::now(); | ||
| 32 | _mm_mfence(); | 32 | _mm_mfence(); |
| 33 | const u64 tscEnd = __rdtsc(); | 33 | const u64 tsc_end = __rdtsc(); |
| 34 | // calculate difference | 34 | // Calculate differences. |
| 35 | const u64 timer_diff = | 35 | const u64 timer_diff = static_cast<u64>( |
| 36 | std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count(); | 36 | std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count()); |
| 37 | const u64 tsc_diff = tscEnd - tscStart; | 37 | const u64 tsc_diff = tsc_end - tsc_start; |
| 38 | const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff); | 38 | const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff); |
| 39 | return tsc_freq; | 39 | return tsc_freq; |
| 40 | } | 40 | } |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index eee8e2ccd..506885659 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -179,6 +179,8 @@ add_library(core STATIC | |||
| 179 | hle/kernel/k_client_port.h | 179 | hle/kernel/k_client_port.h |
| 180 | hle/kernel/k_client_session.cpp | 180 | hle/kernel/k_client_session.cpp |
| 181 | hle/kernel/k_client_session.h | 181 | hle/kernel/k_client_session.h |
| 182 | hle/kernel/k_code_memory.cpp | ||
| 183 | hle/kernel/k_code_memory.h | ||
| 182 | hle/kernel/k_condition_variable.cpp | 184 | hle/kernel/k_condition_variable.cpp |
| 183 | hle/kernel/k_condition_variable.h | 185 | hle/kernel/k_condition_variable.h |
| 184 | hle/kernel/k_event.cpp | 186 | hle/kernel/k_event.cpp |
| @@ -408,6 +410,8 @@ add_library(core STATIC | |||
| 408 | hle/service/glue/glue.h | 410 | hle/service/glue/glue.h |
| 409 | hle/service/glue/glue_manager.cpp | 411 | hle/service/glue/glue_manager.cpp |
| 410 | hle/service/glue/glue_manager.h | 412 | hle/service/glue/glue_manager.h |
| 413 | hle/service/glue/notif.cpp | ||
| 414 | hle/service/glue/notif.h | ||
| 411 | hle/service/grc/grc.cpp | 415 | hle/service/grc/grc.cpp |
| 412 | hle/service/grc/grc.h | 416 | hle/service/grc/grc.h |
| 413 | hle/service/hid/hid.cpp | 417 | hle/service/hid/hid.cpp |
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 466ff5542..fbb19f230 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -866,7 +866,52 @@ void EmulatedController::SetLedPattern() { | |||
| 866 | } | 866 | } |
| 867 | } | 867 | } |
| 868 | 868 | ||
| 869 | void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) { | ||
| 870 | supported_style_tag = supported_styles; | ||
| 871 | if (!is_connected) { | ||
| 872 | return; | ||
| 873 | } | ||
| 874 | if (!IsControllerSupported()) { | ||
| 875 | LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller", | ||
| 876 | npad_type); | ||
| 877 | Disconnect(); | ||
| 878 | } | ||
| 879 | } | ||
| 880 | |||
| 881 | bool EmulatedController::IsControllerSupported() const { | ||
| 882 | switch (npad_type) { | ||
| 883 | case NpadStyleIndex::ProController: | ||
| 884 | return supported_style_tag.fullkey; | ||
| 885 | case NpadStyleIndex::Handheld: | ||
| 886 | return supported_style_tag.handheld; | ||
| 887 | case NpadStyleIndex::JoyconDual: | ||
| 888 | return supported_style_tag.joycon_dual; | ||
| 889 | case NpadStyleIndex::JoyconLeft: | ||
| 890 | return supported_style_tag.joycon_left; | ||
| 891 | case NpadStyleIndex::JoyconRight: | ||
| 892 | return supported_style_tag.joycon_right; | ||
| 893 | case NpadStyleIndex::GameCube: | ||
| 894 | return supported_style_tag.gamecube; | ||
| 895 | case NpadStyleIndex::Pokeball: | ||
| 896 | return supported_style_tag.palma; | ||
| 897 | case NpadStyleIndex::NES: | ||
| 898 | return supported_style_tag.lark; | ||
| 899 | case NpadStyleIndex::SNES: | ||
| 900 | return supported_style_tag.lucia; | ||
| 901 | case NpadStyleIndex::N64: | ||
| 902 | return supported_style_tag.lagoon; | ||
| 903 | case NpadStyleIndex::SegaGenesis: | ||
| 904 | return supported_style_tag.lager; | ||
| 905 | default: | ||
| 906 | return false; | ||
| 907 | } | ||
| 908 | } | ||
| 909 | |||
| 869 | void EmulatedController::Connect() { | 910 | void EmulatedController::Connect() { |
| 911 | if (!IsControllerSupported()) { | ||
| 912 | LOG_ERROR(Service_HID, "Controller type {} is not supported", npad_type); | ||
| 913 | return; | ||
| 914 | } | ||
| 870 | { | 915 | { |
| 871 | std::lock_guard lock{mutex}; | 916 | std::lock_guard lock{mutex}; |
| 872 | if (is_configuring) { | 917 | if (is_configuring) { |
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 5887e3e38..425b3e7c4 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h | |||
| @@ -160,6 +160,13 @@ public: | |||
| 160 | */ | 160 | */ |
| 161 | NpadStyleIndex GetNpadStyleIndex(bool get_temporary_value = false) const; | 161 | NpadStyleIndex GetNpadStyleIndex(bool get_temporary_value = false) const; |
| 162 | 162 | ||
| 163 | /** | ||
| 164 | * Sets the supported controller types. Disconnects the controller if current type is not | ||
| 165 | * supported | ||
| 166 | * @param supported_styles bitflag with supported types | ||
| 167 | */ | ||
| 168 | void SetSupportedNpadStyleTag(NpadStyleTag supported_styles); | ||
| 169 | |||
| 163 | /// Sets the connected status to true | 170 | /// Sets the connected status to true |
| 164 | void Connect(); | 171 | void Connect(); |
| 165 | 172 | ||
| @@ -311,6 +318,12 @@ private: | |||
| 311 | void LoadTASParams(); | 318 | void LoadTASParams(); |
| 312 | 319 | ||
| 313 | /** | 320 | /** |
| 321 | * Checks the current controller type against the supported_style_tag | ||
| 322 | * @return true if the controller is supported | ||
| 323 | */ | ||
| 324 | bool IsControllerSupported() const; | ||
| 325 | |||
| 326 | /** | ||
| 314 | * Updates the button status of the controller | 327 | * Updates the button status of the controller |
| 315 | * @param callback A CallbackStatus containing the button status | 328 | * @param callback A CallbackStatus containing the button status |
| 316 | * @param index Button ID of the to be updated | 329 | * @param index Button ID of the to be updated |
| @@ -354,6 +367,7 @@ private: | |||
| 354 | 367 | ||
| 355 | NpadIdType npad_id_type; | 368 | NpadIdType npad_id_type; |
| 356 | NpadStyleIndex npad_type{NpadStyleIndex::None}; | 369 | NpadStyleIndex npad_type{NpadStyleIndex::None}; |
| 370 | NpadStyleTag supported_style_tag{NpadStyleSet::All}; | ||
| 357 | bool is_connected{false}; | 371 | bool is_connected{false}; |
| 358 | bool is_configuring{false}; | 372 | bool is_configuring{false}; |
| 359 | f32 motion_sensitivity{0.01f}; | 373 | f32 motion_sensitivity{0.01f}; |
diff --git a/src/core/hid/hid_core.cpp b/src/core/hid/hid_core.cpp index 946adde00..a1c3bbb57 100644 --- a/src/core/hid/hid_core.cpp +++ b/src/core/hid/hid_core.cpp | |||
| @@ -108,6 +108,16 @@ const EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t inde | |||
| 108 | 108 | ||
| 109 | void HIDCore::SetSupportedStyleTag(NpadStyleTag style_tag) { | 109 | void HIDCore::SetSupportedStyleTag(NpadStyleTag style_tag) { |
| 110 | supported_style_tag.raw = style_tag.raw; | 110 | supported_style_tag.raw = style_tag.raw; |
| 111 | player_1->SetSupportedNpadStyleTag(supported_style_tag); | ||
| 112 | player_2->SetSupportedNpadStyleTag(supported_style_tag); | ||
| 113 | player_3->SetSupportedNpadStyleTag(supported_style_tag); | ||
| 114 | player_4->SetSupportedNpadStyleTag(supported_style_tag); | ||
| 115 | player_5->SetSupportedNpadStyleTag(supported_style_tag); | ||
| 116 | player_6->SetSupportedNpadStyleTag(supported_style_tag); | ||
| 117 | player_7->SetSupportedNpadStyleTag(supported_style_tag); | ||
| 118 | player_8->SetSupportedNpadStyleTag(supported_style_tag); | ||
| 119 | other->SetSupportedNpadStyleTag(supported_style_tag); | ||
| 120 | handheld->SetSupportedNpadStyleTag(supported_style_tag); | ||
| 111 | } | 121 | } |
| 112 | 122 | ||
| 113 | NpadStyleTag HIDCore::GetSupportedStyleTag() const { | 123 | NpadStyleTag HIDCore::GetSupportedStyleTag() const { |
| @@ -135,6 +145,16 @@ NpadIdType HIDCore::GetFirstNpadId() const { | |||
| 135 | return NpadIdType::Player1; | 145 | return NpadIdType::Player1; |
| 136 | } | 146 | } |
| 137 | 147 | ||
| 148 | NpadIdType HIDCore::GetFirstDisconnectedNpadId() const { | ||
| 149 | for (std::size_t player_index = 0; player_index < available_controllers; ++player_index) { | ||
| 150 | const auto* const controller = GetEmulatedControllerByIndex(player_index); | ||
| 151 | if (!controller->IsConnected()) { | ||
| 152 | return controller->GetNpadIdType(); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | return NpadIdType::Player1; | ||
| 156 | } | ||
| 157 | |||
| 138 | void HIDCore::EnableAllControllerConfiguration() { | 158 | void HIDCore::EnableAllControllerConfiguration() { |
| 139 | player_1->EnableConfiguration(); | 159 | player_1->EnableConfiguration(); |
| 140 | player_2->EnableConfiguration(); | 160 | player_2->EnableConfiguration(); |
diff --git a/src/core/hid/hid_core.h b/src/core/hid/hid_core.h index 140a0e962..837f7de49 100644 --- a/src/core/hid/hid_core.h +++ b/src/core/hid/hid_core.h | |||
| @@ -45,6 +45,9 @@ public: | |||
| 45 | /// Returns the first connected npad id | 45 | /// Returns the first connected npad id |
| 46 | NpadIdType GetFirstNpadId() const; | 46 | NpadIdType GetFirstNpadId() const; |
| 47 | 47 | ||
| 48 | /// Returns the first disconnected npad id | ||
| 49 | NpadIdType GetFirstDisconnectedNpadId() const; | ||
| 50 | |||
| 48 | /// Sets all emulated controllers into configuring mode. | 51 | /// Sets all emulated controllers into configuring mode. |
| 49 | void EnableAllControllerConfiguration(); | 52 | void EnableAllControllerConfiguration(); |
| 50 | 53 | ||
| @@ -73,7 +76,7 @@ private: | |||
| 73 | std::unique_ptr<EmulatedController> handheld; | 76 | std::unique_ptr<EmulatedController> handheld; |
| 74 | std::unique_ptr<EmulatedConsole> console; | 77 | std::unique_ptr<EmulatedConsole> console; |
| 75 | std::unique_ptr<EmulatedDevices> devices; | 78 | std::unique_ptr<EmulatedDevices> devices; |
| 76 | NpadStyleTag supported_style_tag; | 79 | NpadStyleTag supported_style_tag{NpadStyleSet::All}; |
| 77 | }; | 80 | }; |
| 78 | 81 | ||
| 79 | } // namespace Core::HID | 82 | } // namespace Core::HID |
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h index 780659b86..7c12f01fc 100644 --- a/src/core/hid/hid_types.h +++ b/src/core/hid/hid_types.h | |||
| @@ -256,6 +256,8 @@ enum class NpadStyleSet : u32 { | |||
| 256 | Lager = 1U << 11, | 256 | Lager = 1U << 11, |
| 257 | SystemExt = 1U << 29, | 257 | SystemExt = 1U << 29, |
| 258 | System = 1U << 30, | 258 | System = 1U << 30, |
| 259 | |||
| 260 | All = 0xFFFFFFFFU, | ||
| 259 | }; | 261 | }; |
| 260 | static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size"); | 262 | static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size"); |
| 261 | 263 | ||
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index 8ff0f695d..36fc0944a 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hardware_properties.h" | 10 | #include "core/hardware_properties.h" |
| 11 | #include "core/hle/kernel/init/init_slab_setup.h" | 11 | #include "core/hle/kernel/init/init_slab_setup.h" |
| 12 | #include "core/hle/kernel/k_code_memory.h" | ||
| 12 | #include "core/hle/kernel/k_event.h" | 13 | #include "core/hle/kernel/k_event.h" |
| 13 | #include "core/hle/kernel/k_memory_layout.h" | 14 | #include "core/hle/kernel/k_memory_layout.h" |
| 14 | #include "core/hle/kernel/k_memory_manager.h" | 15 | #include "core/hle/kernel/k_memory_manager.h" |
| @@ -32,6 +33,7 @@ namespace Kernel::Init { | |||
| 32 | HANDLER(KPort, (SLAB_COUNT(KPort)), ##__VA_ARGS__) \ | 33 | HANDLER(KPort, (SLAB_COUNT(KPort)), ##__VA_ARGS__) \ |
| 33 | HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \ | 34 | HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \ |
| 34 | HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \ | 35 | HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \ |
| 36 | HANDLER(KCodeMemory, (SLAB_COUNT(KCodeMemory)), ##__VA_ARGS__) \ | ||
| 35 | HANDLER(KSession, (SLAB_COUNT(KSession)), ##__VA_ARGS__) \ | 37 | HANDLER(KSession, (SLAB_COUNT(KSession)), ##__VA_ARGS__) \ |
| 36 | HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) | 38 | HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) |
| 37 | 39 | ||
diff --git a/src/core/hle/kernel/k_class_token.cpp b/src/core/hle/kernel/k_class_token.cpp index 0be0027be..21e2fe494 100644 --- a/src/core/hle/kernel/k_class_token.cpp +++ b/src/core/hle/kernel/k_class_token.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include "core/hle/kernel/k_class_token.h" | 6 | #include "core/hle/kernel/k_class_token.h" |
| 7 | #include "core/hle/kernel/k_client_port.h" | 7 | #include "core/hle/kernel/k_client_port.h" |
| 8 | #include "core/hle/kernel/k_client_session.h" | 8 | #include "core/hle/kernel/k_client_session.h" |
| 9 | #include "core/hle/kernel/k_code_memory.h" | ||
| 9 | #include "core/hle/kernel/k_event.h" | 10 | #include "core/hle/kernel/k_event.h" |
| 10 | #include "core/hle/kernel/k_port.h" | 11 | #include "core/hle/kernel/k_port.h" |
| 11 | #include "core/hle/kernel/k_process.h" | 12 | #include "core/hle/kernel/k_process.h" |
| @@ -48,7 +49,7 @@ static_assert(ClassToken<KWritableEvent> == 0b10001001'00000000); | |||
| 48 | static_assert(ClassToken<KTransferMemory> == 0b10010001'00000000); | 49 | static_assert(ClassToken<KTransferMemory> == 0b10010001'00000000); |
| 49 | // static_assert(ClassToken<KDeviceAddressSpace> == 0b01100001'00000000); | 50 | // static_assert(ClassToken<KDeviceAddressSpace> == 0b01100001'00000000); |
| 50 | // static_assert(ClassToken<KSessionRequest> == 0b10100001'00000000); | 51 | // static_assert(ClassToken<KSessionRequest> == 0b10100001'00000000); |
| 51 | // static_assert(ClassToken<KCodeMemory> == 0b11000001'00000000); | 52 | static_assert(ClassToken<KCodeMemory> == 0b11000001'00000000); |
| 52 | 53 | ||
| 53 | // Ensure that the token hierarchy is correct. | 54 | // Ensure that the token hierarchy is correct. |
| 54 | 55 | ||
| @@ -79,7 +80,7 @@ static_assert(ClassToken<KWritableEvent> == ((0b10001001 << 8) | ClassToken<KAut | |||
| 79 | static_assert(ClassToken<KTransferMemory> == ((0b10010001 << 8) | ClassToken<KAutoObject>)); | 80 | static_assert(ClassToken<KTransferMemory> == ((0b10010001 << 8) | ClassToken<KAutoObject>)); |
| 80 | // static_assert(ClassToken<KDeviceAddressSpace> == ((0b01100001 << 8) | ClassToken<KAutoObject>)); | 81 | // static_assert(ClassToken<KDeviceAddressSpace> == ((0b01100001 << 8) | ClassToken<KAutoObject>)); |
| 81 | // static_assert(ClassToken<KSessionRequest> == ((0b10100001 << 8) | ClassToken<KAutoObject>)); | 82 | // static_assert(ClassToken<KSessionRequest> == ((0b10100001 << 8) | ClassToken<KAutoObject>)); |
| 82 | // static_assert(ClassToken<KCodeMemory> == ((0b11000001 << 8) | ClassToken<KAutoObject>)); | 83 | static_assert(ClassToken<KCodeMemory> == ((0b11000001 << 8) | ClassToken<KAutoObject>)); |
| 83 | 84 | ||
| 84 | // Ensure that the token hierarchy reflects the class hierarchy. | 85 | // Ensure that the token hierarchy reflects the class hierarchy. |
| 85 | 86 | ||
diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp new file mode 100644 index 000000000..d69f7ffb7 --- /dev/null +++ b/src/core/hle/kernel/k_code_memory.cpp | |||
| @@ -0,0 +1,146 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/common_types.h" | ||
| 6 | #include "core/device_memory.h" | ||
| 7 | #include "core/hle/kernel/k_auto_object.h" | ||
| 8 | #include "core/hle/kernel/k_code_memory.h" | ||
| 9 | #include "core/hle/kernel/k_light_lock.h" | ||
| 10 | #include "core/hle/kernel/k_memory_block.h" | ||
| 11 | #include "core/hle/kernel/k_page_linked_list.h" | ||
| 12 | #include "core/hle/kernel/k_page_table.h" | ||
| 13 | #include "core/hle/kernel/k_process.h" | ||
| 14 | #include "core/hle/kernel/slab_helpers.h" | ||
| 15 | #include "core/hle/kernel/svc_types.h" | ||
| 16 | #include "core/hle/result.h" | ||
| 17 | |||
| 18 | namespace Kernel { | ||
| 19 | |||
| 20 | KCodeMemory::KCodeMemory(KernelCore& kernel_) | ||
| 21 | : KAutoObjectWithSlabHeapAndContainer{kernel_}, m_lock(kernel_) {} | ||
| 22 | |||
| 23 | ResultCode KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, size_t size) { | ||
| 24 | // Set members. | ||
| 25 | m_owner = kernel.CurrentProcess(); | ||
| 26 | |||
| 27 | // Get the owner page table. | ||
| 28 | auto& page_table = m_owner->PageTable(); | ||
| 29 | |||
| 30 | // Construct the page group. | ||
| 31 | KMemoryInfo kBlockInfo = page_table.QueryInfo(addr); | ||
| 32 | m_page_group = KPageLinkedList(kBlockInfo.GetAddress(), kBlockInfo.GetNumPages()); | ||
| 33 | |||
| 34 | // Lock the memory. | ||
| 35 | R_TRY(page_table.LockForCodeMemory(addr, size)) | ||
| 36 | |||
| 37 | // Clear the memory. | ||
| 38 | for (const auto& block : m_page_group.Nodes()) { | ||
| 39 | std::memset(device_memory.GetPointer(block.GetAddress()), 0xFF, block.GetSize()); | ||
| 40 | } | ||
| 41 | |||
| 42 | // Set remaining tracking members. | ||
| 43 | m_address = addr; | ||
| 44 | m_is_initialized = true; | ||
| 45 | m_is_owner_mapped = false; | ||
| 46 | m_is_mapped = false; | ||
| 47 | |||
| 48 | // We succeeded. | ||
| 49 | return ResultSuccess; | ||
| 50 | } | ||
| 51 | |||
| 52 | void KCodeMemory::Finalize() { | ||
| 53 | // Unlock. | ||
| 54 | if (!m_is_mapped && !m_is_owner_mapped) { | ||
| 55 | const size_t size = m_page_group.GetNumPages() * PageSize; | ||
| 56 | m_owner->PageTable().UnlockForCodeMemory(m_address, size); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | ResultCode KCodeMemory::Map(VAddr address, size_t size) { | ||
| 61 | // Validate the size. | ||
| 62 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); | ||
| 63 | |||
| 64 | // Lock ourselves. | ||
| 65 | KScopedLightLock lk(m_lock); | ||
| 66 | |||
| 67 | // Ensure we're not already mapped. | ||
| 68 | R_UNLESS(!m_is_mapped, ResultInvalidState); | ||
| 69 | |||
| 70 | // Map the memory. | ||
| 71 | R_TRY(kernel.CurrentProcess()->PageTable().MapPages( | ||
| 72 | address, m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite)); | ||
| 73 | |||
| 74 | // Mark ourselves as mapped. | ||
| 75 | m_is_mapped = true; | ||
| 76 | |||
| 77 | return ResultSuccess; | ||
| 78 | } | ||
| 79 | |||
| 80 | ResultCode KCodeMemory::Unmap(VAddr address, size_t size) { | ||
| 81 | // Validate the size. | ||
| 82 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); | ||
| 83 | |||
| 84 | // Lock ourselves. | ||
| 85 | KScopedLightLock lk(m_lock); | ||
| 86 | |||
| 87 | // Unmap the memory. | ||
| 88 | R_TRY(kernel.CurrentProcess()->PageTable().UnmapPages(address, m_page_group, | ||
| 89 | KMemoryState::CodeOut)); | ||
| 90 | |||
| 91 | // Mark ourselves as unmapped. | ||
| 92 | m_is_mapped = false; | ||
| 93 | |||
| 94 | return ResultSuccess; | ||
| 95 | } | ||
| 96 | |||
| 97 | ResultCode KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm) { | ||
| 98 | // Validate the size. | ||
| 99 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); | ||
| 100 | |||
| 101 | // Lock ourselves. | ||
| 102 | KScopedLightLock lk(m_lock); | ||
| 103 | |||
| 104 | // Ensure we're not already mapped. | ||
| 105 | R_UNLESS(!m_is_owner_mapped, ResultInvalidState); | ||
| 106 | |||
| 107 | // Convert the memory permission. | ||
| 108 | KMemoryPermission k_perm{}; | ||
| 109 | switch (perm) { | ||
| 110 | case Svc::MemoryPermission::Read: | ||
| 111 | k_perm = KMemoryPermission::UserRead; | ||
| 112 | break; | ||
| 113 | case Svc::MemoryPermission::ReadExecute: | ||
| 114 | k_perm = KMemoryPermission::UserReadExecute; | ||
| 115 | break; | ||
| 116 | default: | ||
| 117 | break; | ||
| 118 | } | ||
| 119 | |||
| 120 | // Map the memory. | ||
| 121 | R_TRY( | ||
| 122 | m_owner->PageTable().MapPages(address, m_page_group, KMemoryState::GeneratedCode, k_perm)); | ||
| 123 | |||
| 124 | // Mark ourselves as mapped. | ||
| 125 | m_is_owner_mapped = true; | ||
| 126 | |||
| 127 | return ResultSuccess; | ||
| 128 | } | ||
| 129 | |||
| 130 | ResultCode KCodeMemory::UnmapFromOwner(VAddr address, size_t size) { | ||
| 131 | // Validate the size. | ||
| 132 | R_UNLESS(m_page_group.GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); | ||
| 133 | |||
| 134 | // Lock ourselves. | ||
| 135 | KScopedLightLock lk(m_lock); | ||
| 136 | |||
| 137 | // Unmap the memory. | ||
| 138 | R_TRY(m_owner->PageTable().UnmapPages(address, m_page_group, KMemoryState::GeneratedCode)); | ||
| 139 | |||
| 140 | // Mark ourselves as unmapped. | ||
| 141 | m_is_owner_mapped = false; | ||
| 142 | |||
| 143 | return ResultSuccess; | ||
| 144 | } | ||
| 145 | |||
| 146 | } // namespace Kernel \ No newline at end of file | ||
diff --git a/src/core/hle/kernel/k_code_memory.h b/src/core/hle/kernel/k_code_memory.h new file mode 100644 index 000000000..e0ba19a53 --- /dev/null +++ b/src/core/hle/kernel/k_code_memory.h | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | #include "core/device_memory.h" | ||
| 9 | #include "core/hle/kernel/k_auto_object.h" | ||
| 10 | #include "core/hle/kernel/k_light_lock.h" | ||
| 11 | #include "core/hle/kernel/k_page_linked_list.h" | ||
| 12 | #include "core/hle/kernel/k_process.h" | ||
| 13 | #include "core/hle/kernel/slab_helpers.h" | ||
| 14 | #include "core/hle/kernel/svc_types.h" | ||
| 15 | #include "core/hle/result.h" | ||
| 16 | |||
| 17 | namespace Kernel { | ||
| 18 | |||
| 19 | enum class CodeMemoryOperation : u32 { | ||
| 20 | Map = 0, | ||
| 21 | MapToOwner = 1, | ||
| 22 | Unmap = 2, | ||
| 23 | UnmapFromOwner = 3, | ||
| 24 | }; | ||
| 25 | |||
| 26 | class KCodeMemory final | ||
| 27 | : public KAutoObjectWithSlabHeapAndContainer<KCodeMemory, KAutoObjectWithList> { | ||
| 28 | KERNEL_AUTOOBJECT_TRAITS(KCodeMemory, KAutoObject); | ||
| 29 | |||
| 30 | public: | ||
| 31 | explicit KCodeMemory(KernelCore& kernel_); | ||
| 32 | |||
| 33 | ResultCode Initialize(Core::DeviceMemory& device_memory, VAddr address, size_t size); | ||
| 34 | void Finalize(); | ||
| 35 | |||
| 36 | ResultCode Map(VAddr address, size_t size); | ||
| 37 | ResultCode Unmap(VAddr address, size_t size); | ||
| 38 | ResultCode MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm); | ||
| 39 | ResultCode UnmapFromOwner(VAddr address, size_t size); | ||
| 40 | |||
| 41 | bool IsInitialized() const { | ||
| 42 | return m_is_initialized; | ||
| 43 | } | ||
| 44 | static void PostDestroy([[maybe_unused]] uintptr_t arg) {} | ||
| 45 | |||
| 46 | KProcess* GetOwner() const { | ||
| 47 | return m_owner; | ||
| 48 | } | ||
| 49 | VAddr GetSourceAddress() const { | ||
| 50 | return m_address; | ||
| 51 | } | ||
| 52 | size_t GetSize() const { | ||
| 53 | return m_is_initialized ? m_page_group.GetNumPages() * PageSize : 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | private: | ||
| 57 | KPageLinkedList m_page_group{}; | ||
| 58 | KProcess* m_owner{}; | ||
| 59 | VAddr m_address{}; | ||
| 60 | KLightLock m_lock; | ||
| 61 | bool m_is_initialized{}; | ||
| 62 | bool m_is_owner_mapped{}; | ||
| 63 | bool m_is_mapped{}; | ||
| 64 | }; | ||
| 65 | |||
| 66 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_memory_block.h b/src/core/hle/kernel/k_memory_block.h index a7fdb5fb8..fd491146f 100644 --- a/src/core/hle/kernel/k_memory_block.h +++ b/src/core/hle/kernel/k_memory_block.h | |||
| @@ -131,6 +131,26 @@ enum class KMemoryPermission : u8 { | |||
| 131 | 131 | ||
| 132 | UserMask = static_cast<u8>(Svc::MemoryPermission::Read | Svc::MemoryPermission::Write | | 132 | UserMask = static_cast<u8>(Svc::MemoryPermission::Read | Svc::MemoryPermission::Write | |
| 133 | Svc::MemoryPermission::Execute), | 133 | Svc::MemoryPermission::Execute), |
| 134 | |||
| 135 | KernelShift = 3, | ||
| 136 | |||
| 137 | KernelRead = Read << KernelShift, | ||
| 138 | KernelWrite = Write << KernelShift, | ||
| 139 | KernelExecute = Execute << KernelShift, | ||
| 140 | |||
| 141 | NotMapped = (1 << (2 * KernelShift)), | ||
| 142 | |||
| 143 | KernelReadWrite = KernelRead | KernelWrite, | ||
| 144 | KernelReadExecute = KernelRead | KernelExecute, | ||
| 145 | |||
| 146 | UserRead = Read | KernelRead, | ||
| 147 | UserWrite = Write | KernelWrite, | ||
| 148 | UserExecute = Execute, | ||
| 149 | |||
| 150 | UserReadWrite = UserRead | UserWrite, | ||
| 151 | UserReadExecute = UserRead | UserExecute, | ||
| 152 | |||
| 153 | IpcLockChangeMask = NotMapped | UserReadWrite | ||
| 134 | }; | 154 | }; |
| 135 | DECLARE_ENUM_FLAG_OPERATORS(KMemoryPermission); | 155 | DECLARE_ENUM_FLAG_OPERATORS(KMemoryPermission); |
| 136 | 156 | ||
diff --git a/src/core/hle/kernel/k_page_linked_list.h b/src/core/hle/kernel/k_page_linked_list.h index 3362fb236..0e2ae582a 100644 --- a/src/core/hle/kernel/k_page_linked_list.h +++ b/src/core/hle/kernel/k_page_linked_list.h | |||
| @@ -27,6 +27,10 @@ public: | |||
| 27 | return num_pages; | 27 | return num_pages; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | constexpr std::size_t GetSize() const { | ||
| 31 | return GetNumPages() * PageSize; | ||
| 32 | } | ||
| 33 | |||
| 30 | private: | 34 | private: |
| 31 | u64 addr{}; | 35 | u64 addr{}; |
| 32 | std::size_t num_pages{}; | 36 | std::size_t num_pages{}; |
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 9bda5c5b2..99982e5a3 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -368,6 +368,33 @@ ResultCode KPageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, st | |||
| 368 | return ResultSuccess; | 368 | return ResultSuccess; |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | ResultCode KPageTable::UnmapProcessMemory(VAddr dst_addr, std::size_t size, | ||
| 372 | KPageTable& src_page_table, VAddr src_addr) { | ||
| 373 | std::lock_guard lock{page_table_lock}; | ||
| 374 | |||
| 375 | const std::size_t num_pages{size / PageSize}; | ||
| 376 | |||
| 377 | // Check that the memory is mapped in the destination process. | ||
| 378 | size_t num_allocator_blocks; | ||
| 379 | R_TRY(CheckMemoryState(&num_allocator_blocks, dst_addr, size, KMemoryState::All, | ||
| 380 | KMemoryState::SharedCode, KMemoryPermission::UserReadWrite, | ||
| 381 | KMemoryPermission::UserReadWrite, KMemoryAttribute::All, | ||
| 382 | KMemoryAttribute::None)); | ||
| 383 | |||
| 384 | // Check that the memory is mapped in the source process. | ||
| 385 | R_TRY(src_page_table.CheckMemoryState(src_addr, size, KMemoryState::FlagCanMapProcess, | ||
| 386 | KMemoryState::FlagCanMapProcess, KMemoryPermission::None, | ||
| 387 | KMemoryPermission::None, KMemoryAttribute::All, | ||
| 388 | KMemoryAttribute::None)); | ||
| 389 | |||
| 390 | CASCADE_CODE(Operate(dst_addr, num_pages, KMemoryPermission::None, OperationType::Unmap)); | ||
| 391 | |||
| 392 | // Apply the memory block update. | ||
| 393 | block_manager->Update(dst_addr, num_pages, KMemoryState::Free, KMemoryPermission::None, | ||
| 394 | KMemoryAttribute::None); | ||
| 395 | |||
| 396 | return ResultSuccess; | ||
| 397 | } | ||
| 371 | void KPageTable::MapPhysicalMemory(KPageLinkedList& page_linked_list, VAddr start, VAddr end) { | 398 | void KPageTable::MapPhysicalMemory(KPageLinkedList& page_linked_list, VAddr start, VAddr end) { |
| 372 | auto node{page_linked_list.Nodes().begin()}; | 399 | auto node{page_linked_list.Nodes().begin()}; |
| 373 | PAddr map_addr{node->GetAddress()}; | 400 | PAddr map_addr{node->GetAddress()}; |
| @@ -942,6 +969,60 @@ ResultCode KPageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) | |||
| 942 | return ResultSuccess; | 969 | return ResultSuccess; |
| 943 | } | 970 | } |
| 944 | 971 | ||
| 972 | ResultCode KPageTable::LockForCodeMemory(VAddr addr, std::size_t size) { | ||
| 973 | std::lock_guard lock{page_table_lock}; | ||
| 974 | |||
| 975 | KMemoryPermission new_perm = KMemoryPermission::NotMapped | KMemoryPermission::KernelReadWrite; | ||
| 976 | |||
| 977 | KMemoryPermission old_perm{}; | ||
| 978 | |||
| 979 | if (const ResultCode result{CheckMemoryState( | ||
| 980 | nullptr, &old_perm, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, | ||
| 981 | KMemoryState::FlagCanCodeMemory, KMemoryPermission::Mask, | ||
| 982 | KMemoryPermission::UserReadWrite, KMemoryAttribute::All, KMemoryAttribute::None)}; | ||
| 983 | result.IsError()) { | ||
| 984 | return result; | ||
| 985 | } | ||
| 986 | |||
| 987 | new_perm = (new_perm != KMemoryPermission::None) ? new_perm : old_perm; | ||
| 988 | |||
| 989 | block_manager->UpdateLock( | ||
| 990 | addr, size / PageSize, | ||
| 991 | [](KMemoryBlockManager::iterator block, KMemoryPermission permission) { | ||
| 992 | block->ShareToDevice(permission); | ||
| 993 | }, | ||
| 994 | new_perm); | ||
| 995 | |||
| 996 | return ResultSuccess; | ||
| 997 | } | ||
| 998 | |||
| 999 | ResultCode KPageTable::UnlockForCodeMemory(VAddr addr, std::size_t size) { | ||
| 1000 | std::lock_guard lock{page_table_lock}; | ||
| 1001 | |||
| 1002 | KMemoryPermission new_perm = KMemoryPermission::UserReadWrite; | ||
| 1003 | |||
| 1004 | KMemoryPermission old_perm{}; | ||
| 1005 | |||
| 1006 | if (const ResultCode result{CheckMemoryState( | ||
| 1007 | nullptr, &old_perm, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, | ||
| 1008 | KMemoryState::FlagCanCodeMemory, KMemoryPermission::None, KMemoryPermission::None, | ||
| 1009 | KMemoryAttribute::All, KMemoryAttribute::Locked)}; | ||
| 1010 | result.IsError()) { | ||
| 1011 | return result; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | new_perm = (new_perm != KMemoryPermission::None) ? new_perm : old_perm; | ||
| 1015 | |||
| 1016 | block_manager->UpdateLock( | ||
| 1017 | addr, size / PageSize, | ||
| 1018 | [](KMemoryBlockManager::iterator block, KMemoryPermission permission) { | ||
| 1019 | block->UnshareToDevice(permission); | ||
| 1020 | }, | ||
| 1021 | new_perm); | ||
| 1022 | |||
| 1023 | return ResultSuccess; | ||
| 1024 | } | ||
| 1025 | |||
| 945 | ResultCode KPageTable::InitializeMemoryLayout(VAddr start, VAddr end) { | 1026 | ResultCode KPageTable::InitializeMemoryLayout(VAddr start, VAddr end) { |
| 946 | block_manager = std::make_unique<KMemoryBlockManager>(start, end); | 1027 | block_manager = std::make_unique<KMemoryBlockManager>(start, end); |
| 947 | 1028 | ||
| @@ -1231,4 +1312,42 @@ ResultCode KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermissi | |||
| 1231 | return ResultSuccess; | 1312 | return ResultSuccess; |
| 1232 | } | 1313 | } |
| 1233 | 1314 | ||
| 1315 | ResultCode KPageTable::CheckMemoryState(size_t* out_blocks_needed, VAddr addr, size_t size, | ||
| 1316 | KMemoryState state_mask, KMemoryState state, | ||
| 1317 | KMemoryPermission perm_mask, KMemoryPermission perm, | ||
| 1318 | KMemoryAttribute attr_mask, KMemoryAttribute attr) const { | ||
| 1319 | // Get information about the first block. | ||
| 1320 | const VAddr last_addr = addr + size - 1; | ||
| 1321 | KMemoryBlockManager::const_iterator it{block_manager->FindIterator(addr)}; | ||
| 1322 | KMemoryInfo info = it->GetMemoryInfo(); | ||
| 1323 | |||
| 1324 | // If the start address isn't aligned, we need a block. | ||
| 1325 | const size_t blocks_for_start_align = | ||
| 1326 | (Common::AlignDown(addr, PageSize) != info.GetAddress()) ? 1 : 0; | ||
| 1327 | |||
| 1328 | while (true) { | ||
| 1329 | // Validate against the provided masks. | ||
| 1330 | R_TRY(CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); | ||
| 1331 | |||
| 1332 | // Break once we're done. | ||
| 1333 | if (last_addr <= info.GetLastAddress()) { | ||
| 1334 | break; | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | // Advance our iterator. | ||
| 1338 | it++; | ||
| 1339 | info = it->GetMemoryInfo(); | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | // If the end address isn't aligned, we need a block. | ||
| 1343 | const size_t blocks_for_end_align = | ||
| 1344 | (Common::AlignUp(addr + size, PageSize) != info.GetEndAddress()) ? 1 : 0; | ||
| 1345 | |||
| 1346 | if (out_blocks_needed != nullptr) { | ||
| 1347 | *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; | ||
| 1348 | } | ||
| 1349 | |||
| 1350 | return ResultSuccess; | ||
| 1351 | } | ||
| 1352 | |||
| 1234 | } // namespace Kernel | 1353 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index b7ec38f06..d784aa67e 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -33,6 +33,8 @@ public: | |||
| 33 | KMemoryPermission perm); | 33 | KMemoryPermission perm); |
| 34 | ResultCode MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); | 34 | ResultCode MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); |
| 35 | ResultCode UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); | 35 | ResultCode UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size); |
| 36 | ResultCode UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table, | ||
| 37 | VAddr src_addr); | ||
| 36 | ResultCode MapPhysicalMemory(VAddr addr, std::size_t size); | 38 | ResultCode MapPhysicalMemory(VAddr addr, std::size_t size); |
| 37 | ResultCode UnmapPhysicalMemory(VAddr addr, std::size_t size); | 39 | ResultCode UnmapPhysicalMemory(VAddr addr, std::size_t size); |
| 38 | ResultCode UnmapMemory(VAddr addr, std::size_t size); | 40 | ResultCode UnmapMemory(VAddr addr, std::size_t size); |
| @@ -55,6 +57,8 @@ public: | |||
| 55 | KMemoryPermission perm, PAddr map_addr = 0); | 57 | KMemoryPermission perm, PAddr map_addr = 0); |
| 56 | ResultCode LockForDeviceAddressSpace(VAddr addr, std::size_t size); | 58 | ResultCode LockForDeviceAddressSpace(VAddr addr, std::size_t size); |
| 57 | ResultCode UnlockForDeviceAddressSpace(VAddr addr, std::size_t size); | 59 | ResultCode UnlockForDeviceAddressSpace(VAddr addr, std::size_t size); |
| 60 | ResultCode LockForCodeMemory(VAddr addr, std::size_t size); | ||
| 61 | ResultCode UnlockForCodeMemory(VAddr addr, std::size_t size); | ||
| 58 | 62 | ||
| 59 | Common::PageTable& PageTableImpl() { | 63 | Common::PageTable& PageTableImpl() { |
| 60 | return page_table_impl; | 64 | return page_table_impl; |
| @@ -115,6 +119,10 @@ private: | |||
| 115 | return CheckMemoryState(nullptr, nullptr, nullptr, addr, size, state_mask, state, perm_mask, | 119 | return CheckMemoryState(nullptr, nullptr, nullptr, addr, size, state_mask, state, perm_mask, |
| 116 | perm, attr_mask, attr, ignore_attr); | 120 | perm, attr_mask, attr, ignore_attr); |
| 117 | } | 121 | } |
| 122 | ResultCode CheckMemoryState(size_t* out_blocks_needed, VAddr addr, size_t size, | ||
| 123 | KMemoryState state_mask, KMemoryState state, | ||
| 124 | KMemoryPermission perm_mask, KMemoryPermission perm, | ||
| 125 | KMemoryAttribute attr_mask, KMemoryAttribute attr) const; | ||
| 118 | 126 | ||
| 119 | std::recursive_mutex page_table_lock; | 127 | std::recursive_mutex page_table_lock; |
| 120 | std::unique_ptr<KMemoryBlockManager> block_manager; | 128 | std::unique_ptr<KMemoryBlockManager> block_manager; |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index d2ceae950..d847fd0c5 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -53,6 +53,7 @@ class KSharedMemoryInfo; | |||
| 53 | class KThread; | 53 | class KThread; |
| 54 | class KTransferMemory; | 54 | class KTransferMemory; |
| 55 | class KWritableEvent; | 55 | class KWritableEvent; |
| 56 | class KCodeMemory; | ||
| 56 | class PhysicalCore; | 57 | class PhysicalCore; |
| 57 | class ServiceThread; | 58 | class ServiceThread; |
| 58 | class Synchronization; | 59 | class Synchronization; |
| @@ -326,6 +327,8 @@ public: | |||
| 326 | return slab_heap_container->transfer_memory; | 327 | return slab_heap_container->transfer_memory; |
| 327 | } else if constexpr (std::is_same_v<T, KWritableEvent>) { | 328 | } else if constexpr (std::is_same_v<T, KWritableEvent>) { |
| 328 | return slab_heap_container->writeable_event; | 329 | return slab_heap_container->writeable_event; |
| 330 | } else if constexpr (std::is_same_v<T, KCodeMemory>) { | ||
| 331 | return slab_heap_container->code_memory; | ||
| 329 | } | 332 | } |
| 330 | } | 333 | } |
| 331 | 334 | ||
| @@ -377,6 +380,7 @@ private: | |||
| 377 | KSlabHeap<KThread> thread; | 380 | KSlabHeap<KThread> thread; |
| 378 | KSlabHeap<KTransferMemory> transfer_memory; | 381 | KSlabHeap<KTransferMemory> transfer_memory; |
| 379 | KSlabHeap<KWritableEvent> writeable_event; | 382 | KSlabHeap<KWritableEvent> writeable_event; |
| 383 | KSlabHeap<KCodeMemory> code_memory; | ||
| 380 | }; | 384 | }; |
| 381 | 385 | ||
| 382 | std::unique_ptr<SlabHeapContainer> slab_heap_container; | 386 | std::unique_ptr<SlabHeapContainer> slab_heap_container; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index f0cd8471e..b37db918e 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "core/core_timing.h" | 18 | #include "core/core_timing.h" |
| 19 | #include "core/hle/kernel/k_client_port.h" | 19 | #include "core/hle/kernel/k_client_port.h" |
| 20 | #include "core/hle/kernel/k_client_session.h" | 20 | #include "core/hle/kernel/k_client_session.h" |
| 21 | #include "core/hle/kernel/k_code_memory.h" | ||
| 21 | #include "core/hle/kernel/k_event.h" | 22 | #include "core/hle/kernel/k_event.h" |
| 22 | #include "core/hle/kernel/k_handle_table.h" | 23 | #include "core/hle/kernel/k_handle_table.h" |
| 23 | #include "core/hle/kernel/k_memory_block.h" | 24 | #include "core/hle/kernel/k_memory_block.h" |
| @@ -1197,6 +1198,22 @@ constexpr bool IsValidProcessMemoryPermission(Svc::MemoryPermission perm) { | |||
| 1197 | } | 1198 | } |
| 1198 | } | 1199 | } |
| 1199 | 1200 | ||
| 1201 | constexpr bool IsValidMapCodeMemoryPermission(Svc::MemoryPermission perm) { | ||
| 1202 | return perm == Svc::MemoryPermission::ReadWrite; | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | constexpr bool IsValidMapToOwnerCodeMemoryPermission(Svc::MemoryPermission perm) { | ||
| 1206 | return perm == Svc::MemoryPermission::Read || perm == Svc::MemoryPermission::ReadExecute; | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | constexpr bool IsValidUnmapCodeMemoryPermission(Svc::MemoryPermission perm) { | ||
| 1210 | return perm == Svc::MemoryPermission::None; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(Svc::MemoryPermission perm) { | ||
| 1214 | return perm == Svc::MemoryPermission::None; | ||
| 1215 | } | ||
| 1216 | |||
| 1200 | } // Anonymous namespace | 1217 | } // Anonymous namespace |
| 1201 | 1218 | ||
| 1202 | static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, | 1219 | static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, |
| @@ -1306,6 +1323,195 @@ static ResultCode SetProcessMemoryPermission(Core::System& system, Handle proces | |||
| 1306 | return page_table.SetProcessMemoryPermission(address, size, ConvertToKMemoryPermission(perm)); | 1323 | return page_table.SetProcessMemoryPermission(address, size, ConvertToKMemoryPermission(perm)); |
| 1307 | } | 1324 | } |
| 1308 | 1325 | ||
| 1326 | static ResultCode MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, | ||
| 1327 | VAddr src_address, u64 size) { | ||
| 1328 | LOG_TRACE(Kernel_SVC, | ||
| 1329 | "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}", | ||
| 1330 | dst_address, process_handle, src_address, size); | ||
| 1331 | |||
| 1332 | // Validate the address/size. | ||
| 1333 | R_UNLESS(Common::IsAligned(dst_address, PageSize), ResultInvalidAddress); | ||
| 1334 | R_UNLESS(Common::IsAligned(src_address, PageSize), ResultInvalidAddress); | ||
| 1335 | R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); | ||
| 1336 | R_UNLESS(size > 0, ResultInvalidSize); | ||
| 1337 | R_UNLESS((dst_address < dst_address + size), ResultInvalidCurrentMemory); | ||
| 1338 | R_UNLESS((src_address < src_address + size), ResultInvalidCurrentMemory); | ||
| 1339 | |||
| 1340 | // Get the processes. | ||
| 1341 | KProcess* dst_process = system.CurrentProcess(); | ||
| 1342 | KScopedAutoObject src_process = | ||
| 1343 | dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle); | ||
| 1344 | R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle); | ||
| 1345 | |||
| 1346 | // Get the page tables. | ||
| 1347 | auto& dst_pt = dst_process->PageTable(); | ||
| 1348 | auto& src_pt = src_process->PageTable(); | ||
| 1349 | |||
| 1350 | // Validate that the mapping is in range. | ||
| 1351 | R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory); | ||
| 1352 | R_UNLESS(dst_pt.CanContain(dst_address, size, KMemoryState::SharedCode), | ||
| 1353 | ResultInvalidMemoryRegion); | ||
| 1354 | |||
| 1355 | // Create a new page group. | ||
| 1356 | KMemoryInfo kBlockInfo = dst_pt.QueryInfo(dst_address); | ||
| 1357 | KPageLinkedList pg(kBlockInfo.GetAddress(), kBlockInfo.GetNumPages()); | ||
| 1358 | |||
| 1359 | // Map the group. | ||
| 1360 | R_TRY(dst_pt.MapPages(dst_address, pg, KMemoryState::SharedCode, | ||
| 1361 | KMemoryPermission::UserReadWrite)); | ||
| 1362 | |||
| 1363 | return ResultSuccess; | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | static ResultCode UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle, | ||
| 1367 | VAddr src_address, u64 size) { | ||
| 1368 | LOG_TRACE(Kernel_SVC, | ||
| 1369 | "called, dst_address=0x{:X}, process_handle=0x{:X}, src_address=0x{:X}, size=0x{:X}", | ||
| 1370 | dst_address, process_handle, src_address, size); | ||
| 1371 | |||
| 1372 | // Validate the address/size. | ||
| 1373 | R_UNLESS(Common::IsAligned(dst_address, PageSize), ResultInvalidAddress); | ||
| 1374 | R_UNLESS(Common::IsAligned(src_address, PageSize), ResultInvalidAddress); | ||
| 1375 | R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); | ||
| 1376 | R_UNLESS(size > 0, ResultInvalidSize); | ||
| 1377 | R_UNLESS((dst_address < dst_address + size), ResultInvalidCurrentMemory); | ||
| 1378 | R_UNLESS((src_address < src_address + size), ResultInvalidCurrentMemory); | ||
| 1379 | |||
| 1380 | // Get the processes. | ||
| 1381 | KProcess* dst_process = system.CurrentProcess(); | ||
| 1382 | KScopedAutoObject src_process = | ||
| 1383 | dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle); | ||
| 1384 | R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle); | ||
| 1385 | |||
| 1386 | // Get the page tables. | ||
| 1387 | auto& dst_pt = dst_process->PageTable(); | ||
| 1388 | auto& src_pt = src_process->PageTable(); | ||
| 1389 | |||
| 1390 | // Validate that the mapping is in range. | ||
| 1391 | R_UNLESS(src_pt.Contains(src_address, size), ResultInvalidCurrentMemory); | ||
| 1392 | R_UNLESS(dst_pt.CanContain(dst_address, size, KMemoryState::SharedCode), | ||
| 1393 | ResultInvalidMemoryRegion); | ||
| 1394 | |||
| 1395 | // Unmap the memory. | ||
| 1396 | R_TRY(dst_pt.UnmapProcessMemory(dst_address, size, src_pt, src_address)); | ||
| 1397 | |||
| 1398 | return ResultSuccess; | ||
| 1399 | } | ||
| 1400 | |||
| 1401 | static ResultCode CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t size) { | ||
| 1402 | LOG_TRACE(Kernel_SVC, "called, handle_out=0x{:X}, address=0x{:X}, size=0x{:X}", | ||
| 1403 | static_cast<void*>(out), address, size); | ||
| 1404 | // Get kernel instance. | ||
| 1405 | auto& kernel = system.Kernel(); | ||
| 1406 | |||
| 1407 | // Validate address / size. | ||
| 1408 | R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); | ||
| 1409 | R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); | ||
| 1410 | R_UNLESS(size > 0, ResultInvalidSize); | ||
| 1411 | R_UNLESS((address < address + size), ResultInvalidCurrentMemory); | ||
| 1412 | |||
| 1413 | // Create the code memory. | ||
| 1414 | |||
| 1415 | KCodeMemory* code_mem = KCodeMemory::Create(kernel); | ||
| 1416 | R_UNLESS(code_mem != nullptr, ResultOutOfResource); | ||
| 1417 | |||
| 1418 | // Verify that the region is in range. | ||
| 1419 | R_UNLESS(system.CurrentProcess()->PageTable().Contains(address, size), | ||
| 1420 | ResultInvalidCurrentMemory); | ||
| 1421 | |||
| 1422 | // Initialize the code memory. | ||
| 1423 | R_TRY(code_mem->Initialize(system.DeviceMemory(), address, size)); | ||
| 1424 | |||
| 1425 | // Register the code memory. | ||
| 1426 | KCodeMemory::Register(kernel, code_mem); | ||
| 1427 | |||
| 1428 | // Add the code memory to the handle table. | ||
| 1429 | R_TRY(system.CurrentProcess()->GetHandleTable().Add(out, code_mem)); | ||
| 1430 | |||
| 1431 | code_mem->Close(); | ||
| 1432 | |||
| 1433 | return ResultSuccess; | ||
| 1434 | } | ||
| 1435 | |||
| 1436 | static ResultCode ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation, | ||
| 1437 | VAddr address, size_t size, Svc::MemoryPermission perm) { | ||
| 1438 | |||
| 1439 | LOG_TRACE(Kernel_SVC, | ||
| 1440 | "called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, " | ||
| 1441 | "permission=0x{:X}", | ||
| 1442 | code_memory_handle, operation, address, size, perm); | ||
| 1443 | |||
| 1444 | // Validate the address / size. | ||
| 1445 | R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); | ||
| 1446 | R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); | ||
| 1447 | R_UNLESS(size > 0, ResultInvalidSize); | ||
| 1448 | R_UNLESS((address < address + size), ResultInvalidCurrentMemory); | ||
| 1449 | |||
| 1450 | // Get the code memory from its handle. | ||
| 1451 | KScopedAutoObject code_mem = | ||
| 1452 | system.CurrentProcess()->GetHandleTable().GetObject<KCodeMemory>(code_memory_handle); | ||
| 1453 | R_UNLESS(code_mem.IsNotNull(), ResultInvalidHandle); | ||
| 1454 | |||
| 1455 | // NOTE: Here, Atmosphere extends the SVC to allow code memory operations on one's own process. | ||
| 1456 | // This enables homebrew usage of these SVCs for JIT. | ||
| 1457 | |||
| 1458 | // Perform the operation. | ||
| 1459 | switch (static_cast<CodeMemoryOperation>(operation)) { | ||
| 1460 | case CodeMemoryOperation::Map: { | ||
| 1461 | // Check that the region is in range. | ||
| 1462 | R_UNLESS( | ||
| 1463 | system.CurrentProcess()->PageTable().CanContain(address, size, KMemoryState::CodeOut), | ||
| 1464 | ResultInvalidMemoryRegion); | ||
| 1465 | |||
| 1466 | // Check the memory permission. | ||
| 1467 | R_UNLESS(IsValidMapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission); | ||
| 1468 | |||
| 1469 | // Map the memory. | ||
| 1470 | R_TRY(code_mem->Map(address, size)); | ||
| 1471 | } break; | ||
| 1472 | case CodeMemoryOperation::Unmap: { | ||
| 1473 | // Check that the region is in range. | ||
| 1474 | R_UNLESS( | ||
| 1475 | system.CurrentProcess()->PageTable().CanContain(address, size, KMemoryState::CodeOut), | ||
| 1476 | ResultInvalidMemoryRegion); | ||
| 1477 | |||
| 1478 | // Check the memory permission. | ||
| 1479 | R_UNLESS(IsValidUnmapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission); | ||
| 1480 | |||
| 1481 | // Unmap the memory. | ||
| 1482 | R_TRY(code_mem->Unmap(address, size)); | ||
| 1483 | } break; | ||
| 1484 | case CodeMemoryOperation::MapToOwner: { | ||
| 1485 | // Check that the region is in range. | ||
| 1486 | R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size, | ||
| 1487 | KMemoryState::GeneratedCode), | ||
| 1488 | ResultInvalidMemoryRegion); | ||
| 1489 | |||
| 1490 | // Check the memory permission. | ||
| 1491 | R_UNLESS(IsValidMapToOwnerCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission); | ||
| 1492 | |||
| 1493 | // Map the memory to its owner. | ||
| 1494 | R_TRY(code_mem->MapToOwner(address, size, perm)); | ||
| 1495 | } break; | ||
| 1496 | case CodeMemoryOperation::UnmapFromOwner: { | ||
| 1497 | // Check that the region is in range. | ||
| 1498 | R_UNLESS(code_mem->GetOwner()->PageTable().CanContain(address, size, | ||
| 1499 | KMemoryState::GeneratedCode), | ||
| 1500 | ResultInvalidMemoryRegion); | ||
| 1501 | |||
| 1502 | // Check the memory permission. | ||
| 1503 | R_UNLESS(IsValidUnmapFromOwnerCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission); | ||
| 1504 | |||
| 1505 | // Unmap the memory from its owner. | ||
| 1506 | R_TRY(code_mem->UnmapFromOwner(address, size)); | ||
| 1507 | } break; | ||
| 1508 | default: | ||
| 1509 | return ResultInvalidEnumValue; | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | return ResultSuccess; | ||
| 1513 | } | ||
| 1514 | |||
| 1309 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, | 1515 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, |
| 1310 | VAddr page_info_address, Handle process_handle, | 1516 | VAddr page_info_address, Handle process_handle, |
| 1311 | VAddr address) { | 1517 | VAddr address) { |
| @@ -2600,8 +2806,8 @@ static const FunctionDef SVC_Table_64[] = { | |||
| 2600 | {0x48, nullptr, "MapPhysicalMemoryUnsafe"}, | 2806 | {0x48, nullptr, "MapPhysicalMemoryUnsafe"}, |
| 2601 | {0x49, nullptr, "UnmapPhysicalMemoryUnsafe"}, | 2807 | {0x49, nullptr, "UnmapPhysicalMemoryUnsafe"}, |
| 2602 | {0x4A, nullptr, "SetUnsafeLimit"}, | 2808 | {0x4A, nullptr, "SetUnsafeLimit"}, |
| 2603 | {0x4B, nullptr, "CreateCodeMemory"}, | 2809 | {0x4B, SvcWrap64<CreateCodeMemory>, "CreateCodeMemory"}, |
| 2604 | {0x4C, nullptr, "ControlCodeMemory"}, | 2810 | {0x4C, SvcWrap64<ControlCodeMemory>, "ControlCodeMemory"}, |
| 2605 | {0x4D, nullptr, "SleepSystem"}, | 2811 | {0x4D, nullptr, "SleepSystem"}, |
| 2606 | {0x4E, nullptr, "ReadWriteRegister"}, | 2812 | {0x4E, nullptr, "ReadWriteRegister"}, |
| 2607 | {0x4F, nullptr, "SetProcessActivity"}, | 2813 | {0x4F, nullptr, "SetProcessActivity"}, |
| @@ -2641,8 +2847,8 @@ static const FunctionDef SVC_Table_64[] = { | |||
| 2641 | {0x71, nullptr, "ManageNamedPort"}, | 2847 | {0x71, nullptr, "ManageNamedPort"}, |
| 2642 | {0x72, nullptr, "ConnectToPort"}, | 2848 | {0x72, nullptr, "ConnectToPort"}, |
| 2643 | {0x73, SvcWrap64<SetProcessMemoryPermission>, "SetProcessMemoryPermission"}, | 2849 | {0x73, SvcWrap64<SetProcessMemoryPermission>, "SetProcessMemoryPermission"}, |
| 2644 | {0x74, nullptr, "MapProcessMemory"}, | 2850 | {0x74, SvcWrap64<MapProcessMemory>, "MapProcessMemory"}, |
| 2645 | {0x75, nullptr, "UnmapProcessMemory"}, | 2851 | {0x75, SvcWrap64<UnmapProcessMemory>, "UnmapProcessMemory"}, |
| 2646 | {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, | 2852 | {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, |
| 2647 | {0x77, SvcWrap64<MapProcessCodeMemory>, "MapProcessCodeMemory"}, | 2853 | {0x77, SvcWrap64<MapProcessCodeMemory>, "MapProcessCodeMemory"}, |
| 2648 | {0x78, SvcWrap64<UnmapProcessCodeMemory>, "UnmapProcessCodeMemory"}, | 2854 | {0x78, SvcWrap64<UnmapProcessCodeMemory>, "UnmapProcessCodeMemory"}, |
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 6e62e656f..86255fe6d 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h | |||
| @@ -73,6 +73,23 @@ void SvcWrap64(Core::System& system) { | |||
| 73 | .raw); | 73 | .raw); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | // Used by MapProcessMemory and UnmapProcessMemory | ||
| 77 | template <ResultCode func(Core::System&, u64, u32, u64, u64)> | ||
| 78 | void SvcWrap64(Core::System& system) { | ||
| 79 | FuncReturn(system, func(system, Param(system, 0), static_cast<u32>(Param(system, 1)), | ||
| 80 | Param(system, 2), Param(system, 3)) | ||
| 81 | .raw); | ||
| 82 | } | ||
| 83 | |||
| 84 | // Used by ControlCodeMemory | ||
| 85 | template <ResultCode func(Core::System&, Handle, u32, u64, u64, Svc::MemoryPermission)> | ||
| 86 | void SvcWrap64(Core::System& system) { | ||
| 87 | FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), | ||
| 88 | static_cast<u32>(Param(system, 1)), Param(system, 2), Param(system, 3), | ||
| 89 | static_cast<Svc::MemoryPermission>(Param(system, 4))) | ||
| 90 | .raw); | ||
| 91 | } | ||
| 92 | |||
| 76 | template <ResultCode func(Core::System&, u32*)> | 93 | template <ResultCode func(Core::System&, u32*)> |
| 77 | void SvcWrap64(Core::System& system) { | 94 | void SvcWrap64(Core::System& system) { |
| 78 | u32 param = 0; | 95 | u32 param = 0; |
| @@ -301,6 +318,16 @@ void SvcWrap64(Core::System& system) { | |||
| 301 | FuncReturn(system, retval); | 318 | FuncReturn(system, retval); |
| 302 | } | 319 | } |
| 303 | 320 | ||
| 321 | // Used by CreateCodeMemory | ||
| 322 | template <ResultCode func(Core::System&, Handle*, u64, u64)> | ||
| 323 | void SvcWrap64(Core::System& system) { | ||
| 324 | u32 param_1 = 0; | ||
| 325 | const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2)).raw; | ||
| 326 | |||
| 327 | system.CurrentArmInterface().SetReg(1, param_1); | ||
| 328 | FuncReturn(system, retval); | ||
| 329 | } | ||
| 330 | |||
| 304 | template <ResultCode func(Core::System&, Handle*, u64, u32, u32)> | 331 | template <ResultCode func(Core::System&, Handle*, u64, u32, u32)> |
| 305 | void SvcWrap64(Core::System& system) { | 332 | void SvcWrap64(Core::System& system) { |
| 306 | u32 param_1 = 0; | 333 | u32 param_1 = 0; |
diff --git a/src/core/hle/service/glue/glue.cpp b/src/core/hle/service/glue/glue.cpp index a08dc9758..b24d469cf 100644 --- a/src/core/hle/service/glue/glue.cpp +++ b/src/core/hle/service/glue/glue.cpp | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "core/hle/service/glue/bgtc.h" | 8 | #include "core/hle/service/glue/bgtc.h" |
| 9 | #include "core/hle/service/glue/ectx.h" | 9 | #include "core/hle/service/glue/ectx.h" |
| 10 | #include "core/hle/service/glue/glue.h" | 10 | #include "core/hle/service/glue/glue.h" |
| 11 | #include "core/hle/service/glue/notif.h" | ||
| 11 | 12 | ||
| 12 | namespace Service::Glue { | 13 | namespace Service::Glue { |
| 13 | 14 | ||
| @@ -24,6 +25,9 @@ void InstallInterfaces(Core::System& system) { | |||
| 24 | 25 | ||
| 25 | // Error Context | 26 | // Error Context |
| 26 | std::make_shared<ECTX_AW>(system)->InstallAsService(system.ServiceManager()); | 27 | std::make_shared<ECTX_AW>(system)->InstallAsService(system.ServiceManager()); |
| 28 | |||
| 29 | // Notification Services for application | ||
| 30 | std::make_shared<NOTIF_A>(system)->InstallAsService(system.ServiceManager()); | ||
| 27 | } | 31 | } |
| 28 | 32 | ||
| 29 | } // namespace Service::Glue | 33 | } // namespace Service::Glue |
diff --git a/src/core/hle/service/glue/notif.cpp b/src/core/hle/service/glue/notif.cpp new file mode 100644 index 000000000..c559ec9df --- /dev/null +++ b/src/core/hle/service/glue/notif.cpp | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/ipc_helpers.h" | ||
| 6 | #include "core/hle/service/glue/notif.h" | ||
| 7 | |||
| 8 | namespace Service::Glue { | ||
| 9 | |||
| 10 | NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {500, nullptr, "RegisterAlarmSetting"}, | ||
| 14 | {510, nullptr, "UpdateAlarmSetting"}, | ||
| 15 | {520, &NOTIF_A::ListAlarmSettings, "ListAlarmSettings"}, | ||
| 16 | {530, nullptr, "LoadApplicationParameter"}, | ||
| 17 | {540, nullptr, "DeleteAlarmSetting"}, | ||
| 18 | {1000, &NOTIF_A::Initialize, "Initialize"}, | ||
| 19 | }; | ||
| 20 | // clang-format on | ||
| 21 | |||
| 22 | RegisterHandlers(functions); | ||
| 23 | } | ||
| 24 | |||
| 25 | NOTIF_A::~NOTIF_A() = default; | ||
| 26 | |||
| 27 | void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) { | ||
| 28 | // Returns an array of AlarmSetting | ||
| 29 | constexpr s32 alarm_count = 0; | ||
| 30 | |||
| 31 | LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | ||
| 32 | |||
| 33 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 34 | rb.Push(ResultSuccess); | ||
| 35 | rb.Push(alarm_count); | ||
| 36 | } | ||
| 37 | |||
| 38 | void NOTIF_A::Initialize(Kernel::HLERequestContext& ctx) { | ||
| 39 | LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | ||
| 40 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 41 | rb.Push(ResultSuccess); | ||
| 42 | } | ||
| 43 | |||
| 44 | } // namespace Service::Glue | ||
diff --git a/src/core/hle/service/glue/notif.h b/src/core/hle/service/glue/notif.h new file mode 100644 index 000000000..6ecf2015c --- /dev/null +++ b/src/core/hle/service/glue/notif.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Service::Glue { | ||
| 14 | |||
| 15 | class NOTIF_A final : public ServiceFramework<NOTIF_A> { | ||
| 16 | public: | ||
| 17 | explicit NOTIF_A(Core::System& system_); | ||
| 18 | ~NOTIF_A() override; | ||
| 19 | |||
| 20 | private: | ||
| 21 | void ListAlarmSettings(Kernel::HLERequestContext& ctx); | ||
| 22 | void Initialize(Kernel::HLERequestContext& ctx); | ||
| 23 | }; | ||
| 24 | |||
| 25 | } // namespace Service::Glue | ||
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 6916930f7..2705e9dcb 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -110,7 +110,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | |||
| 110 | UpdateControllerAt(npad_type, npad_id, is_connected); | 110 | UpdateControllerAt(npad_type, npad_id, is_connected); |
| 111 | break; | 111 | break; |
| 112 | case Core::HID::ControllerTriggerType::Battery: { | 112 | case Core::HID::ControllerTriggerType::Battery: { |
| 113 | if (!controller.is_connected) { | 113 | if (!controller.device->IsConnected()) { |
| 114 | return; | 114 | return; |
| 115 | } | 115 | } |
| 116 | auto& shared_memory = controller.shared_memory_entry; | 116 | auto& shared_memory = controller.shared_memory_entry; |
| @@ -126,8 +126,11 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | |||
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | 128 | void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { |
| 129 | LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); | ||
| 130 | auto& controller = GetControllerFromNpadIdType(npad_id); | 129 | auto& controller = GetControllerFromNpadIdType(npad_id); |
| 130 | if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) { | ||
| 131 | return; | ||
| 132 | } | ||
| 133 | LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); | ||
| 131 | const auto controller_type = controller.device->GetNpadStyleIndex(); | 134 | const auto controller_type = controller.device->GetNpadStyleIndex(); |
| 132 | auto& shared_memory = controller.shared_memory_entry; | 135 | auto& shared_memory = controller.shared_memory_entry; |
| 133 | if (controller_type == Core::HID::NpadStyleIndex::None) { | 136 | if (controller_type == Core::HID::NpadStyleIndex::None) { |
| @@ -147,7 +150,6 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | |||
| 147 | shared_memory.system_properties.is_vertical.Assign(1); | 150 | shared_memory.system_properties.is_vertical.Assign(1); |
| 148 | shared_memory.system_properties.use_plus.Assign(1); | 151 | shared_memory.system_properties.use_plus.Assign(1); |
| 149 | shared_memory.system_properties.use_minus.Assign(1); | 152 | shared_memory.system_properties.use_minus.Assign(1); |
| 150 | shared_memory.assignment_mode = NpadJoyAssignmentMode::Single; | ||
| 151 | shared_memory.applet_footer.type = AppletFooterUiType::SwitchProController; | 153 | shared_memory.applet_footer.type = AppletFooterUiType::SwitchProController; |
| 152 | break; | 154 | break; |
| 153 | case Core::HID::NpadStyleIndex::Handheld: | 155 | case Core::HID::NpadStyleIndex::Handheld: |
| @@ -163,21 +165,30 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | |||
| 163 | break; | 165 | break; |
| 164 | case Core::HID::NpadStyleIndex::JoyconDual: | 166 | case Core::HID::NpadStyleIndex::JoyconDual: |
| 165 | shared_memory.style_tag.joycon_dual.Assign(1); | 167 | shared_memory.style_tag.joycon_dual.Assign(1); |
| 166 | shared_memory.device_type.joycon_left.Assign(1); | 168 | if (controller.is_dual_left_connected) { |
| 167 | shared_memory.device_type.joycon_right.Assign(1); | 169 | shared_memory.device_type.joycon_left.Assign(1); |
| 168 | shared_memory.system_properties.is_vertical.Assign(1); | 170 | shared_memory.system_properties.use_minus.Assign(1); |
| 169 | shared_memory.system_properties.use_plus.Assign(1); | 171 | } |
| 170 | shared_memory.system_properties.use_minus.Assign(1); | 172 | if (controller.is_dual_right_connected) { |
| 173 | shared_memory.device_type.joycon_right.Assign(1); | ||
| 174 | shared_memory.system_properties.use_plus.Assign(1); | ||
| 175 | } | ||
| 171 | shared_memory.system_properties.use_directional_buttons.Assign(1); | 176 | shared_memory.system_properties.use_directional_buttons.Assign(1); |
| 177 | shared_memory.system_properties.is_vertical.Assign(1); | ||
| 172 | shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual; | 178 | shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual; |
| 173 | shared_memory.applet_footer.type = AppletFooterUiType::JoyDual; | 179 | if (controller.is_dual_left_connected && controller.is_dual_right_connected) { |
| 180 | shared_memory.applet_footer.type = AppletFooterUiType::JoyDual; | ||
| 181 | } else if (controller.is_dual_left_connected) { | ||
| 182 | shared_memory.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly; | ||
| 183 | } else { | ||
| 184 | shared_memory.applet_footer.type = AppletFooterUiType::JoyDualRightOnly; | ||
| 185 | } | ||
| 174 | break; | 186 | break; |
| 175 | case Core::HID::NpadStyleIndex::JoyconLeft: | 187 | case Core::HID::NpadStyleIndex::JoyconLeft: |
| 176 | shared_memory.style_tag.joycon_left.Assign(1); | 188 | shared_memory.style_tag.joycon_left.Assign(1); |
| 177 | shared_memory.device_type.joycon_left.Assign(1); | 189 | shared_memory.device_type.joycon_left.Assign(1); |
| 178 | shared_memory.system_properties.is_horizontal.Assign(1); | 190 | shared_memory.system_properties.is_horizontal.Assign(1); |
| 179 | shared_memory.system_properties.use_minus.Assign(1); | 191 | shared_memory.system_properties.use_minus.Assign(1); |
| 180 | shared_memory.assignment_mode = NpadJoyAssignmentMode::Single; | ||
| 181 | shared_memory.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal; | 192 | shared_memory.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal; |
| 182 | break; | 193 | break; |
| 183 | case Core::HID::NpadStyleIndex::JoyconRight: | 194 | case Core::HID::NpadStyleIndex::JoyconRight: |
| @@ -185,7 +196,6 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | |||
| 185 | shared_memory.device_type.joycon_right.Assign(1); | 196 | shared_memory.device_type.joycon_right.Assign(1); |
| 186 | shared_memory.system_properties.is_horizontal.Assign(1); | 197 | shared_memory.system_properties.is_horizontal.Assign(1); |
| 187 | shared_memory.system_properties.use_plus.Assign(1); | 198 | shared_memory.system_properties.use_plus.Assign(1); |
| 188 | shared_memory.assignment_mode = NpadJoyAssignmentMode::Single; | ||
| 189 | shared_memory.applet_footer.type = AppletFooterUiType::JoyRightHorizontal; | 199 | shared_memory.applet_footer.type = AppletFooterUiType::JoyRightHorizontal; |
| 190 | break; | 200 | break; |
| 191 | case Core::HID::NpadStyleIndex::GameCube: | 201 | case Core::HID::NpadStyleIndex::GameCube: |
| @@ -197,7 +207,6 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { | |||
| 197 | case Core::HID::NpadStyleIndex::Pokeball: | 207 | case Core::HID::NpadStyleIndex::Pokeball: |
| 198 | shared_memory.style_tag.palma.Assign(1); | 208 | shared_memory.style_tag.palma.Assign(1); |
| 199 | shared_memory.device_type.palma.Assign(1); | 209 | shared_memory.device_type.palma.Assign(1); |
| 200 | shared_memory.assignment_mode = NpadJoyAssignmentMode::Single; | ||
| 201 | break; | 210 | break; |
| 202 | case Core::HID::NpadStyleIndex::NES: | 211 | case Core::HID::NpadStyleIndex::NES: |
| 203 | shared_memory.style_tag.lark.Assign(1); | 212 | shared_memory.style_tag.lark.Assign(1); |
| @@ -255,19 +264,7 @@ void Controller_NPad::OnInit() { | |||
| 255 | 264 | ||
| 256 | if (hid_core.GetSupportedStyleTag().raw == Core::HID::NpadStyleSet::None) { | 265 | if (hid_core.GetSupportedStyleTag().raw == Core::HID::NpadStyleSet::None) { |
| 257 | // We want to support all controllers | 266 | // We want to support all controllers |
| 258 | Core::HID::NpadStyleTag style{}; | 267 | hid_core.SetSupportedStyleTag({Core::HID::NpadStyleSet::All}); |
| 259 | style.handheld.Assign(1); | ||
| 260 | style.joycon_left.Assign(1); | ||
| 261 | style.joycon_right.Assign(1); | ||
| 262 | style.joycon_dual.Assign(1); | ||
| 263 | style.fullkey.Assign(1); | ||
| 264 | style.gamecube.Assign(1); | ||
| 265 | style.palma.Assign(1); | ||
| 266 | style.lark.Assign(1); | ||
| 267 | style.lucia.Assign(1); | ||
| 268 | style.lagoon.Assign(1); | ||
| 269 | style.lager.Assign(1); | ||
| 270 | hid_core.SetSupportedStyleTag(style); | ||
| 271 | } | 268 | } |
| 272 | 269 | ||
| 273 | supported_npad_id_types.resize(npad_id_list.size()); | 270 | supported_npad_id_types.resize(npad_id_list.size()); |
| @@ -452,11 +449,15 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 452 | case Core::HID::NpadStyleIndex::JoyconDual: | 449 | case Core::HID::NpadStyleIndex::JoyconDual: |
| 453 | pad_state.connection_status.raw = 0; | 450 | pad_state.connection_status.raw = 0; |
| 454 | pad_state.connection_status.is_connected.Assign(1); | 451 | pad_state.connection_status.is_connected.Assign(1); |
| 455 | pad_state.connection_status.is_left_connected.Assign(1); | 452 | if (controller.is_dual_left_connected) { |
| 456 | pad_state.connection_status.is_right_connected.Assign(1); | 453 | pad_state.connection_status.is_left_connected.Assign(1); |
| 454 | libnx_state.connection_status.is_left_connected.Assign(1); | ||
| 455 | } | ||
| 456 | if (controller.is_dual_right_connected) { | ||
| 457 | pad_state.connection_status.is_right_connected.Assign(1); | ||
| 458 | libnx_state.connection_status.is_right_connected.Assign(1); | ||
| 459 | } | ||
| 457 | 460 | ||
| 458 | libnx_state.connection_status.is_left_connected.Assign(1); | ||
| 459 | libnx_state.connection_status.is_right_connected.Assign(1); | ||
| 460 | pad_state.sampling_number = | 461 | pad_state.sampling_number = |
| 461 | npad.joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1; | 462 | npad.joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 462 | npad.joy_dual_lifo.WriteNextEntry(pad_state); | 463 | npad.joy_dual_lifo.WriteNextEntry(pad_state); |
| @@ -696,7 +697,7 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode | |||
| 696 | return communication_mode; | 697 | return communication_mode; |
| 697 | } | 698 | } |
| 698 | 699 | ||
| 699 | void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, | 700 | void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type, |
| 700 | NpadJoyAssignmentMode assignment_mode) { | 701 | NpadJoyAssignmentMode assignment_mode) { |
| 701 | if (!IsNpadIdValid(npad_id)) { | 702 | if (!IsNpadIdValid(npad_id)) { |
| 702 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); | 703 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); |
| @@ -707,6 +708,62 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, | |||
| 707 | if (controller.shared_memory_entry.assignment_mode != assignment_mode) { | 708 | if (controller.shared_memory_entry.assignment_mode != assignment_mode) { |
| 708 | controller.shared_memory_entry.assignment_mode = assignment_mode; | 709 | controller.shared_memory_entry.assignment_mode = assignment_mode; |
| 709 | } | 710 | } |
| 711 | |||
| 712 | if (!controller.device->IsConnected()) { | ||
| 713 | return; | ||
| 714 | } | ||
| 715 | |||
| 716 | if (assignment_mode == NpadJoyAssignmentMode::Dual) { | ||
| 717 | if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft) { | ||
| 718 | DisconnectNpad(npad_id); | ||
| 719 | controller.is_dual_left_connected = true; | ||
| 720 | controller.is_dual_right_connected = false; | ||
| 721 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); | ||
| 722 | return; | ||
| 723 | } | ||
| 724 | if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) { | ||
| 725 | DisconnectNpad(npad_id); | ||
| 726 | controller.is_dual_left_connected = false; | ||
| 727 | controller.is_dual_right_connected = true; | ||
| 728 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); | ||
| 729 | return; | ||
| 730 | } | ||
| 731 | return; | ||
| 732 | } | ||
| 733 | |||
| 734 | // This is for NpadJoyAssignmentMode::Single | ||
| 735 | |||
| 736 | // Only JoyconDual get affected by this function | ||
| 737 | if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) { | ||
| 738 | return; | ||
| 739 | } | ||
| 740 | |||
| 741 | if (controller.is_dual_left_connected && !controller.is_dual_right_connected) { | ||
| 742 | DisconnectNpad(npad_id); | ||
| 743 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); | ||
| 744 | return; | ||
| 745 | } | ||
| 746 | if (!controller.is_dual_left_connected && controller.is_dual_right_connected) { | ||
| 747 | DisconnectNpad(npad_id); | ||
| 748 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); | ||
| 749 | return; | ||
| 750 | } | ||
| 751 | |||
| 752 | // We have two controllers connected to the same npad_id we need to split them | ||
| 753 | const auto npad_id_2 = hid_core.GetFirstDisconnectedNpadId(); | ||
| 754 | auto& controller_2 = GetControllerFromNpadIdType(npad_id_2); | ||
| 755 | DisconnectNpad(npad_id); | ||
| 756 | if (npad_device_type == NpadJoyDeviceType::Left) { | ||
| 757 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); | ||
| 758 | controller_2.is_dual_left_connected = false; | ||
| 759 | controller_2.is_dual_right_connected = true; | ||
| 760 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true); | ||
| 761 | } else { | ||
| 762 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); | ||
| 763 | controller_2.is_dual_left_connected = true; | ||
| 764 | controller_2.is_dual_right_connected = false; | ||
| 765 | UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true); | ||
| 766 | } | ||
| 710 | } | 767 | } |
| 711 | 768 | ||
| 712 | bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, | 769 | bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, |
| @@ -916,6 +973,7 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { | |||
| 916 | } | 973 | } |
| 917 | 974 | ||
| 918 | auto& shared_memory_entry = controller.shared_memory_entry; | 975 | auto& shared_memory_entry = controller.shared_memory_entry; |
| 976 | // Don't reset shared_memory_entry.assignment_mode this value is persistent | ||
| 919 | shared_memory_entry.style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out | 977 | shared_memory_entry.style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out |
| 920 | shared_memory_entry.device_type.raw = 0; | 978 | shared_memory_entry.device_type.raw = 0; |
| 921 | shared_memory_entry.system_properties.raw = 0; | 979 | shared_memory_entry.system_properties.raw = 0; |
| @@ -932,9 +990,10 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { | |||
| 932 | .left = {}, | 990 | .left = {}, |
| 933 | .right = {}, | 991 | .right = {}, |
| 934 | }; | 992 | }; |
| 935 | shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual; | ||
| 936 | shared_memory_entry.applet_footer.type = AppletFooterUiType::None; | 993 | shared_memory_entry.applet_footer.type = AppletFooterUiType::None; |
| 937 | 994 | ||
| 995 | controller.is_dual_left_connected = true; | ||
| 996 | controller.is_dual_right_connected = true; | ||
| 938 | controller.is_connected = false; | 997 | controller.is_connected = false; |
| 939 | controller.device->Disconnect(); | 998 | controller.device->Disconnect(); |
| 940 | SignalStyleSetChangedEvent(npad_id); | 999 | SignalStyleSetChangedEvent(npad_id); |
| @@ -1031,19 +1090,70 @@ void Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, | |||
| 1031 | npad_id_2); | 1090 | npad_id_2); |
| 1032 | return; | 1091 | return; |
| 1033 | } | 1092 | } |
| 1034 | auto& controller_1 = GetControllerFromNpadIdType(npad_id_1).device; | 1093 | auto& controller_1 = GetControllerFromNpadIdType(npad_id_1); |
| 1035 | auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device; | 1094 | auto& controller_2 = GetControllerFromNpadIdType(npad_id_2); |
| 1095 | const auto controller_style_1 = controller_1.device->GetNpadStyleIndex(); | ||
| 1096 | const auto controller_style_2 = controller_2.device->GetNpadStyleIndex(); | ||
| 1097 | bool merge_controllers = false; | ||
| 1036 | 1098 | ||
| 1037 | // If the controllers at both npad indices form a pair of left and right joycons, merge them. | 1099 | // If the controllers at both npad indices form a pair of left and right joycons, merge them. |
| 1038 | // Otherwise, do nothing. | 1100 | // Otherwise, do nothing. |
| 1039 | if ((controller_1->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft && | 1101 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft && |
| 1040 | controller_2->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) || | 1102 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) { |
| 1041 | (controller_2->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft && | 1103 | merge_controllers = true; |
| 1042 | controller_1->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight)) { | 1104 | } |
| 1105 | if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft && | ||
| 1106 | controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight) { | ||
| 1107 | merge_controllers = true; | ||
| 1108 | } | ||
| 1109 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1110 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight && | ||
| 1111 | controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) { | ||
| 1112 | merge_controllers = true; | ||
| 1113 | } | ||
| 1114 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1115 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft && | ||
| 1116 | !controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) { | ||
| 1117 | merge_controllers = true; | ||
| 1118 | } | ||
| 1119 | if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1120 | controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight && | ||
| 1121 | controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) { | ||
| 1122 | merge_controllers = true; | ||
| 1123 | } | ||
| 1124 | if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1125 | controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft && | ||
| 1126 | !controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) { | ||
| 1127 | merge_controllers = true; | ||
| 1128 | } | ||
| 1129 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1130 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1131 | controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected && | ||
| 1132 | !controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) { | ||
| 1133 | merge_controllers = true; | ||
| 1134 | } | ||
| 1135 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1136 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1137 | !controller_1.is_dual_left_connected && controller_1.is_dual_right_connected && | ||
| 1138 | controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) { | ||
| 1139 | merge_controllers = true; | ||
| 1140 | } | ||
| 1141 | |||
| 1142 | if (merge_controllers) { | ||
| 1043 | // Disconnect the joycon at the second id and connect the dual joycon at the first index. | 1143 | // Disconnect the joycon at the second id and connect the dual joycon at the first index. |
| 1044 | DisconnectNpad(npad_id_2); | 1144 | DisconnectNpad(npad_id_2); |
| 1145 | controller_1.is_dual_left_connected = true; | ||
| 1146 | controller_1.is_dual_right_connected = true; | ||
| 1045 | AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1); | 1147 | AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1); |
| 1148 | return; | ||
| 1046 | } | 1149 | } |
| 1150 | LOG_WARNING(Service_HID, | ||
| 1151 | "Controllers can't be merged npad_id_1:{}, npad_id_2:{}, type_1:{}, type_2:{}, " | ||
| 1152 | "dual_1(left/right):{}/{}, dual_2(left/right):{}/{}", | ||
| 1153 | npad_id_1, npad_id_2, controller_1.device->GetNpadStyleIndex(), | ||
| 1154 | controller_2.device->GetNpadStyleIndex(), controller_1.is_dual_left_connected, | ||
| 1155 | controller_1.is_dual_right_connected, controller_2.is_dual_left_connected, | ||
| 1156 | controller_2.is_dual_right_connected); | ||
| 1047 | } | 1157 | } |
| 1048 | 1158 | ||
| 1049 | void Controller_NPad::StartLRAssignmentMode() { | 1159 | void Controller_NPad::StartLRAssignmentMode() { |
| @@ -1072,13 +1182,18 @@ bool Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, | |||
| 1072 | const auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device; | 1182 | const auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device; |
| 1073 | const auto type_index_1 = controller_1->GetNpadStyleIndex(); | 1183 | const auto type_index_1 = controller_1->GetNpadStyleIndex(); |
| 1074 | const auto type_index_2 = controller_2->GetNpadStyleIndex(); | 1184 | const auto type_index_2 = controller_2->GetNpadStyleIndex(); |
| 1185 | const auto is_connected_1 = controller_1->IsConnected(); | ||
| 1186 | const auto is_connected_2 = controller_2->IsConnected(); | ||
| 1075 | 1187 | ||
| 1076 | if (!IsControllerSupported(type_index_1) || !IsControllerSupported(type_index_2)) { | 1188 | if (!IsControllerSupported(type_index_1) && is_connected_1) { |
| 1189 | return false; | ||
| 1190 | } | ||
| 1191 | if (!IsControllerSupported(type_index_2) && is_connected_2) { | ||
| 1077 | return false; | 1192 | return false; |
| 1078 | } | 1193 | } |
| 1079 | 1194 | ||
| 1080 | AddNewControllerAt(type_index_2, npad_id_1); | 1195 | UpdateControllerAt(type_index_2, npad_id_1, is_connected_2); |
| 1081 | AddNewControllerAt(type_index_1, npad_id_2); | 1196 | UpdateControllerAt(type_index_1, npad_id_2, is_connected_1); |
| 1082 | 1197 | ||
| 1083 | return true; | 1198 | return true; |
| 1084 | } | 1199 | } |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index de5fa5a64..63281cb35 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -113,7 +113,8 @@ public: | |||
| 113 | void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_); | 113 | void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_); |
| 114 | NpadCommunicationMode GetNpadCommunicationMode() const; | 114 | NpadCommunicationMode GetNpadCommunicationMode() const; |
| 115 | 115 | ||
| 116 | void SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyAssignmentMode assignment_mode); | 116 | void SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type, |
| 117 | NpadJoyAssignmentMode assignment_mode); | ||
| 117 | 118 | ||
| 118 | bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index, | 119 | bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index, |
| 119 | const Core::HID::VibrationValue& vibration_value); | 120 | const Core::HID::VibrationValue& vibration_value); |
| @@ -464,7 +465,10 @@ private: | |||
| 464 | std::array<VibrationData, 2> vibration{}; | 465 | std::array<VibrationData, 2> vibration{}; |
| 465 | bool unintended_home_button_input_protection{}; | 466 | bool unintended_home_button_input_protection{}; |
| 466 | bool is_connected{}; | 467 | bool is_connected{}; |
| 467 | Core::HID::NpadStyleIndex npad_type{Core::HID::NpadStyleIndex::None}; | 468 | |
| 469 | // Dual joycons can have only one side connected | ||
| 470 | bool is_dual_left_connected{true}; | ||
| 471 | bool is_dual_right_connected{true}; | ||
| 468 | 472 | ||
| 469 | // Motion parameters | 473 | // Motion parameters |
| 470 | bool sixaxis_at_rest{true}; | 474 | bool sixaxis_at_rest{true}; |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index b36689552..7163e1a4e 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -293,8 +293,8 @@ Hid::Hid(Core::System& system_) | |||
| 293 | {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"}, | 293 | {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"}, |
| 294 | {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, | 294 | {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, |
| 295 | {134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"}, | 295 | {134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"}, |
| 296 | {135, nullptr, "SetNpadCaptureButtonAssignment"}, | 296 | {135, &Hid::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"}, |
| 297 | {136, nullptr, "ClearNpadCaptureButtonAssignment"}, | 297 | {136, &Hid::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"}, |
| 298 | {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"}, | 298 | {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"}, |
| 299 | {201, &Hid::SendVibrationValue, "SendVibrationValue"}, | 299 | {201, &Hid::SendVibrationValue, "SendVibrationValue"}, |
| 300 | {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"}, | 300 | {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"}, |
| @@ -975,35 +975,35 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx | |||
| 975 | const auto parameters{rp.PopRaw<Parameters>()}; | 975 | const auto parameters{rp.PopRaw<Parameters>()}; |
| 976 | 976 | ||
| 977 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | 977 | applet_resource->GetController<Controller_NPad>(HidController::NPad) |
| 978 | .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyAssignmentMode::Single); | 978 | .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left, |
| 979 | Controller_NPad::NpadJoyAssignmentMode::Single); | ||
| 979 | 980 | ||
| 980 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", | 981 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, |
| 981 | parameters.npad_id, parameters.applet_resource_user_id); | 982 | parameters.applet_resource_user_id); |
| 982 | 983 | ||
| 983 | IPC::ResponseBuilder rb{ctx, 2}; | 984 | IPC::ResponseBuilder rb{ctx, 2}; |
| 984 | rb.Push(ResultSuccess); | 985 | rb.Push(ResultSuccess); |
| 985 | } | 986 | } |
| 986 | 987 | ||
| 987 | void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) { | 988 | void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) { |
| 988 | // TODO: Check the differences between this and SetNpadJoyAssignmentModeSingleByDefault | ||
| 989 | IPC::RequestParser rp{ctx}; | 989 | IPC::RequestParser rp{ctx}; |
| 990 | struct Parameters { | 990 | struct Parameters { |
| 991 | Core::HID::NpadIdType npad_id; | 991 | Core::HID::NpadIdType npad_id; |
| 992 | INSERT_PADDING_WORDS_NOINIT(1); | 992 | INSERT_PADDING_WORDS_NOINIT(1); |
| 993 | u64 applet_resource_user_id; | 993 | u64 applet_resource_user_id; |
| 994 | u64 npad_joy_device_type; | 994 | Controller_NPad::NpadJoyDeviceType npad_joy_device_type; |
| 995 | }; | 995 | }; |
| 996 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | 996 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); |
| 997 | 997 | ||
| 998 | const auto parameters{rp.PopRaw<Parameters>()}; | 998 | const auto parameters{rp.PopRaw<Parameters>()}; |
| 999 | 999 | ||
| 1000 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | 1000 | applet_resource->GetController<Controller_NPad>(HidController::NPad) |
| 1001 | .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyAssignmentMode::Single); | 1001 | .SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type, |
| 1002 | Controller_NPad::NpadJoyAssignmentMode::Single); | ||
| 1002 | 1003 | ||
| 1003 | LOG_WARNING(Service_HID, | 1004 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", |
| 1004 | "(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | 1005 | parameters.npad_id, parameters.applet_resource_user_id, |
| 1005 | parameters.npad_id, parameters.applet_resource_user_id, | 1006 | parameters.npad_joy_device_type); |
| 1006 | parameters.npad_joy_device_type); | ||
| 1007 | 1007 | ||
| 1008 | IPC::ResponseBuilder rb{ctx, 2}; | 1008 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1009 | rb.Push(ResultSuccess); | 1009 | rb.Push(ResultSuccess); |
| @@ -1021,10 +1021,10 @@ void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { | |||
| 1021 | const auto parameters{rp.PopRaw<Parameters>()}; | 1021 | const auto parameters{rp.PopRaw<Parameters>()}; |
| 1022 | 1022 | ||
| 1023 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | 1023 | applet_resource->GetController<Controller_NPad>(HidController::NPad) |
| 1024 | .SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyAssignmentMode::Dual); | 1024 | .SetNpadMode(parameters.npad_id, {}, Controller_NPad::NpadJoyAssignmentMode::Dual); |
| 1025 | 1025 | ||
| 1026 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", | 1026 | LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, |
| 1027 | parameters.npad_id, parameters.applet_resource_user_id); | 1027 | parameters.applet_resource_user_id); |
| 1028 | 1028 | ||
| 1029 | IPC::ResponseBuilder rb{ctx, 2}; | 1029 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1030 | rb.Push(ResultSuccess); | 1030 | rb.Push(ResultSuccess); |
| @@ -1186,6 +1186,37 @@ void Hid::SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx) { | |||
| 1186 | rb.Push(ResultSuccess); | 1186 | rb.Push(ResultSuccess); |
| 1187 | } | 1187 | } |
| 1188 | 1188 | ||
| 1189 | void Hid::SetNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx) { | ||
| 1190 | IPC::RequestParser rp{ctx}; | ||
| 1191 | struct Parameters { | ||
| 1192 | Core::HID::NpadStyleSet npad_styleset; | ||
| 1193 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1194 | u64 applet_resource_user_id; | ||
| 1195 | Core::HID::NpadButton button; | ||
| 1196 | }; | ||
| 1197 | static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||
| 1198 | |||
| 1199 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
| 1200 | |||
| 1201 | LOG_WARNING(Service_HID, | ||
| 1202 | "(STUBBED) called, npad_styleset={}, applet_resource_user_id={}, button={}", | ||
| 1203 | parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button); | ||
| 1204 | |||
| 1205 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1206 | rb.Push(ResultSuccess); | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | void Hid::ClearNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx) { | ||
| 1210 | IPC::RequestParser rp{ctx}; | ||
| 1211 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 1212 | |||
| 1213 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 1214 | applet_resource_user_id); | ||
| 1215 | |||
| 1216 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1217 | rb.Push(ResultSuccess); | ||
| 1218 | } | ||
| 1219 | |||
| 1189 | void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { | 1220 | void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { |
| 1190 | IPC::RequestParser rp{ctx}; | 1221 | IPC::RequestParser rp{ctx}; |
| 1191 | const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; | 1222 | const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index ab0084118..d290df161 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -136,6 +136,8 @@ private: | |||
| 136 | void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx); | 136 | void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx); |
| 137 | void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx); | 137 | void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx); |
| 138 | void SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx); | 138 | void SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx); |
| 139 | void SetNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx); | ||
| 140 | void ClearNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx); | ||
| 139 | void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); | 141 | void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); |
| 140 | void SendVibrationValue(Kernel::HLERequestContext& ctx); | 142 | void SendVibrationValue(Kernel::HLERequestContext& ctx); |
| 141 | void GetActualVibrationValue(Kernel::HLERequestContext& ctx); | 143 | void GetActualVibrationValue(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index 0d7d4ad03..8314d1ec2 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | |||
| @@ -20,8 +20,12 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& | |||
| 20 | switch (command.group) { | 20 | switch (command.group) { |
| 21 | case 0x0: | 21 | case 0x0: |
| 22 | switch (command.cmd) { | 22 | switch (command.cmd) { |
| 23 | case 0x1: | 23 | case 0x1: { |
| 24 | return Submit(input, output); | 24 | if (!fd_to_id.contains(fd)) { |
| 25 | fd_to_id[fd] = next_id++; | ||
| 26 | } | ||
| 27 | return Submit(fd, input, output); | ||
| 28 | } | ||
| 25 | case 0x2: | 29 | case 0x2: |
| 26 | return GetSyncpoint(input, output); | 30 | return GetSyncpoint(input, output); |
| 27 | case 0x3: | 31 | case 0x3: |
| @@ -66,7 +70,10 @@ void nvhost_nvdec::OnOpen(DeviceFD fd) {} | |||
| 66 | 70 | ||
| 67 | void nvhost_nvdec::OnClose(DeviceFD fd) { | 71 | void nvhost_nvdec::OnClose(DeviceFD fd) { |
| 68 | LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); | 72 | LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); |
| 69 | system.GPU().ClearCdmaInstance(); | 73 | const auto iter = fd_to_id.find(fd); |
| 74 | if (iter != fd_to_id.end()) { | ||
| 75 | system.GPU().ClearCdmaInstance(iter->second); | ||
| 76 | } | ||
| 70 | } | 77 | } |
| 71 | 78 | ||
| 72 | } // namespace Service::Nvidia::Devices | 79 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index 523d96e3a..a507c4d0a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | |||
| @@ -24,6 +24,9 @@ public: | |||
| 24 | 24 | ||
| 25 | void OnOpen(DeviceFD fd) override; | 25 | void OnOpen(DeviceFD fd) override; |
| 26 | void OnClose(DeviceFD fd) override; | 26 | void OnClose(DeviceFD fd) override; |
| 27 | |||
| 28 | private: | ||
| 29 | u32 next_id{}; | ||
| 27 | }; | 30 | }; |
| 28 | 31 | ||
| 29 | } // namespace Service::Nvidia::Devices | 32 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index e61261f98..8a05f0668 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -59,7 +59,8 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(const std::vector<u8>& input) { | |||
| 59 | return NvResult::Success; | 59 | return NvResult::Success; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u8>& output) { | 62 | NvResult nvhost_nvdec_common::Submit(DeviceFD fd, const std::vector<u8>& input, |
| 63 | std::vector<u8>& output) { | ||
| 63 | IoctlSubmit params{}; | 64 | IoctlSubmit params{}; |
| 64 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); | 65 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); |
| 65 | LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); | 66 | LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); |
| @@ -93,7 +94,7 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u | |||
| 93 | Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); | 94 | Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); |
| 94 | system.Memory().ReadBlock(object->addr + cmd_buffer.offset, cmdlist.data(), | 95 | system.Memory().ReadBlock(object->addr + cmd_buffer.offset, cmdlist.data(), |
| 95 | cmdlist.size() * sizeof(u32)); | 96 | cmdlist.size() * sizeof(u32)); |
| 96 | gpu.PushCommandBuffer(cmdlist); | 97 | gpu.PushCommandBuffer(fd_to_id[fd], cmdlist); |
| 97 | } | 98 | } |
| 98 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | 99 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); |
| 99 | // Some games expect command_buffers to be written back | 100 | // Some games expect command_buffers to be written back |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h index 351625c17..e28c54df6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h | |||
| @@ -104,13 +104,14 @@ protected: | |||
| 104 | 104 | ||
| 105 | /// Ioctl command implementations | 105 | /// Ioctl command implementations |
| 106 | NvResult SetNVMAPfd(const std::vector<u8>& input); | 106 | NvResult SetNVMAPfd(const std::vector<u8>& input); |
| 107 | NvResult Submit(const std::vector<u8>& input, std::vector<u8>& output); | 107 | NvResult Submit(DeviceFD fd, const std::vector<u8>& input, std::vector<u8>& output); |
| 108 | NvResult GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output); | 108 | NvResult GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output); |
| 109 | NvResult GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); | 109 | NvResult GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); |
| 110 | NvResult MapBuffer(const std::vector<u8>& input, std::vector<u8>& output); | 110 | NvResult MapBuffer(const std::vector<u8>& input, std::vector<u8>& output); |
| 111 | NvResult UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output); | 111 | NvResult UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output); |
| 112 | NvResult SetSubmitTimeout(const std::vector<u8>& input, std::vector<u8>& output); | 112 | NvResult SetSubmitTimeout(const std::vector<u8>& input, std::vector<u8>& output); |
| 113 | 113 | ||
| 114 | std::unordered_map<DeviceFD, u32> fd_to_id{}; | ||
| 114 | s32_le nvmap_fd{}; | 115 | s32_le nvmap_fd{}; |
| 115 | u32_le submit_timeout{}; | 116 | u32_le submit_timeout{}; |
| 116 | std::shared_ptr<nvmap> nvmap_dev; | 117 | std::shared_ptr<nvmap> nvmap_dev; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index eac4dd530..76b39806f 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | |||
| @@ -21,7 +21,10 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& i | |||
| 21 | case 0x0: | 21 | case 0x0: |
| 22 | switch (command.cmd) { | 22 | switch (command.cmd) { |
| 23 | case 0x1: | 23 | case 0x1: |
| 24 | return Submit(input, output); | 24 | if (!fd_to_id.contains(fd)) { |
| 25 | fd_to_id[fd] = next_id++; | ||
| 26 | } | ||
| 27 | return Submit(fd, input, output); | ||
| 25 | case 0x2: | 28 | case 0x2: |
| 26 | return GetSyncpoint(input, output); | 29 | return GetSyncpoint(input, output); |
| 27 | case 0x3: | 30 | case 0x3: |
| @@ -65,7 +68,10 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& i | |||
| 65 | void nvhost_vic::OnOpen(DeviceFD fd) {} | 68 | void nvhost_vic::OnOpen(DeviceFD fd) {} |
| 66 | 69 | ||
| 67 | void nvhost_vic::OnClose(DeviceFD fd) { | 70 | void nvhost_vic::OnClose(DeviceFD fd) { |
| 68 | system.GPU().ClearCdmaInstance(); | 71 | const auto iter = fd_to_id.find(fd); |
| 72 | if (iter != fd_to_id.end()) { | ||
| 73 | system.GPU().ClearCdmaInstance(iter->second); | ||
| 74 | } | ||
| 69 | } | 75 | } |
| 70 | 76 | ||
| 71 | } // namespace Service::Nvidia::Devices | 77 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index 6d7fda9d1..c9732c037 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h | |||
| @@ -23,5 +23,8 @@ public: | |||
| 23 | 23 | ||
| 24 | void OnOpen(DeviceFD fd) override; | 24 | void OnOpen(DeviceFD fd) override; |
| 25 | void OnClose(DeviceFD fd) override; | 25 | void OnClose(DeviceFD fd) override; |
| 26 | |||
| 27 | private: | ||
| 28 | u32 next_id{}; | ||
| 26 | }; | 29 | }; |
| 27 | } // namespace Service::Nvidia::Devices | 30 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h index 3294bc0e7..5ab221fc1 100644 --- a/src/core/hle/service/nvdrv/nvdata.h +++ b/src/core/hle/service/nvdrv/nvdata.h | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 1 | #pragma once | 5 | #pragma once |
| 2 | 6 | ||
| 3 | #include <array> | 7 | #include <array> |
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 1b5aca65d..b47e3bf69 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp | |||
| @@ -125,8 +125,9 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect | |||
| 125 | } | 125 | } |
| 126 | metadata.Print(); | 126 | metadata.Print(); |
| 127 | 127 | ||
| 128 | const auto static_modules = {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", | 128 | const auto static_modules = {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", |
| 129 | "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}; | 129 | "subsdk3", "subsdk4", "subsdk5", "subsdk6", "subsdk7", |
| 130 | "subsdk8", "subsdk9", "sdk"}; | ||
| 130 | 131 | ||
| 131 | // Use the NSO module loader to figure out the code layout | 132 | // Use the NSO module loader to figure out the code layout |
| 132 | std::size_t code_size{}; | 133 | std::size_t code_size{}; |
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index bc3df80c8..4c76ce1ea 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt | |||
| @@ -1,7 +1,5 @@ | |||
| 1 | add_library(shader_recompiler STATIC | 1 | add_library(shader_recompiler STATIC |
| 2 | backend/bindings.h | 2 | backend/bindings.h |
| 3 | backend/glasm/emit_context.cpp | ||
| 4 | backend/glasm/emit_context.h | ||
| 5 | backend/glasm/emit_glasm.cpp | 3 | backend/glasm/emit_glasm.cpp |
| 6 | backend/glasm/emit_glasm.h | 4 | backend/glasm/emit_glasm.h |
| 7 | backend/glasm/emit_glasm_barriers.cpp | 5 | backend/glasm/emit_glasm_barriers.cpp |
| @@ -22,10 +20,10 @@ add_library(shader_recompiler STATIC | |||
| 22 | backend/glasm/emit_glasm_special.cpp | 20 | backend/glasm/emit_glasm_special.cpp |
| 23 | backend/glasm/emit_glasm_undefined.cpp | 21 | backend/glasm/emit_glasm_undefined.cpp |
| 24 | backend/glasm/emit_glasm_warp.cpp | 22 | backend/glasm/emit_glasm_warp.cpp |
| 23 | backend/glasm/glasm_emit_context.cpp | ||
| 24 | backend/glasm/glasm_emit_context.h | ||
| 25 | backend/glasm/reg_alloc.cpp | 25 | backend/glasm/reg_alloc.cpp |
| 26 | backend/glasm/reg_alloc.h | 26 | backend/glasm/reg_alloc.h |
| 27 | backend/glsl/emit_context.cpp | ||
| 28 | backend/glsl/emit_context.h | ||
| 29 | backend/glsl/emit_glsl.cpp | 27 | backend/glsl/emit_glsl.cpp |
| 30 | backend/glsl/emit_glsl.h | 28 | backend/glsl/emit_glsl.h |
| 31 | backend/glsl/emit_glsl_atomic.cpp | 29 | backend/glsl/emit_glsl_atomic.cpp |
| @@ -47,10 +45,10 @@ add_library(shader_recompiler STATIC | |||
| 47 | backend/glsl/emit_glsl_special.cpp | 45 | backend/glsl/emit_glsl_special.cpp |
| 48 | backend/glsl/emit_glsl_undefined.cpp | 46 | backend/glsl/emit_glsl_undefined.cpp |
| 49 | backend/glsl/emit_glsl_warp.cpp | 47 | backend/glsl/emit_glsl_warp.cpp |
| 48 | backend/glsl/glsl_emit_context.cpp | ||
| 49 | backend/glsl/glsl_emit_context.h | ||
| 50 | backend/glsl/var_alloc.cpp | 50 | backend/glsl/var_alloc.cpp |
| 51 | backend/glsl/var_alloc.h | 51 | backend/glsl/var_alloc.h |
| 52 | backend/spirv/emit_context.cpp | ||
| 53 | backend/spirv/emit_context.h | ||
| 54 | backend/spirv/emit_spirv.cpp | 52 | backend/spirv/emit_spirv.cpp |
| 55 | backend/spirv/emit_spirv.h | 53 | backend/spirv/emit_spirv.h |
| 56 | backend/spirv/emit_spirv_atomic.cpp | 54 | backend/spirv/emit_spirv_atomic.cpp |
| @@ -72,6 +70,8 @@ add_library(shader_recompiler STATIC | |||
| 72 | backend/spirv/emit_spirv_special.cpp | 70 | backend/spirv/emit_spirv_special.cpp |
| 73 | backend/spirv/emit_spirv_undefined.cpp | 71 | backend/spirv/emit_spirv_undefined.cpp |
| 74 | backend/spirv/emit_spirv_warp.cpp | 72 | backend/spirv/emit_spirv_warp.cpp |
| 73 | backend/spirv/spirv_emit_context.cpp | ||
| 74 | backend/spirv/spirv_emit_context.h | ||
| 75 | environment.h | 75 | environment.h |
| 76 | exception.h | 76 | exception.h |
| 77 | frontend/ir/abstract_syntax_list.h | 77 | frontend/ir/abstract_syntax_list.h |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp index 004658546..42eff443f 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp | |||
| @@ -9,9 +9,9 @@ | |||
| 9 | #include "common/div_ceil.h" | 9 | #include "common/div_ceil.h" |
| 10 | #include "common/settings.h" | 10 | #include "common/settings.h" |
| 11 | #include "shader_recompiler/backend/bindings.h" | 11 | #include "shader_recompiler/backend/bindings.h" |
| 12 | #include "shader_recompiler/backend/glasm/emit_context.h" | ||
| 13 | #include "shader_recompiler/backend/glasm/emit_glasm.h" | 12 | #include "shader_recompiler/backend/glasm/emit_glasm.h" |
| 14 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 13 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 14 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 15 | #include "shader_recompiler/frontend/ir/ir_emitter.h" | 15 | #include "shader_recompiler/frontend/ir/ir_emitter.h" |
| 16 | #include "shader_recompiler/frontend/ir/program.h" | 16 | #include "shader_recompiler/frontend/ir/program.h" |
| 17 | #include "shader_recompiler/profile.h" | 17 | #include "shader_recompiler/profile.h" |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_barriers.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_barriers.cpp index e69de29bb..c0b97683e 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_barriers.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_barriers.cpp | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | ||
| 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 7 | |||
| 8 | namespace Shader::Backend::GLASM { | ||
| 9 | |||
| 10 | void EmitBarrier(EmitContext& ctx) { | ||
| 11 | ctx.Add("BAR;"); | ||
| 12 | } | ||
| 13 | |||
| 14 | void EmitWorkgroupMemoryBarrier(EmitContext& ctx) { | ||
| 15 | ctx.Add("MEMBAR.CTA;"); | ||
| 16 | } | ||
| 17 | |||
| 18 | void EmitDeviceMemoryBarrier(EmitContext& ctx) { | ||
| 19 | ctx.Add("MEMBAR;"); | ||
| 20 | } | ||
| 21 | |||
| 22 | } // namespace Shader::Backend::GLASM | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp index 9201ccd39..3bfcbbe65 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp | |||
| @@ -2,8 +2,8 @@ | |||
| 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 "shader_recompiler/backend/glasm/emit_context.h" | ||
| 6 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 7 | #include "shader_recompiler/frontend/ir/value.h" | 7 | #include "shader_recompiler/frontend/ir/value.h" |
| 8 | 8 | ||
| 9 | namespace Shader::Backend::GLASM { | 9 | namespace Shader::Backend::GLASM { |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp index bff0b7c1c..babbe6654 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_composite.cpp | |||
| @@ -2,8 +2,8 @@ | |||
| 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 "shader_recompiler/backend/glasm/emit_context.h" | ||
| 6 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 7 | #include "shader_recompiler/frontend/ir/value.h" | 7 | #include "shader_recompiler/frontend/ir/value.h" |
| 8 | 8 | ||
| 9 | namespace Shader::Backend::GLASM { | 9 | namespace Shader::Backend::GLASM { |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp index 02c9dc6d7..081b2c8e0 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glasm/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 8 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | #include "shader_recompiler/profile.h" | 10 | #include "shader_recompiler/profile.h" |
| 11 | #include "shader_recompiler/shader_info.h" | 11 | #include "shader_recompiler/shader_info.h" |
| @@ -335,6 +335,35 @@ void EmitSetFragDepth(EmitContext& ctx, ScalarF32 value) { | |||
| 335 | ctx.Add("MOV.F result.depth.z,{};", value); | 335 | ctx.Add("MOV.F result.depth.z,{};", value); |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst) { | ||
| 339 | ctx.Add("MOV.S {},invocation.groupid;", inst); | ||
| 340 | } | ||
| 341 | |||
| 342 | void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst) { | ||
| 343 | ctx.Add("MOV.S {},invocation.localid;", inst); | ||
| 344 | } | ||
| 345 | |||
| 346 | void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) { | ||
| 347 | ctx.Add("MOV.S {}.x,primitive_invocation.x;", inst); | ||
| 348 | } | ||
| 349 | |||
| 350 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst) { | ||
| 351 | ctx.Add("MOV.S {}.x,fragment.sampleid.x;", inst); | ||
| 352 | } | ||
| 353 | |||
| 354 | void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst) { | ||
| 355 | ctx.Add("MOV.S {}.x,fragment.helperthread.x;", inst); | ||
| 356 | } | ||
| 357 | |||
| 358 | void EmitYDirection(EmitContext& ctx, IR::Inst& inst) { | ||
| 359 | ctx.uses_y_direction = true; | ||
| 360 | ctx.Add("MOV.F {}.x,y_direction[0].w;", inst); | ||
| 361 | } | ||
| 362 | |||
| 363 | void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst) { | ||
| 364 | ctx.Add("MOV.F {}.x,scaling[0].z;", inst); | ||
| 365 | } | ||
| 366 | |||
| 338 | void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, ScalarU32 word_offset) { | 367 | void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, ScalarU32 word_offset) { |
| 339 | ctx.Add("MOV.U {},lmem[{}].x;", inst, word_offset); | 368 | ctx.Add("MOV.U {},lmem[{}].x;", inst, word_offset); |
| 340 | } | 369 | } |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_control_flow.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_control_flow.cpp index e69de29bb..8a14fc8d9 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_control_flow.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_control_flow.cpp | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | ||
| 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 7 | |||
| 8 | namespace Shader::Backend::GLASM { | ||
| 9 | |||
| 10 | void EmitJoin(EmitContext&) { | ||
| 11 | throw NotImplementedException("Join shouldn't be emitted"); | ||
| 12 | } | ||
| 13 | |||
| 14 | void EmitDemoteToHelperInvocation(EmitContext& ctx) { | ||
| 15 | ctx.Add("KIL TR.x;"); | ||
| 16 | } | ||
| 17 | |||
| 18 | } // namespace Shader::Backend::GLASM | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp index ccdf1cbc8..4cff70fe4 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glasm/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 8 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/modifiers.h" | 9 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 10 | #include "shader_recompiler/frontend/ir/value.h" | 10 | #include "shader_recompiler/frontend/ir/value.h" |
| 11 | 11 | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp index 4ed58619d..356640471 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glasm/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 8 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/modifiers.h" | 9 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 10 | #include "shader_recompiler/frontend/ir/value.h" | 10 | #include "shader_recompiler/frontend/ir/value.h" |
| 11 | 11 | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp index d325d31c7..237a5af3f 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <utility> | 5 | #include <utility> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glasm/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 8 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/modifiers.h" | 9 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 10 | #include "shader_recompiler/frontend/ir/value.h" | 10 | #include "shader_recompiler/frontend/ir/value.h" |
| 11 | 11 | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp index 8aa494a4d..f698b8b9b 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp | |||
| @@ -2,8 +2,8 @@ | |||
| 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 "shader_recompiler/backend/glasm/emit_context.h" | ||
| 6 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 7 | #include "shader_recompiler/frontend/ir/value.h" | 7 | #include "shader_recompiler/frontend/ir/value.h" |
| 8 | 8 | ||
| 9 | namespace Shader::Backend::GLASM { | 9 | namespace Shader::Backend::GLASM { |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_logical.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_logical.cpp index e69de29bb..eed7bfec2 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_logical.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_logical.cpp | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | ||
| 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 7 | |||
| 8 | namespace Shader::Backend::GLASM { | ||
| 9 | |||
| 10 | void EmitLogicalOr(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||
| 11 | ctx.Add("OR.S {},{},{};", inst, a, b); | ||
| 12 | } | ||
| 13 | |||
| 14 | void EmitLogicalAnd(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||
| 15 | ctx.Add("AND.S {},{},{};", inst, a, b); | ||
| 16 | } | ||
| 17 | |||
| 18 | void EmitLogicalXor(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||
| 19 | ctx.Add("XOR.S {},{},{};", inst, a, b); | ||
| 20 | } | ||
| 21 | |||
| 22 | void EmitLogicalNot(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) { | ||
| 23 | ctx.Add("SEQ.S {},{},0;", inst, value); | ||
| 24 | } | ||
| 25 | |||
| 26 | } // namespace Shader::Backend::GLASM | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp index af9fac7c1..f135b67f5 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glasm/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 8 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/program.h" | 9 | #include "shader_recompiler/frontend/ir/program.h" |
| 10 | #include "shader_recompiler/frontend/ir/value.h" | 10 | #include "shader_recompiler/frontend/ir/value.h" |
| 11 | #include "shader_recompiler/runtime_info.h" | 11 | #include "shader_recompiler/runtime_info.h" |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp index 681aeda8d..86287ee3f 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glasm/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 8 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/program.h" | 9 | #include "shader_recompiler/frontend/ir/program.h" |
| 10 | #include "shader_recompiler/frontend/ir/value.h" | 10 | #include "shader_recompiler/frontend/ir/value.h" |
| 11 | 11 | ||
| @@ -17,110 +17,6 @@ namespace Shader::Backend::GLASM { | |||
| 17 | 17 | ||
| 18 | #define NotImplemented() throw NotImplementedException("GLASM instruction {}", __LINE__) | 18 | #define NotImplemented() throw NotImplementedException("GLASM instruction {}", __LINE__) |
| 19 | 19 | ||
| 20 | static void DefinePhi(EmitContext& ctx, IR::Inst& phi) { | ||
| 21 | switch (phi.Type()) { | ||
| 22 | case IR::Type::U1: | ||
| 23 | case IR::Type::U32: | ||
| 24 | case IR::Type::F32: | ||
| 25 | ctx.reg_alloc.Define(phi); | ||
| 26 | break; | ||
| 27 | case IR::Type::U64: | ||
| 28 | case IR::Type::F64: | ||
| 29 | ctx.reg_alloc.LongDefine(phi); | ||
| 30 | break; | ||
| 31 | default: | ||
| 32 | throw NotImplementedException("Phi node type {}", phi.Type()); | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | void EmitPhi(EmitContext& ctx, IR::Inst& phi) { | ||
| 37 | const size_t num_args{phi.NumArgs()}; | ||
| 38 | for (size_t i = 0; i < num_args; ++i) { | ||
| 39 | ctx.reg_alloc.Consume(phi.Arg(i)); | ||
| 40 | } | ||
| 41 | if (!phi.Definition<Id>().is_valid) { | ||
| 42 | // The phi node wasn't forward defined | ||
| 43 | DefinePhi(ctx, phi); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | void EmitVoid(EmitContext&) {} | ||
| 48 | |||
| 49 | void EmitReference(EmitContext& ctx, const IR::Value& value) { | ||
| 50 | ctx.reg_alloc.Consume(value); | ||
| 51 | } | ||
| 52 | |||
| 53 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { | ||
| 54 | IR::Inst& phi{RegAlloc::AliasInst(*phi_value.Inst())}; | ||
| 55 | if (!phi.Definition<Id>().is_valid) { | ||
| 56 | // The phi node wasn't forward defined | ||
| 57 | DefinePhi(ctx, phi); | ||
| 58 | } | ||
| 59 | const Register phi_reg{ctx.reg_alloc.Consume(IR::Value{&phi})}; | ||
| 60 | const Value eval_value{ctx.reg_alloc.Consume(value)}; | ||
| 61 | |||
| 62 | if (phi_reg == eval_value) { | ||
| 63 | return; | ||
| 64 | } | ||
| 65 | switch (phi.Flags<IR::Type>()) { | ||
| 66 | case IR::Type::U1: | ||
| 67 | case IR::Type::U32: | ||
| 68 | case IR::Type::F32: | ||
| 69 | ctx.Add("MOV.S {}.x,{};", phi_reg, ScalarS32{eval_value}); | ||
| 70 | break; | ||
| 71 | case IR::Type::U64: | ||
| 72 | case IR::Type::F64: | ||
| 73 | ctx.Add("MOV.U64 {}.x,{};", phi_reg, ScalarRegister{eval_value}); | ||
| 74 | break; | ||
| 75 | default: | ||
| 76 | throw NotImplementedException("Phi node type {}", phi.Type()); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | void EmitJoin(EmitContext& ctx) { | ||
| 81 | NotImplemented(); | ||
| 82 | } | ||
| 83 | |||
| 84 | void EmitDemoteToHelperInvocation(EmitContext& ctx) { | ||
| 85 | ctx.Add("KIL TR.x;"); | ||
| 86 | } | ||
| 87 | |||
| 88 | void EmitBarrier(EmitContext& ctx) { | ||
| 89 | ctx.Add("BAR;"); | ||
| 90 | } | ||
| 91 | |||
| 92 | void EmitWorkgroupMemoryBarrier(EmitContext& ctx) { | ||
| 93 | ctx.Add("MEMBAR.CTA;"); | ||
| 94 | } | ||
| 95 | |||
| 96 | void EmitDeviceMemoryBarrier(EmitContext& ctx) { | ||
| 97 | ctx.Add("MEMBAR;"); | ||
| 98 | } | ||
| 99 | |||
| 100 | void EmitPrologue(EmitContext& ctx) { | ||
| 101 | // TODO | ||
| 102 | } | ||
| 103 | |||
| 104 | void EmitEpilogue(EmitContext& ctx) { | ||
| 105 | // TODO | ||
| 106 | } | ||
| 107 | |||
| 108 | void EmitEmitVertex(EmitContext& ctx, ScalarS32 stream) { | ||
| 109 | if (stream.type == Type::U32 && stream.imm_u32 == 0) { | ||
| 110 | ctx.Add("EMIT;"); | ||
| 111 | } else { | ||
| 112 | ctx.Add("EMITS {};", stream); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { | ||
| 117 | if (!stream.IsImmediate()) { | ||
| 118 | LOG_WARNING(Shader_GLASM, "Stream is not immediate"); | ||
| 119 | } | ||
| 120 | ctx.reg_alloc.Consume(stream); | ||
| 121 | ctx.Add("ENDPRIM;"); | ||
| 122 | } | ||
| 123 | |||
| 124 | void EmitGetRegister(EmitContext& ctx) { | 20 | void EmitGetRegister(EmitContext& ctx) { |
| 125 | NotImplemented(); | 21 | NotImplemented(); |
| 126 | } | 22 | } |
| @@ -185,55 +81,6 @@ void EmitSetOFlag(EmitContext& ctx) { | |||
| 185 | NotImplemented(); | 81 | NotImplemented(); |
| 186 | } | 82 | } |
| 187 | 83 | ||
| 188 | void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst) { | ||
| 189 | ctx.Add("MOV.S {},invocation.groupid;", inst); | ||
| 190 | } | ||
| 191 | |||
| 192 | void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst) { | ||
| 193 | ctx.Add("MOV.S {},invocation.localid;", inst); | ||
| 194 | } | ||
| 195 | |||
| 196 | void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) { | ||
| 197 | ctx.Add("MOV.S {}.x,primitive_invocation.x;", inst); | ||
| 198 | } | ||
| 199 | |||
| 200 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst) { | ||
| 201 | ctx.Add("MOV.S {}.x,fragment.sampleid.x;", inst); | ||
| 202 | } | ||
| 203 | |||
| 204 | void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst) { | ||
| 205 | ctx.Add("MOV.S {}.x,fragment.helperthread.x;", inst); | ||
| 206 | } | ||
| 207 | |||
| 208 | void EmitYDirection(EmitContext& ctx, IR::Inst& inst) { | ||
| 209 | ctx.uses_y_direction = true; | ||
| 210 | ctx.Add("MOV.F {}.x,y_direction[0].w;", inst); | ||
| 211 | } | ||
| 212 | |||
| 213 | void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst) { | ||
| 214 | ctx.Add("MOV.F {}.x,scaling[0].z;", inst); | ||
| 215 | } | ||
| 216 | |||
| 217 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) { | ||
| 218 | ctx.Add("MOV.S {}.x,0;", inst); | ||
| 219 | } | ||
| 220 | |||
| 221 | void EmitUndefU8(EmitContext& ctx, IR::Inst& inst) { | ||
| 222 | ctx.Add("MOV.S {}.x,0;", inst); | ||
| 223 | } | ||
| 224 | |||
| 225 | void EmitUndefU16(EmitContext& ctx, IR::Inst& inst) { | ||
| 226 | ctx.Add("MOV.S {}.x,0;", inst); | ||
| 227 | } | ||
| 228 | |||
| 229 | void EmitUndefU32(EmitContext& ctx, IR::Inst& inst) { | ||
| 230 | ctx.Add("MOV.S {}.x,0;", inst); | ||
| 231 | } | ||
| 232 | |||
| 233 | void EmitUndefU64(EmitContext& ctx, IR::Inst& inst) { | ||
| 234 | ctx.LongAdd("MOV.S64 {}.x,0;", inst); | ||
| 235 | } | ||
| 236 | |||
| 237 | void EmitGetZeroFromOp(EmitContext& ctx) { | 84 | void EmitGetZeroFromOp(EmitContext& ctx) { |
| 238 | NotImplemented(); | 85 | NotImplemented(); |
| 239 | } | 86 | } |
| @@ -258,20 +105,4 @@ void EmitGetInBoundsFromOp(EmitContext& ctx) { | |||
| 258 | NotImplemented(); | 105 | NotImplemented(); |
| 259 | } | 106 | } |
| 260 | 107 | ||
| 261 | void EmitLogicalOr(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||
| 262 | ctx.Add("OR.S {},{},{};", inst, a, b); | ||
| 263 | } | ||
| 264 | |||
| 265 | void EmitLogicalAnd(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||
| 266 | ctx.Add("AND.S {},{},{};", inst, a, b); | ||
| 267 | } | ||
| 268 | |||
| 269 | void EmitLogicalXor(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||
| 270 | ctx.Add("XOR.S {},{},{};", inst, a, b); | ||
| 271 | } | ||
| 272 | |||
| 273 | void EmitLogicalNot(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) { | ||
| 274 | ctx.Add("SEQ.S {},{},0;", inst, value); | ||
| 275 | } | ||
| 276 | |||
| 277 | } // namespace Shader::Backend::GLASM | 108 | } // namespace Shader::Backend::GLASM |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_select.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_select.cpp index 68fff613c..dc441c56d 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_select.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_select.cpp | |||
| @@ -3,8 +3,8 @@ | |||
| 3 | // Licensed under GPLv2 or any later version | 3 | // Licensed under GPLv2 or any later version |
| 4 | // Refer to the license.txt file included. | 4 | // Refer to the license.txt file included. |
| 5 | 5 | ||
| 6 | #include "shader_recompiler/backend/glasm/emit_context.h" | ||
| 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 6 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 7 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 8 | #include "shader_recompiler/frontend/ir/value.h" | 8 | #include "shader_recompiler/frontend/ir/value.h" |
| 9 | 9 | ||
| 10 | namespace Shader::Backend::GLASM { | 10 | namespace Shader::Backend::GLASM { |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_shared_memory.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_shared_memory.cpp index c1498f449..39e1c6c3a 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_shared_memory.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_shared_memory.cpp | |||
| @@ -3,8 +3,8 @@ | |||
| 3 | // Licensed under GPLv2 or any later version | 3 | // Licensed under GPLv2 or any later version |
| 4 | // Refer to the license.txt file included. | 4 | // Refer to the license.txt file included. |
| 5 | 5 | ||
| 6 | #include "shader_recompiler/backend/glasm/emit_context.h" | ||
| 7 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 6 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 7 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 8 | #include "shader_recompiler/frontend/ir/value.h" | 8 | #include "shader_recompiler/frontend/ir/value.h" |
| 9 | 9 | ||
| 10 | namespace Shader::Backend::GLASM { | 10 | namespace Shader::Backend::GLASM { |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_special.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_special.cpp index e69de29bb..e7a5fb13a 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_special.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_special.cpp | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | ||
| 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 7 | #include "shader_recompiler/frontend/ir/value.h" | ||
| 8 | |||
| 9 | namespace Shader::Backend::GLASM { | ||
| 10 | |||
| 11 | static void DefinePhi(EmitContext& ctx, IR::Inst& phi) { | ||
| 12 | switch (phi.Type()) { | ||
| 13 | case IR::Type::U1: | ||
| 14 | case IR::Type::U32: | ||
| 15 | case IR::Type::F32: | ||
| 16 | ctx.reg_alloc.Define(phi); | ||
| 17 | break; | ||
| 18 | case IR::Type::U64: | ||
| 19 | case IR::Type::F64: | ||
| 20 | ctx.reg_alloc.LongDefine(phi); | ||
| 21 | break; | ||
| 22 | default: | ||
| 23 | throw NotImplementedException("Phi node type {}", phi.Type()); | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | void EmitPhi(EmitContext& ctx, IR::Inst& phi) { | ||
| 28 | const size_t num_args{phi.NumArgs()}; | ||
| 29 | for (size_t i = 0; i < num_args; ++i) { | ||
| 30 | ctx.reg_alloc.Consume(phi.Arg(i)); | ||
| 31 | } | ||
| 32 | if (!phi.Definition<Id>().is_valid) { | ||
| 33 | // The phi node wasn't forward defined | ||
| 34 | DefinePhi(ctx, phi); | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | void EmitVoid(EmitContext&) {} | ||
| 39 | |||
| 40 | void EmitReference(EmitContext& ctx, const IR::Value& value) { | ||
| 41 | ctx.reg_alloc.Consume(value); | ||
| 42 | } | ||
| 43 | |||
| 44 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { | ||
| 45 | IR::Inst& phi{RegAlloc::AliasInst(*phi_value.Inst())}; | ||
| 46 | if (!phi.Definition<Id>().is_valid) { | ||
| 47 | // The phi node wasn't forward defined | ||
| 48 | DefinePhi(ctx, phi); | ||
| 49 | } | ||
| 50 | const Register phi_reg{ctx.reg_alloc.Consume(IR::Value{&phi})}; | ||
| 51 | const Value eval_value{ctx.reg_alloc.Consume(value)}; | ||
| 52 | |||
| 53 | if (phi_reg == eval_value) { | ||
| 54 | return; | ||
| 55 | } | ||
| 56 | switch (phi.Flags<IR::Type>()) { | ||
| 57 | case IR::Type::U1: | ||
| 58 | case IR::Type::U32: | ||
| 59 | case IR::Type::F32: | ||
| 60 | ctx.Add("MOV.S {}.x,{};", phi_reg, ScalarS32{eval_value}); | ||
| 61 | break; | ||
| 62 | case IR::Type::U64: | ||
| 63 | case IR::Type::F64: | ||
| 64 | ctx.Add("MOV.U64 {}.x,{};", phi_reg, ScalarRegister{eval_value}); | ||
| 65 | break; | ||
| 66 | default: | ||
| 67 | throw NotImplementedException("Phi node type {}", phi.Type()); | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | void EmitPrologue(EmitContext&) { | ||
| 72 | // TODO | ||
| 73 | } | ||
| 74 | |||
| 75 | void EmitEpilogue(EmitContext&) { | ||
| 76 | // TODO | ||
| 77 | } | ||
| 78 | |||
| 79 | void EmitEmitVertex(EmitContext& ctx, ScalarS32 stream) { | ||
| 80 | if (stream.type == Type::U32 && stream.imm_u32 == 0) { | ||
| 81 | ctx.Add("EMIT;"); | ||
| 82 | } else { | ||
| 83 | ctx.Add("EMITS {};", stream); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { | ||
| 88 | if (!stream.IsImmediate()) { | ||
| 89 | LOG_WARNING(Shader_GLASM, "Stream is not immediate"); | ||
| 90 | } | ||
| 91 | ctx.reg_alloc.Consume(stream); | ||
| 92 | ctx.Add("ENDPRIM;"); | ||
| 93 | } | ||
| 94 | |||
| 95 | } // namespace Shader::Backend::GLASM | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_undefined.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_undefined.cpp index e69de29bb..875e9d991 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_undefined.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_undefined.cpp | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | ||
| 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 7 | |||
| 8 | namespace Shader::Backend::GLASM { | ||
| 9 | |||
| 10 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) { | ||
| 11 | ctx.Add("MOV.S {}.x,0;", inst); | ||
| 12 | } | ||
| 13 | |||
| 14 | void EmitUndefU8(EmitContext& ctx, IR::Inst& inst) { | ||
| 15 | ctx.Add("MOV.S {}.x,0;", inst); | ||
| 16 | } | ||
| 17 | |||
| 18 | void EmitUndefU16(EmitContext& ctx, IR::Inst& inst) { | ||
| 19 | ctx.Add("MOV.S {}.x,0;", inst); | ||
| 20 | } | ||
| 21 | |||
| 22 | void EmitUndefU32(EmitContext& ctx, IR::Inst& inst) { | ||
| 23 | ctx.Add("MOV.S {}.x,0;", inst); | ||
| 24 | } | ||
| 25 | |||
| 26 | void EmitUndefU64(EmitContext& ctx, IR::Inst& inst) { | ||
| 27 | ctx.LongAdd("MOV.S64 {}.x,0;", inst); | ||
| 28 | } | ||
| 29 | |||
| 30 | } // namespace Shader::Backend::GLASM | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp index 544d475b4..32e0dd923 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_warp.cpp | |||
| @@ -2,8 +2,8 @@ | |||
| 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 "shader_recompiler/backend/glasm/emit_context.h" | ||
| 6 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" | 5 | #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" |
| 6 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 7 | #include "shader_recompiler/frontend/ir/value.h" | 7 | #include "shader_recompiler/frontend/ir/value.h" |
| 8 | #include "shader_recompiler/profile.h" | 8 | #include "shader_recompiler/profile.h" |
| 9 | 9 | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_context.cpp b/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp index 8fd459dfe..0401953f7 100644 --- a/src/shader_recompiler/backend/glasm/emit_context.cpp +++ b/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/bindings.h" | 7 | #include "shader_recompiler/backend/bindings.h" |
| 8 | #include "shader_recompiler/backend/glasm/emit_context.h" | ||
| 9 | #include "shader_recompiler/backend/glasm/emit_glasm.h" | 8 | #include "shader_recompiler/backend/glasm/emit_glasm.h" |
| 9 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" | ||
| 10 | #include "shader_recompiler/frontend/ir/program.h" | 10 | #include "shader_recompiler/frontend/ir/program.h" |
| 11 | #include "shader_recompiler/profile.h" | 11 | #include "shader_recompiler/profile.h" |
| 12 | #include "shader_recompiler/runtime_info.h" | 12 | #include "shader_recompiler/runtime_info.h" |
diff --git a/src/shader_recompiler/backend/glasm/emit_context.h b/src/shader_recompiler/backend/glasm/glasm_emit_context.h index 8433e5c00..8433e5c00 100644 --- a/src/shader_recompiler/backend/glasm/emit_context.h +++ b/src/shader_recompiler/backend/glasm/glasm_emit_context.h | |||
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.cpp b/src/shader_recompiler/backend/glasm/reg_alloc.cpp index 4c046db6e..201e428c1 100644 --- a/src/shader_recompiler/backend/glasm/reg_alloc.cpp +++ b/src/shader_recompiler/backend/glasm/reg_alloc.cpp | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <fmt/format.h> | 7 | #include <fmt/format.h> |
| 8 | 8 | ||
| 9 | #include "shader_recompiler/backend/glasm/emit_context.h" | 9 | #include "shader_recompiler/backend/glasm/glasm_emit_context.h" |
| 10 | #include "shader_recompiler/backend/glasm/reg_alloc.h" | 10 | #include "shader_recompiler/backend/glasm/reg_alloc.h" |
| 11 | #include "shader_recompiler/exception.h" | 11 | #include "shader_recompiler/exception.h" |
| 12 | #include "shader_recompiler/frontend/ir/value.h" | 12 | #include "shader_recompiler/frontend/ir/value.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp index 8a430d573..78b2eeaa2 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp | |||
| @@ -9,9 +9,9 @@ | |||
| 9 | 9 | ||
| 10 | #include "common/div_ceil.h" | 10 | #include "common/div_ceil.h" |
| 11 | #include "common/settings.h" | 11 | #include "common/settings.h" |
| 12 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 13 | #include "shader_recompiler/backend/glsl/emit_glsl.h" | 12 | #include "shader_recompiler/backend/glsl/emit_glsl.h" |
| 14 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 13 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 14 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 15 | #include "shader_recompiler/frontend/ir/ir_emitter.h" | 15 | #include "shader_recompiler/frontend/ir/ir_emitter.h" |
| 16 | 16 | ||
| 17 | namespace Shader::Backend::GLSL { | 17 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp index 772acc5a4..dc377b053 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_barriers.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_barriers.cpp index e1d1b558e..8a9faa394 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_barriers.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_barriers.cpp | |||
| @@ -2,8 +2,8 @@ | |||
| 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 "shader_recompiler/backend/glsl/emit_context.h" | ||
| 6 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 5 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 6 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 7 | #include "shader_recompiler/frontend/ir/value.h" | 7 | #include "shader_recompiler/frontend/ir/value.h" |
| 8 | 8 | ||
| 9 | namespace Shader::Backend::GLSL { | 9 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp index 3c1714e89..0f2668d9e 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp index 49a66e3ec..98cc57e58 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp index 4c26f3829..1920047f4 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | #include "shader_recompiler/profile.h" | 10 | #include "shader_recompiler/profile.h" |
| 11 | #include "shader_recompiler/runtime_info.h" | 11 | #include "shader_recompiler/runtime_info.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp index 53f8896be..c86465e8b 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/exception.h" | 9 | #include "shader_recompiler/exception.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp index eeae6562c..ce6ea1bb7 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp index d423bfb1b..b765a251b 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/modifiers.h" | 9 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 10 | #include "shader_recompiler/frontend/ir/value.h" | 10 | #include "shader_recompiler/frontend/ir/value.h" |
| 11 | 11 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index 2f78d0267..fae2e397a 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/modifiers.h" | 9 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 10 | #include "shader_recompiler/frontend/ir/value.h" | 10 | #include "shader_recompiler/frontend/ir/value.h" |
| 11 | #include "shader_recompiler/profile.h" | 11 | #include "shader_recompiler/profile.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp index 88c1d4c5e..44060df33 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_logical.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_logical.cpp index 338ff4bd6..742fec9cf 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_logical.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_logical.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp index e3957491f..9fd41b4fd 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | #include "shader_recompiler/profile.h" | 10 | #include "shader_recompiler/profile.h" |
| 11 | 11 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp index f420fe388..4ebdfb3bc 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | #ifdef _MSC_VER | 11 | #ifdef _MSC_VER |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp index 49fba9073..b1e486e5f 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp index 518b78f06..74ae345e5 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp index 67f9dad68..b8ddafe48 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/program.h" | 9 | #include "shader_recompiler/frontend/ir/program.h" |
| 10 | #include "shader_recompiler/frontend/ir/value.h" | 10 | #include "shader_recompiler/frontend/ir/value.h" |
| 11 | #include "shader_recompiler/profile.h" | 11 | #include "shader_recompiler/profile.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp index 15bf02dd6..cace1db85 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | 9 | ||
| 10 | namespace Shader::Backend::GLSL { | 10 | namespace Shader::Backend::GLSL { |
| 11 | 11 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp index cd285e2c8..6e01979b4 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <string_view> | 5 | #include <string_view> |
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 7 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 8 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | #include "shader_recompiler/profile.h" | 10 | #include "shader_recompiler/profile.h" |
| 11 | 11 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp index 97bd59302..1de017e76 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/bindings.h" | 5 | #include "shader_recompiler/backend/bindings.h" |
| 6 | #include "shader_recompiler/backend/glsl/emit_context.h" | 6 | #include "shader_recompiler/backend/glsl/glsl_emit_context.h" |
| 7 | #include "shader_recompiler/frontend/ir/program.h" | 7 | #include "shader_recompiler/frontend/ir/program.h" |
| 8 | #include "shader_recompiler/profile.h" | 8 | #include "shader_recompiler/profile.h" |
| 9 | #include "shader_recompiler/runtime_info.h" | 9 | #include "shader_recompiler/runtime_info.h" |
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/glsl_emit_context.h index d9b639d29..d9b639d29 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.h +++ b/src/shader_recompiler/backend/glsl/glsl_emit_context.h | |||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index d7a86e270..6ce7ed12a 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include "common/settings.h" | 11 | #include "common/settings.h" |
| 12 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 12 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 13 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 13 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 14 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 14 | #include "shader_recompiler/frontend/ir/basic_block.h" | 15 | #include "shader_recompiler/frontend/ir/basic_block.h" |
| 15 | #include "shader_recompiler/frontend/ir/program.h" | 16 | #include "shader_recompiler/frontend/ir/program.h" |
| 16 | 17 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 4b25534ce..b412957c7 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -6,13 +6,11 @@ | |||
| 6 | 6 | ||
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | 8 | ||
| 9 | #include <sirit/sirit.h> | ||
| 10 | |||
| 11 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 12 | #include "shader_recompiler/backend/bindings.h" | 10 | #include "shader_recompiler/backend/bindings.h" |
| 13 | #include "shader_recompiler/backend/spirv/emit_context.h" | ||
| 14 | #include "shader_recompiler/frontend/ir/program.h" | 11 | #include "shader_recompiler/frontend/ir/program.h" |
| 15 | #include "shader_recompiler/profile.h" | 12 | #include "shader_recompiler/profile.h" |
| 13 | #include "shader_recompiler/runtime_info.h" | ||
| 16 | 14 | ||
| 17 | namespace Shader::Backend::SPIRV { | 15 | namespace Shader::Backend::SPIRV { |
| 18 | 16 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp index 9af8bb9e1..0d37b405c 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | namespace { | 10 | namespace { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp index e0b52a001..9ce95a41b 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | #include "shader_recompiler/frontend/ir/modifiers.h" | 8 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 8 | 9 | ||
| 9 | namespace Shader::Backend::SPIRV { | 10 | namespace Shader::Backend::SPIRV { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp index bb11f4f4e..02d1e63f7 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_bitwise_conversion.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | 10 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp index 10ff4ecab..5c3e1ee2b 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | #include "shader_recompiler/frontend/ir/modifiers.h" | 8 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 8 | 9 | ||
| 9 | namespace Shader::Backend::SPIRV { | 10 | namespace Shader::Backend::SPIRV { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index bac683ae1..ad84966b5 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 8 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 9 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 9 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 10 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 10 | 11 | ||
| 11 | namespace Shader::Backend::SPIRV { | 12 | namespace Shader::Backend::SPIRV { |
| 12 | namespace { | 13 | namespace { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp index d33486f28..1eca3aa85 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | 10 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp index fd42b7a16..832de2452 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_convert.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | namespace { | 10 | namespace { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp index 61cf25f9c..0cdc46495 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_floating_point.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | #include "shader_recompiler/frontend/ir/modifiers.h" | 8 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 8 | 9 | ||
| 9 | namespace Shader::Backend::SPIRV { | 10 | namespace Shader::Backend::SPIRV { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 4d168a96d..d18d5f1d5 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 7 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 8 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 8 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 9 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/modifiers.h" | 10 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 10 | 11 | ||
| 11 | namespace Shader::Backend::SPIRV { | 12 | namespace Shader::Backend::SPIRV { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp index d7f1a365a..a96190bc6 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | #include "shader_recompiler/frontend/ir/modifiers.h" | 8 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 8 | 9 | ||
| 9 | namespace Shader::Backend::SPIRV { | 10 | namespace Shader::Backend::SPIRV { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp index 50277eec3..44521f539 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | namespace { | 10 | namespace { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp index b9a9500fc..47745f7ee 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | 10 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp index 679ee2684..175f4be19 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_memory.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 7 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 8 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 8 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 9 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 9 | 10 | ||
| 10 | namespace Shader::Backend::SPIRV { | 11 | namespace Shader::Backend::SPIRV { |
| 11 | namespace { | 12 | namespace { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp index c5b4f4720..48caf1ffc 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_select.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | 10 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp index 9a79fc7a2..330c9052c 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | namespace { | 10 | namespace { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp index 9e7eb3cb1..d96a17583 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | namespace { | 10 | namespace { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp index c9f469e90..b5766fc52 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_undefined.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | 10 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp index cef52c56e..7034228bf 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 5 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" | 6 | #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" |
| 7 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 7 | 8 | ||
| 8 | namespace Shader::Backend::SPIRV { | 9 | namespace Shader::Backend::SPIRV { |
| 9 | namespace { | 10 | namespace { |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 723455462..4b6f792bf 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | |||
| @@ -13,8 +13,8 @@ | |||
| 13 | 13 | ||
| 14 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 15 | #include "common/div_ceil.h" | 15 | #include "common/div_ceil.h" |
| 16 | #include "shader_recompiler/backend/spirv/emit_context.h" | ||
| 17 | #include "shader_recompiler/backend/spirv/emit_spirv.h" | 16 | #include "shader_recompiler/backend/spirv/emit_spirv.h" |
| 17 | #include "shader_recompiler/backend/spirv/spirv_emit_context.h" | ||
| 18 | 18 | ||
| 19 | namespace Shader::Backend::SPIRV { | 19 | namespace Shader::Backend::SPIRV { |
| 20 | namespace { | 20 | namespace { |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index 63f8185d9..63f8185d9 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h | |||
diff --git a/src/shader_recompiler/environment.h b/src/shader_recompiler/environment.h index 8369d0d84..b4df73e8a 100644 --- a/src/shader_recompiler/environment.h +++ b/src/shader_recompiler/environment.h | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 1 | #pragma once | 5 | #pragma once |
| 2 | 6 | ||
| 3 | #include <array> | 7 | #include <array> |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index ab7c21a49..8788f5148 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -185,16 +185,6 @@ struct GPU::Impl { | |||
| 185 | return *dma_pusher; | 185 | return *dma_pusher; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | /// Returns a reference to the GPU CDMA pusher. | ||
| 189 | [[nodiscard]] Tegra::CDmaPusher& CDmaPusher() { | ||
| 190 | return *cdma_pusher; | ||
| 191 | } | ||
| 192 | |||
| 193 | /// Returns a const reference to the GPU CDMA pusher. | ||
| 194 | [[nodiscard]] const Tegra::CDmaPusher& CDmaPusher() const { | ||
| 195 | return *cdma_pusher; | ||
| 196 | } | ||
| 197 | |||
| 198 | /// Returns a reference to the underlying renderer. | 188 | /// Returns a reference to the underlying renderer. |
| 199 | [[nodiscard]] VideoCore::RendererBase& Renderer() { | 189 | [[nodiscard]] VideoCore::RendererBase& Renderer() { |
| 200 | return *renderer; | 190 | return *renderer; |
| @@ -338,25 +328,27 @@ struct GPU::Impl { | |||
| 338 | } | 328 | } |
| 339 | 329 | ||
| 340 | /// Push GPU command buffer entries to be processed | 330 | /// Push GPU command buffer entries to be processed |
| 341 | void PushCommandBuffer(Tegra::ChCommandHeaderList& entries) { | 331 | void PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries) { |
| 342 | if (!use_nvdec) { | 332 | if (!use_nvdec) { |
| 343 | return; | 333 | return; |
| 344 | } | 334 | } |
| 345 | 335 | ||
| 346 | if (!cdma_pusher) { | 336 | if (!cdma_pushers.contains(id)) { |
| 347 | cdma_pusher = std::make_unique<Tegra::CDmaPusher>(gpu); | 337 | cdma_pushers.insert_or_assign(id, std::make_unique<Tegra::CDmaPusher>(gpu)); |
| 348 | } | 338 | } |
| 349 | 339 | ||
| 350 | // SubmitCommandBuffer would make the nvdec operations async, this is not currently working | 340 | // SubmitCommandBuffer would make the nvdec operations async, this is not currently working |
| 351 | // TODO(ameerj): RE proper async nvdec operation | 341 | // TODO(ameerj): RE proper async nvdec operation |
| 352 | // gpu_thread.SubmitCommandBuffer(std::move(entries)); | 342 | // gpu_thread.SubmitCommandBuffer(std::move(entries)); |
| 353 | 343 | cdma_pushers[id]->ProcessEntries(std::move(entries)); | |
| 354 | cdma_pusher->ProcessEntries(std::move(entries)); | ||
| 355 | } | 344 | } |
| 356 | 345 | ||
| 357 | /// Frees the CDMAPusher instance to free up resources | 346 | /// Frees the CDMAPusher instance to free up resources |
| 358 | void ClearCdmaInstance() { | 347 | void ClearCdmaInstance(u32 id) { |
| 359 | cdma_pusher.reset(); | 348 | const auto iter = cdma_pushers.find(id); |
| 349 | if (iter != cdma_pushers.end()) { | ||
| 350 | cdma_pushers.erase(iter); | ||
| 351 | } | ||
| 360 | } | 352 | } |
| 361 | 353 | ||
| 362 | /// Swap buffers (render frame) | 354 | /// Swap buffers (render frame) |
| @@ -659,7 +651,7 @@ struct GPU::Impl { | |||
| 659 | Core::System& system; | 651 | Core::System& system; |
| 660 | std::unique_ptr<Tegra::MemoryManager> memory_manager; | 652 | std::unique_ptr<Tegra::MemoryManager> memory_manager; |
| 661 | std::unique_ptr<Tegra::DmaPusher> dma_pusher; | 653 | std::unique_ptr<Tegra::DmaPusher> dma_pusher; |
| 662 | std::unique_ptr<Tegra::CDmaPusher> cdma_pusher; | 654 | std::map<u32, std::unique_ptr<Tegra::CDmaPusher>> cdma_pushers; |
| 663 | std::unique_ptr<VideoCore::RendererBase> renderer; | 655 | std::unique_ptr<VideoCore::RendererBase> renderer; |
| 664 | VideoCore::RasterizerInterface* rasterizer = nullptr; | 656 | VideoCore::RasterizerInterface* rasterizer = nullptr; |
| 665 | const bool use_nvdec; | 657 | const bool use_nvdec; |
| @@ -811,14 +803,6 @@ const Tegra::DmaPusher& GPU::DmaPusher() const { | |||
| 811 | return impl->DmaPusher(); | 803 | return impl->DmaPusher(); |
| 812 | } | 804 | } |
| 813 | 805 | ||
| 814 | Tegra::CDmaPusher& GPU::CDmaPusher() { | ||
| 815 | return impl->CDmaPusher(); | ||
| 816 | } | ||
| 817 | |||
| 818 | const Tegra::CDmaPusher& GPU::CDmaPusher() const { | ||
| 819 | return impl->CDmaPusher(); | ||
| 820 | } | ||
| 821 | |||
| 822 | VideoCore::RendererBase& GPU::Renderer() { | 806 | VideoCore::RendererBase& GPU::Renderer() { |
| 823 | return impl->Renderer(); | 807 | return impl->Renderer(); |
| 824 | } | 808 | } |
| @@ -887,12 +871,12 @@ void GPU::PushGPUEntries(Tegra::CommandList&& entries) { | |||
| 887 | impl->PushGPUEntries(std::move(entries)); | 871 | impl->PushGPUEntries(std::move(entries)); |
| 888 | } | 872 | } |
| 889 | 873 | ||
| 890 | void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) { | 874 | void GPU::PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries) { |
| 891 | impl->PushCommandBuffer(entries); | 875 | impl->PushCommandBuffer(id, entries); |
| 892 | } | 876 | } |
| 893 | 877 | ||
| 894 | void GPU::ClearCdmaInstance() { | 878 | void GPU::ClearCdmaInstance(u32 id) { |
| 895 | impl->ClearCdmaInstance(); | 879 | impl->ClearCdmaInstance(id); |
| 896 | } | 880 | } |
| 897 | 881 | ||
| 898 | void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | 882 | void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index c89a5d693..500411176 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -242,10 +242,10 @@ public: | |||
| 242 | void PushGPUEntries(Tegra::CommandList&& entries); | 242 | void PushGPUEntries(Tegra::CommandList&& entries); |
| 243 | 243 | ||
| 244 | /// Push GPU command buffer entries to be processed | 244 | /// Push GPU command buffer entries to be processed |
| 245 | void PushCommandBuffer(Tegra::ChCommandHeaderList& entries); | 245 | void PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries); |
| 246 | 246 | ||
| 247 | /// Frees the CDMAPusher instance to free up resources | 247 | /// Frees the CDMAPusher instance to free up resources |
| 248 | void ClearCdmaInstance(); | 248 | void ClearCdmaInstance(u32 id); |
| 249 | 249 | ||
| 250 | /// Swap buffers (render frame) | 250 | /// Swap buffers (render frame) |
| 251 | void SwapBuffers(const Tegra::FramebufferConfig* framebuffer); | 251 | void SwapBuffers(const Tegra::FramebufferConfig* framebuffer); |
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 31adada56..e38cfbc6c 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp | |||
| @@ -162,7 +162,7 @@ struct FormatTuple { | |||
| 162 | {VK_FORMAT_UNDEFINED}, // R16_SINT | 162 | {VK_FORMAT_UNDEFINED}, // R16_SINT |
| 163 | {VK_FORMAT_R16G16_UNORM, Attachable | Storage}, // R16G16_UNORM | 163 | {VK_FORMAT_R16G16_UNORM, Attachable | Storage}, // R16G16_UNORM |
| 164 | {VK_FORMAT_R16G16_SFLOAT, Attachable | Storage}, // R16G16_FLOAT | 164 | {VK_FORMAT_R16G16_SFLOAT, Attachable | Storage}, // R16G16_FLOAT |
| 165 | {VK_FORMAT_UNDEFINED}, // R16G16_UINT | 165 | {VK_FORMAT_R16G16_UINT, Attachable | Storage}, // R16G16_UINT |
| 166 | {VK_FORMAT_R16G16_SINT, Attachable | Storage}, // R16G16_SINT | 166 | {VK_FORMAT_R16G16_SINT, Attachable | Storage}, // R16G16_SINT |
| 167 | {VK_FORMAT_R16G16_SNORM, Attachable | Storage}, // R16G16_SNORM | 167 | {VK_FORMAT_R16G16_SNORM, Attachable | Storage}, // R16G16_SNORM |
| 168 | {VK_FORMAT_UNDEFINED}, // R32G32B32_FLOAT | 168 | {VK_FORMAT_UNDEFINED}, // R32G32B32_FLOAT |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 70c52aaac..7bf5b6578 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -130,6 +130,7 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::Physica | |||
| 130 | VK_FORMAT_R16G16_UNORM, | 130 | VK_FORMAT_R16G16_UNORM, |
| 131 | VK_FORMAT_R16G16_SNORM, | 131 | VK_FORMAT_R16G16_SNORM, |
| 132 | VK_FORMAT_R16G16_SFLOAT, | 132 | VK_FORMAT_R16G16_SFLOAT, |
| 133 | VK_FORMAT_R16G16_UINT, | ||
| 133 | VK_FORMAT_R16G16_SINT, | 134 | VK_FORMAT_R16G16_SINT, |
| 134 | VK_FORMAT_R16_UNORM, | 135 | VK_FORMAT_R16_UNORM, |
| 135 | VK_FORMAT_R16_SNORM, | 136 | VK_FORMAT_R16_SNORM, |
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 34099bc83..8a8be8e40 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -907,88 +907,79 @@ void ConfigureInputPlayer::UpdateUI() { | |||
| 907 | } | 907 | } |
| 908 | 908 | ||
| 909 | void ConfigureInputPlayer::SetConnectableControllers() { | 909 | void ConfigureInputPlayer::SetConnectableControllers() { |
| 910 | const auto add_controllers = [this](bool enable_all, | 910 | Core::HID::NpadStyleTag npad_style_set = hid_core.GetSupportedStyleTag(); |
| 911 | Core::HID::NpadStyleTag npad_style_set = {}) { | 911 | index_controller_type_pairs.clear(); |
| 912 | index_controller_type_pairs.clear(); | 912 | ui->comboControllerType->clear(); |
| 913 | ui->comboControllerType->clear(); | ||
| 914 | |||
| 915 | if (enable_all || npad_style_set.fullkey == 1) { | ||
| 916 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | ||
| 917 | Core::HID::NpadStyleIndex::ProController); | ||
| 918 | ui->comboControllerType->addItem(tr("Pro Controller")); | ||
| 919 | } | ||
| 920 | |||
| 921 | if (enable_all || npad_style_set.joycon_dual == 1) { | ||
| 922 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | ||
| 923 | Core::HID::NpadStyleIndex::JoyconDual); | ||
| 924 | ui->comboControllerType->addItem(tr("Dual Joycons")); | ||
| 925 | } | ||
| 926 | 913 | ||
| 927 | if (enable_all || npad_style_set.joycon_left == 1) { | 914 | if (npad_style_set.fullkey == 1) { |
| 928 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | 915 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), |
| 929 | Core::HID::NpadStyleIndex::JoyconLeft); | 916 | Core::HID::NpadStyleIndex::ProController); |
| 930 | ui->comboControllerType->addItem(tr("Left Joycon")); | 917 | ui->comboControllerType->addItem(tr("Pro Controller")); |
| 931 | } | 918 | } |
| 932 | 919 | ||
| 933 | if (enable_all || npad_style_set.joycon_right == 1) { | 920 | if (npad_style_set.joycon_dual == 1) { |
| 934 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | 921 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), |
| 935 | Core::HID::NpadStyleIndex::JoyconRight); | 922 | Core::HID::NpadStyleIndex::JoyconDual); |
| 936 | ui->comboControllerType->addItem(tr("Right Joycon")); | 923 | ui->comboControllerType->addItem(tr("Dual Joycons")); |
| 937 | } | 924 | } |
| 938 | 925 | ||
| 939 | if (player_index == 0 && (enable_all || npad_style_set.handheld == 1)) { | 926 | if (npad_style_set.joycon_left == 1) { |
| 940 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | 927 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), |
| 941 | Core::HID::NpadStyleIndex::Handheld); | 928 | Core::HID::NpadStyleIndex::JoyconLeft); |
| 942 | ui->comboControllerType->addItem(tr("Handheld")); | 929 | ui->comboControllerType->addItem(tr("Left Joycon")); |
| 943 | } | 930 | } |
| 944 | 931 | ||
| 945 | if (enable_all || npad_style_set.gamecube == 1) { | 932 | if (npad_style_set.joycon_right == 1) { |
| 946 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | 933 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), |
| 947 | Core::HID::NpadStyleIndex::GameCube); | 934 | Core::HID::NpadStyleIndex::JoyconRight); |
| 948 | ui->comboControllerType->addItem(tr("GameCube Controller")); | 935 | ui->comboControllerType->addItem(tr("Right Joycon")); |
| 949 | } | 936 | } |
| 950 | 937 | ||
| 951 | // Disable all unsupported controllers | 938 | if (player_index == 0 && npad_style_set.handheld == 1) { |
| 952 | if (!Settings::values.enable_all_controllers) { | 939 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), |
| 953 | return; | 940 | Core::HID::NpadStyleIndex::Handheld); |
| 954 | } | 941 | ui->comboControllerType->addItem(tr("Handheld")); |
| 955 | if (enable_all || npad_style_set.palma == 1) { | 942 | } |
| 956 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | ||
| 957 | Core::HID::NpadStyleIndex::Pokeball); | ||
| 958 | ui->comboControllerType->addItem(tr("Poke Ball Plus")); | ||
| 959 | } | ||
| 960 | 943 | ||
| 961 | if (enable_all || npad_style_set.lark == 1) { | 944 | if (npad_style_set.gamecube == 1) { |
| 962 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | 945 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), |
| 963 | Core::HID::NpadStyleIndex::NES); | 946 | Core::HID::NpadStyleIndex::GameCube); |
| 964 | ui->comboControllerType->addItem(tr("NES Controller")); | 947 | ui->comboControllerType->addItem(tr("GameCube Controller")); |
| 965 | } | 948 | } |
| 966 | 949 | ||
| 967 | if (enable_all || npad_style_set.lucia == 1) { | 950 | // Disable all unsupported controllers |
| 968 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | 951 | if (!Settings::values.enable_all_controllers) { |
| 969 | Core::HID::NpadStyleIndex::SNES); | 952 | return; |
| 970 | ui->comboControllerType->addItem(tr("SNES Controller")); | 953 | } |
| 971 | } | 954 | if (npad_style_set.palma == 1) { |
| 955 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | ||
| 956 | Core::HID::NpadStyleIndex::Pokeball); | ||
| 957 | ui->comboControllerType->addItem(tr("Poke Ball Plus")); | ||
| 958 | } | ||
| 972 | 959 | ||
| 973 | if (enable_all || npad_style_set.lagoon == 1) { | 960 | if (npad_style_set.lark == 1) { |
| 974 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | 961 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), |
| 975 | Core::HID::NpadStyleIndex::N64); | 962 | Core::HID::NpadStyleIndex::NES); |
| 976 | ui->comboControllerType->addItem(tr("N64 Controller")); | 963 | ui->comboControllerType->addItem(tr("NES Controller")); |
| 977 | } | 964 | } |
| 978 | 965 | ||
| 979 | if (enable_all || npad_style_set.lager == 1) { | 966 | if (npad_style_set.lucia == 1) { |
| 980 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | 967 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), |
| 981 | Core::HID::NpadStyleIndex::SegaGenesis); | 968 | Core::HID::NpadStyleIndex::SNES); |
| 982 | ui->comboControllerType->addItem(tr("Sega Genesis")); | 969 | ui->comboControllerType->addItem(tr("SNES Controller")); |
| 983 | } | 970 | } |
| 984 | }; | ||
| 985 | 971 | ||
| 986 | if (!is_powered_on) { | 972 | if (npad_style_set.lagoon == 1) { |
| 987 | add_controllers(true); | 973 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), |
| 988 | return; | 974 | Core::HID::NpadStyleIndex::N64); |
| 975 | ui->comboControllerType->addItem(tr("N64 Controller")); | ||
| 989 | } | 976 | } |
| 990 | 977 | ||
| 991 | add_controllers(false, hid_core.GetSupportedStyleTag()); | 978 | if (npad_style_set.lager == 1) { |
| 979 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | ||
| 980 | Core::HID::NpadStyleIndex::SegaGenesis); | ||
| 981 | ui->comboControllerType->addItem(tr("Sega Genesis")); | ||
| 982 | } | ||
| 992 | } | 983 | } |
| 993 | 984 | ||
| 994 | Core::HID::NpadStyleIndex ConfigureInputPlayer::GetControllerTypeFromIndex(int index) const { | 985 | Core::HID::NpadStyleIndex ConfigureInputPlayer::GetControllerTypeFromIndex(int index) const { |
diff --git a/src/yuzu/debugger/profiler.cpp b/src/yuzu/debugger/profiler.cpp index a8b254199..33110685a 100644 --- a/src/yuzu/debugger/profiler.cpp +++ b/src/yuzu/debugger/profiler.cpp | |||
| @@ -163,7 +163,7 @@ void MicroProfileWidget::mouseReleaseEvent(QMouseEvent* ev) { | |||
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | void MicroProfileWidget::wheelEvent(QWheelEvent* ev) { | 165 | void MicroProfileWidget::wheelEvent(QWheelEvent* ev) { |
| 166 | const auto wheel_position = ev->pos(); | 166 | const auto wheel_position = ev->position().toPoint(); |
| 167 | MicroProfileMousePosition(wheel_position.x() / x_scale, wheel_position.y() / y_scale, | 167 | MicroProfileMousePosition(wheel_position.x() / x_scale, wheel_position.y() / y_scale, |
| 168 | ev->angleDelta().y() / 120); | 168 | ev->angleDelta().y() / 120); |
| 169 | ev->accept(); | 169 | ev->accept(); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f266fd963..cc84ea11c 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1082,14 +1082,15 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) { | |||
| 1082 | state != Qt::ApplicationActive) { | 1082 | state != Qt::ApplicationActive) { |
| 1083 | LOG_DEBUG(Frontend, "ApplicationState unusual flag: {} ", state); | 1083 | LOG_DEBUG(Frontend, "ApplicationState unusual flag: {} ", state); |
| 1084 | } | 1084 | } |
| 1085 | if (ui->action_Pause->isEnabled() && | 1085 | if (emulation_running) { |
| 1086 | (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { | 1086 | if (emu_thread->IsRunning() && |
| 1087 | auto_paused = true; | 1087 | (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { |
| 1088 | OnPauseGame(); | 1088 | auto_paused = true; |
| 1089 | } else if (emulation_running && !emu_thread->IsRunning() && auto_paused && | 1089 | OnPauseGame(); |
| 1090 | state == Qt::ApplicationActive) { | 1090 | } else if (!emu_thread->IsRunning() && auto_paused && state == Qt::ApplicationActive) { |
| 1091 | auto_paused = false; | 1091 | auto_paused = false; |
| 1092 | OnStartGame(); | 1092 | OnStartGame(); |
| 1093 | } | ||
| 1093 | } | 1094 | } |
| 1094 | } | 1095 | } |
| 1095 | 1096 | ||
| @@ -1516,6 +1517,9 @@ void GMainWindow::ShutdownGame() { | |||
| 1516 | input_subsystem->GetTas()->Stop(); | 1517 | input_subsystem->GetTas()->Stop(); |
| 1517 | OnTasStateChanged(); | 1518 | OnTasStateChanged(); |
| 1518 | 1519 | ||
| 1520 | // Enable all controllers | ||
| 1521 | system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All}); | ||
| 1522 | |||
| 1519 | render_window->removeEventFilter(render_window); | 1523 | render_window->removeEventFilter(render_window); |
| 1520 | render_window->setAttribute(Qt::WA_Hover, false); | 1524 | render_window->setAttribute(Qt::WA_Hover, false); |
| 1521 | 1525 | ||