diff options
Diffstat (limited to 'src')
190 files changed, 1415 insertions, 623 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7ddc87539..26f727d96 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -388,7 +388,7 @@ add_library(core STATIC | |||
| 388 | create_target_directory_groups(core) | 388 | create_target_directory_groups(core) |
| 389 | 389 | ||
| 390 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) | 390 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) |
| 391 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static mbedtls opus unicorn) | 391 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static mbedtls opus unicorn open_source_archives) |
| 392 | 392 | ||
| 393 | if (ARCHITECTURE_x86_64) | 393 | if (ARCHITECTURE_x86_64) |
| 394 | target_sources(core PRIVATE | 394 | target_sources(core PRIVATE |
diff --git a/src/core/hle/service/acc/acc_aa.cpp b/src/core/hle/service/acc/acc_aa.cpp index 9bd595a37..e84d9f7cf 100644 --- a/src/core/hle/service/acc/acc_aa.cpp +++ b/src/core/hle/service/acc/acc_aa.cpp | |||
| @@ -18,4 +18,6 @@ ACC_AA::ACC_AA(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 18 | RegisterHandlers(functions); | 18 | RegisterHandlers(functions); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | ACC_AA::~ACC_AA() = default; | ||
| 22 | |||
| 21 | } // namespace Service::Account | 23 | } // namespace Service::Account |
diff --git a/src/core/hle/service/acc/acc_aa.h b/src/core/hle/service/acc/acc_aa.h index 2e08c781a..9edb0421b 100644 --- a/src/core/hle/service/acc/acc_aa.h +++ b/src/core/hle/service/acc/acc_aa.h | |||
| @@ -12,6 +12,7 @@ class ACC_AA final : public Module::Interface { | |||
| 12 | public: | 12 | public: |
| 13 | explicit ACC_AA(std::shared_ptr<Module> module, | 13 | explicit ACC_AA(std::shared_ptr<Module> module, |
| 14 | std::shared_ptr<ProfileManager> profile_manager); | 14 | std::shared_ptr<ProfileManager> profile_manager); |
| 15 | ~ACC_AA() override; | ||
| 15 | }; | 16 | }; |
| 16 | 17 | ||
| 17 | } // namespace Service::Account | 18 | } // namespace Service::Account |
diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp index 0218ee859..ad455c3a7 100644 --- a/src/core/hle/service/acc/acc_su.cpp +++ b/src/core/hle/service/acc/acc_su.cpp | |||
| @@ -51,4 +51,6 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 51 | RegisterHandlers(functions); | 51 | RegisterHandlers(functions); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | ACC_SU::~ACC_SU() = default; | ||
| 55 | |||
| 54 | } // namespace Service::Account | 56 | } // namespace Service::Account |
diff --git a/src/core/hle/service/acc/acc_su.h b/src/core/hle/service/acc/acc_su.h index 79a47d88d..a3eb885bf 100644 --- a/src/core/hle/service/acc/acc_su.h +++ b/src/core/hle/service/acc/acc_su.h | |||
| @@ -13,6 +13,7 @@ class ACC_SU final : public Module::Interface { | |||
| 13 | public: | 13 | public: |
| 14 | explicit ACC_SU(std::shared_ptr<Module> module, | 14 | explicit ACC_SU(std::shared_ptr<Module> module, |
| 15 | std::shared_ptr<ProfileManager> profile_manager); | 15 | std::shared_ptr<ProfileManager> profile_manager); |
| 16 | ~ACC_SU() override; | ||
| 16 | }; | 17 | }; |
| 17 | 18 | ||
| 18 | } // namespace Account | 19 | } // namespace Account |
diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp index 84a4d05b8..72d4adf35 100644 --- a/src/core/hle/service/acc/acc_u0.cpp +++ b/src/core/hle/service/acc/acc_u0.cpp | |||
| @@ -31,4 +31,6 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 31 | RegisterHandlers(functions); | 31 | RegisterHandlers(functions); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | ACC_U0::~ACC_U0() = default; | ||
| 35 | |||
| 34 | } // namespace Service::Account | 36 | } // namespace Service::Account |
diff --git a/src/core/hle/service/acc/acc_u0.h b/src/core/hle/service/acc/acc_u0.h index e8a114f99..a1290e0bd 100644 --- a/src/core/hle/service/acc/acc_u0.h +++ b/src/core/hle/service/acc/acc_u0.h | |||
| @@ -12,6 +12,7 @@ class ACC_U0 final : public Module::Interface { | |||
| 12 | public: | 12 | public: |
| 13 | explicit ACC_U0(std::shared_ptr<Module> module, | 13 | explicit ACC_U0(std::shared_ptr<Module> module, |
| 14 | std::shared_ptr<ProfileManager> profile_manager); | 14 | std::shared_ptr<ProfileManager> profile_manager); |
| 15 | ~ACC_U0() override; | ||
| 15 | }; | 16 | }; |
| 16 | 17 | ||
| 17 | } // namespace Service::Account | 18 | } // namespace Service::Account |
diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp index 495693949..d480f08e5 100644 --- a/src/core/hle/service/acc/acc_u1.cpp +++ b/src/core/hle/service/acc/acc_u1.cpp | |||
| @@ -38,4 +38,6 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 38 | RegisterHandlers(functions); | 38 | RegisterHandlers(functions); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | ACC_U1::~ACC_U1() = default; | ||
| 42 | |||
| 41 | } // namespace Service::Account | 43 | } // namespace Service::Account |
diff --git a/src/core/hle/service/acc/acc_u1.h b/src/core/hle/service/acc/acc_u1.h index a77520e6f..9e79daee3 100644 --- a/src/core/hle/service/acc/acc_u1.h +++ b/src/core/hle/service/acc/acc_u1.h | |||
| @@ -12,6 +12,7 @@ class ACC_U1 final : public Module::Interface { | |||
| 12 | public: | 12 | public: |
| 13 | explicit ACC_U1(std::shared_ptr<Module> module, | 13 | explicit ACC_U1(std::shared_ptr<Module> module, |
| 14 | std::shared_ptr<ProfileManager> profile_manager); | 14 | std::shared_ptr<ProfileManager> profile_manager); |
| 15 | ~ACC_U1() override; | ||
| 15 | }; | 16 | }; |
| 16 | 17 | ||
| 17 | } // namespace Service::Account | 18 | } // namespace Service::Account |
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index e0b03d763..4ccebef23 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp | |||
| @@ -29,6 +29,8 @@ ProfileManager::ProfileManager() { | |||
| 29 | OpenUser(user_uuid); | 29 | OpenUser(user_uuid); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | ProfileManager::~ProfileManager() = default; | ||
| 33 | |||
| 32 | /// After a users creation it needs to be "registered" to the system. AddToProfiles handles the | 34 | /// After a users creation it needs to be "registered" to the system. AddToProfiles handles the |
| 33 | /// internal management of the users profiles | 35 | /// internal management of the users profiles |
| 34 | boost::optional<size_t> ProfileManager::AddToProfiles(const ProfileInfo& user) { | 36 | boost::optional<size_t> ProfileManager::AddToProfiles(const ProfileInfo& user) { |
diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 52967844d..cd8df93a5 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h | |||
| @@ -82,6 +82,8 @@ static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase is an invalid size"); | |||
| 82 | class ProfileManager { | 82 | class ProfileManager { |
| 83 | public: | 83 | public: |
| 84 | ProfileManager(); // TODO(ogniK): Load from system save | 84 | ProfileManager(); // TODO(ogniK): Load from system save |
| 85 | ~ProfileManager(); | ||
| 86 | |||
| 85 | ResultCode AddUser(const ProfileInfo& user); | 87 | ResultCode AddUser(const ProfileInfo& user); |
| 86 | ResultCode CreateNewUser(UUID uuid, const ProfileUsername& username); | 88 | ResultCode CreateNewUser(UUID uuid, const ProfileUsername& username); |
| 87 | ResultCode CreateNewUser(UUID uuid, const std::string& username); | 89 | ResultCode CreateNewUser(UUID uuid, const std::string& username); |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 818c03e0f..a57ed3042 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -35,6 +35,8 @@ IWindowController::IWindowController() : ServiceFramework("IWindowController") { | |||
| 35 | RegisterHandlers(functions); | 35 | RegisterHandlers(functions); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | IWindowController::~IWindowController() = default; | ||
| 39 | |||
| 38 | void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) { | 40 | void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) { |
| 39 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 41 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 40 | IPC::ResponseBuilder rb{ctx, 4}; | 42 | IPC::ResponseBuilder rb{ctx, 4}; |
| @@ -61,6 +63,8 @@ IAudioController::IAudioController() : ServiceFramework("IAudioController") { | |||
| 61 | RegisterHandlers(functions); | 63 | RegisterHandlers(functions); |
| 62 | } | 64 | } |
| 63 | 65 | ||
| 66 | IAudioController::~IAudioController() = default; | ||
| 67 | |||
| 64 | void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) { | 68 | void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) { |
| 65 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 69 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 66 | IPC::ResponseBuilder rb{ctx, 2}; | 70 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -116,7 +120,10 @@ IDisplayController::IDisplayController() : ServiceFramework("IDisplayController" | |||
| 116 | RegisterHandlers(functions); | 120 | RegisterHandlers(functions); |
| 117 | } | 121 | } |
| 118 | 122 | ||
| 123 | IDisplayController::~IDisplayController() = default; | ||
| 124 | |||
| 119 | IDebugFunctions::IDebugFunctions() : ServiceFramework("IDebugFunctions") {} | 125 | IDebugFunctions::IDebugFunctions() : ServiceFramework("IDebugFunctions") {} |
| 126 | IDebugFunctions::~IDebugFunctions() = default; | ||
| 120 | 127 | ||
| 121 | ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) | 128 | ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) |
| 122 | : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) { | 129 | : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) { |
| @@ -165,6 +172,8 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger | |||
| 165 | Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "ISelfController:LaunchableEvent"); | 172 | Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "ISelfController:LaunchableEvent"); |
| 166 | } | 173 | } |
| 167 | 174 | ||
| 175 | ISelfController::~ISelfController() = default; | ||
| 176 | |||
| 168 | void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) { | 177 | void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) { |
| 169 | // Takes 3 input u8s with each field located immediately after the previous u8, these are | 178 | // Takes 3 input u8s with each field located immediately after the previous u8, these are |
| 170 | // bool flags. No output. | 179 | // bool flags. No output. |
| @@ -337,6 +346,8 @@ ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter" | |||
| 337 | event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "ICommonStateGetter:Event"); | 346 | event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "ICommonStateGetter:Event"); |
| 338 | } | 347 | } |
| 339 | 348 | ||
| 349 | ICommonStateGetter::~ICommonStateGetter() = default; | ||
| 350 | |||
| 340 | void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) { | 351 | void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) { |
| 341 | IPC::ResponseBuilder rb{ctx, 3}; | 352 | IPC::ResponseBuilder rb{ctx, 3}; |
| 342 | rb.Push(RESULT_SUCCESS); | 353 | rb.Push(RESULT_SUCCESS); |
| @@ -573,6 +584,8 @@ ILibraryAppletCreator::ILibraryAppletCreator() : ServiceFramework("ILibraryApple | |||
| 573 | RegisterHandlers(functions); | 584 | RegisterHandlers(functions); |
| 574 | } | 585 | } |
| 575 | 586 | ||
| 587 | ILibraryAppletCreator::~ILibraryAppletCreator() = default; | ||
| 588 | |||
| 576 | void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { | 589 | void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { |
| 577 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 590 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 578 | 591 | ||
| @@ -638,6 +651,8 @@ IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationF | |||
| 638 | RegisterHandlers(functions); | 651 | RegisterHandlers(functions); |
| 639 | } | 652 | } |
| 640 | 653 | ||
| 654 | IApplicationFunctions::~IApplicationFunctions() = default; | ||
| 655 | |||
| 641 | void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) { | 656 | void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) { |
| 642 | constexpr std::array<u8, 0x88> data{{ | 657 | constexpr std::array<u8, 0x88> data{{ |
| 643 | 0xca, 0x97, 0x94, 0xc7, // Magic | 658 | 0xca, 0x97, 0x94, 0xc7, // Magic |
| @@ -760,6 +775,8 @@ IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions" | |||
| 760 | RegisterHandlers(functions); | 775 | RegisterHandlers(functions); |
| 761 | } | 776 | } |
| 762 | 777 | ||
| 778 | IHomeMenuFunctions::~IHomeMenuFunctions() = default; | ||
| 779 | |||
| 763 | void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) { | 780 | void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) { |
| 764 | IPC::ResponseBuilder rb{ctx, 2}; | 781 | IPC::ResponseBuilder rb{ctx, 2}; |
| 765 | rb.Push(RESULT_SUCCESS); | 782 | rb.Push(RESULT_SUCCESS); |
| @@ -783,6 +800,8 @@ IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStat | |||
| 783 | RegisterHandlers(functions); | 800 | RegisterHandlers(functions); |
| 784 | } | 801 | } |
| 785 | 802 | ||
| 803 | IGlobalStateController::~IGlobalStateController() = default; | ||
| 804 | |||
| 786 | IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreator") { | 805 | IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreator") { |
| 787 | static const FunctionInfo functions[] = { | 806 | static const FunctionInfo functions[] = { |
| 788 | {0, nullptr, "CreateApplication"}, | 807 | {0, nullptr, "CreateApplication"}, |
| @@ -793,6 +812,8 @@ IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreat | |||
| 793 | RegisterHandlers(functions); | 812 | RegisterHandlers(functions); |
| 794 | } | 813 | } |
| 795 | 814 | ||
| 815 | IApplicationCreator::~IApplicationCreator() = default; | ||
| 816 | |||
| 796 | IProcessWindingController::IProcessWindingController() | 817 | IProcessWindingController::IProcessWindingController() |
| 797 | : ServiceFramework("IProcessWindingController") { | 818 | : ServiceFramework("IProcessWindingController") { |
| 798 | static const FunctionInfo functions[] = { | 819 | static const FunctionInfo functions[] = { |
| @@ -807,4 +828,6 @@ IProcessWindingController::IProcessWindingController() | |||
| 807 | }; | 828 | }; |
| 808 | RegisterHandlers(functions); | 829 | RegisterHandlers(functions); |
| 809 | } | 830 | } |
| 831 | |||
| 832 | IProcessWindingController::~IProcessWindingController() = default; | ||
| 810 | } // namespace Service::AM | 833 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 9e8bb4e43..fd9ae296b 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -42,6 +42,7 @@ enum SystemLanguage { | |||
| 42 | class IWindowController final : public ServiceFramework<IWindowController> { | 42 | class IWindowController final : public ServiceFramework<IWindowController> { |
| 43 | public: | 43 | public: |
| 44 | IWindowController(); | 44 | IWindowController(); |
| 45 | ~IWindowController() override; | ||
| 45 | 46 | ||
| 46 | private: | 47 | private: |
| 47 | void GetAppletResourceUserId(Kernel::HLERequestContext& ctx); | 48 | void GetAppletResourceUserId(Kernel::HLERequestContext& ctx); |
| @@ -51,6 +52,7 @@ private: | |||
| 51 | class IAudioController final : public ServiceFramework<IAudioController> { | 52 | class IAudioController final : public ServiceFramework<IAudioController> { |
| 52 | public: | 53 | public: |
| 53 | IAudioController(); | 54 | IAudioController(); |
| 55 | ~IAudioController() override; | ||
| 54 | 56 | ||
| 55 | private: | 57 | private: |
| 56 | void SetExpectedMasterVolume(Kernel::HLERequestContext& ctx); | 58 | void SetExpectedMasterVolume(Kernel::HLERequestContext& ctx); |
| @@ -63,16 +65,19 @@ private: | |||
| 63 | class IDisplayController final : public ServiceFramework<IDisplayController> { | 65 | class IDisplayController final : public ServiceFramework<IDisplayController> { |
| 64 | public: | 66 | public: |
| 65 | IDisplayController(); | 67 | IDisplayController(); |
| 68 | ~IDisplayController() override; | ||
| 66 | }; | 69 | }; |
| 67 | 70 | ||
| 68 | class IDebugFunctions final : public ServiceFramework<IDebugFunctions> { | 71 | class IDebugFunctions final : public ServiceFramework<IDebugFunctions> { |
| 69 | public: | 72 | public: |
| 70 | IDebugFunctions(); | 73 | IDebugFunctions(); |
| 74 | ~IDebugFunctions() override; | ||
| 71 | }; | 75 | }; |
| 72 | 76 | ||
| 73 | class ISelfController final : public ServiceFramework<ISelfController> { | 77 | class ISelfController final : public ServiceFramework<ISelfController> { |
| 74 | public: | 78 | public: |
| 75 | explicit ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); | 79 | explicit ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); |
| 80 | ~ISelfController() override; | ||
| 76 | 81 | ||
| 77 | private: | 82 | private: |
| 78 | void SetFocusHandlingMode(Kernel::HLERequestContext& ctx); | 83 | void SetFocusHandlingMode(Kernel::HLERequestContext& ctx); |
| @@ -98,6 +103,7 @@ private: | |||
| 98 | class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { | 103 | class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { |
| 99 | public: | 104 | public: |
| 100 | ICommonStateGetter(); | 105 | ICommonStateGetter(); |
| 106 | ~ICommonStateGetter() override; | ||
| 101 | 107 | ||
| 102 | private: | 108 | private: |
| 103 | enum class FocusState : u8 { | 109 | enum class FocusState : u8 { |
| @@ -124,6 +130,7 @@ private: | |||
| 124 | class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { | 130 | class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { |
| 125 | public: | 131 | public: |
| 126 | ILibraryAppletCreator(); | 132 | ILibraryAppletCreator(); |
| 133 | ~ILibraryAppletCreator() override; | ||
| 127 | 134 | ||
| 128 | private: | 135 | private: |
| 129 | void CreateLibraryApplet(Kernel::HLERequestContext& ctx); | 136 | void CreateLibraryApplet(Kernel::HLERequestContext& ctx); |
| @@ -133,6 +140,7 @@ private: | |||
| 133 | class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { | 140 | class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { |
| 134 | public: | 141 | public: |
| 135 | IApplicationFunctions(); | 142 | IApplicationFunctions(); |
| 143 | ~IApplicationFunctions() override; | ||
| 136 | 144 | ||
| 137 | private: | 145 | private: |
| 138 | void PopLaunchParameter(Kernel::HLERequestContext& ctx); | 146 | void PopLaunchParameter(Kernel::HLERequestContext& ctx); |
| @@ -150,6 +158,7 @@ private: | |||
| 150 | class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { | 158 | class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { |
| 151 | public: | 159 | public: |
| 152 | IHomeMenuFunctions(); | 160 | IHomeMenuFunctions(); |
| 161 | ~IHomeMenuFunctions() override; | ||
| 153 | 162 | ||
| 154 | private: | 163 | private: |
| 155 | void RequestToGetForeground(Kernel::HLERequestContext& ctx); | 164 | void RequestToGetForeground(Kernel::HLERequestContext& ctx); |
| @@ -158,16 +167,19 @@ private: | |||
| 158 | class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { | 167 | class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { |
| 159 | public: | 168 | public: |
| 160 | IGlobalStateController(); | 169 | IGlobalStateController(); |
| 170 | ~IGlobalStateController() override; | ||
| 161 | }; | 171 | }; |
| 162 | 172 | ||
| 163 | class IApplicationCreator final : public ServiceFramework<IApplicationCreator> { | 173 | class IApplicationCreator final : public ServiceFramework<IApplicationCreator> { |
| 164 | public: | 174 | public: |
| 165 | IApplicationCreator(); | 175 | IApplicationCreator(); |
| 176 | ~IApplicationCreator() override; | ||
| 166 | }; | 177 | }; |
| 167 | 178 | ||
| 168 | class IProcessWindingController final : public ServiceFramework<IProcessWindingController> { | 179 | class IProcessWindingController final : public ServiceFramework<IProcessWindingController> { |
| 169 | public: | 180 | public: |
| 170 | IProcessWindingController(); | 181 | IProcessWindingController(); |
| 182 | ~IProcessWindingController() override; | ||
| 171 | }; | 183 | }; |
| 172 | 184 | ||
| 173 | /// Registers all AM services with the specified service manager. | 185 | /// Registers all AM services with the specified service manager. |
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp index 7cebc918a..4296c255e 100644 --- a/src/core/hle/service/am/applet_ae.cpp +++ b/src/core/hle/service/am/applet_ae.cpp | |||
| @@ -222,4 +222,6 @@ AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) | |||
| 222 | RegisterHandlers(functions); | 222 | RegisterHandlers(functions); |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | AppletAE::~AppletAE() = default; | ||
| 226 | |||
| 225 | } // namespace Service::AM | 227 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h index bdc57b9bc..1ed77baa4 100644 --- a/src/core/hle/service/am/applet_ae.h +++ b/src/core/hle/service/am/applet_ae.h | |||
| @@ -18,7 +18,7 @@ namespace AM { | |||
| 18 | class AppletAE final : public ServiceFramework<AppletAE> { | 18 | class AppletAE final : public ServiceFramework<AppletAE> { |
| 19 | public: | 19 | public: |
| 20 | explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); | 20 | explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); |
| 21 | ~AppletAE() = default; | 21 | ~AppletAE() override; |
| 22 | 22 | ||
| 23 | private: | 23 | private: |
| 24 | void OpenSystemAppletProxy(Kernel::HLERequestContext& ctx); | 24 | void OpenSystemAppletProxy(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index beea7d19b..e45cf6e20 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp | |||
| @@ -103,4 +103,6 @@ AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) | |||
| 103 | RegisterHandlers(functions); | 103 | RegisterHandlers(functions); |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | AppletOE::~AppletOE() = default; | ||
| 107 | |||
| 106 | } // namespace Service::AM | 108 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h index c52e2a322..60cfdfd9d 100644 --- a/src/core/hle/service/am/applet_oe.h +++ b/src/core/hle/service/am/applet_oe.h | |||
| @@ -18,7 +18,7 @@ namespace AM { | |||
| 18 | class AppletOE final : public ServiceFramework<AppletOE> { | 18 | class AppletOE final : public ServiceFramework<AppletOE> { |
| 19 | public: | 19 | public: |
| 20 | explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); | 20 | explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); |
| 21 | ~AppletOE() = default; | 21 | ~AppletOE() override; |
| 22 | 22 | ||
| 23 | private: | 23 | private: |
| 24 | void OpenApplicationProxy(Kernel::HLERequestContext& ctx); | 24 | void OpenApplicationProxy(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/am/idle.cpp b/src/core/hle/service/am/idle.cpp index af46e9494..0e3088bc8 100644 --- a/src/core/hle/service/am/idle.cpp +++ b/src/core/hle/service/am/idle.cpp | |||
| @@ -21,4 +21,6 @@ IdleSys::IdleSys() : ServiceFramework{"idle:sys"} { | |||
| 21 | RegisterHandlers(functions); | 21 | RegisterHandlers(functions); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | IdleSys::~IdleSys() = default; | ||
| 25 | |||
| 24 | } // namespace Service::AM | 26 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/idle.h b/src/core/hle/service/am/idle.h index 1eb68d2c9..c44e856b1 100644 --- a/src/core/hle/service/am/idle.h +++ b/src/core/hle/service/am/idle.h | |||
| @@ -11,6 +11,7 @@ namespace Service::AM { | |||
| 11 | class IdleSys final : public ServiceFramework<IdleSys> { | 11 | class IdleSys final : public ServiceFramework<IdleSys> { |
| 12 | public: | 12 | public: |
| 13 | explicit IdleSys(); | 13 | explicit IdleSys(); |
| 14 | ~IdleSys() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::AM | 17 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/omm.cpp b/src/core/hle/service/am/omm.cpp index 447fe8669..1c37f849f 100644 --- a/src/core/hle/service/am/omm.cpp +++ b/src/core/hle/service/am/omm.cpp | |||
| @@ -39,4 +39,6 @@ OMM::OMM() : ServiceFramework{"omm"} { | |||
| 39 | RegisterHandlers(functions); | 39 | RegisterHandlers(functions); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | OMM::~OMM() = default; | ||
| 43 | |||
| 42 | } // namespace Service::AM | 44 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/omm.h b/src/core/hle/service/am/omm.h index 49e5d331c..59dc91b72 100644 --- a/src/core/hle/service/am/omm.h +++ b/src/core/hle/service/am/omm.h | |||
| @@ -11,6 +11,7 @@ namespace Service::AM { | |||
| 11 | class OMM final : public ServiceFramework<OMM> { | 11 | class OMM final : public ServiceFramework<OMM> { |
| 12 | public: | 12 | public: |
| 13 | explicit OMM(); | 13 | explicit OMM(); |
| 14 | ~OMM() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::AM | 17 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/spsm.cpp b/src/core/hle/service/am/spsm.cpp index a05d433d0..003ee8667 100644 --- a/src/core/hle/service/am/spsm.cpp +++ b/src/core/hle/service/am/spsm.cpp | |||
| @@ -27,4 +27,6 @@ SPSM::SPSM() : ServiceFramework{"spsm"} { | |||
| 27 | RegisterHandlers(functions); | 27 | RegisterHandlers(functions); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | SPSM::~SPSM() = default; | ||
| 31 | |||
| 30 | } // namespace Service::AM | 32 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/spsm.h b/src/core/hle/service/am/spsm.h index 57dde62e1..3a0b979fa 100644 --- a/src/core/hle/service/am/spsm.h +++ b/src/core/hle/service/am/spsm.h | |||
| @@ -11,6 +11,7 @@ namespace Service::AM { | |||
| 11 | class SPSM final : public ServiceFramework<SPSM> { | 11 | class SPSM final : public ServiceFramework<SPSM> { |
| 12 | public: | 12 | public: |
| 13 | explicit SPSM(); | 13 | explicit SPSM(); |
| 14 | ~SPSM() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::AM | 17 | } // namespace Service::AM |
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 6e7438580..d9eeac9ec 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp | |||
| @@ -23,6 +23,8 @@ AOC_U::AOC_U() : ServiceFramework("aoc:u") { | |||
| 23 | RegisterHandlers(functions); | 23 | RegisterHandlers(functions); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | AOC_U::~AOC_U() = default; | ||
| 27 | |||
| 26 | void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) { | 28 | void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) { |
| 27 | IPC::ResponseBuilder rb{ctx, 4}; | 29 | IPC::ResponseBuilder rb{ctx, 4}; |
| 28 | rb.Push(RESULT_SUCCESS); | 30 | rb.Push(RESULT_SUCCESS); |
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h index 17d48ef30..29ce8f488 100644 --- a/src/core/hle/service/aoc/aoc_u.h +++ b/src/core/hle/service/aoc/aoc_u.h | |||
| @@ -11,7 +11,7 @@ namespace Service::AOC { | |||
| 11 | class AOC_U final : public ServiceFramework<AOC_U> { | 11 | class AOC_U final : public ServiceFramework<AOC_U> { |
| 12 | public: | 12 | public: |
| 13 | AOC_U(); | 13 | AOC_U(); |
| 14 | ~AOC_U() = default; | 14 | ~AOC_U() override; |
| 15 | 15 | ||
| 16 | private: | 16 | private: |
| 17 | void CountAddOnContent(Kernel::HLERequestContext& ctx); | 17 | void CountAddOnContent(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 4109cb7f7..f3c09bbb1 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp | |||
| @@ -9,6 +9,9 @@ | |||
| 9 | 9 | ||
| 10 | namespace Service::APM { | 10 | namespace Service::APM { |
| 11 | 11 | ||
| 12 | Module::Module() = default; | ||
| 13 | Module::~Module() = default; | ||
| 14 | |||
| 12 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 15 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 13 | auto module_ = std::make_shared<Module>(); | 16 | auto module_ = std::make_shared<Module>(); |
| 14 | std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager); | 17 | std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager); |
diff --git a/src/core/hle/service/apm/apm.h b/src/core/hle/service/apm/apm.h index 90a80d51b..4d7d5bb7c 100644 --- a/src/core/hle/service/apm/apm.h +++ b/src/core/hle/service/apm/apm.h | |||
| @@ -15,8 +15,8 @@ enum class PerformanceMode : u8 { | |||
| 15 | 15 | ||
| 16 | class Module final { | 16 | class Module final { |
| 17 | public: | 17 | public: |
| 18 | Module() = default; | 18 | Module(); |
| 19 | ~Module() = default; | 19 | ~Module(); |
| 20 | }; | 20 | }; |
| 21 | 21 | ||
| 22 | /// Registers all AM services with the specified service manager. | 22 | /// Registers all AM services with the specified service manager. |
diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index 4cd8132f5..c22bd3859 100644 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp | |||
| @@ -70,6 +70,8 @@ APM::APM(std::shared_ptr<Module> apm, const char* name) | |||
| 70 | RegisterHandlers(functions); | 70 | RegisterHandlers(functions); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | APM::~APM() = default; | ||
| 74 | |||
| 73 | void APM::OpenSession(Kernel::HLERequestContext& ctx) { | 75 | void APM::OpenSession(Kernel::HLERequestContext& ctx) { |
| 74 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 76 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 75 | rb.Push(RESULT_SUCCESS); | 77 | rb.Push(RESULT_SUCCESS); |
| @@ -93,6 +95,8 @@ APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} { | |||
| 93 | RegisterHandlers(functions); | 95 | RegisterHandlers(functions); |
| 94 | } | 96 | } |
| 95 | 97 | ||
| 98 | APM_Sys::~APM_Sys() = default; | ||
| 99 | |||
| 96 | void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) { | 100 | void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) { |
| 97 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 101 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 98 | rb.Push(RESULT_SUCCESS); | 102 | rb.Push(RESULT_SUCCESS); |
diff --git a/src/core/hle/service/apm/interface.h b/src/core/hle/service/apm/interface.h index d14264ad7..773541aa4 100644 --- a/src/core/hle/service/apm/interface.h +++ b/src/core/hle/service/apm/interface.h | |||
| @@ -11,7 +11,7 @@ namespace Service::APM { | |||
| 11 | class APM final : public ServiceFramework<APM> { | 11 | class APM final : public ServiceFramework<APM> { |
| 12 | public: | 12 | public: |
| 13 | explicit APM(std::shared_ptr<Module> apm, const char* name); | 13 | explicit APM(std::shared_ptr<Module> apm, const char* name); |
| 14 | ~APM() = default; | 14 | ~APM() override; |
| 15 | 15 | ||
| 16 | private: | 16 | private: |
| 17 | void OpenSession(Kernel::HLERequestContext& ctx); | 17 | void OpenSession(Kernel::HLERequestContext& ctx); |
| @@ -22,6 +22,7 @@ private: | |||
| 22 | class APM_Sys final : public ServiceFramework<APM_Sys> { | 22 | class APM_Sys final : public ServiceFramework<APM_Sys> { |
| 23 | public: | 23 | public: |
| 24 | explicit APM_Sys(); | 24 | explicit APM_Sys(); |
| 25 | ~APM_Sys() override; | ||
| 25 | 26 | ||
| 26 | private: | 27 | private: |
| 27 | void GetPerformanceEvent(Kernel::HLERequestContext& ctx); | 28 | void GetPerformanceEvent(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp index 37c3fdcac..b6b71f966 100644 --- a/src/core/hle/service/audio/audctl.cpp +++ b/src/core/hle/service/audio/audctl.cpp | |||
| @@ -42,4 +42,6 @@ AudCtl::AudCtl() : ServiceFramework{"audctl"} { | |||
| 42 | RegisterHandlers(functions); | 42 | RegisterHandlers(functions); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | AudCtl::~AudCtl() = default; | ||
| 46 | |||
| 45 | } // namespace Service::Audio | 47 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audctl.h b/src/core/hle/service/audio/audctl.h index ed837bdf2..9d2d9e83b 100644 --- a/src/core/hle/service/audio/audctl.h +++ b/src/core/hle/service/audio/audctl.h | |||
| @@ -11,6 +11,7 @@ namespace Service::Audio { | |||
| 11 | class AudCtl final : public ServiceFramework<AudCtl> { | 11 | class AudCtl final : public ServiceFramework<AudCtl> { |
| 12 | public: | 12 | public: |
| 13 | explicit AudCtl(); | 13 | explicit AudCtl(); |
| 14 | ~AudCtl() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::Audio | 17 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/auddbg.cpp b/src/core/hle/service/audio/auddbg.cpp index b08c21a20..8fff3e4b4 100644 --- a/src/core/hle/service/audio/auddbg.cpp +++ b/src/core/hle/service/audio/auddbg.cpp | |||
| @@ -17,4 +17,6 @@ AudDbg::AudDbg(const char* name) : ServiceFramework{name} { | |||
| 17 | RegisterHandlers(functions); | 17 | RegisterHandlers(functions); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | AudDbg::~AudDbg() = default; | ||
| 21 | |||
| 20 | } // namespace Service::Audio | 22 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/auddbg.h b/src/core/hle/service/audio/auddbg.h index a2f540b75..6689f4759 100644 --- a/src/core/hle/service/audio/auddbg.h +++ b/src/core/hle/service/audio/auddbg.h | |||
| @@ -11,6 +11,7 @@ namespace Service::Audio { | |||
| 11 | class AudDbg final : public ServiceFramework<AudDbg> { | 11 | class AudDbg final : public ServiceFramework<AudDbg> { |
| 12 | public: | 12 | public: |
| 13 | explicit AudDbg(const char* name); | 13 | explicit AudDbg(const char* name); |
| 14 | ~AudDbg() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::Audio | 17 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audin_a.cpp b/src/core/hle/service/audio/audin_a.cpp index a70d5bca4..ddd12f35e 100644 --- a/src/core/hle/service/audio/audin_a.cpp +++ b/src/core/hle/service/audio/audin_a.cpp | |||
| @@ -19,4 +19,6 @@ AudInA::AudInA() : ServiceFramework{"audin:a"} { | |||
| 19 | RegisterHandlers(functions); | 19 | RegisterHandlers(functions); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | AudInA::~AudInA() = default; | ||
| 23 | |||
| 22 | } // namespace Service::Audio | 24 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audin_a.h b/src/core/hle/service/audio/audin_a.h index e4c75510f..e7623bc29 100644 --- a/src/core/hle/service/audio/audin_a.h +++ b/src/core/hle/service/audio/audin_a.h | |||
| @@ -11,6 +11,7 @@ namespace Service::Audio { | |||
| 11 | class AudInA final : public ServiceFramework<AudInA> { | 11 | class AudInA final : public ServiceFramework<AudInA> { |
| 12 | public: | 12 | public: |
| 13 | explicit AudInA(); | 13 | explicit AudInA(); |
| 14 | ~AudInA() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::Audio | 17 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index cbc49e55e..657010312 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp | |||
| @@ -41,4 +41,6 @@ AudInU::AudInU() : ServiceFramework("audin:u") { | |||
| 41 | RegisterHandlers(functions); | 41 | RegisterHandlers(functions); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | AudInU::~AudInU() = default; | ||
| 45 | |||
| 44 | } // namespace Service::Audio | 46 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audin_u.h b/src/core/hle/service/audio/audin_u.h index 2e65efb5b..0538b9560 100644 --- a/src/core/hle/service/audio/audin_u.h +++ b/src/core/hle/service/audio/audin_u.h | |||
| @@ -15,7 +15,7 @@ namespace Service::Audio { | |||
| 15 | class AudInU final : public ServiceFramework<AudInU> { | 15 | class AudInU final : public ServiceFramework<AudInU> { |
| 16 | public: | 16 | public: |
| 17 | explicit AudInU(); | 17 | explicit AudInU(); |
| 18 | ~AudInU() = default; | 18 | ~AudInU() override; |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | } // namespace Service::Audio | 21 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audout_a.cpp b/src/core/hle/service/audio/audout_a.cpp index bf8d40157..85febbca3 100644 --- a/src/core/hle/service/audio/audout_a.cpp +++ b/src/core/hle/service/audio/audout_a.cpp | |||
| @@ -21,4 +21,6 @@ AudOutA::AudOutA() : ServiceFramework{"audout:a"} { | |||
| 21 | RegisterHandlers(functions); | 21 | RegisterHandlers(functions); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | AudOutA::~AudOutA() = default; | ||
| 25 | |||
| 24 | } // namespace Service::Audio | 26 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audout_a.h b/src/core/hle/service/audio/audout_a.h index 91a069152..d65b66e8e 100644 --- a/src/core/hle/service/audio/audout_a.h +++ b/src/core/hle/service/audio/audout_a.h | |||
| @@ -11,6 +11,7 @@ namespace Service::Audio { | |||
| 11 | class AudOutA final : public ServiceFramework<AudOutA> { | 11 | class AudOutA final : public ServiceFramework<AudOutA> { |
| 12 | public: | 12 | public: |
| 13 | explicit AudOutA(); | 13 | explicit AudOutA(); |
| 14 | ~AudOutA() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::Audio | 17 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 5f370bbdf..05100ca8f 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -218,4 +218,6 @@ AudOutU::AudOutU() : ServiceFramework("audout:u") { | |||
| 218 | audio_core = std::make_unique<AudioCore::AudioOut>(); | 218 | audio_core = std::make_unique<AudioCore::AudioOut>(); |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | AudOutU::~AudOutU() = default; | ||
| 222 | |||
| 221 | } // namespace Service::Audio | 223 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h index fd491f65d..aa52d3855 100644 --- a/src/core/hle/service/audio/audout_u.h +++ b/src/core/hle/service/audio/audout_u.h | |||
| @@ -30,7 +30,7 @@ class IAudioOut; | |||
| 30 | class AudOutU final : public ServiceFramework<AudOutU> { | 30 | class AudOutU final : public ServiceFramework<AudOutU> { |
| 31 | public: | 31 | public: |
| 32 | AudOutU(); | 32 | AudOutU(); |
| 33 | ~AudOutU() = default; | 33 | ~AudOutU() override; |
| 34 | 34 | ||
| 35 | private: | 35 | private: |
| 36 | std::shared_ptr<IAudioOut> audio_out_interface; | 36 | std::shared_ptr<IAudioOut> audio_out_interface; |
diff --git a/src/core/hle/service/audio/audrec_a.cpp b/src/core/hle/service/audio/audrec_a.cpp index 016eabf53..ce1bfb48d 100644 --- a/src/core/hle/service/audio/audrec_a.cpp +++ b/src/core/hle/service/audio/audrec_a.cpp | |||
| @@ -17,4 +17,6 @@ AudRecA::AudRecA() : ServiceFramework{"audrec:a"} { | |||
| 17 | RegisterHandlers(functions); | 17 | RegisterHandlers(functions); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | AudRecA::~AudRecA() = default; | ||
| 21 | |||
| 20 | } // namespace Service::Audio | 22 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audrec_a.h b/src/core/hle/service/audio/audrec_a.h index 9685047f2..384d24c69 100644 --- a/src/core/hle/service/audio/audrec_a.h +++ b/src/core/hle/service/audio/audrec_a.h | |||
| @@ -11,6 +11,7 @@ namespace Service::Audio { | |||
| 11 | class AudRecA final : public ServiceFramework<AudRecA> { | 11 | class AudRecA final : public ServiceFramework<AudRecA> { |
| 12 | public: | 12 | public: |
| 13 | explicit AudRecA(); | 13 | explicit AudRecA(); |
| 14 | ~AudRecA() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::Audio | 17 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audrec_u.cpp b/src/core/hle/service/audio/audrec_u.cpp index 74909415c..34974afa9 100644 --- a/src/core/hle/service/audio/audrec_u.cpp +++ b/src/core/hle/service/audio/audrec_u.cpp | |||
| @@ -36,4 +36,6 @@ AudRecU::AudRecU() : ServiceFramework("audrec:u") { | |||
| 36 | RegisterHandlers(functions); | 36 | RegisterHandlers(functions); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | AudRecU::~AudRecU() = default; | ||
| 40 | |||
| 39 | } // namespace Service::Audio | 41 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audrec_u.h b/src/core/hle/service/audio/audrec_u.h index 46daa33a4..ca3d638e8 100644 --- a/src/core/hle/service/audio/audrec_u.h +++ b/src/core/hle/service/audio/audrec_u.h | |||
| @@ -15,7 +15,7 @@ namespace Service::Audio { | |||
| 15 | class AudRecU final : public ServiceFramework<AudRecU> { | 15 | class AudRecU final : public ServiceFramework<AudRecU> { |
| 16 | public: | 16 | public: |
| 17 | explicit AudRecU(); | 17 | explicit AudRecU(); |
| 18 | ~AudRecU() = default; | 18 | ~AudRecU() override; |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | } // namespace Service::Audio | 21 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audren_a.cpp b/src/core/hle/service/audio/audren_a.cpp index 616ff3dc4..edb66d985 100644 --- a/src/core/hle/service/audio/audren_a.cpp +++ b/src/core/hle/service/audio/audren_a.cpp | |||
| @@ -23,4 +23,6 @@ AudRenA::AudRenA() : ServiceFramework{"audren:a"} { | |||
| 23 | RegisterHandlers(functions); | 23 | RegisterHandlers(functions); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | AudRenA::~AudRenA() = default; | ||
| 27 | |||
| 26 | } // namespace Service::Audio | 28 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audren_a.h b/src/core/hle/service/audio/audren_a.h index 5ecf2e184..81fef0ffe 100644 --- a/src/core/hle/service/audio/audren_a.h +++ b/src/core/hle/service/audio/audren_a.h | |||
| @@ -11,6 +11,7 @@ namespace Service::Audio { | |||
| 11 | class AudRenA final : public ServiceFramework<AudRenA> { | 11 | class AudRenA final : public ServiceFramework<AudRenA> { |
| 12 | public: | 12 | public: |
| 13 | explicit AudRenA(); | 13 | explicit AudRenA(); |
| 14 | ~AudRenA() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::Audio | 17 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 016db7c82..3870bec65 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -198,6 +198,8 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") { | |||
| 198 | RegisterHandlers(functions); | 198 | RegisterHandlers(functions); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | AudRenU::~AudRenU() = default; | ||
| 202 | |||
| 201 | void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { | 203 | void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { |
| 202 | IPC::RequestParser rp{ctx}; | 204 | IPC::RequestParser rp{ctx}; |
| 203 | auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); | 205 | auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); |
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h index 8600ac6e4..85a995a2f 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audren_u.h | |||
| @@ -16,7 +16,7 @@ namespace Service::Audio { | |||
| 16 | class AudRenU final : public ServiceFramework<AudRenU> { | 16 | class AudRenU final : public ServiceFramework<AudRenU> { |
| 17 | public: | 17 | public: |
| 18 | explicit AudRenU(); | 18 | explicit AudRenU(); |
| 19 | ~AudRenU() = default; | 19 | ~AudRenU() override; |
| 20 | 20 | ||
| 21 | private: | 21 | private: |
| 22 | void OpenAudioRenderer(Kernel::HLERequestContext& ctx); | 22 | void OpenAudioRenderer(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/audio/codecctl.cpp b/src/core/hle/service/audio/codecctl.cpp index 212c8d448..c6864146d 100644 --- a/src/core/hle/service/audio/codecctl.cpp +++ b/src/core/hle/service/audio/codecctl.cpp | |||
| @@ -28,4 +28,6 @@ CodecCtl::CodecCtl() : ServiceFramework("codecctl") { | |||
| 28 | RegisterHandlers(functions); | 28 | RegisterHandlers(functions); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | CodecCtl::~CodecCtl() = default; | ||
| 32 | |||
| 31 | } // namespace Service::Audio | 33 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/codecctl.h b/src/core/hle/service/audio/codecctl.h index d9ac29b67..2fe75b6e2 100644 --- a/src/core/hle/service/audio/codecctl.h +++ b/src/core/hle/service/audio/codecctl.h | |||
| @@ -15,7 +15,7 @@ namespace Service::Audio { | |||
| 15 | class CodecCtl final : public ServiceFramework<CodecCtl> { | 15 | class CodecCtl final : public ServiceFramework<CodecCtl> { |
| 16 | public: | 16 | public: |
| 17 | explicit CodecCtl(); | 17 | explicit CodecCtl(); |
| 18 | ~CodecCtl() = default; | 18 | ~CodecCtl() override; |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | } // namespace Service::Audio | 21 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index 371cd4997..341bfda42 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp | |||
| @@ -151,4 +151,6 @@ HwOpus::HwOpus() : ServiceFramework("hwopus") { | |||
| 151 | RegisterHandlers(functions); | 151 | RegisterHandlers(functions); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | HwOpus::~HwOpus() = default; | ||
| 155 | |||
| 154 | } // namespace Service::Audio | 156 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hwopus.h index 5258d59f3..602ede8ba 100644 --- a/src/core/hle/service/audio/hwopus.h +++ b/src/core/hle/service/audio/hwopus.h | |||
| @@ -11,7 +11,7 @@ namespace Service::Audio { | |||
| 11 | class HwOpus final : public ServiceFramework<HwOpus> { | 11 | class HwOpus final : public ServiceFramework<HwOpus> { |
| 12 | public: | 12 | public: |
| 13 | explicit HwOpus(); | 13 | explicit HwOpus(); |
| 14 | ~HwOpus() = default; | 14 | ~HwOpus() override; |
| 15 | 15 | ||
| 16 | private: | 16 | private: |
| 17 | void OpenOpusDecoder(Kernel::HLERequestContext& ctx); | 17 | void OpenOpusDecoder(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/bcat/bcat.cpp b/src/core/hle/service/bcat/bcat.cpp index 20ce692dc..179aa4949 100644 --- a/src/core/hle/service/bcat/bcat.cpp +++ b/src/core/hle/service/bcat/bcat.cpp | |||
| @@ -13,4 +13,6 @@ BCAT::BCAT(std::shared_ptr<Module> module, const char* name) | |||
| 13 | }; | 13 | }; |
| 14 | RegisterHandlers(functions); | 14 | RegisterHandlers(functions); |
| 15 | } | 15 | } |
| 16 | |||
| 17 | BCAT::~BCAT() = default; | ||
| 16 | } // namespace Service::BCAT | 18 | } // namespace Service::BCAT |
diff --git a/src/core/hle/service/bcat/bcat.h b/src/core/hle/service/bcat/bcat.h index 6632996a0..802bd689a 100644 --- a/src/core/hle/service/bcat/bcat.h +++ b/src/core/hle/service/bcat/bcat.h | |||
| @@ -11,6 +11,7 @@ namespace Service::BCAT { | |||
| 11 | class BCAT final : public Module::Interface { | 11 | class BCAT final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit BCAT(std::shared_ptr<Module> module, const char* name); | 13 | explicit BCAT(std::shared_ptr<Module> module, const char* name); |
| 14 | ~BCAT() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::BCAT | 17 | } // namespace Service::BCAT |
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp index 35e024c3d..6e7b795fb 100644 --- a/src/core/hle/service/bcat/module.cpp +++ b/src/core/hle/service/bcat/module.cpp | |||
| @@ -42,6 +42,8 @@ void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) { | |||
| 42 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | 42 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) |
| 43 | : ServiceFramework(name), module(std::move(module)) {} | 43 | : ServiceFramework(name), module(std::move(module)) {} |
| 44 | 44 | ||
| 45 | Module::Interface::~Interface() = default; | ||
| 46 | |||
| 45 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 47 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 46 | auto module = std::make_shared<Module>(); | 48 | auto module = std::make_shared<Module>(); |
| 47 | std::make_shared<BCAT>(module, "bcat:a")->InstallAsService(service_manager); | 49 | std::make_shared<BCAT>(module, "bcat:a")->InstallAsService(service_manager); |
diff --git a/src/core/hle/service/bcat/module.h b/src/core/hle/service/bcat/module.h index 62f6f5f9d..f0d63cab0 100644 --- a/src/core/hle/service/bcat/module.h +++ b/src/core/hle/service/bcat/module.h | |||
| @@ -13,6 +13,7 @@ public: | |||
| 13 | class Interface : public ServiceFramework<Interface> { | 13 | class Interface : public ServiceFramework<Interface> { |
| 14 | public: | 14 | public: |
| 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); | 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); |
| 16 | ~Interface() override; | ||
| 16 | 17 | ||
| 17 | void CreateBcatService(Kernel::HLERequestContext& ctx); | 18 | void CreateBcatService(Kernel::HLERequestContext& ctx); |
| 18 | 19 | ||
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 299b9474f..b436ce4e6 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp | |||
| @@ -13,6 +13,8 @@ namespace Service::Fatal { | |||
| 13 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | 13 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) |
| 14 | : ServiceFramework(name), module(std::move(module)) {} | 14 | : ServiceFramework(name), module(std::move(module)) {} |
| 15 | 15 | ||
| 16 | Module::Interface::~Interface() = default; | ||
| 17 | |||
| 16 | void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) { | 18 | void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) { |
| 17 | IPC::RequestParser rp(ctx); | 19 | IPC::RequestParser rp(ctx); |
| 18 | u32 error_code = rp.Pop<u32>(); | 20 | u32 error_code = rp.Pop<u32>(); |
diff --git a/src/core/hle/service/fatal/fatal.h b/src/core/hle/service/fatal/fatal.h index ca607e236..4d9a5be52 100644 --- a/src/core/hle/service/fatal/fatal.h +++ b/src/core/hle/service/fatal/fatal.h | |||
| @@ -13,6 +13,7 @@ public: | |||
| 13 | class Interface : public ServiceFramework<Interface> { | 13 | class Interface : public ServiceFramework<Interface> { |
| 14 | public: | 14 | public: |
| 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); | 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); |
| 16 | ~Interface() override; | ||
| 16 | 17 | ||
| 17 | void ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx); | 18 | void ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx); |
| 18 | void ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx); | 19 | void ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/fatal/fatal_p.cpp b/src/core/hle/service/fatal/fatal_p.cpp index a5254ac2f..9e5f872ff 100644 --- a/src/core/hle/service/fatal/fatal_p.cpp +++ b/src/core/hle/service/fatal/fatal_p.cpp | |||
| @@ -9,4 +9,6 @@ namespace Service::Fatal { | |||
| 9 | Fatal_P::Fatal_P(std::shared_ptr<Module> module) | 9 | Fatal_P::Fatal_P(std::shared_ptr<Module> module) |
| 10 | : Module::Interface(std::move(module), "fatal:p") {} | 10 | : Module::Interface(std::move(module), "fatal:p") {} |
| 11 | 11 | ||
| 12 | Fatal_P::~Fatal_P() = default; | ||
| 13 | |||
| 12 | } // namespace Service::Fatal | 14 | } // namespace Service::Fatal |
diff --git a/src/core/hle/service/fatal/fatal_p.h b/src/core/hle/service/fatal/fatal_p.h index bfd8c8b74..6e9c5979f 100644 --- a/src/core/hle/service/fatal/fatal_p.h +++ b/src/core/hle/service/fatal/fatal_p.h | |||
| @@ -11,6 +11,7 @@ namespace Service::Fatal { | |||
| 11 | class Fatal_P final : public Module::Interface { | 11 | class Fatal_P final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit Fatal_P(std::shared_ptr<Module> module); | 13 | explicit Fatal_P(std::shared_ptr<Module> module); |
| 14 | ~Fatal_P() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::Fatal | 17 | } // namespace Service::Fatal |
diff --git a/src/core/hle/service/fatal/fatal_u.cpp b/src/core/hle/service/fatal/fatal_u.cpp index f0631329e..befc307cf 100644 --- a/src/core/hle/service/fatal/fatal_u.cpp +++ b/src/core/hle/service/fatal/fatal_u.cpp | |||
| @@ -15,4 +15,6 @@ Fatal_U::Fatal_U(std::shared_ptr<Module> module) : Module::Interface(std::move(m | |||
| 15 | RegisterHandlers(functions); | 15 | RegisterHandlers(functions); |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | Fatal_U::~Fatal_U() = default; | ||
| 19 | |||
| 18 | } // namespace Service::Fatal | 20 | } // namespace Service::Fatal |
diff --git a/src/core/hle/service/fatal/fatal_u.h b/src/core/hle/service/fatal/fatal_u.h index 9b1a9e97a..72cb6d076 100644 --- a/src/core/hle/service/fatal/fatal_u.h +++ b/src/core/hle/service/fatal/fatal_u.h | |||
| @@ -11,6 +11,7 @@ namespace Service::Fatal { | |||
| 11 | class Fatal_U final : public Module::Interface { | 11 | class Fatal_U final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit Fatal_U(std::shared_ptr<Module> module); | 13 | explicit Fatal_U(std::shared_ptr<Module> module); |
| 14 | ~Fatal_U() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::Fatal | 17 | } // namespace Service::Fatal |
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 04c9d750f..5c4971724 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -40,6 +40,8 @@ static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base, | |||
| 40 | VfsDirectoryServiceWrapper::VfsDirectoryServiceWrapper(FileSys::VirtualDir backing_) | 40 | VfsDirectoryServiceWrapper::VfsDirectoryServiceWrapper(FileSys::VirtualDir backing_) |
| 41 | : backing(std::move(backing_)) {} | 41 | : backing(std::move(backing_)) {} |
| 42 | 42 | ||
| 43 | VfsDirectoryServiceWrapper::~VfsDirectoryServiceWrapper() = default; | ||
| 44 | |||
| 43 | std::string VfsDirectoryServiceWrapper::GetName() const { | 45 | std::string VfsDirectoryServiceWrapper::GetName() const { |
| 44 | return backing->GetName(); | 46 | return backing->GetName(); |
| 45 | } | 47 | } |
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 793a7b06f..aab65a2b8 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h | |||
| @@ -64,6 +64,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager, const FileSys::Virtu | |||
| 64 | class VfsDirectoryServiceWrapper { | 64 | class VfsDirectoryServiceWrapper { |
| 65 | public: | 65 | public: |
| 66 | explicit VfsDirectoryServiceWrapper(FileSys::VirtualDir backing); | 66 | explicit VfsDirectoryServiceWrapper(FileSys::VirtualDir backing); |
| 67 | ~VfsDirectoryServiceWrapper(); | ||
| 67 | 68 | ||
| 68 | /** | 69 | /** |
| 69 | * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) | 70 | * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) |
diff --git a/src/core/hle/service/filesystem/fsp_ldr.cpp b/src/core/hle/service/filesystem/fsp_ldr.cpp index 0ab9c2606..fb487d5bc 100644 --- a/src/core/hle/service/filesystem/fsp_ldr.cpp +++ b/src/core/hle/service/filesystem/fsp_ldr.cpp | |||
| @@ -19,4 +19,6 @@ FSP_LDR::FSP_LDR() : ServiceFramework{"fsp:ldr"} { | |||
| 19 | RegisterHandlers(functions); | 19 | RegisterHandlers(functions); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | FSP_LDR::~FSP_LDR() = default; | ||
| 23 | |||
| 22 | } // namespace Service::FileSystem | 24 | } // namespace Service::FileSystem |
diff --git a/src/core/hle/service/filesystem/fsp_ldr.h b/src/core/hle/service/filesystem/fsp_ldr.h index fa8e11b4c..8210b7729 100644 --- a/src/core/hle/service/filesystem/fsp_ldr.h +++ b/src/core/hle/service/filesystem/fsp_ldr.h | |||
| @@ -11,6 +11,7 @@ namespace Service::FileSystem { | |||
| 11 | class FSP_LDR final : public ServiceFramework<FSP_LDR> { | 11 | class FSP_LDR final : public ServiceFramework<FSP_LDR> { |
| 12 | public: | 12 | public: |
| 13 | explicit FSP_LDR(); | 13 | explicit FSP_LDR(); |
| 14 | ~FSP_LDR() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::FileSystem | 17 | } // namespace Service::FileSystem |
diff --git a/src/core/hle/service/filesystem/fsp_pr.cpp b/src/core/hle/service/filesystem/fsp_pr.cpp index 32b0ae454..378201610 100644 --- a/src/core/hle/service/filesystem/fsp_pr.cpp +++ b/src/core/hle/service/filesystem/fsp_pr.cpp | |||
| @@ -20,4 +20,6 @@ FSP_PR::FSP_PR() : ServiceFramework{"fsp:pr"} { | |||
| 20 | RegisterHandlers(functions); | 20 | RegisterHandlers(functions); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | FSP_PR::~FSP_PR() = default; | ||
| 24 | |||
| 23 | } // namespace Service::FileSystem | 25 | } // namespace Service::FileSystem |
diff --git a/src/core/hle/service/filesystem/fsp_pr.h b/src/core/hle/service/filesystem/fsp_pr.h index 62edcd08a..556ae5ce9 100644 --- a/src/core/hle/service/filesystem/fsp_pr.h +++ b/src/core/hle/service/filesystem/fsp_pr.h | |||
| @@ -11,6 +11,7 @@ namespace Service::FileSystem { | |||
| 11 | class FSP_PR final : public ServiceFramework<FSP_PR> { | 11 | class FSP_PR final : public ServiceFramework<FSP_PR> { |
| 12 | public: | 12 | public: |
| 13 | explicit FSP_PR(); | 13 | explicit FSP_PR(); |
| 14 | ~FSP_PR() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::FileSystem | 17 | } // namespace Service::FileSystem |
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 3f8ff67e8..cabaf5a55 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp | |||
| @@ -520,6 +520,8 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { | |||
| 520 | RegisterHandlers(functions); | 520 | RegisterHandlers(functions); |
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | FSP_SRV::~FSP_SRV() = default; | ||
| 524 | |||
| 523 | void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { | 525 | void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { |
| 524 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 526 | LOG_WARNING(Service_FS, "(STUBBED) called"); |
| 525 | 527 | ||
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index 2b5c21abb..4aa0358cb 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h | |||
| @@ -16,7 +16,7 @@ namespace Service::FileSystem { | |||
| 16 | class FSP_SRV final : public ServiceFramework<FSP_SRV> { | 16 | class FSP_SRV final : public ServiceFramework<FSP_SRV> { |
| 17 | public: | 17 | public: |
| 18 | explicit FSP_SRV(); | 18 | explicit FSP_SRV(); |
| 19 | ~FSP_SRV() = default; | 19 | ~FSP_SRV() override; |
| 20 | 20 | ||
| 21 | private: | 21 | private: |
| 22 | void Initialize(Kernel::HLERequestContext& ctx); | 22 | void Initialize(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index f2b0e509a..d9225d624 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp | |||
| @@ -118,6 +118,8 @@ void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) { | |||
| 118 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | 118 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) |
| 119 | : ServiceFramework(name), module(std::move(module)) {} | 119 | : ServiceFramework(name), module(std::move(module)) {} |
| 120 | 120 | ||
| 121 | Module::Interface::~Interface() = default; | ||
| 122 | |||
| 121 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 123 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 122 | auto module = std::make_shared<Module>(); | 124 | auto module = std::make_shared<Module>(); |
| 123 | std::make_shared<Friend>(module, "friend:a")->InstallAsService(service_manager); | 125 | std::make_shared<Friend>(module, "friend:a")->InstallAsService(service_manager); |
diff --git a/src/core/hle/service/friend/friend.h b/src/core/hle/service/friend/friend.h index c1b36518a..e762840cb 100644 --- a/src/core/hle/service/friend/friend.h +++ b/src/core/hle/service/friend/friend.h | |||
| @@ -13,6 +13,7 @@ public: | |||
| 13 | class Interface : public ServiceFramework<Interface> { | 13 | class Interface : public ServiceFramework<Interface> { |
| 14 | public: | 14 | public: |
| 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); | 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); |
| 16 | ~Interface() override; | ||
| 16 | 17 | ||
| 17 | void CreateFriendService(Kernel::HLERequestContext& ctx); | 18 | void CreateFriendService(Kernel::HLERequestContext& ctx); |
| 18 | 19 | ||
diff --git a/src/core/hle/service/friend/interface.cpp b/src/core/hle/service/friend/interface.cpp index 27c6a09e2..5a6840af5 100644 --- a/src/core/hle/service/friend/interface.cpp +++ b/src/core/hle/service/friend/interface.cpp | |||
| @@ -16,4 +16,6 @@ Friend::Friend(std::shared_ptr<Module> module, const char* name) | |||
| 16 | RegisterHandlers(functions); | 16 | RegisterHandlers(functions); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | Friend::~Friend() = default; | ||
| 20 | |||
| 19 | } // namespace Service::Friend | 21 | } // namespace Service::Friend |
diff --git a/src/core/hle/service/friend/interface.h b/src/core/hle/service/friend/interface.h index 89dae8471..1963def39 100644 --- a/src/core/hle/service/friend/interface.h +++ b/src/core/hle/service/friend/interface.h | |||
| @@ -11,6 +11,7 @@ namespace Service::Friend { | |||
| 11 | class Friend final : public Module::Interface { | 11 | class Friend final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit Friend(std::shared_ptr<Module> module, const char* name); | 13 | explicit Friend(std::shared_ptr<Module> module, const char* name); |
| 14 | ~Friend() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::Friend | 17 | } // namespace Service::Friend |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 0d31abe8b..a8e0c869f 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -2,7 +2,6 @@ | |||
| 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 <atomic> | ||
| 6 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 6 | #include "core/core.h" |
| 8 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| @@ -78,7 +77,7 @@ private: | |||
| 78 | SharedMemory mem{}; | 77 | SharedMemory mem{}; |
| 79 | std::memcpy(&mem, shared_mem->GetPointer(), sizeof(SharedMemory)); | 78 | std::memcpy(&mem, shared_mem->GetPointer(), sizeof(SharedMemory)); |
| 80 | 79 | ||
| 81 | if (is_device_reload_pending.exchange(false)) | 80 | if (Settings::values.is_device_reload_pending.exchange(false)) |
| 82 | LoadInputDevices(); | 81 | LoadInputDevices(); |
| 83 | 82 | ||
| 84 | // Set up controllers as neon red+blue Joy-Con attached to console | 83 | // Set up controllers as neon red+blue Joy-Con attached to console |
| @@ -267,7 +266,6 @@ private: | |||
| 267 | CoreTiming::EventType* pad_update_event; | 266 | CoreTiming::EventType* pad_update_event; |
| 268 | 267 | ||
| 269 | // Stored input state info | 268 | // Stored input state info |
| 270 | std::atomic<bool> is_device_reload_pending{true}; | ||
| 271 | std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID> | 269 | std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID> |
| 272 | buttons; | 270 | buttons; |
| 273 | std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID> sticks; | 271 | std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID> sticks; |
| @@ -797,7 +795,9 @@ public: | |||
| 797 | } | 795 | } |
| 798 | }; | 796 | }; |
| 799 | 797 | ||
| 800 | void ReloadInputDevices() {} | 798 | void ReloadInputDevices() { |
| 799 | Settings::values.is_device_reload_pending.store(true); | ||
| 800 | } | ||
| 801 | 801 | ||
| 802 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 802 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 803 | std::make_shared<Hid>()->InstallAsService(service_manager); | 803 | std::make_shared<Hid>()->InstallAsService(service_manager); |
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index aaf311912..e587ad0d8 100644 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp | |||
| @@ -33,6 +33,8 @@ IRS::IRS() : ServiceFramework{"irs"} { | |||
| 33 | RegisterHandlers(functions); | 33 | RegisterHandlers(functions); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | IRS::~IRS() = default; | ||
| 37 | |||
| 36 | IRS_SYS::IRS_SYS() : ServiceFramework{"irs:sys"} { | 38 | IRS_SYS::IRS_SYS() : ServiceFramework{"irs:sys"} { |
| 37 | // clang-format off | 39 | // clang-format off |
| 38 | static const FunctionInfo functions[] = { | 40 | static const FunctionInfo functions[] = { |
| @@ -46,4 +48,6 @@ IRS_SYS::IRS_SYS() : ServiceFramework{"irs:sys"} { | |||
| 46 | RegisterHandlers(functions); | 48 | RegisterHandlers(functions); |
| 47 | } | 49 | } |
| 48 | 50 | ||
| 51 | IRS_SYS::~IRS_SYS() = default; | ||
| 52 | |||
| 49 | } // namespace Service::HID | 53 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h index a8be701c7..6fb16b45d 100644 --- a/src/core/hle/service/hid/irs.h +++ b/src/core/hle/service/hid/irs.h | |||
| @@ -11,11 +11,13 @@ namespace Service::HID { | |||
| 11 | class IRS final : public ServiceFramework<IRS> { | 11 | class IRS final : public ServiceFramework<IRS> { |
| 12 | public: | 12 | public: |
| 13 | explicit IRS(); | 13 | explicit IRS(); |
| 14 | ~IRS() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | class IRS_SYS final : public ServiceFramework<IRS_SYS> { | 17 | class IRS_SYS final : public ServiceFramework<IRS_SYS> { |
| 17 | public: | 18 | public: |
| 18 | explicit IRS_SYS(); | 19 | explicit IRS_SYS(); |
| 20 | ~IRS_SYS() override; | ||
| 19 | }; | 21 | }; |
| 20 | 22 | ||
| 21 | } // namespace Service::HID | 23 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/xcd.cpp b/src/core/hle/service/hid/xcd.cpp index 49f733f60..c8e9125f6 100644 --- a/src/core/hle/service/hid/xcd.cpp +++ b/src/core/hle/service/hid/xcd.cpp | |||
| @@ -34,4 +34,6 @@ XCD_SYS::XCD_SYS() : ServiceFramework{"xcd:sys"} { | |||
| 34 | RegisterHandlers(functions); | 34 | RegisterHandlers(functions); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | XCD_SYS::~XCD_SYS() = default; | ||
| 38 | |||
| 37 | } // namespace Service::HID | 39 | } // namespace Service::HID |
diff --git a/src/core/hle/service/hid/xcd.h b/src/core/hle/service/hid/xcd.h index 232a044df..fd506d303 100644 --- a/src/core/hle/service/hid/xcd.h +++ b/src/core/hle/service/hid/xcd.h | |||
| @@ -11,6 +11,7 @@ namespace Service::HID { | |||
| 11 | class XCD_SYS final : public ServiceFramework<XCD_SYS> { | 11 | class XCD_SYS final : public ServiceFramework<XCD_SYS> { |
| 12 | public: | 12 | public: |
| 13 | explicit XCD_SYS(); | 13 | explicit XCD_SYS(); |
| 14 | ~XCD_SYS() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::HID | 17 | } // namespace Service::HID |
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index 4f7543af5..f8d2127d9 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp | |||
| @@ -14,6 +14,8 @@ namespace Service::NFP { | |||
| 14 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | 14 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) |
| 15 | : ServiceFramework(name), module(std::move(module)) {} | 15 | : ServiceFramework(name), module(std::move(module)) {} |
| 16 | 16 | ||
| 17 | Module::Interface::~Interface() = default; | ||
| 18 | |||
| 17 | class IUser final : public ServiceFramework<IUser> { | 19 | class IUser final : public ServiceFramework<IUser> { |
| 18 | public: | 20 | public: |
| 19 | IUser() : ServiceFramework("IUser") { | 21 | IUser() : ServiceFramework("IUser") { |
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h index 0cd7be3d5..77df343c4 100644 --- a/src/core/hle/service/nfp/nfp.h +++ b/src/core/hle/service/nfp/nfp.h | |||
| @@ -13,6 +13,7 @@ public: | |||
| 13 | class Interface : public ServiceFramework<Interface> { | 13 | class Interface : public ServiceFramework<Interface> { |
| 14 | public: | 14 | public: |
| 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); | 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); |
| 16 | ~Interface() override; | ||
| 16 | 17 | ||
| 17 | void CreateUserInterface(Kernel::HLERequestContext& ctx); | 18 | void CreateUserInterface(Kernel::HLERequestContext& ctx); |
| 18 | 19 | ||
diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp index b608fe693..784a87c1b 100644 --- a/src/core/hle/service/nfp/nfp_user.cpp +++ b/src/core/hle/service/nfp/nfp_user.cpp | |||
| @@ -14,4 +14,6 @@ NFP_User::NFP_User(std::shared_ptr<Module> module) | |||
| 14 | RegisterHandlers(functions); | 14 | RegisterHandlers(functions); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | NFP_User::~NFP_User() = default; | ||
| 18 | |||
| 17 | } // namespace Service::NFP | 19 | } // namespace Service::NFP |
diff --git a/src/core/hle/service/nfp/nfp_user.h b/src/core/hle/service/nfp/nfp_user.h index 700043114..65d9aaf48 100644 --- a/src/core/hle/service/nfp/nfp_user.h +++ b/src/core/hle/service/nfp/nfp_user.h | |||
| @@ -11,6 +11,7 @@ namespace Service::NFP { | |||
| 11 | class NFP_User final : public Module::Interface { | 11 | class NFP_User final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit NFP_User(std::shared_ptr<Module> module); | 13 | explicit NFP_User(std::shared_ptr<Module> module); |
| 14 | ~NFP_User() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::NFP | 17 | } // namespace Service::NFP |
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 878bbe439..da1c46d59 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp | |||
| @@ -2,6 +2,13 @@ | |||
| 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 <FontChineseSimplified.h> | ||
| 6 | #include <FontChineseTraditional.h> | ||
| 7 | #include <FontExtendedChineseSimplified.h> | ||
| 8 | #include <FontKorean.h> | ||
| 9 | #include <FontNintendoExtended.h> | ||
| 10 | #include <FontStandard.h> | ||
| 11 | |||
| 5 | #include "common/common_paths.h" | 12 | #include "common/common_paths.h" |
| 6 | #include "common/file_util.h" | 13 | #include "common/file_util.h" |
| 7 | #include "core/core.h" | 14 | #include "core/core.h" |
| @@ -218,11 +225,30 @@ PL_U::PL_U() : ServiceFramework("pl:u") { | |||
| 218 | file.ReadBytes(shared_font->data(), shared_font->size()); | 225 | file.ReadBytes(shared_font->data(), shared_font->size()); |
| 219 | BuildSharedFontsRawRegions(*shared_font); | 226 | BuildSharedFontsRawRegions(*shared_font); |
| 220 | } else { | 227 | } else { |
| 221 | LOG_WARNING(Service_NS, "Unable to load shared font: {}", filepath); | 228 | LOG_WARNING(Service_NS, |
| 229 | "Shared Font file missing. Loading open source replacement from memory"); | ||
| 230 | |||
| 231 | const std::vector<std::vector<u8>> open_source_shared_fonts_ttf = { | ||
| 232 | {std::begin(FontChineseSimplified), std::end(FontChineseSimplified)}, | ||
| 233 | {std::begin(FontChineseTraditional), std::end(FontChineseTraditional)}, | ||
| 234 | {std::begin(FontExtendedChineseSimplified), | ||
| 235 | std::end(FontExtendedChineseSimplified)}, | ||
| 236 | {std::begin(FontNintendoExtended), std::end(FontNintendoExtended)}, | ||
| 237 | {std::begin(FontStandard), std::end(FontStandard)}, | ||
| 238 | }; | ||
| 239 | |||
| 240 | for (const std::vector<u8>& font_ttf : open_source_shared_fonts_ttf) { | ||
| 241 | const FontRegion region{static_cast<u32>(offset + 8), | ||
| 242 | static_cast<u32>(font_ttf.size())}; | ||
| 243 | EncryptSharedFont(font_ttf, *shared_font, offset); | ||
| 244 | SHARED_FONT_REGIONS.push_back(region); | ||
| 245 | } | ||
| 222 | } | 246 | } |
| 223 | } | 247 | } |
| 224 | } | 248 | } |
| 225 | 249 | ||
| 250 | PL_U::~PL_U() = default; | ||
| 251 | |||
| 226 | void PL_U::RequestLoad(Kernel::HLERequestContext& ctx) { | 252 | void PL_U::RequestLoad(Kernel::HLERequestContext& ctx) { |
| 227 | IPC::RequestParser rp{ctx}; | 253 | IPC::RequestParser rp{ctx}; |
| 228 | const u32 shared_font_type{rp.Pop<u32>()}; | 254 | const u32 shared_font_type{rp.Pop<u32>()}; |
diff --git a/src/core/hle/service/ns/pl_u.h b/src/core/hle/service/ns/pl_u.h index fcc2acab7..296c3db05 100644 --- a/src/core/hle/service/ns/pl_u.h +++ b/src/core/hle/service/ns/pl_u.h | |||
| @@ -13,7 +13,7 @@ namespace Service::NS { | |||
| 13 | class PL_U final : public ServiceFramework<PL_U> { | 13 | class PL_U final : public ServiceFramework<PL_U> { |
| 14 | public: | 14 | public: |
| 15 | PL_U(); | 15 | PL_U(); |
| 16 | ~PL_U() = default; | 16 | ~PL_U() override; |
| 17 | 17 | ||
| 18 | private: | 18 | private: |
| 19 | void RequestLoad(Kernel::HLERequestContext& ctx); | 19 | void RequestLoad(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 0b37098e1..92acc57b1 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -13,6 +13,9 @@ | |||
| 13 | 13 | ||
| 14 | namespace Service::Nvidia::Devices { | 14 | namespace Service::Nvidia::Devices { |
| 15 | 15 | ||
| 16 | nvdisp_disp0::nvdisp_disp0(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {} | ||
| 17 | nvdisp_disp0 ::~nvdisp_disp0() = default; | ||
| 18 | |||
| 16 | u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 19 | u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 17 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); | 20 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); |
| 18 | return 0; | 21 | return 0; |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h index 6f0697b58..a45086e45 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | |||
| @@ -17,8 +17,8 @@ class nvmap; | |||
| 17 | 17 | ||
| 18 | class nvdisp_disp0 final : public nvdevice { | 18 | class nvdisp_disp0 final : public nvdevice { |
| 19 | public: | 19 | public: |
| 20 | explicit nvdisp_disp0(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {} | 20 | explicit nvdisp_disp0(std::shared_ptr<nvmap> nvmap_dev); |
| 21 | ~nvdisp_disp0() = default; | 21 | ~nvdisp_disp0(); |
| 22 | 22 | ||
| 23 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 23 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| 24 | 24 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 75487c4e8..25d5a93fa 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | #include <utility> | ||
| 7 | |||
| 6 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 7 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 8 | #include "core/core.h" | 10 | #include "core/core.h" |
| @@ -14,6 +16,9 @@ | |||
| 14 | 16 | ||
| 15 | namespace Service::Nvidia::Devices { | 17 | namespace Service::Nvidia::Devices { |
| 16 | 18 | ||
| 19 | nvhost_as_gpu::nvhost_as_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {} | ||
| 20 | nvhost_as_gpu::~nvhost_as_gpu() = default; | ||
| 21 | |||
| 17 | u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 22 | u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 18 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 23 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 19 | command.raw, input.size(), output.size()); | 24 | command.raw, input.size(), output.size()); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index 9f8999d9c..eb14b1da8 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <unordered_map> | 8 | #include <unordered_map> |
| 9 | #include <utility> | ||
| 10 | #include <vector> | 9 | #include <vector> |
| 11 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 12 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| @@ -18,8 +17,8 @@ class nvmap; | |||
| 18 | 17 | ||
| 19 | class nvhost_as_gpu final : public nvdevice { | 18 | class nvhost_as_gpu final : public nvdevice { |
| 20 | public: | 19 | public: |
| 21 | explicit nvhost_as_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {} | 20 | explicit nvhost_as_gpu(std::shared_ptr<nvmap> nvmap_dev); |
| 22 | ~nvhost_as_gpu() override = default; | 21 | ~nvhost_as_gpu() override; |
| 23 | 22 | ||
| 24 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 23 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| 25 | 24 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 5685eb2be..b39fb9ef9 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -11,6 +11,9 @@ | |||
| 11 | 11 | ||
| 12 | namespace Service::Nvidia::Devices { | 12 | namespace Service::Nvidia::Devices { |
| 13 | 13 | ||
| 14 | nvhost_ctrl::nvhost_ctrl() = default; | ||
| 15 | nvhost_ctrl::~nvhost_ctrl() = default; | ||
| 16 | |||
| 14 | u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 17 | u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 15 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 18 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 16 | command.raw, input.size(), output.size()); | 19 | command.raw, input.size(), output.size()); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 6b496e9fe..6d0de2212 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | |||
| @@ -13,8 +13,8 @@ namespace Service::Nvidia::Devices { | |||
| 13 | 13 | ||
| 14 | class nvhost_ctrl final : public nvdevice { | 14 | class nvhost_ctrl final : public nvdevice { |
| 15 | public: | 15 | public: |
| 16 | nvhost_ctrl() = default; | 16 | nvhost_ctrl(); |
| 17 | ~nvhost_ctrl() override = default; | 17 | ~nvhost_ctrl() override; |
| 18 | 18 | ||
| 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| 20 | 20 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index ae421247d..7a88ae029 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | |||
| @@ -9,6 +9,9 @@ | |||
| 9 | 9 | ||
| 10 | namespace Service::Nvidia::Devices { | 10 | namespace Service::Nvidia::Devices { |
| 11 | 11 | ||
| 12 | nvhost_ctrl_gpu::nvhost_ctrl_gpu() = default; | ||
| 13 | nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; | ||
| 14 | |||
| 12 | u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 15 | u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 13 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 16 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 14 | command.raw, input.size(), output.size()); | 17 | command.raw, input.size(), output.size()); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index f09113e67..3bbf028ad 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h | |||
| @@ -13,8 +13,8 @@ namespace Service::Nvidia::Devices { | |||
| 13 | 13 | ||
| 14 | class nvhost_ctrl_gpu final : public nvdevice { | 14 | class nvhost_ctrl_gpu final : public nvdevice { |
| 15 | public: | 15 | public: |
| 16 | nvhost_ctrl_gpu() = default; | 16 | nvhost_ctrl_gpu(); |
| 17 | ~nvhost_ctrl_gpu() override = default; | 17 | ~nvhost_ctrl_gpu() override; |
| 18 | 18 | ||
| 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| 20 | 20 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 4cdf7f613..874d5e1c3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -8,11 +8,15 @@ | |||
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" | 9 | #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" |
| 10 | #include "core/memory.h" | 10 | #include "core/memory.h" |
| 11 | #include "video_core/command_processor.h" | ||
| 11 | #include "video_core/gpu.h" | 12 | #include "video_core/gpu.h" |
| 12 | #include "video_core/memory_manager.h" | 13 | #include "video_core/memory_manager.h" |
| 13 | 14 | ||
| 14 | namespace Service::Nvidia::Devices { | 15 | namespace Service::Nvidia::Devices { |
| 15 | 16 | ||
| 17 | nvhost_gpu::nvhost_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {} | ||
| 18 | nvhost_gpu::~nvhost_gpu() = default; | ||
| 19 | |||
| 16 | u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 20 | u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 17 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 21 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 18 | command.raw, input.size(), output.size()); | 22 | command.raw, input.size(), output.size()); |
| @@ -134,17 +138,16 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp | |||
| 134 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", | 138 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", |
| 135 | params.address, params.num_entries, params.flags); | 139 | params.address, params.num_entries, params.flags); |
| 136 | 140 | ||
| 137 | ASSERT_MSG(input.size() == | 141 | ASSERT_MSG(input.size() == sizeof(IoctlSubmitGpfifo) + |
| 138 | sizeof(IoctlSubmitGpfifo) + params.num_entries * sizeof(IoctlGpfifoEntry), | 142 | params.num_entries * sizeof(Tegra::CommandListHeader), |
| 139 | "Incorrect input size"); | 143 | "Incorrect input size"); |
| 140 | 144 | ||
| 141 | std::vector<IoctlGpfifoEntry> entries(params.num_entries); | 145 | std::vector<Tegra::CommandListHeader> entries(params.num_entries); |
| 142 | std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)], | 146 | std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)], |
| 143 | params.num_entries * sizeof(IoctlGpfifoEntry)); | 147 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
| 144 | for (auto entry : entries) { | 148 | |
| 145 | Tegra::GPUVAddr va_addr = entry.Address(); | 149 | Core::System::GetInstance().GPU().ProcessCommandLists(entries); |
| 146 | Core::System::GetInstance().GPU().ProcessCommandList(va_addr, entry.sz); | 150 | |
| 147 | } | ||
| 148 | params.fence_out.id = 0; | 151 | params.fence_out.id = 0; |
| 149 | params.fence_out.value = 0; | 152 | params.fence_out.value = 0; |
| 150 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmitGpfifo)); | 153 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmitGpfifo)); |
| @@ -160,14 +163,12 @@ u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output) | |||
| 160 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", | 163 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", |
| 161 | params.address, params.num_entries, params.flags); | 164 | params.address, params.num_entries, params.flags); |
| 162 | 165 | ||
| 163 | std::vector<IoctlGpfifoEntry> entries(params.num_entries); | 166 | std::vector<Tegra::CommandListHeader> entries(params.num_entries); |
| 164 | Memory::ReadBlock(params.address, entries.data(), | 167 | Memory::ReadBlock(params.address, entries.data(), |
| 165 | params.num_entries * sizeof(IoctlGpfifoEntry)); | 168 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
| 169 | |||
| 170 | Core::System::GetInstance().GPU().ProcessCommandLists(entries); | ||
| 166 | 171 | ||
| 167 | for (auto entry : entries) { | ||
| 168 | Tegra::GPUVAddr va_addr = entry.Address(); | ||
| 169 | Core::System::GetInstance().GPU().ProcessCommandList(va_addr, entry.sz); | ||
| 170 | } | ||
| 171 | params.fence_out.id = 0; | 172 | params.fence_out.id = 0; |
| 172 | params.fence_out.value = 0; | 173 | params.fence_out.value = 0; |
| 173 | std::memcpy(output.data(), ¶ms, output.size()); | 174 | std::memcpy(output.data(), ¶ms, output.size()); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index 03b7356d0..62beb5c0c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h | |||
| @@ -10,7 +10,6 @@ | |||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| 12 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 12 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| 13 | #include "video_core/memory_manager.h" | ||
| 14 | 13 | ||
| 15 | namespace Service::Nvidia::Devices { | 14 | namespace Service::Nvidia::Devices { |
| 16 | 15 | ||
| @@ -21,8 +20,8 @@ constexpr u32 NVGPU_IOCTL_CHANNEL_KICKOFF_PB(0x1b); | |||
| 21 | 20 | ||
| 22 | class nvhost_gpu final : public nvdevice { | 21 | class nvhost_gpu final : public nvdevice { |
| 23 | public: | 22 | public: |
| 24 | explicit nvhost_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {} | 23 | explicit nvhost_gpu(std::shared_ptr<nvmap> nvmap_dev); |
| 25 | ~nvhost_gpu() override = default; | 24 | ~nvhost_gpu() override; |
| 26 | 25 | ||
| 27 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 26 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| 28 | 27 | ||
| @@ -151,22 +150,6 @@ private: | |||
| 151 | }; | 150 | }; |
| 152 | static_assert(sizeof(IoctlAllocObjCtx) == 16, "IoctlAllocObjCtx is incorrect size"); | 151 | static_assert(sizeof(IoctlAllocObjCtx) == 16, "IoctlAllocObjCtx is incorrect size"); |
| 153 | 152 | ||
| 154 | struct IoctlGpfifoEntry { | ||
| 155 | u32_le entry0; // gpu_va_lo | ||
| 156 | union { | ||
| 157 | u32_le entry1; // gpu_va_hi | (unk_0x02 << 0x08) | (size << 0x0A) | (unk_0x01 << 0x1F) | ||
| 158 | BitField<0, 8, u32_le> gpu_va_hi; | ||
| 159 | BitField<8, 2, u32_le> unk1; | ||
| 160 | BitField<10, 21, u32_le> sz; | ||
| 161 | BitField<31, 1, u32_le> unk2; | ||
| 162 | }; | ||
| 163 | |||
| 164 | Tegra::GPUVAddr Address() const { | ||
| 165 | return (static_cast<Tegra::GPUVAddr>(gpu_va_hi) << 32) | entry0; | ||
| 166 | } | ||
| 167 | }; | ||
| 168 | static_assert(sizeof(IoctlGpfifoEntry) == 8, "IoctlGpfifoEntry is incorrect size"); | ||
| 169 | |||
| 170 | struct IoctlSubmitGpfifo { | 153 | struct IoctlSubmitGpfifo { |
| 171 | u64_le address; // pointer to gpfifo entry structs | 154 | u64_le address; // pointer to gpfifo entry structs |
| 172 | u32_le num_entries; // number of fence objects being submitted | 155 | u32_le num_entries; // number of fence objects being submitted |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index 364619e67..46dbbc37c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | |||
| @@ -10,6 +10,9 @@ | |||
| 10 | 10 | ||
| 11 | namespace Service::Nvidia::Devices { | 11 | namespace Service::Nvidia::Devices { |
| 12 | 12 | ||
| 13 | nvhost_nvdec::nvhost_nvdec() = default; | ||
| 14 | nvhost_nvdec::~nvhost_nvdec() = default; | ||
| 15 | |||
| 13 | u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 16 | u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 14 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 17 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 15 | command.raw, input.size(), output.size()); | 18 | command.raw, input.size(), output.size()); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index 6ad74421b..0e7b284f8 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | |||
| @@ -13,8 +13,8 @@ namespace Service::Nvidia::Devices { | |||
| 13 | 13 | ||
| 14 | class nvhost_nvdec final : public nvdevice { | 14 | class nvhost_nvdec final : public nvdevice { |
| 15 | public: | 15 | public: |
| 16 | nvhost_nvdec() = default; | 16 | nvhost_nvdec(); |
| 17 | ~nvhost_nvdec() override = default; | 17 | ~nvhost_nvdec() override; |
| 18 | 18 | ||
| 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| 20 | 20 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp index 51f01077b..c67f934f6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp | |||
| @@ -10,6 +10,9 @@ | |||
| 10 | 10 | ||
| 11 | namespace Service::Nvidia::Devices { | 11 | namespace Service::Nvidia::Devices { |
| 12 | 12 | ||
| 13 | nvhost_nvjpg::nvhost_nvjpg() = default; | ||
| 14 | nvhost_nvjpg::~nvhost_nvjpg() = default; | ||
| 15 | |||
| 13 | u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 16 | u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 14 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 17 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 15 | command.raw, input.size(), output.size()); | 18 | command.raw, input.size(), output.size()); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h index 2b0eb43ee..89fd5e95e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h | |||
| @@ -13,8 +13,8 @@ namespace Service::Nvidia::Devices { | |||
| 13 | 13 | ||
| 14 | class nvhost_nvjpg final : public nvdevice { | 14 | class nvhost_nvjpg final : public nvdevice { |
| 15 | public: | 15 | public: |
| 16 | nvhost_nvjpg() = default; | 16 | nvhost_nvjpg(); |
| 17 | ~nvhost_nvjpg() override = default; | 17 | ~nvhost_nvjpg() override; |
| 18 | 18 | ||
| 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| 20 | 20 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index fcb488d50..727b9fee4 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | |||
| @@ -10,6 +10,9 @@ | |||
| 10 | 10 | ||
| 11 | namespace Service::Nvidia::Devices { | 11 | namespace Service::Nvidia::Devices { |
| 12 | 12 | ||
| 13 | nvhost_vic::nvhost_vic() = default; | ||
| 14 | nvhost_vic::~nvhost_vic() = default; | ||
| 15 | |||
| 13 | u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 16 | u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 14 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", | 17 | LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", |
| 15 | command.raw, input.size(), output.size()); | 18 | command.raw, input.size(), output.size()); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index c7d681e52..fc24c3f9c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h | |||
| @@ -13,8 +13,8 @@ namespace Service::Nvidia::Devices { | |||
| 13 | 13 | ||
| 14 | class nvhost_vic final : public nvdevice { | 14 | class nvhost_vic final : public nvdevice { |
| 15 | public: | 15 | public: |
| 16 | nvhost_vic() = default; | 16 | nvhost_vic(); |
| 17 | ~nvhost_vic() override = default; | 17 | ~nvhost_vic() override; |
| 18 | 18 | ||
| 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 19 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| 20 | 20 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index e9305bfb3..a2287cc1b 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -11,6 +11,9 @@ | |||
| 11 | 11 | ||
| 12 | namespace Service::Nvidia::Devices { | 12 | namespace Service::Nvidia::Devices { |
| 13 | 13 | ||
| 14 | nvmap::nvmap() = default; | ||
| 15 | nvmap::~nvmap() = default; | ||
| 16 | |||
| 14 | VAddr nvmap::GetObjectAddress(u32 handle) const { | 17 | VAddr nvmap::GetObjectAddress(u32 handle) const { |
| 15 | auto object = GetObject(handle); | 18 | auto object = GetObject(handle); |
| 16 | ASSERT(object); | 19 | ASSERT(object); |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index f2eec6409..396230c19 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h | |||
| @@ -16,8 +16,8 @@ namespace Service::Nvidia::Devices { | |||
| 16 | 16 | ||
| 17 | class nvmap final : public nvdevice { | 17 | class nvmap final : public nvdevice { |
| 18 | public: | 18 | public: |
| 19 | nvmap() = default; | 19 | nvmap(); |
| 20 | ~nvmap() override = default; | 20 | ~nvmap() override; |
| 21 | 21 | ||
| 22 | /// Returns the allocated address of an nvmap object given its handle. | 22 | /// Returns the allocated address of an nvmap object given its handle. |
| 23 | VAddr GetObjectAddress(u32 handle) const; | 23 | VAddr GetObjectAddress(u32 handle) const; |
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index 634ab9196..ac3859353 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp | |||
| @@ -112,4 +112,6 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name) | |||
| 112 | query_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "NVDRV::query_event"); | 112 | query_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "NVDRV::query_event"); |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | NVDRV::~NVDRV() = default; | ||
| 116 | |||
| 115 | } // namespace Service::Nvidia | 117 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h index 1c3529bb6..d340893c2 100644 --- a/src/core/hle/service/nvdrv/interface.h +++ b/src/core/hle/service/nvdrv/interface.h | |||
| @@ -14,7 +14,7 @@ namespace Service::Nvidia { | |||
| 14 | class NVDRV final : public ServiceFramework<NVDRV> { | 14 | class NVDRV final : public ServiceFramework<NVDRV> { |
| 15 | public: | 15 | public: |
| 16 | NVDRV(std::shared_ptr<Module> nvdrv, const char* name); | 16 | NVDRV(std::shared_ptr<Module> nvdrv, const char* name); |
| 17 | ~NVDRV() = default; | 17 | ~NVDRV(); |
| 18 | 18 | ||
| 19 | private: | 19 | private: |
| 20 | void Open(Kernel::HLERequestContext& ctx); | 20 | void Open(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 2de39822f..6e4b8f2c6 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -45,6 +45,8 @@ Module::Module() { | |||
| 45 | devices["/dev/nvhost-vic"] = std::make_shared<Devices::nvhost_vic>(); | 45 | devices["/dev/nvhost-vic"] = std::make_shared<Devices::nvhost_vic>(); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | Module::~Module() = default; | ||
| 49 | |||
| 48 | u32 Module::Open(const std::string& device_name) { | 50 | u32 Module::Open(const std::string& device_name) { |
| 49 | ASSERT_MSG(devices.find(device_name) != devices.end(), "Trying to open unknown device {}", | 51 | ASSERT_MSG(devices.find(device_name) != devices.end(), "Trying to open unknown device {}", |
| 50 | device_name); | 52 | device_name); |
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index 99eb1128a..53564f696 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h | |||
| @@ -30,7 +30,7 @@ static_assert(sizeof(IoctlFence) == 8, "IoctlFence has wrong size"); | |||
| 30 | class Module final { | 30 | class Module final { |
| 31 | public: | 31 | public: |
| 32 | Module(); | 32 | Module(); |
| 33 | ~Module() = default; | 33 | ~Module(); |
| 34 | 34 | ||
| 35 | /// Returns a pointer to one of the available devices, identified by its name. | 35 | /// Returns a pointer to one of the available devices, identified by its name. |
| 36 | template <typename T> | 36 | template <typename T> |
diff --git a/src/core/hle/service/nvdrv/nvmemp.cpp b/src/core/hle/service/nvdrv/nvmemp.cpp index 0e8e21bad..b7b8b7a1b 100644 --- a/src/core/hle/service/nvdrv/nvmemp.cpp +++ b/src/core/hle/service/nvdrv/nvmemp.cpp | |||
| @@ -16,6 +16,8 @@ NVMEMP::NVMEMP() : ServiceFramework("nvmemp") { | |||
| 16 | RegisterHandlers(functions); | 16 | RegisterHandlers(functions); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | NVMEMP::~NVMEMP() = default; | ||
| 20 | |||
| 19 | void NVMEMP::Cmd0(Kernel::HLERequestContext& ctx) { | 21 | void NVMEMP::Cmd0(Kernel::HLERequestContext& ctx) { |
| 20 | UNIMPLEMENTED(); | 22 | UNIMPLEMENTED(); |
| 21 | } | 23 | } |
diff --git a/src/core/hle/service/nvdrv/nvmemp.h b/src/core/hle/service/nvdrv/nvmemp.h index dfdcabf4a..5a4dfc1f9 100644 --- a/src/core/hle/service/nvdrv/nvmemp.h +++ b/src/core/hle/service/nvdrv/nvmemp.h | |||
| @@ -11,7 +11,7 @@ namespace Service::Nvidia { | |||
| 11 | class NVMEMP final : public ServiceFramework<NVMEMP> { | 11 | class NVMEMP final : public ServiceFramework<NVMEMP> { |
| 12 | public: | 12 | public: |
| 13 | NVMEMP(); | 13 | NVMEMP(); |
| 14 | ~NVMEMP() = default; | 14 | ~NVMEMP(); |
| 15 | 15 | ||
| 16 | private: | 16 | private: |
| 17 | void Cmd0(Kernel::HLERequestContext& ctx); | 17 | void Cmd0(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 8d8962276..34f98fe5a 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -18,6 +18,8 @@ BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { | |||
| 18 | Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "BufferQueue NativeHandle"); | 18 | Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "BufferQueue NativeHandle"); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | BufferQueue::~BufferQueue() = default; | ||
| 22 | |||
| 21 | void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) { | 23 | void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) { |
| 22 | Buffer buffer{}; | 24 | Buffer buffer{}; |
| 23 | buffer.slot = slot; | 25 | buffer.slot = slot; |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index db2e17c0c..17c81928a 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h | |||
| @@ -46,7 +46,7 @@ public: | |||
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | BufferQueue(u32 id, u64 layer_id); | 48 | BufferQueue(u32 id, u64 layer_id); |
| 49 | ~BufferQueue() = default; | 49 | ~BufferQueue(); |
| 50 | 50 | ||
| 51 | enum class BufferTransformFlags : u32 { | 51 | enum class BufferTransformFlags : u32 { |
| 52 | /// No transform flags are set | 52 | /// No transform flags are set |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 06040da6f..7455ddd19 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -160,10 +160,13 @@ void NVFlinger::Compose() { | |||
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {} | 162 | Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {} |
| 163 | Layer::~Layer() = default; | ||
| 163 | 164 | ||
| 164 | Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) { | 165 | Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) { |
| 165 | auto& kernel = Core::System::GetInstance().Kernel(); | 166 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 166 | vsync_event = Kernel::Event::Create(kernel, Kernel::ResetType::Pulse, "Display VSync Event"); | 167 | vsync_event = Kernel::Event::Create(kernel, Kernel::ResetType::Pulse, "Display VSync Event"); |
| 167 | } | 168 | } |
| 168 | 169 | ||
| 170 | Display::~Display() = default; | ||
| 171 | |||
| 169 | } // namespace Service::NVFlinger | 172 | } // namespace Service::NVFlinger |
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index f7112949f..3dc69e69b 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h | |||
| @@ -26,7 +26,7 @@ class BufferQueue; | |||
| 26 | 26 | ||
| 27 | struct Layer { | 27 | struct Layer { |
| 28 | Layer(u64 id, std::shared_ptr<BufferQueue> queue); | 28 | Layer(u64 id, std::shared_ptr<BufferQueue> queue); |
| 29 | ~Layer() = default; | 29 | ~Layer(); |
| 30 | 30 | ||
| 31 | u64 id; | 31 | u64 id; |
| 32 | std::shared_ptr<BufferQueue> buffer_queue; | 32 | std::shared_ptr<BufferQueue> buffer_queue; |
| @@ -34,7 +34,7 @@ struct Layer { | |||
| 34 | 34 | ||
| 35 | struct Display { | 35 | struct Display { |
| 36 | Display(u64 id, std::string name); | 36 | Display(u64 id, std::string name); |
| 37 | ~Display() = default; | 37 | ~Display(); |
| 38 | 38 | ||
| 39 | u64 id; | 39 | u64 id; |
| 40 | std::string name; | 40 | std::string name; |
diff --git a/src/core/hle/service/pctl/module.cpp b/src/core/hle/service/pctl/module.cpp index 6cc3b1992..4fd185f69 100644 --- a/src/core/hle/service/pctl/module.cpp +++ b/src/core/hle/service/pctl/module.cpp | |||
| @@ -142,6 +142,8 @@ void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext | |||
| 142 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | 142 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) |
| 143 | : ServiceFramework(name), module(std::move(module)) {} | 143 | : ServiceFramework(name), module(std::move(module)) {} |
| 144 | 144 | ||
| 145 | Module::Interface::~Interface() = default; | ||
| 146 | |||
| 145 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 147 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 146 | auto module = std::make_shared<Module>(); | 148 | auto module = std::make_shared<Module>(); |
| 147 | std::make_shared<PCTL>(module, "pctl")->InstallAsService(service_manager); | 149 | std::make_shared<PCTL>(module, "pctl")->InstallAsService(service_manager); |
diff --git a/src/core/hle/service/pctl/module.h b/src/core/hle/service/pctl/module.h index e7d492760..3e449110d 100644 --- a/src/core/hle/service/pctl/module.h +++ b/src/core/hle/service/pctl/module.h | |||
| @@ -13,6 +13,7 @@ public: | |||
| 13 | class Interface : public ServiceFramework<Interface> { | 13 | class Interface : public ServiceFramework<Interface> { |
| 14 | public: | 14 | public: |
| 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); | 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); |
| 16 | ~Interface() override; | ||
| 16 | 17 | ||
| 17 | void CreateService(Kernel::HLERequestContext& ctx); | 18 | void CreateService(Kernel::HLERequestContext& ctx); |
| 18 | void CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx); | 19 | void CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/pctl/pctl.cpp b/src/core/hle/service/pctl/pctl.cpp index de2741d66..af9d1433a 100644 --- a/src/core/hle/service/pctl/pctl.cpp +++ b/src/core/hle/service/pctl/pctl.cpp | |||
| @@ -14,4 +14,6 @@ PCTL::PCTL(std::shared_ptr<Module> module, const char* name) | |||
| 14 | }; | 14 | }; |
| 15 | RegisterHandlers(functions); | 15 | RegisterHandlers(functions); |
| 16 | } | 16 | } |
| 17 | |||
| 18 | PCTL::~PCTL() = default; | ||
| 17 | } // namespace Service::PCTL | 19 | } // namespace Service::PCTL |
diff --git a/src/core/hle/service/pctl/pctl.h b/src/core/hle/service/pctl/pctl.h index 8ddf69128..c33ea80b6 100644 --- a/src/core/hle/service/pctl/pctl.h +++ b/src/core/hle/service/pctl/pctl.h | |||
| @@ -11,6 +11,7 @@ namespace Service::PCTL { | |||
| 11 | class PCTL final : public Module::Interface { | 11 | class PCTL final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit PCTL(std::shared_ptr<Module> module, const char* name); | 13 | explicit PCTL(std::shared_ptr<Module> module, const char* name); |
| 14 | ~PCTL() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::PCTL | 17 | } // namespace Service::PCTL |
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 9d804652e..9bb7c7b26 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -74,8 +74,6 @@ using Kernel::SharedPtr; | |||
| 74 | 74 | ||
| 75 | namespace Service { | 75 | namespace Service { |
| 76 | 76 | ||
| 77 | std::unordered_map<std::string, SharedPtr<ClientPort>> g_kernel_named_ports; | ||
| 78 | |||
| 79 | /** | 77 | /** |
| 80 | * Creates a function string for logging, complete with the name (or header code, depending | 78 | * Creates a function string for logging, complete with the name (or header code, depending |
| 81 | * on what's passed in) the port name, and all the cmd_buff arguments. | 79 | * on what's passed in) the port name, and all the cmd_buff arguments. |
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 92b0640e8..59eb20155 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp | |||
| @@ -112,4 +112,6 @@ SET::SET() : ServiceFramework("set") { | |||
| 112 | RegisterHandlers(functions); | 112 | RegisterHandlers(functions); |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | SET::~SET() = default; | ||
| 116 | |||
| 115 | } // namespace Service::Set | 117 | } // namespace Service::Set |
diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h index 669e740b7..5f0214359 100644 --- a/src/core/hle/service/set/set.h +++ b/src/core/hle/service/set/set.h | |||
| @@ -33,7 +33,7 @@ LanguageCode GetLanguageCodeFromIndex(size_t idx); | |||
| 33 | class SET final : public ServiceFramework<SET> { | 33 | class SET final : public ServiceFramework<SET> { |
| 34 | public: | 34 | public: |
| 35 | explicit SET(); | 35 | explicit SET(); |
| 36 | ~SET() = default; | 36 | ~SET() override; |
| 37 | 37 | ||
| 38 | private: | 38 | private: |
| 39 | void GetLanguageCode(Kernel::HLERequestContext& ctx); | 39 | void GetLanguageCode(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/set/set_cal.cpp b/src/core/hle/service/set/set_cal.cpp index 7066ef725..5af356d10 100644 --- a/src/core/hle/service/set/set_cal.cpp +++ b/src/core/hle/service/set/set_cal.cpp | |||
| @@ -44,4 +44,6 @@ SET_CAL::SET_CAL() : ServiceFramework("set:cal") { | |||
| 44 | RegisterHandlers(functions); | 44 | RegisterHandlers(functions); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | SET_CAL::~SET_CAL() = default; | ||
| 48 | |||
| 47 | } // namespace Service::Set | 49 | } // namespace Service::Set |
diff --git a/src/core/hle/service/set/set_cal.h b/src/core/hle/service/set/set_cal.h index bb50336aa..583036eac 100644 --- a/src/core/hle/service/set/set_cal.h +++ b/src/core/hle/service/set/set_cal.h | |||
| @@ -11,7 +11,7 @@ namespace Service::Set { | |||
| 11 | class SET_CAL final : public ServiceFramework<SET_CAL> { | 11 | class SET_CAL final : public ServiceFramework<SET_CAL> { |
| 12 | public: | 12 | public: |
| 13 | explicit SET_CAL(); | 13 | explicit SET_CAL(); |
| 14 | ~SET_CAL() = default; | 14 | ~SET_CAL(); |
| 15 | }; | 15 | }; |
| 16 | 16 | ||
| 17 | } // namespace Service::Set | 17 | } // namespace Service::Set |
diff --git a/src/core/hle/service/set/set_fd.cpp b/src/core/hle/service/set/set_fd.cpp index c9f938716..cac6af86d 100644 --- a/src/core/hle/service/set/set_fd.cpp +++ b/src/core/hle/service/set/set_fd.cpp | |||
| @@ -20,4 +20,6 @@ SET_FD::SET_FD() : ServiceFramework("set:fd") { | |||
| 20 | RegisterHandlers(functions); | 20 | RegisterHandlers(functions); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | SET_FD::~SET_FD() = default; | ||
| 24 | |||
| 23 | } // namespace Service::Set | 25 | } // namespace Service::Set |
diff --git a/src/core/hle/service/set/set_fd.h b/src/core/hle/service/set/set_fd.h index dbd850bc7..216e65f1f 100644 --- a/src/core/hle/service/set/set_fd.h +++ b/src/core/hle/service/set/set_fd.h | |||
| @@ -11,7 +11,7 @@ namespace Service::Set { | |||
| 11 | class SET_FD final : public ServiceFramework<SET_FD> { | 11 | class SET_FD final : public ServiceFramework<SET_FD> { |
| 12 | public: | 12 | public: |
| 13 | explicit SET_FD(); | 13 | explicit SET_FD(); |
| 14 | ~SET_FD() = default; | 14 | ~SET_FD() override; |
| 15 | }; | 15 | }; |
| 16 | 16 | ||
| 17 | } // namespace Service::Set | 17 | } // namespace Service::Set |
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 3211a8346..4342f3b2d 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp | |||
| @@ -109,6 +109,8 @@ BSD::BSD(const char* name) : ServiceFramework(name) { | |||
| 109 | RegisterHandlers(functions); | 109 | RegisterHandlers(functions); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | BSD::~BSD() = default; | ||
| 113 | |||
| 112 | BSDCFG::BSDCFG() : ServiceFramework{"bsdcfg"} { | 114 | BSDCFG::BSDCFG() : ServiceFramework{"bsdcfg"} { |
| 113 | // clang-format off | 115 | // clang-format off |
| 114 | static const FunctionInfo functions[] = { | 116 | static const FunctionInfo functions[] = { |
| @@ -131,4 +133,6 @@ BSDCFG::BSDCFG() : ServiceFramework{"bsdcfg"} { | |||
| 131 | RegisterHandlers(functions); | 133 | RegisterHandlers(functions); |
| 132 | } | 134 | } |
| 133 | 135 | ||
| 136 | BSDCFG::~BSDCFG() = default; | ||
| 137 | |||
| 134 | } // namespace Service::Sockets | 138 | } // namespace Service::Sockets |
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index c1da59b24..0fe0e65c6 100644 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h | |||
| @@ -12,7 +12,7 @@ namespace Service::Sockets { | |||
| 12 | class BSD final : public ServiceFramework<BSD> { | 12 | class BSD final : public ServiceFramework<BSD> { |
| 13 | public: | 13 | public: |
| 14 | explicit BSD(const char* name); | 14 | explicit BSD(const char* name); |
| 15 | ~BSD() = default; | 15 | ~BSD() override; |
| 16 | 16 | ||
| 17 | private: | 17 | private: |
| 18 | void RegisterClient(Kernel::HLERequestContext& ctx); | 18 | void RegisterClient(Kernel::HLERequestContext& ctx); |
| @@ -29,6 +29,7 @@ private: | |||
| 29 | class BSDCFG final : public ServiceFramework<BSDCFG> { | 29 | class BSDCFG final : public ServiceFramework<BSDCFG> { |
| 30 | public: | 30 | public: |
| 31 | explicit BSDCFG(); | 31 | explicit BSDCFG(); |
| 32 | ~BSDCFG() override; | ||
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 34 | } // namespace Service::Sockets | 35 | } // namespace Service::Sockets |
diff --git a/src/core/hle/service/sockets/ethc.cpp b/src/core/hle/service/sockets/ethc.cpp index d53c25eec..abbeb4c50 100644 --- a/src/core/hle/service/sockets/ethc.cpp +++ b/src/core/hle/service/sockets/ethc.cpp | |||
| @@ -21,6 +21,8 @@ ETHC_C::ETHC_C() : ServiceFramework{"ethc:c"} { | |||
| 21 | RegisterHandlers(functions); | 21 | RegisterHandlers(functions); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | ETHC_C::~ETHC_C() = default; | ||
| 25 | |||
| 24 | ETHC_I::ETHC_I() : ServiceFramework{"ethc:i"} { | 26 | ETHC_I::ETHC_I() : ServiceFramework{"ethc:i"} { |
| 25 | // clang-format off | 27 | // clang-format off |
| 26 | static const FunctionInfo functions[] = { | 28 | static const FunctionInfo functions[] = { |
| @@ -35,4 +37,6 @@ ETHC_I::ETHC_I() : ServiceFramework{"ethc:i"} { | |||
| 35 | RegisterHandlers(functions); | 37 | RegisterHandlers(functions); |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 40 | ETHC_I::~ETHC_I() = default; | ||
| 41 | |||
| 38 | } // namespace Service::Sockets | 42 | } // namespace Service::Sockets |
diff --git a/src/core/hle/service/sockets/ethc.h b/src/core/hle/service/sockets/ethc.h index 9a3c88100..da2c7f741 100644 --- a/src/core/hle/service/sockets/ethc.h +++ b/src/core/hle/service/sockets/ethc.h | |||
| @@ -11,11 +11,13 @@ namespace Service::Sockets { | |||
| 11 | class ETHC_C final : public ServiceFramework<ETHC_C> { | 11 | class ETHC_C final : public ServiceFramework<ETHC_C> { |
| 12 | public: | 12 | public: |
| 13 | explicit ETHC_C(); | 13 | explicit ETHC_C(); |
| 14 | ~ETHC_C() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | class ETHC_I final : public ServiceFramework<ETHC_I> { | 17 | class ETHC_I final : public ServiceFramework<ETHC_I> { |
| 17 | public: | 18 | public: |
| 18 | explicit ETHC_I(); | 19 | explicit ETHC_I(); |
| 20 | ~ETHC_I() override; | ||
| 19 | }; | 21 | }; |
| 20 | 22 | ||
| 21 | } // namespace Service::Sockets | 23 | } // namespace Service::Sockets |
diff --git a/src/core/hle/service/sockets/nsd.cpp b/src/core/hle/service/sockets/nsd.cpp index 8682dc2e0..e6d73065e 100644 --- a/src/core/hle/service/sockets/nsd.cpp +++ b/src/core/hle/service/sockets/nsd.cpp | |||
| @@ -29,4 +29,6 @@ NSD::NSD(const char* name) : ServiceFramework(name) { | |||
| 29 | RegisterHandlers(functions); | 29 | RegisterHandlers(functions); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | NSD::~NSD() = default; | ||
| 33 | |||
| 32 | } // namespace Service::Sockets | 34 | } // namespace Service::Sockets |
diff --git a/src/core/hle/service/sockets/nsd.h b/src/core/hle/service/sockets/nsd.h index 3b7edfc43..d842e3232 100644 --- a/src/core/hle/service/sockets/nsd.h +++ b/src/core/hle/service/sockets/nsd.h | |||
| @@ -12,7 +12,7 @@ namespace Service::Sockets { | |||
| 12 | class NSD final : public ServiceFramework<NSD> { | 12 | class NSD final : public ServiceFramework<NSD> { |
| 13 | public: | 13 | public: |
| 14 | explicit NSD(const char* name); | 14 | explicit NSD(const char* name); |
| 15 | ~NSD() = default; | 15 | ~NSD() override; |
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| 18 | } // namespace Service::Sockets | 18 | } // namespace Service::Sockets |
diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index d235c4cfd..13ab1d31e 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp | |||
| @@ -34,4 +34,6 @@ SFDNSRES::SFDNSRES() : ServiceFramework("sfdnsres") { | |||
| 34 | RegisterHandlers(functions); | 34 | RegisterHandlers(functions); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | SFDNSRES::~SFDNSRES() = default; | ||
| 38 | |||
| 37 | } // namespace Service::Sockets | 39 | } // namespace Service::Sockets |
diff --git a/src/core/hle/service/sockets/sfdnsres.h b/src/core/hle/service/sockets/sfdnsres.h index 62c7e35bf..eda432903 100644 --- a/src/core/hle/service/sockets/sfdnsres.h +++ b/src/core/hle/service/sockets/sfdnsres.h | |||
| @@ -12,7 +12,7 @@ namespace Service::Sockets { | |||
| 12 | class SFDNSRES final : public ServiceFramework<SFDNSRES> { | 12 | class SFDNSRES final : public ServiceFramework<SFDNSRES> { |
| 13 | public: | 13 | public: |
| 14 | explicit SFDNSRES(); | 14 | explicit SFDNSRES(); |
| 15 | ~SFDNSRES() = default; | 15 | ~SFDNSRES() override; |
| 16 | 16 | ||
| 17 | private: | 17 | private: |
| 18 | void GetAddrInfo(Kernel::HLERequestContext& ctx); | 18 | void GetAddrInfo(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/spl/csrng.cpp b/src/core/hle/service/spl/csrng.cpp index b9e6b799d..674928798 100644 --- a/src/core/hle/service/spl/csrng.cpp +++ b/src/core/hle/service/spl/csrng.cpp | |||
| @@ -13,4 +13,6 @@ CSRNG::CSRNG(std::shared_ptr<Module> module) : Module::Interface(std::move(modul | |||
| 13 | RegisterHandlers(functions); | 13 | RegisterHandlers(functions); |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | CSRNG::~CSRNG() = default; | ||
| 17 | |||
| 16 | } // namespace Service::SPL | 18 | } // namespace Service::SPL |
diff --git a/src/core/hle/service/spl/csrng.h b/src/core/hle/service/spl/csrng.h index 3f849b5a7..764d5ceb0 100644 --- a/src/core/hle/service/spl/csrng.h +++ b/src/core/hle/service/spl/csrng.h | |||
| @@ -11,6 +11,7 @@ namespace Service::SPL { | |||
| 11 | class CSRNG final : public Module::Interface { | 11 | class CSRNG final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit CSRNG(std::shared_ptr<Module> module); | 13 | explicit CSRNG(std::shared_ptr<Module> module); |
| 14 | ~CSRNG() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::SPL | 17 | } // namespace Service::SPL |
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp index 3f5a342a7..0d8441fb1 100644 --- a/src/core/hle/service/spl/module.cpp +++ b/src/core/hle/service/spl/module.cpp | |||
| @@ -16,6 +16,8 @@ namespace Service::SPL { | |||
| 16 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | 16 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) |
| 17 | : ServiceFramework(name), module(std::move(module)) {} | 17 | : ServiceFramework(name), module(std::move(module)) {} |
| 18 | 18 | ||
| 19 | Module::Interface::~Interface() = default; | ||
| 20 | |||
| 19 | void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) { | 21 | void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) { |
| 20 | IPC::RequestParser rp{ctx}; | 22 | IPC::RequestParser rp{ctx}; |
| 21 | 23 | ||
diff --git a/src/core/hle/service/spl/module.h b/src/core/hle/service/spl/module.h index f24d998e8..48fda6099 100644 --- a/src/core/hle/service/spl/module.h +++ b/src/core/hle/service/spl/module.h | |||
| @@ -13,6 +13,7 @@ public: | |||
| 13 | class Interface : public ServiceFramework<Interface> { | 13 | class Interface : public ServiceFramework<Interface> { |
| 14 | public: | 14 | public: |
| 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); | 15 | explicit Interface(std::shared_ptr<Module> module, const char* name); |
| 16 | ~Interface() override; | ||
| 16 | 17 | ||
| 17 | void GetRandomBytes(Kernel::HLERequestContext& ctx); | 18 | void GetRandomBytes(Kernel::HLERequestContext& ctx); |
| 18 | 19 | ||
diff --git a/src/core/hle/service/spl/spl.cpp b/src/core/hle/service/spl/spl.cpp index bb1e03342..70cb41905 100644 --- a/src/core/hle/service/spl/spl.cpp +++ b/src/core/hle/service/spl/spl.cpp | |||
| @@ -42,4 +42,6 @@ SPL::SPL(std::shared_ptr<Module> module) : Module::Interface(std::move(module), | |||
| 42 | RegisterHandlers(functions); | 42 | RegisterHandlers(functions); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | SPL::~SPL() = default; | ||
| 46 | |||
| 45 | } // namespace Service::SPL | 47 | } // namespace Service::SPL |
diff --git a/src/core/hle/service/spl/spl.h b/src/core/hle/service/spl/spl.h index 69c4c1747..3637d1623 100644 --- a/src/core/hle/service/spl/spl.h +++ b/src/core/hle/service/spl/spl.h | |||
| @@ -11,6 +11,7 @@ namespace Service::SPL { | |||
| 11 | class SPL final : public Module::Interface { | 11 | class SPL final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit SPL(std::shared_ptr<Module> module); | 13 | explicit SPL(std::shared_ptr<Module> module); |
| 14 | ~SPL() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::SPL | 17 | } // namespace Service::SPL |
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp index 048d5b077..18a5d71d5 100644 --- a/src/core/hle/service/time/interface.cpp +++ b/src/core/hle/service/time/interface.cpp | |||
| @@ -29,4 +29,6 @@ Time::Time(std::shared_ptr<Module> time, const char* name) | |||
| 29 | RegisterHandlers(functions); | 29 | RegisterHandlers(functions); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | Time::~Time() = default; | ||
| 33 | |||
| 32 | } // namespace Service::Time | 34 | } // namespace Service::Time |
diff --git a/src/core/hle/service/time/interface.h b/src/core/hle/service/time/interface.h index 183a53db1..cd6b44dec 100644 --- a/src/core/hle/service/time/interface.h +++ b/src/core/hle/service/time/interface.h | |||
| @@ -11,6 +11,7 @@ namespace Service::Time { | |||
| 11 | class Time final : public Module::Interface { | 11 | class Time final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit Time(std::shared_ptr<Module> time, const char* name); | 13 | explicit Time(std::shared_ptr<Module> time, const char* name); |
| 14 | ~Time() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::Time | 17 | } // namespace Service::Time |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 2172c681b..28fd8debc 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -210,6 +210,8 @@ void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& c | |||
| 210 | Module::Interface::Interface(std::shared_ptr<Module> time, const char* name) | 210 | Module::Interface::Interface(std::shared_ptr<Module> time, const char* name) |
| 211 | : ServiceFramework(name), time(std::move(time)) {} | 211 | : ServiceFramework(name), time(std::move(time)) {} |
| 212 | 212 | ||
| 213 | Module::Interface::~Interface() = default; | ||
| 214 | |||
| 213 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 215 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 214 | auto time = std::make_shared<Module>(); | 216 | auto time = std::make_shared<Module>(); |
| 215 | std::make_shared<Time>(time, "time:a")->InstallAsService(service_manager); | 217 | std::make_shared<Time>(time, "time:a")->InstallAsService(service_manager); |
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 8dde28a94..5659ecad3 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h | |||
| @@ -58,6 +58,7 @@ public: | |||
| 58 | class Interface : public ServiceFramework<Interface> { | 58 | class Interface : public ServiceFramework<Interface> { |
| 59 | public: | 59 | public: |
| 60 | explicit Interface(std::shared_ptr<Module> time, const char* name); | 60 | explicit Interface(std::shared_ptr<Module> time, const char* name); |
| 61 | ~Interface() override; | ||
| 61 | 62 | ||
| 62 | void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); | 63 | void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); |
| 63 | void GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx); | 64 | void GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 993f1e65a..85244ac3b 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -984,6 +984,8 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name, | |||
| 984 | std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) | 984 | std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) |
| 985 | : ServiceFramework(name), module(std::move(module)), nv_flinger(std::move(nv_flinger)) {} | 985 | : ServiceFramework(name), module(std::move(module)), nv_flinger(std::move(nv_flinger)) {} |
| 986 | 986 | ||
| 987 | Module::Interface::~Interface() = default; | ||
| 988 | |||
| 987 | void Module::Interface::GetDisplayService(Kernel::HLERequestContext& ctx) { | 989 | void Module::Interface::GetDisplayService(Kernel::HLERequestContext& ctx) { |
| 988 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 990 | LOG_WARNING(Service_VI, "(STUBBED) called"); |
| 989 | 991 | ||
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h index 92f5b6059..c2dc83605 100644 --- a/src/core/hle/service/vi/vi.h +++ b/src/core/hle/service/vi/vi.h | |||
| @@ -26,6 +26,7 @@ public: | |||
| 26 | public: | 26 | public: |
| 27 | explicit Interface(std::shared_ptr<Module> module, const char* name, | 27 | explicit Interface(std::shared_ptr<Module> module, const char* name, |
| 28 | std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); | 28 | std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); |
| 29 | ~Interface() override; | ||
| 29 | 30 | ||
| 30 | void GetDisplayService(Kernel::HLERequestContext& ctx); | 31 | void GetDisplayService(Kernel::HLERequestContext& ctx); |
| 31 | 32 | ||
diff --git a/src/core/hle/service/vi/vi_m.cpp b/src/core/hle/service/vi/vi_m.cpp index d47da565b..207c06b16 100644 --- a/src/core/hle/service/vi/vi_m.cpp +++ b/src/core/hle/service/vi/vi_m.cpp | |||
| @@ -15,4 +15,6 @@ VI_M::VI_M(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> | |||
| 15 | RegisterHandlers(functions); | 15 | RegisterHandlers(functions); |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | VI_M::~VI_M() = default; | ||
| 19 | |||
| 18 | } // namespace Service::VI | 20 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/vi_m.h b/src/core/hle/service/vi/vi_m.h index 6abb9b3a3..487d58d50 100644 --- a/src/core/hle/service/vi/vi_m.h +++ b/src/core/hle/service/vi/vi_m.h | |||
| @@ -11,6 +11,7 @@ namespace Service::VI { | |||
| 11 | class VI_M final : public Module::Interface { | 11 | class VI_M final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit VI_M(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); | 13 | explicit VI_M(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); |
| 14 | ~VI_M() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::VI | 17 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/vi_s.cpp b/src/core/hle/service/vi/vi_s.cpp index 8f82e797f..920e6a1f6 100644 --- a/src/core/hle/service/vi/vi_s.cpp +++ b/src/core/hle/service/vi/vi_s.cpp | |||
| @@ -15,4 +15,6 @@ VI_S::VI_S(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> | |||
| 15 | RegisterHandlers(functions); | 15 | RegisterHandlers(functions); |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | VI_S::~VI_S() = default; | ||
| 19 | |||
| 18 | } // namespace Service::VI | 20 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/vi_s.h b/src/core/hle/service/vi/vi_s.h index 8f16f804f..bbc31148f 100644 --- a/src/core/hle/service/vi/vi_s.h +++ b/src/core/hle/service/vi/vi_s.h | |||
| @@ -11,6 +11,7 @@ namespace Service::VI { | |||
| 11 | class VI_S final : public Module::Interface { | 11 | class VI_S final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit VI_S(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); | 13 | explicit VI_S(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); |
| 14 | ~VI_S() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::VI | 17 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/vi_u.cpp b/src/core/hle/service/vi/vi_u.cpp index b84aed1d5..d81e410d6 100644 --- a/src/core/hle/service/vi/vi_u.cpp +++ b/src/core/hle/service/vi/vi_u.cpp | |||
| @@ -14,4 +14,6 @@ VI_U::VI_U(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> | |||
| 14 | RegisterHandlers(functions); | 14 | RegisterHandlers(functions); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | VI_U::~VI_U() = default; | ||
| 18 | |||
| 17 | } // namespace Service::VI | 19 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/vi_u.h b/src/core/hle/service/vi/vi_u.h index e9b4f76b2..b92f28c92 100644 --- a/src/core/hle/service/vi/vi_u.h +++ b/src/core/hle/service/vi/vi_u.h | |||
| @@ -11,6 +11,7 @@ namespace Service::VI { | |||
| 11 | class VI_U final : public Module::Interface { | 11 | class VI_U final : public Module::Interface { |
| 12 | public: | 12 | public: |
| 13 | explicit VI_U(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); | 13 | explicit VI_U(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); |
| 14 | ~VI_U() override; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | } // namespace Service::VI | 17 | } // namespace Service::VI |
diff --git a/src/core/settings.h b/src/core/settings.h index 5bf1863e6..08a16ef2c 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <atomic> | ||
| 8 | #include <string> | 9 | #include <string> |
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | 11 | ||
| @@ -120,6 +121,7 @@ struct Values { | |||
| 120 | std::array<std::string, NativeAnalog::NumAnalogs> analogs; | 121 | std::array<std::string, NativeAnalog::NumAnalogs> analogs; |
| 121 | std::string motion_device; | 122 | std::string motion_device; |
| 122 | std::string touch_device; | 123 | std::string touch_device; |
| 124 | std::atomic_bool is_device_reload_pending{true}; | ||
| 123 | 125 | ||
| 124 | // Core | 126 | // Core |
| 125 | bool use_cpu_jit; | 127 | bool use_cpu_jit; |
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index b12623d55..37f572853 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | #include <thread> | ||
| 6 | #include "common/param_package.h" | 7 | #include "common/param_package.h" |
| 7 | #include "input_common/analog_from_button.h" | 8 | #include "input_common/analog_from_button.h" |
| 8 | #include "input_common/keyboard.h" | 9 | #include "input_common/keyboard.h" |
| @@ -17,6 +18,10 @@ namespace InputCommon { | |||
| 17 | static std::shared_ptr<Keyboard> keyboard; | 18 | static std::shared_ptr<Keyboard> keyboard; |
| 18 | static std::shared_ptr<MotionEmu> motion_emu; | 19 | static std::shared_ptr<MotionEmu> motion_emu; |
| 19 | 20 | ||
| 21 | #ifdef HAVE_SDL2 | ||
| 22 | static std::thread poll_thread; | ||
| 23 | #endif | ||
| 24 | |||
| 20 | void Init() { | 25 | void Init() { |
| 21 | keyboard = std::make_shared<Keyboard>(); | 26 | keyboard = std::make_shared<Keyboard>(); |
| 22 | Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard); | 27 | Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard); |
| @@ -30,6 +35,12 @@ void Init() { | |||
| 30 | #endif | 35 | #endif |
| 31 | } | 36 | } |
| 32 | 37 | ||
| 38 | void StartJoystickEventHandler() { | ||
| 39 | #ifdef HAVE_SDL2 | ||
| 40 | poll_thread = std::thread(SDL::PollLoop); | ||
| 41 | #endif | ||
| 42 | } | ||
| 43 | |||
| 33 | void Shutdown() { | 44 | void Shutdown() { |
| 34 | Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); | 45 | Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); |
| 35 | keyboard.reset(); | 46 | keyboard.reset(); |
| @@ -39,6 +50,7 @@ void Shutdown() { | |||
| 39 | 50 | ||
| 40 | #ifdef HAVE_SDL2 | 51 | #ifdef HAVE_SDL2 |
| 41 | SDL::Shutdown(); | 52 | SDL::Shutdown(); |
| 53 | poll_thread.join(); | ||
| 42 | #endif | 54 | #endif |
| 43 | } | 55 | } |
| 44 | 56 | ||
diff --git a/src/input_common/main.h b/src/input_common/main.h index 77a0ce90b..9eb13106e 100644 --- a/src/input_common/main.h +++ b/src/input_common/main.h | |||
| @@ -20,6 +20,8 @@ void Init(); | |||
| 20 | /// Deregisters all built-in input device factories and shuts them down. | 20 | /// Deregisters all built-in input device factories and shuts them down. |
| 21 | void Shutdown(); | 21 | void Shutdown(); |
| 22 | 22 | ||
| 23 | void StartJoystickEventHandler(); | ||
| 24 | |||
| 23 | class Keyboard; | 25 | class Keyboard; |
| 24 | 26 | ||
| 25 | /// Gets the keyboard button device factory. | 27 | /// Gets the keyboard button device factory. |
diff --git a/src/input_common/sdl/sdl.cpp b/src/input_common/sdl/sdl.cpp index d1b960fd7..faf3c1fa3 100644 --- a/src/input_common/sdl/sdl.cpp +++ b/src/input_common/sdl/sdl.cpp | |||
| @@ -2,15 +2,24 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 6 | #include <atomic> | ||
| 5 | #include <cmath> | 7 | #include <cmath> |
| 8 | #include <functional> | ||
| 9 | #include <iterator> | ||
| 10 | #include <mutex> | ||
| 6 | #include <string> | 11 | #include <string> |
| 12 | #include <thread> | ||
| 7 | #include <tuple> | 13 | #include <tuple> |
| 8 | #include <unordered_map> | 14 | #include <unordered_map> |
| 9 | #include <utility> | 15 | #include <utility> |
| 16 | #include <vector> | ||
| 10 | #include <SDL.h> | 17 | #include <SDL.h> |
| 18 | #include "common/assert.h" | ||
| 11 | #include "common/logging/log.h" | 19 | #include "common/logging/log.h" |
| 12 | #include "common/math_util.h" | 20 | #include "common/math_util.h" |
| 13 | #include "common/param_package.h" | 21 | #include "common/param_package.h" |
| 22 | #include "common/threadsafe_queue.h" | ||
| 14 | #include "input_common/main.h" | 23 | #include "input_common/main.h" |
| 15 | #include "input_common/sdl/sdl.h" | 24 | #include "input_common/sdl/sdl.h" |
| 16 | 25 | ||
| @@ -21,33 +30,51 @@ namespace SDL { | |||
| 21 | class SDLJoystick; | 30 | class SDLJoystick; |
| 22 | class SDLButtonFactory; | 31 | class SDLButtonFactory; |
| 23 | class SDLAnalogFactory; | 32 | class SDLAnalogFactory; |
| 24 | static std::unordered_map<int, std::weak_ptr<SDLJoystick>> joystick_list; | 33 | |
| 34 | /// Map of GUID of a list of corresponding virtual Joysticks | ||
| 35 | static std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map; | ||
| 36 | static std::mutex joystick_map_mutex; | ||
| 37 | |||
| 25 | static std::shared_ptr<SDLButtonFactory> button_factory; | 38 | static std::shared_ptr<SDLButtonFactory> button_factory; |
| 26 | static std::shared_ptr<SDLAnalogFactory> analog_factory; | 39 | static std::shared_ptr<SDLAnalogFactory> analog_factory; |
| 27 | 40 | ||
| 28 | static bool initialized = false; | 41 | /// Used by the Pollers during config |
| 42 | static std::atomic<bool> polling; | ||
| 43 | static Common::SPSCQueue<SDL_Event> event_queue; | ||
| 44 | |||
| 45 | static std::atomic<bool> initialized = false; | ||
| 46 | |||
| 47 | static std::string GetGUID(SDL_Joystick* joystick) { | ||
| 48 | SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); | ||
| 49 | char guid_str[33]; | ||
| 50 | SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)); | ||
| 51 | return guid_str; | ||
| 52 | } | ||
| 29 | 53 | ||
| 30 | class SDLJoystick { | 54 | class SDLJoystick { |
| 31 | public: | 55 | public: |
| 32 | explicit SDLJoystick(int joystick_index) | 56 | SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick, |
| 33 | : joystick{SDL_JoystickOpen(joystick_index), SDL_JoystickClose} { | 57 | decltype(&SDL_JoystickClose) deleter = &SDL_JoystickClose) |
| 34 | if (!joystick) { | 58 | : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, deleter} {} |
| 35 | LOG_ERROR(Input, "failed to open joystick {}", joystick_index); | 59 | |
| 36 | } | 60 | void SetButton(int button, bool value) { |
| 61 | std::lock_guard<std::mutex> lock(mutex); | ||
| 62 | state.buttons[button] = value; | ||
| 37 | } | 63 | } |
| 38 | 64 | ||
| 39 | bool GetButton(int button) const { | 65 | bool GetButton(int button) const { |
| 40 | if (!joystick) | 66 | std::lock_guard<std::mutex> lock(mutex); |
| 41 | return {}; | 67 | return state.buttons.at(button); |
| 42 | SDL_JoystickUpdate(); | 68 | } |
| 43 | return SDL_JoystickGetButton(joystick.get(), button) == 1; | 69 | |
| 70 | void SetAxis(int axis, Sint16 value) { | ||
| 71 | std::lock_guard<std::mutex> lock(mutex); | ||
| 72 | state.axes[axis] = value; | ||
| 44 | } | 73 | } |
| 45 | 74 | ||
| 46 | float GetAxis(int axis) const { | 75 | float GetAxis(int axis) const { |
| 47 | if (!joystick) | 76 | std::lock_guard<std::mutex> lock(mutex); |
| 48 | return {}; | 77 | return state.axes.at(axis) / 32767.0f; |
| 49 | SDL_JoystickUpdate(); | ||
| 50 | return SDL_JoystickGetAxis(joystick.get(), axis) / 32767.0f; | ||
| 51 | } | 78 | } |
| 52 | 79 | ||
| 53 | std::tuple<float, float> GetAnalog(int axis_x, int axis_y) const { | 80 | std::tuple<float, float> GetAnalog(int axis_x, int axis_y) const { |
| @@ -67,18 +94,213 @@ public: | |||
| 67 | return std::make_tuple(x, y); | 94 | return std::make_tuple(x, y); |
| 68 | } | 95 | } |
| 69 | 96 | ||
| 97 | void SetHat(int hat, Uint8 direction) { | ||
| 98 | std::lock_guard<std::mutex> lock(mutex); | ||
| 99 | state.hats[hat] = direction; | ||
| 100 | } | ||
| 101 | |||
| 70 | bool GetHatDirection(int hat, Uint8 direction) const { | 102 | bool GetHatDirection(int hat, Uint8 direction) const { |
| 71 | return (SDL_JoystickGetHat(joystick.get(), hat) & direction) != 0; | 103 | std::lock_guard<std::mutex> lock(mutex); |
| 104 | return (state.hats.at(hat) & direction) != 0; | ||
| 105 | } | ||
| 106 | /** | ||
| 107 | * The guid of the joystick | ||
| 108 | */ | ||
| 109 | const std::string& GetGUID() const { | ||
| 110 | return guid; | ||
| 111 | } | ||
| 112 | |||
| 113 | /** | ||
| 114 | * The number of joystick from the same type that were connected before this joystick | ||
| 115 | */ | ||
| 116 | int GetPort() const { | ||
| 117 | return port; | ||
| 118 | } | ||
| 119 | |||
| 120 | SDL_Joystick* GetSDLJoystick() const { | ||
| 121 | return sdl_joystick.get(); | ||
| 72 | } | 122 | } |
| 73 | 123 | ||
| 74 | SDL_JoystickID GetJoystickID() const { | 124 | void SetSDLJoystick(SDL_Joystick* joystick, |
| 75 | return SDL_JoystickInstanceID(joystick.get()); | 125 | decltype(&SDL_JoystickClose) deleter = &SDL_JoystickClose) { |
| 126 | sdl_joystick = | ||
| 127 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)>(joystick, deleter); | ||
| 76 | } | 128 | } |
| 77 | 129 | ||
| 78 | private: | 130 | private: |
| 79 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> joystick; | 131 | struct State { |
| 132 | std::unordered_map<int, bool> buttons; | ||
| 133 | std::unordered_map<int, Sint16> axes; | ||
| 134 | std::unordered_map<int, Uint8> hats; | ||
| 135 | } state; | ||
| 136 | std::string guid; | ||
| 137 | int port; | ||
| 138 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; | ||
| 139 | mutable std::mutex mutex; | ||
| 80 | }; | 140 | }; |
| 81 | 141 | ||
| 142 | /** | ||
| 143 | * Get the nth joystick with the corresponding GUID | ||
| 144 | */ | ||
| 145 | static std::shared_ptr<SDLJoystick> GetSDLJoystickByGUID(const std::string& guid, int port) { | ||
| 146 | std::lock_guard<std::mutex> lock(joystick_map_mutex); | ||
| 147 | const auto it = joystick_map.find(guid); | ||
| 148 | if (it != joystick_map.end()) { | ||
| 149 | while (it->second.size() <= port) { | ||
| 150 | auto joystick = std::make_shared<SDLJoystick>(guid, it->second.size(), nullptr, | ||
| 151 | [](SDL_Joystick*) {}); | ||
| 152 | it->second.emplace_back(std::move(joystick)); | ||
| 153 | } | ||
| 154 | return it->second[port]; | ||
| 155 | } | ||
| 156 | auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr, [](SDL_Joystick*) {}); | ||
| 157 | return joystick_map[guid].emplace_back(std::move(joystick)); | ||
| 158 | } | ||
| 159 | |||
| 160 | /** | ||
| 161 | * Check how many identical joysticks (by guid) were connected before the one with sdl_id and so tie | ||
| 162 | * it to a SDLJoystick with the same guid and that port | ||
| 163 | */ | ||
| 164 | static std::shared_ptr<SDLJoystick> GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { | ||
| 165 | std::lock_guard<std::mutex> lock(joystick_map_mutex); | ||
| 166 | auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); | ||
| 167 | const std::string guid = GetGUID(sdl_joystick); | ||
| 168 | auto map_it = joystick_map.find(guid); | ||
| 169 | if (map_it != joystick_map.end()) { | ||
| 170 | auto vec_it = std::find_if(map_it->second.begin(), map_it->second.end(), | ||
| 171 | [&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) { | ||
| 172 | return sdl_joystick == joystick->GetSDLJoystick(); | ||
| 173 | }); | ||
| 174 | if (vec_it != map_it->second.end()) { | ||
| 175 | // This is the common case: There is already an existing SDL_Joystick maped to a | ||
| 176 | // SDLJoystick. return the SDLJoystick | ||
| 177 | return *vec_it; | ||
| 178 | } | ||
| 179 | // Search for a SDLJoystick without a mapped SDL_Joystick... | ||
| 180 | auto nullptr_it = std::find_if(map_it->second.begin(), map_it->second.end(), | ||
| 181 | [](const std::shared_ptr<SDLJoystick>& joystick) { | ||
| 182 | return !joystick->GetSDLJoystick(); | ||
| 183 | }); | ||
| 184 | if (nullptr_it != map_it->second.end()) { | ||
| 185 | // ... and map it | ||
| 186 | (*nullptr_it)->SetSDLJoystick(sdl_joystick); | ||
| 187 | return *nullptr_it; | ||
| 188 | } | ||
| 189 | // There is no SDLJoystick without a mapped SDL_Joystick | ||
| 190 | // Create a new SDLJoystick | ||
| 191 | auto joystick = std::make_shared<SDLJoystick>(guid, map_it->second.size(), sdl_joystick); | ||
| 192 | return map_it->second.emplace_back(std::move(joystick)); | ||
| 193 | } | ||
| 194 | auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick); | ||
| 195 | return joystick_map[guid].emplace_back(std::move(joystick)); | ||
| 196 | } | ||
| 197 | |||
| 198 | void InitJoystick(int joystick_index) { | ||
| 199 | std::lock_guard<std::mutex> lock(joystick_map_mutex); | ||
| 200 | SDL_Joystick* sdl_joystick = SDL_JoystickOpen(joystick_index); | ||
| 201 | if (!sdl_joystick) { | ||
| 202 | LOG_ERROR(Input, "failed to open joystick {}", joystick_index); | ||
| 203 | return; | ||
| 204 | } | ||
| 205 | std::string guid = GetGUID(sdl_joystick); | ||
| 206 | if (joystick_map.find(guid) == joystick_map.end()) { | ||
| 207 | auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick); | ||
| 208 | joystick_map[guid].emplace_back(std::move(joystick)); | ||
| 209 | return; | ||
| 210 | } | ||
| 211 | auto& joystick_guid_list = joystick_map[guid]; | ||
| 212 | const auto it = std::find_if( | ||
| 213 | joystick_guid_list.begin(), joystick_guid_list.end(), | ||
| 214 | [](const std::shared_ptr<SDLJoystick>& joystick) { return !joystick->GetSDLJoystick(); }); | ||
| 215 | if (it != joystick_guid_list.end()) { | ||
| 216 | (*it)->SetSDLJoystick(sdl_joystick); | ||
| 217 | return; | ||
| 218 | } | ||
| 219 | auto joystick = std::make_shared<SDLJoystick>(guid, joystick_guid_list.size(), sdl_joystick); | ||
| 220 | joystick_guid_list.emplace_back(std::move(joystick)); | ||
| 221 | } | ||
| 222 | |||
| 223 | void CloseJoystick(SDL_Joystick* sdl_joystick) { | ||
| 224 | std::lock_guard<std::mutex> lock(joystick_map_mutex); | ||
| 225 | std::string guid = GetGUID(sdl_joystick); | ||
| 226 | // This call to guid is save since the joystick is guranteed to be in that map | ||
| 227 | auto& joystick_guid_list = joystick_map[guid]; | ||
| 228 | const auto joystick_it = | ||
| 229 | std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), | ||
| 230 | [&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) { | ||
| 231 | return joystick->GetSDLJoystick() == sdl_joystick; | ||
| 232 | }); | ||
| 233 | (*joystick_it)->SetSDLJoystick(nullptr, [](SDL_Joystick*) {}); | ||
| 234 | } | ||
| 235 | |||
| 236 | void HandleGameControllerEvent(const SDL_Event& event) { | ||
| 237 | switch (event.type) { | ||
| 238 | case SDL_JOYBUTTONUP: { | ||
| 239 | auto joystick = GetSDLJoystickBySDLID(event.jbutton.which); | ||
| 240 | if (joystick) { | ||
| 241 | joystick->SetButton(event.jbutton.button, false); | ||
| 242 | } | ||
| 243 | break; | ||
| 244 | } | ||
| 245 | case SDL_JOYBUTTONDOWN: { | ||
| 246 | auto joystick = GetSDLJoystickBySDLID(event.jbutton.which); | ||
| 247 | if (joystick) { | ||
| 248 | joystick->SetButton(event.jbutton.button, true); | ||
| 249 | } | ||
| 250 | break; | ||
| 251 | } | ||
| 252 | case SDL_JOYHATMOTION: { | ||
| 253 | auto joystick = GetSDLJoystickBySDLID(event.jhat.which); | ||
| 254 | if (joystick) { | ||
| 255 | joystick->SetHat(event.jhat.hat, event.jhat.value); | ||
| 256 | } | ||
| 257 | break; | ||
| 258 | } | ||
| 259 | case SDL_JOYAXISMOTION: { | ||
| 260 | auto joystick = GetSDLJoystickBySDLID(event.jaxis.which); | ||
| 261 | if (joystick) { | ||
| 262 | joystick->SetAxis(event.jaxis.axis, event.jaxis.value); | ||
| 263 | } | ||
| 264 | break; | ||
| 265 | } | ||
| 266 | case SDL_JOYDEVICEREMOVED: | ||
| 267 | LOG_DEBUG(Input, "Controller removed with Instance_ID {}", event.jdevice.which); | ||
| 268 | CloseJoystick(SDL_JoystickFromInstanceID(event.jdevice.which)); | ||
| 269 | break; | ||
| 270 | case SDL_JOYDEVICEADDED: | ||
| 271 | LOG_DEBUG(Input, "Controller connected with device index {}", event.jdevice.which); | ||
| 272 | InitJoystick(event.jdevice.which); | ||
| 273 | break; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 277 | void CloseSDLJoysticks() { | ||
| 278 | std::lock_guard<std::mutex> lock(joystick_map_mutex); | ||
| 279 | joystick_map.clear(); | ||
| 280 | } | ||
| 281 | |||
| 282 | void PollLoop() { | ||
| 283 | if (SDL_Init(SDL_INIT_JOYSTICK) < 0) { | ||
| 284 | LOG_CRITICAL(Input, "SDL_Init(SDL_INIT_JOYSTICK) failed with: {}", SDL_GetError()); | ||
| 285 | return; | ||
| 286 | } | ||
| 287 | |||
| 288 | SDL_Event event; | ||
| 289 | while (initialized) { | ||
| 290 | // Wait for 10 ms or until an event happens | ||
| 291 | if (SDL_WaitEventTimeout(&event, 10)) { | ||
| 292 | // Don't handle the event if we are configuring | ||
| 293 | if (polling) { | ||
| 294 | event_queue.Push(event); | ||
| 295 | } else { | ||
| 296 | HandleGameControllerEvent(event); | ||
| 297 | } | ||
| 298 | } | ||
| 299 | } | ||
| 300 | CloseSDLJoysticks(); | ||
| 301 | SDL_QuitSubSystem(SDL_INIT_JOYSTICK); | ||
| 302 | } | ||
| 303 | |||
| 82 | class SDLButton final : public Input::ButtonDevice { | 304 | class SDLButton final : public Input::ButtonDevice { |
| 83 | public: | 305 | public: |
| 84 | explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_) | 306 | explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_) |
| @@ -144,22 +366,14 @@ private: | |||
| 144 | int axis_y; | 366 | int axis_y; |
| 145 | }; | 367 | }; |
| 146 | 368 | ||
| 147 | static std::shared_ptr<SDLJoystick> GetJoystick(int joystick_index) { | ||
| 148 | std::shared_ptr<SDLJoystick> joystick = joystick_list[joystick_index].lock(); | ||
| 149 | if (!joystick) { | ||
| 150 | joystick = std::make_shared<SDLJoystick>(joystick_index); | ||
| 151 | joystick_list[joystick_index] = joystick; | ||
| 152 | } | ||
| 153 | return joystick; | ||
| 154 | } | ||
| 155 | |||
| 156 | /// A button device factory that creates button devices from SDL joystick | 369 | /// A button device factory that creates button devices from SDL joystick |
| 157 | class SDLButtonFactory final : public Input::Factory<Input::ButtonDevice> { | 370 | class SDLButtonFactory final : public Input::Factory<Input::ButtonDevice> { |
| 158 | public: | 371 | public: |
| 159 | /** | 372 | /** |
| 160 | * Creates a button device from a joystick button | 373 | * Creates a button device from a joystick button |
| 161 | * @param params contains parameters for creating the device: | 374 | * @param params contains parameters for creating the device: |
| 162 | * - "joystick": the index of the joystick to bind | 375 | * - "guid": the guid of the joystick to bind |
| 376 | * - "port": the nth joystick of the same type to bind | ||
| 163 | * - "button"(optional): the index of the button to bind | 377 | * - "button"(optional): the index of the button to bind |
| 164 | * - "hat"(optional): the index of the hat to bind as direction buttons | 378 | * - "hat"(optional): the index of the hat to bind as direction buttons |
| 165 | * - "axis"(optional): the index of the axis to bind | 379 | * - "axis"(optional): the index of the axis to bind |
| @@ -167,12 +381,15 @@ public: | |||
| 167 | * "down", "left" or "right" | 381 | * "down", "left" or "right" |
| 168 | * - "threshold"(only used for axis): a float value in (-1.0, 1.0) which the button is | 382 | * - "threshold"(only used for axis): a float value in (-1.0, 1.0) which the button is |
| 169 | * triggered if the axis value crosses | 383 | * triggered if the axis value crosses |
| 170 | * - "direction"(only used for axis): "+" means the button is triggered when the axis value | 384 | * - "direction"(only used for axis): "+" means the button is triggered when the axis |
| 171 | * is greater than the threshold; "-" means the button is triggered when the axis value | 385 | * value is greater than the threshold; "-" means the button is triggered when the axis |
| 172 | * is smaller than the threshold | 386 | * value is smaller than the threshold |
| 173 | */ | 387 | */ |
| 174 | std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override { | 388 | std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override { |
| 175 | const int joystick_index = params.Get("joystick", 0); | 389 | const std::string guid = params.Get("guid", "0"); |
| 390 | const int port = params.Get("port", 0); | ||
| 391 | |||
| 392 | auto joystick = GetSDLJoystickByGUID(guid, port); | ||
| 176 | 393 | ||
| 177 | if (params.Has("hat")) { | 394 | if (params.Has("hat")) { |
| 178 | const int hat = params.Get("hat", 0); | 395 | const int hat = params.Get("hat", 0); |
| @@ -189,8 +406,9 @@ public: | |||
| 189 | } else { | 406 | } else { |
| 190 | direction = 0; | 407 | direction = 0; |
| 191 | } | 408 | } |
| 192 | return std::make_unique<SDLDirectionButton>(GetJoystick(joystick_index), hat, | 409 | // This is necessary so accessing GetHat with hat won't crash |
| 193 | direction); | 410 | joystick->SetHat(hat, SDL_HAT_CENTERED); |
| 411 | return std::make_unique<SDLDirectionButton>(joystick, hat, direction); | ||
| 194 | } | 412 | } |
| 195 | 413 | ||
| 196 | if (params.Has("axis")) { | 414 | if (params.Has("axis")) { |
| @@ -206,12 +424,15 @@ public: | |||
| 206 | trigger_if_greater = true; | 424 | trigger_if_greater = true; |
| 207 | LOG_ERROR(Input, "Unknown direction '{}'", direction_name); | 425 | LOG_ERROR(Input, "Unknown direction '{}'", direction_name); |
| 208 | } | 426 | } |
| 209 | return std::make_unique<SDLAxisButton>(GetJoystick(joystick_index), axis, threshold, | 427 | // This is necessary so accessing GetAxis with axis won't crash |
| 210 | trigger_if_greater); | 428 | joystick->SetAxis(axis, 0); |
| 429 | return std::make_unique<SDLAxisButton>(joystick, axis, threshold, trigger_if_greater); | ||
| 211 | } | 430 | } |
| 212 | 431 | ||
| 213 | const int button = params.Get("button", 0); | 432 | const int button = params.Get("button", 0); |
| 214 | return std::make_unique<SDLButton>(GetJoystick(joystick_index), button); | 433 | // This is necessary so accessing GetButton with button won't crash |
| 434 | joystick->SetButton(button, false); | ||
| 435 | return std::make_unique<SDLButton>(joystick, button); | ||
| 215 | } | 436 | } |
| 216 | }; | 437 | }; |
| 217 | 438 | ||
| @@ -221,27 +442,32 @@ public: | |||
| 221 | /** | 442 | /** |
| 222 | * Creates analog device from joystick axes | 443 | * Creates analog device from joystick axes |
| 223 | * @param params contains parameters for creating the device: | 444 | * @param params contains parameters for creating the device: |
| 224 | * - "joystick": the index of the joystick to bind | 445 | * - "guid": the guid of the joystick to bind |
| 446 | * - "port": the nth joystick of the same type | ||
| 225 | * - "axis_x": the index of the axis to be bind as x-axis | 447 | * - "axis_x": the index of the axis to be bind as x-axis |
| 226 | * - "axis_y": the index of the axis to be bind as y-axis | 448 | * - "axis_y": the index of the axis to be bind as y-axis |
| 227 | */ | 449 | */ |
| 228 | std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override { | 450 | std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override { |
| 229 | const int joystick_index = params.Get("joystick", 0); | 451 | const std::string guid = params.Get("guid", "0"); |
| 452 | const int port = params.Get("port", 0); | ||
| 230 | const int axis_x = params.Get("axis_x", 0); | 453 | const int axis_x = params.Get("axis_x", 0); |
| 231 | const int axis_y = params.Get("axis_y", 1); | 454 | const int axis_y = params.Get("axis_y", 1); |
| 232 | return std::make_unique<SDLAnalog>(GetJoystick(joystick_index), axis_x, axis_y); | 455 | |
| 456 | auto joystick = GetSDLJoystickByGUID(guid, port); | ||
| 457 | |||
| 458 | // This is necessary so accessing GetAxis with axis_x and axis_y won't crash | ||
| 459 | joystick->SetAxis(axis_x, 0); | ||
| 460 | joystick->SetAxis(axis_y, 0); | ||
| 461 | return std::make_unique<SDLAnalog>(joystick, axis_x, axis_y); | ||
| 233 | } | 462 | } |
| 234 | }; | 463 | }; |
| 235 | 464 | ||
| 236 | void Init() { | 465 | void Init() { |
| 237 | if (SDL_Init(SDL_INIT_JOYSTICK) < 0) { | 466 | using namespace Input; |
| 238 | LOG_CRITICAL(Input, "SDL_Init(SDL_INIT_JOYSTICK) failed with: {}", SDL_GetError()); | 467 | RegisterFactory<ButtonDevice>("sdl", std::make_shared<SDLButtonFactory>()); |
| 239 | } else { | 468 | RegisterFactory<AnalogDevice>("sdl", std::make_shared<SDLAnalogFactory>()); |
| 240 | using namespace Input; | 469 | polling = false; |
| 241 | RegisterFactory<ButtonDevice>("sdl", std::make_shared<SDLButtonFactory>()); | 470 | initialized = true; |
| 242 | RegisterFactory<AnalogDevice>("sdl", std::make_shared<SDLAnalogFactory>()); | ||
| 243 | initialized = true; | ||
| 244 | } | ||
| 245 | } | 471 | } |
| 246 | 472 | ||
| 247 | void Shutdown() { | 473 | void Shutdown() { |
| @@ -249,30 +475,17 @@ void Shutdown() { | |||
| 249 | using namespace Input; | 475 | using namespace Input; |
| 250 | UnregisterFactory<ButtonDevice>("sdl"); | 476 | UnregisterFactory<ButtonDevice>("sdl"); |
| 251 | UnregisterFactory<AnalogDevice>("sdl"); | 477 | UnregisterFactory<AnalogDevice>("sdl"); |
| 252 | SDL_QuitSubSystem(SDL_INIT_JOYSTICK); | 478 | initialized = false; |
| 253 | } | 479 | } |
| 254 | } | 480 | } |
| 255 | 481 | ||
| 256 | /** | ||
| 257 | * This function converts a joystick ID used in SDL events to the device index. This is necessary | ||
| 258 | * because Citra opens joysticks using their indices, not their IDs. | ||
| 259 | */ | ||
| 260 | static int JoystickIDToDeviceIndex(SDL_JoystickID id) { | ||
| 261 | int num_joysticks = SDL_NumJoysticks(); | ||
| 262 | for (int i = 0; i < num_joysticks; i++) { | ||
| 263 | auto joystick = GetJoystick(i); | ||
| 264 | if (joystick->GetJoystickID() == id) { | ||
| 265 | return i; | ||
| 266 | } | ||
| 267 | } | ||
| 268 | return -1; | ||
| 269 | } | ||
| 270 | |||
| 271 | Common::ParamPackage SDLEventToButtonParamPackage(const SDL_Event& event) { | 482 | Common::ParamPackage SDLEventToButtonParamPackage(const SDL_Event& event) { |
| 272 | Common::ParamPackage params({{"engine", "sdl"}}); | 483 | Common::ParamPackage params({{"engine", "sdl"}}); |
| 273 | switch (event.type) { | 484 | switch (event.type) { |
| 274 | case SDL_JOYAXISMOTION: | 485 | case SDL_JOYAXISMOTION: { |
| 275 | params.Set("joystick", JoystickIDToDeviceIndex(event.jaxis.which)); | 486 | auto joystick = GetSDLJoystickBySDLID(event.jaxis.which); |
| 487 | params.Set("port", joystick->GetPort()); | ||
| 488 | params.Set("guid", joystick->GetGUID()); | ||
| 276 | params.Set("axis", event.jaxis.axis); | 489 | params.Set("axis", event.jaxis.axis); |
| 277 | if (event.jaxis.value > 0) { | 490 | if (event.jaxis.value > 0) { |
| 278 | params.Set("direction", "+"); | 491 | params.Set("direction", "+"); |
| @@ -282,12 +495,18 @@ Common::ParamPackage SDLEventToButtonParamPackage(const SDL_Event& event) { | |||
| 282 | params.Set("threshold", "-0.5"); | 495 | params.Set("threshold", "-0.5"); |
| 283 | } | 496 | } |
| 284 | break; | 497 | break; |
| 285 | case SDL_JOYBUTTONUP: | 498 | } |
| 286 | params.Set("joystick", JoystickIDToDeviceIndex(event.jbutton.which)); | 499 | case SDL_JOYBUTTONUP: { |
| 500 | auto joystick = GetSDLJoystickBySDLID(event.jbutton.which); | ||
| 501 | params.Set("port", joystick->GetPort()); | ||
| 502 | params.Set("guid", joystick->GetGUID()); | ||
| 287 | params.Set("button", event.jbutton.button); | 503 | params.Set("button", event.jbutton.button); |
| 288 | break; | 504 | break; |
| 289 | case SDL_JOYHATMOTION: | 505 | } |
| 290 | params.Set("joystick", JoystickIDToDeviceIndex(event.jhat.which)); | 506 | case SDL_JOYHATMOTION: { |
| 507 | auto joystick = GetSDLJoystickBySDLID(event.jhat.which); | ||
| 508 | params.Set("port", joystick->GetPort()); | ||
| 509 | params.Set("guid", joystick->GetGUID()); | ||
| 291 | params.Set("hat", event.jhat.hat); | 510 | params.Set("hat", event.jhat.hat); |
| 292 | switch (event.jhat.value) { | 511 | switch (event.jhat.value) { |
| 293 | case SDL_HAT_UP: | 512 | case SDL_HAT_UP: |
| @@ -307,6 +526,7 @@ Common::ParamPackage SDLEventToButtonParamPackage(const SDL_Event& event) { | |||
| 307 | } | 526 | } |
| 308 | break; | 527 | break; |
| 309 | } | 528 | } |
| 529 | } | ||
| 310 | return params; | 530 | return params; |
| 311 | } | 531 | } |
| 312 | 532 | ||
| @@ -315,31 +535,20 @@ namespace Polling { | |||
| 315 | class SDLPoller : public InputCommon::Polling::DevicePoller { | 535 | class SDLPoller : public InputCommon::Polling::DevicePoller { |
| 316 | public: | 536 | public: |
| 317 | void Start() override { | 537 | void Start() override { |
| 318 | // SDL joysticks must be opened, otherwise they don't generate events | 538 | event_queue.Clear(); |
| 319 | SDL_JoystickUpdate(); | 539 | polling = true; |
| 320 | int num_joysticks = SDL_NumJoysticks(); | ||
| 321 | for (int i = 0; i < num_joysticks; i++) { | ||
| 322 | joysticks_opened.emplace_back(GetJoystick(i)); | ||
| 323 | } | ||
| 324 | // Empty event queue to get rid of old events. citra-qt doesn't use the queue | ||
| 325 | SDL_Event dummy; | ||
| 326 | while (SDL_PollEvent(&dummy)) { | ||
| 327 | } | ||
| 328 | } | 540 | } |
| 329 | 541 | ||
| 330 | void Stop() override { | 542 | void Stop() override { |
| 331 | joysticks_opened.clear(); | 543 | polling = false; |
| 332 | } | 544 | } |
| 333 | |||
| 334 | private: | ||
| 335 | std::vector<std::shared_ptr<SDLJoystick>> joysticks_opened; | ||
| 336 | }; | 545 | }; |
| 337 | 546 | ||
| 338 | class SDLButtonPoller final : public SDLPoller { | 547 | class SDLButtonPoller final : public SDLPoller { |
| 339 | public: | 548 | public: |
| 340 | Common::ParamPackage GetNextInput() override { | 549 | Common::ParamPackage GetNextInput() override { |
| 341 | SDL_Event event; | 550 | SDL_Event event; |
| 342 | while (SDL_PollEvent(&event)) { | 551 | while (event_queue.Pop(event)) { |
| 343 | switch (event.type) { | 552 | switch (event.type) { |
| 344 | case SDL_JOYAXISMOTION: | 553 | case SDL_JOYAXISMOTION: |
| 345 | if (std::abs(event.jaxis.value / 32767.0) < 0.5) { | 554 | if (std::abs(event.jaxis.value / 32767.0) < 0.5) { |
| @@ -367,7 +576,7 @@ public: | |||
| 367 | 576 | ||
| 368 | Common::ParamPackage GetNextInput() override { | 577 | Common::ParamPackage GetNextInput() override { |
| 369 | SDL_Event event; | 578 | SDL_Event event; |
| 370 | while (SDL_PollEvent(&event)) { | 579 | while (event_queue.Pop(event)) { |
| 371 | if (event.type != SDL_JOYAXISMOTION || std::abs(event.jaxis.value / 32767.0) < 0.5) { | 580 | if (event.type != SDL_JOYAXISMOTION || std::abs(event.jaxis.value / 32767.0) < 0.5) { |
| 372 | continue; | 581 | continue; |
| 373 | } | 582 | } |
| @@ -384,8 +593,10 @@ public: | |||
| 384 | } | 593 | } |
| 385 | Common::ParamPackage params; | 594 | Common::ParamPackage params; |
| 386 | if (analog_xaxis != -1 && analog_yaxis != -1) { | 595 | if (analog_xaxis != -1 && analog_yaxis != -1) { |
| 596 | auto joystick = GetSDLJoystickBySDLID(event.jaxis.which); | ||
| 387 | params.Set("engine", "sdl"); | 597 | params.Set("engine", "sdl"); |
| 388 | params.Set("joystick", JoystickIDToDeviceIndex(analog_axes_joystick)); | 598 | params.Set("port", joystick->GetPort()); |
| 599 | params.Set("guid", joystick->GetGUID()); | ||
| 389 | params.Set("axis_x", analog_xaxis); | 600 | params.Set("axis_x", analog_xaxis); |
| 390 | params.Set("axis_y", analog_yaxis); | 601 | params.Set("axis_y", analog_yaxis); |
| 391 | analog_xaxis = -1; | 602 | analog_xaxis = -1; |
diff --git a/src/input_common/sdl/sdl.h b/src/input_common/sdl/sdl.h index 7934099d4..0206860d3 100644 --- a/src/input_common/sdl/sdl.h +++ b/src/input_common/sdl/sdl.h | |||
| @@ -28,6 +28,15 @@ void Init(); | |||
| 28 | /// Unresisters SDL device factories and shut them down. | 28 | /// Unresisters SDL device factories and shut them down. |
| 29 | void Shutdown(); | 29 | void Shutdown(); |
| 30 | 30 | ||
| 31 | /// Needs to be called before SDL_QuitSubSystem. | ||
| 32 | void CloseSDLJoysticks(); | ||
| 33 | |||
| 34 | /// Handle SDL_Events for joysticks from SDL_PollEvent | ||
| 35 | void HandleGameControllerEvent(const SDL_Event& event); | ||
| 36 | |||
| 37 | /// A Loop that calls HandleGameControllerEvent until Shutdown is called | ||
| 38 | void PollLoop(); | ||
| 39 | |||
| 31 | /// Creates a ParamPackage from an SDL_Event that can directly be used to create a ButtonDevice | 40 | /// Creates a ParamPackage from an SDL_Event that can directly be used to create a ButtonDevice |
| 32 | Common::ParamPackage SDLEventToButtonParamPackage(const SDL_Event& event); | 41 | Common::ParamPackage SDLEventToButtonParamPackage(const SDL_Event& event); |
| 33 | 42 | ||
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index d5831e752..2625ddfdc 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -28,98 +28,106 @@ enum class BufferMethods { | |||
| 28 | CountBufferMethods = 0x40, | 28 | CountBufferMethods = 0x40, |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) { | 31 | MICROPROFILE_DEFINE(ProcessCommandLists, "GPU", "Execute command buffer", MP_RGB(128, 128, 192)); |
| 32 | LOG_TRACE(HW_GPU, | ||
| 33 | "Processing method {:08X} on subchannel {} value " | ||
| 34 | "{:08X} remaining params {}", | ||
| 35 | method, subchannel, value, remaining_params); | ||
| 36 | |||
| 37 | ASSERT(subchannel < bound_engines.size()); | ||
| 38 | |||
| 39 | if (method == static_cast<u32>(BufferMethods::BindObject)) { | ||
| 40 | // Bind the current subchannel to the desired engine id. | ||
| 41 | LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); | ||
| 42 | bound_engines[subchannel] = static_cast<EngineID>(value); | ||
| 43 | return; | ||
| 44 | } | ||
| 45 | 32 | ||
| 46 | if (method < static_cast<u32>(BufferMethods::CountBufferMethods)) { | 33 | void GPU::ProcessCommandLists(const std::vector<CommandListHeader>& commands) { |
| 47 | // TODO(Subv): Research and implement these methods. | 34 | MICROPROFILE_SCOPE(ProcessCommandLists); |
| 48 | LOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented"); | ||
| 49 | return; | ||
| 50 | } | ||
| 51 | 35 | ||
| 52 | const EngineID engine = bound_engines[subchannel]; | 36 | auto WriteReg = [this](u32 method, u32 subchannel, u32 value, u32 remaining_params) { |
| 53 | 37 | LOG_TRACE(HW_GPU, | |
| 54 | switch (engine) { | 38 | "Processing method {:08X} on subchannel {} value " |
| 55 | case EngineID::FERMI_TWOD_A: | 39 | "{:08X} remaining params {}", |
| 56 | fermi_2d->WriteReg(method, value); | 40 | method, subchannel, value, remaining_params); |
| 57 | break; | ||
| 58 | case EngineID::MAXWELL_B: | ||
| 59 | maxwell_3d->WriteReg(method, value, remaining_params); | ||
| 60 | break; | ||
| 61 | case EngineID::MAXWELL_COMPUTE_B: | ||
| 62 | maxwell_compute->WriteReg(method, value); | ||
| 63 | break; | ||
| 64 | case EngineID::MAXWELL_DMA_COPY_A: | ||
| 65 | maxwell_dma->WriteReg(method, value); | ||
| 66 | break; | ||
| 67 | default: | ||
| 68 | UNIMPLEMENTED_MSG("Unimplemented engine"); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | 41 | ||
| 72 | void GPU::ProcessCommandList(GPUVAddr address, u32 size) { | 42 | ASSERT(subchannel < bound_engines.size()); |
| 73 | const boost::optional<VAddr> head_address = memory_manager->GpuToCpuAddress(address); | 43 | |
| 74 | VAddr current_addr = *head_address; | 44 | if (method == static_cast<u32>(BufferMethods::BindObject)) { |
| 75 | while (current_addr < *head_address + size * sizeof(CommandHeader)) { | 45 | // Bind the current subchannel to the desired engine id. |
| 76 | const CommandHeader header = {Memory::Read32(current_addr)}; | 46 | LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); |
| 77 | current_addr += sizeof(u32); | 47 | bound_engines[subchannel] = static_cast<EngineID>(value); |
| 78 | 48 | return; | |
| 79 | switch (header.mode.Value()) { | ||
| 80 | case SubmissionMode::IncreasingOld: | ||
| 81 | case SubmissionMode::Increasing: { | ||
| 82 | // Increase the method value with each argument. | ||
| 83 | for (unsigned i = 0; i < header.arg_count; ++i) { | ||
| 84 | WriteReg(header.method + i, header.subchannel, Memory::Read32(current_addr), | ||
| 85 | header.arg_count - i - 1); | ||
| 86 | current_addr += sizeof(u32); | ||
| 87 | } | ||
| 88 | break; | ||
| 89 | } | 49 | } |
| 90 | case SubmissionMode::NonIncreasingOld: | 50 | |
| 91 | case SubmissionMode::NonIncreasing: { | 51 | if (method < static_cast<u32>(BufferMethods::CountBufferMethods)) { |
| 92 | // Use the same method value for all arguments. | 52 | // TODO(Subv): Research and implement these methods. |
| 93 | for (unsigned i = 0; i < header.arg_count; ++i) { | 53 | LOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented"); |
| 94 | WriteReg(header.method, header.subchannel, Memory::Read32(current_addr), | 54 | return; |
| 95 | header.arg_count - i - 1); | 55 | } |
| 96 | current_addr += sizeof(u32); | 56 | |
| 97 | } | 57 | const EngineID engine = bound_engines[subchannel]; |
| 58 | |||
| 59 | switch (engine) { | ||
| 60 | case EngineID::FERMI_TWOD_A: | ||
| 61 | fermi_2d->WriteReg(method, value); | ||
| 62 | break; | ||
| 63 | case EngineID::MAXWELL_B: | ||
| 64 | maxwell_3d->WriteReg(method, value, remaining_params); | ||
| 98 | break; | 65 | break; |
| 66 | case EngineID::MAXWELL_COMPUTE_B: | ||
| 67 | maxwell_compute->WriteReg(method, value); | ||
| 68 | break; | ||
| 69 | case EngineID::MAXWELL_DMA_COPY_A: | ||
| 70 | maxwell_dma->WriteReg(method, value); | ||
| 71 | break; | ||
| 72 | default: | ||
| 73 | UNIMPLEMENTED_MSG("Unimplemented engine"); | ||
| 99 | } | 74 | } |
| 100 | case SubmissionMode::IncreaseOnce: { | 75 | }; |
| 101 | ASSERT(header.arg_count.Value() >= 1); | ||
| 102 | 76 | ||
| 103 | // Use the original method for the first argument and then the next method for all other | 77 | for (auto entry : commands) { |
| 104 | // arguments. | 78 | Tegra::GPUVAddr address = entry.Address(); |
| 105 | WriteReg(header.method, header.subchannel, Memory::Read32(current_addr), | 79 | u32 size = entry.sz; |
| 106 | header.arg_count - 1); | 80 | const boost::optional<VAddr> head_address = memory_manager->GpuToCpuAddress(address); |
| 81 | VAddr current_addr = *head_address; | ||
| 82 | while (current_addr < *head_address + size * sizeof(CommandHeader)) { | ||
| 83 | const CommandHeader header = {Memory::Read32(current_addr)}; | ||
| 107 | current_addr += sizeof(u32); | 84 | current_addr += sizeof(u32); |
| 108 | 85 | ||
| 109 | for (unsigned i = 1; i < header.arg_count; ++i) { | 86 | switch (header.mode.Value()) { |
| 110 | WriteReg(header.method + 1, header.subchannel, Memory::Read32(current_addr), | 87 | case SubmissionMode::IncreasingOld: |
| 111 | header.arg_count - i - 1); | 88 | case SubmissionMode::Increasing: { |
| 89 | // Increase the method value with each argument. | ||
| 90 | for (unsigned i = 0; i < header.arg_count; ++i) { | ||
| 91 | WriteReg(header.method + i, header.subchannel, Memory::Read32(current_addr), | ||
| 92 | header.arg_count - i - 1); | ||
| 93 | current_addr += sizeof(u32); | ||
| 94 | } | ||
| 95 | break; | ||
| 96 | } | ||
| 97 | case SubmissionMode::NonIncreasingOld: | ||
| 98 | case SubmissionMode::NonIncreasing: { | ||
| 99 | // Use the same method value for all arguments. | ||
| 100 | for (unsigned i = 0; i < header.arg_count; ++i) { | ||
| 101 | WriteReg(header.method, header.subchannel, Memory::Read32(current_addr), | ||
| 102 | header.arg_count - i - 1); | ||
| 103 | current_addr += sizeof(u32); | ||
| 104 | } | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | case SubmissionMode::IncreaseOnce: { | ||
| 108 | ASSERT(header.arg_count.Value() >= 1); | ||
| 109 | |||
| 110 | // Use the original method for the first argument and then the next method for all | ||
| 111 | // other arguments. | ||
| 112 | WriteReg(header.method, header.subchannel, Memory::Read32(current_addr), | ||
| 113 | header.arg_count - 1); | ||
| 112 | current_addr += sizeof(u32); | 114 | current_addr += sizeof(u32); |
| 115 | |||
| 116 | for (unsigned i = 1; i < header.arg_count; ++i) { | ||
| 117 | WriteReg(header.method + 1, header.subchannel, Memory::Read32(current_addr), | ||
| 118 | header.arg_count - i - 1); | ||
| 119 | current_addr += sizeof(u32); | ||
| 120 | } | ||
| 121 | break; | ||
| 122 | } | ||
| 123 | case SubmissionMode::Inline: { | ||
| 124 | // The register value is stored in the bits 16-28 as an immediate | ||
| 125 | WriteReg(header.method, header.subchannel, header.inline_data, 0); | ||
| 126 | break; | ||
| 127 | } | ||
| 128 | default: | ||
| 129 | UNIMPLEMENTED(); | ||
| 113 | } | 130 | } |
| 114 | break; | ||
| 115 | } | ||
| 116 | case SubmissionMode::Inline: { | ||
| 117 | // The register value is stored in the bits 16-28 as an immediate | ||
| 118 | WriteReg(header.method, header.subchannel, header.inline_data, 0); | ||
| 119 | break; | ||
| 120 | } | ||
| 121 | default: | ||
| 122 | UNIMPLEMENTED(); | ||
| 123 | } | 131 | } |
| 124 | } | 132 | } |
| 125 | } | 133 | } |
diff --git a/src/video_core/command_processor.h b/src/video_core/command_processor.h index a01153e0b..bd766e77a 100644 --- a/src/video_core/command_processor.h +++ b/src/video_core/command_processor.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <type_traits> | 7 | #include <type_traits> |
| 8 | #include "common/bit_field.h" | 8 | #include "common/bit_field.h" |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "video_core/memory_manager.h" | ||
| 10 | 11 | ||
| 11 | namespace Tegra { | 12 | namespace Tegra { |
| 12 | 13 | ||
| @@ -19,6 +20,22 @@ enum class SubmissionMode : u32 { | |||
| 19 | IncreaseOnce = 5 | 20 | IncreaseOnce = 5 |
| 20 | }; | 21 | }; |
| 21 | 22 | ||
| 23 | struct CommandListHeader { | ||
| 24 | u32 entry0; // gpu_va_lo | ||
| 25 | union { | ||
| 26 | u32 entry1; // gpu_va_hi | (unk_0x02 << 0x08) | (size << 0x0A) | (unk_0x01 << 0x1F) | ||
| 27 | BitField<0, 8, u32> gpu_va_hi; | ||
| 28 | BitField<8, 2, u32> unk1; | ||
| 29 | BitField<10, 21, u32> sz; | ||
| 30 | BitField<31, 1, u32> unk2; | ||
| 31 | }; | ||
| 32 | |||
| 33 | GPUVAddr Address() const { | ||
| 34 | return (static_cast<GPUVAddr>(gpu_va_hi) << 32) | entry0; | ||
| 35 | } | ||
| 36 | }; | ||
| 37 | static_assert(sizeof(CommandListHeader) == 8, "CommandListHeader is incorrect size"); | ||
| 38 | |||
| 22 | union CommandHeader { | 39 | union CommandHeader { |
| 23 | u32 hex; | 40 | u32 hex; |
| 24 | 41 | ||
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 1308080b5..329079ddd 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -135,8 +135,6 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 135 | break; | 135 | break; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | rasterizer.NotifyMaxwellRegisterChanged(method); | ||
| 139 | |||
| 140 | if (debug_context) { | 138 | if (debug_context) { |
| 141 | debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr); | 139 | debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr); |
| 142 | } | 140 | } |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index f59d01738..d3be900a4 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -533,7 +533,11 @@ public: | |||
| 533 | u32 stencil_back_mask; | 533 | u32 stencil_back_mask; |
| 534 | u32 stencil_back_func_mask; | 534 | u32 stencil_back_func_mask; |
| 535 | 535 | ||
| 536 | INSERT_PADDING_WORDS(0x20); | 536 | INSERT_PADDING_WORDS(0x13); |
| 537 | |||
| 538 | u32 rt_separate_frag_data; | ||
| 539 | |||
| 540 | INSERT_PADDING_WORDS(0xC); | ||
| 537 | 541 | ||
| 538 | struct { | 542 | struct { |
| 539 | u32 address_high; | 543 | u32 address_high; |
| @@ -557,7 +561,22 @@ public: | |||
| 557 | struct { | 561 | struct { |
| 558 | union { | 562 | union { |
| 559 | BitField<0, 4, u32> count; | 563 | BitField<0, 4, u32> count; |
| 564 | BitField<4, 3, u32> map_0; | ||
| 565 | BitField<7, 3, u32> map_1; | ||
| 566 | BitField<10, 3, u32> map_2; | ||
| 567 | BitField<13, 3, u32> map_3; | ||
| 568 | BitField<16, 3, u32> map_4; | ||
| 569 | BitField<19, 3, u32> map_5; | ||
| 570 | BitField<22, 3, u32> map_6; | ||
| 571 | BitField<25, 3, u32> map_7; | ||
| 560 | }; | 572 | }; |
| 573 | |||
| 574 | u32 GetMap(size_t index) const { | ||
| 575 | const std::array<u32, NumRenderTargets> maps{map_0, map_1, map_2, map_3, | ||
| 576 | map_4, map_5, map_6, map_7}; | ||
| 577 | ASSERT(index < maps.size()); | ||
| 578 | return maps[index]; | ||
| 579 | } | ||
| 561 | } rt_control; | 580 | } rt_control; |
| 562 | 581 | ||
| 563 | INSERT_PADDING_WORDS(0x2); | 582 | INSERT_PADDING_WORDS(0x2); |
| @@ -968,6 +987,7 @@ ASSERT_REG_POSITION(clear_stencil, 0x368); | |||
| 968 | ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5); | 987 | ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5); |
| 969 | ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); | 988 | ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); |
| 970 | ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7); | 989 | ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7); |
| 990 | ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB); | ||
| 971 | ASSERT_REG_POSITION(zeta, 0x3F8); | 991 | ASSERT_REG_POSITION(zeta, 0x3F8); |
| 972 | ASSERT_REG_POSITION(vertex_attrib_format, 0x458); | 992 | ASSERT_REG_POSITION(vertex_attrib_format, 0x458); |
| 973 | ASSERT_REG_POSITION(rt_control, 0x487); | 993 | ASSERT_REG_POSITION(rt_control, 0x487); |
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 6e740713f..c24d33d5c 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -41,7 +41,6 @@ void MaxwellDMA::HandleCopy() { | |||
| 41 | 41 | ||
| 42 | // TODO(Subv): Perform more research and implement all features of this engine. | 42 | // TODO(Subv): Perform more research and implement all features of this engine. |
| 43 | ASSERT(regs.exec.enable_swizzle == 0); | 43 | ASSERT(regs.exec.enable_swizzle == 0); |
| 44 | ASSERT(regs.exec.enable_2d == 1); | ||
| 45 | ASSERT(regs.exec.query_mode == Regs::QueryMode::None); | 44 | ASSERT(regs.exec.query_mode == Regs::QueryMode::None); |
| 46 | ASSERT(regs.exec.query_intr == Regs::QueryIntr::None); | 45 | ASSERT(regs.exec.query_intr == Regs::QueryIntr::None); |
| 47 | ASSERT(regs.exec.copy_mode == Regs::CopyMode::Unk2); | 46 | ASSERT(regs.exec.copy_mode == Regs::CopyMode::Unk2); |
| @@ -51,10 +50,19 @@ void MaxwellDMA::HandleCopy() { | |||
| 51 | ASSERT(regs.dst_params.pos_y == 0); | 50 | ASSERT(regs.dst_params.pos_y == 0); |
| 52 | 51 | ||
| 53 | if (regs.exec.is_dst_linear == regs.exec.is_src_linear) { | 52 | if (regs.exec.is_dst_linear == regs.exec.is_src_linear) { |
| 54 | Memory::CopyBlock(dest_cpu, source_cpu, regs.x_count * regs.y_count); | 53 | size_t copy_size = regs.x_count; |
| 54 | |||
| 55 | // When the enable_2d bit is disabled, the copy is performed as if we were copying a 1D | ||
| 56 | // buffer of length `x_count`, otherwise we copy a 2D buffer of size (x_count, y_count). | ||
| 57 | if (regs.exec.enable_2d) { | ||
| 58 | copy_size = copy_size * regs.y_count; | ||
| 59 | } | ||
| 60 | |||
| 61 | Memory::CopyBlock(dest_cpu, source_cpu, copy_size); | ||
| 55 | return; | 62 | return; |
| 56 | } | 63 | } |
| 57 | 64 | ||
| 65 | ASSERT(regs.exec.enable_2d == 1); | ||
| 58 | u8* src_buffer = Memory::GetPointer(source_cpu); | 66 | u8* src_buffer = Memory::GetPointer(source_cpu); |
| 59 | u8* dst_buffer = Memory::GetPointer(dest_cpu); | 67 | u8* dst_buffer = Memory::GetPointer(dest_cpu); |
| 60 | 68 | ||
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index d2388673e..2db906ea5 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -244,6 +244,16 @@ enum class TextureType : u64 { | |||
| 244 | TextureCube = 3, | 244 | TextureCube = 3, |
| 245 | }; | 245 | }; |
| 246 | 246 | ||
| 247 | enum class TextureQueryType : u64 { | ||
| 248 | Dimension = 1, | ||
| 249 | TextureType = 2, | ||
| 250 | SamplePosition = 5, | ||
| 251 | Filter = 16, | ||
| 252 | LevelOfDetail = 18, | ||
| 253 | Wrap = 20, | ||
| 254 | BorderColor = 22, | ||
| 255 | }; | ||
| 256 | |||
| 247 | enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 }; | 257 | enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 }; |
| 248 | enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 }; | 258 | enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 }; |
| 249 | 259 | ||
| @@ -414,6 +424,45 @@ union Instruction { | |||
| 414 | } bfe; | 424 | } bfe; |
| 415 | 425 | ||
| 416 | union { | 426 | union { |
| 427 | BitField<48, 3, u64> pred48; | ||
| 428 | |||
| 429 | union { | ||
| 430 | BitField<20, 20, u64> entry_a; | ||
| 431 | BitField<39, 5, u64> entry_b; | ||
| 432 | BitField<45, 1, u64> neg; | ||
| 433 | BitField<46, 1, u64> uses_cc; | ||
| 434 | } imm; | ||
| 435 | |||
| 436 | union { | ||
| 437 | BitField<20, 14, u64> cb_index; | ||
| 438 | BitField<34, 5, u64> cb_offset; | ||
| 439 | BitField<56, 1, u64> neg; | ||
| 440 | BitField<57, 1, u64> uses_cc; | ||
| 441 | } hi; | ||
| 442 | |||
| 443 | union { | ||
| 444 | BitField<20, 14, u64> cb_index; | ||
| 445 | BitField<34, 5, u64> cb_offset; | ||
| 446 | BitField<39, 5, u64> entry_a; | ||
| 447 | BitField<45, 1, u64> neg; | ||
| 448 | BitField<46, 1, u64> uses_cc; | ||
| 449 | } rz; | ||
| 450 | |||
| 451 | union { | ||
| 452 | BitField<39, 5, u64> entry_a; | ||
| 453 | BitField<45, 1, u64> neg; | ||
| 454 | BitField<46, 1, u64> uses_cc; | ||
| 455 | } r1; | ||
| 456 | |||
| 457 | union { | ||
| 458 | BitField<28, 8, u64> entry_a; | ||
| 459 | BitField<37, 1, u64> neg; | ||
| 460 | BitField<38, 1, u64> uses_cc; | ||
| 461 | } r2; | ||
| 462 | |||
| 463 | } lea; | ||
| 464 | |||
| 465 | union { | ||
| 417 | BitField<0, 5, FlowCondition> cond; | 466 | BitField<0, 5, FlowCondition> cond; |
| 418 | } flow; | 467 | } flow; |
| 419 | 468 | ||
| @@ -468,6 +517,18 @@ union Instruction { | |||
| 468 | } psetp; | 517 | } psetp; |
| 469 | 518 | ||
| 470 | union { | 519 | union { |
| 520 | BitField<12, 3, u64> pred12; | ||
| 521 | BitField<15, 1, u64> neg_pred12; | ||
| 522 | BitField<24, 2, PredOperation> cond; | ||
| 523 | BitField<29, 3, u64> pred29; | ||
| 524 | BitField<32, 1, u64> neg_pred29; | ||
| 525 | BitField<39, 3, u64> pred39; | ||
| 526 | BitField<42, 1, u64> neg_pred39; | ||
| 527 | BitField<44, 1, u64> bf; | ||
| 528 | BitField<45, 2, PredOperation> op; | ||
| 529 | } pset; | ||
| 530 | |||
| 531 | union { | ||
| 471 | BitField<39, 3, u64> pred39; | 532 | BitField<39, 3, u64> pred39; |
| 472 | BitField<42, 1, u64> neg_pred; | 533 | BitField<42, 1, u64> neg_pred; |
| 473 | BitField<43, 1, u64> neg_a; | 534 | BitField<43, 1, u64> neg_a; |
| @@ -519,6 +580,21 @@ union Instruction { | |||
| 519 | } tex; | 580 | } tex; |
| 520 | 581 | ||
| 521 | union { | 582 | union { |
| 583 | BitField<22, 6, TextureQueryType> query_type; | ||
| 584 | BitField<31, 4, u64> component_mask; | ||
| 585 | } txq; | ||
| 586 | |||
| 587 | union { | ||
| 588 | BitField<28, 1, u64> array; | ||
| 589 | BitField<29, 2, TextureType> texture_type; | ||
| 590 | BitField<31, 4, u64> component_mask; | ||
| 591 | |||
| 592 | bool IsComponentEnabled(size_t component) const { | ||
| 593 | return ((1ull << component) & component_mask) != 0; | ||
| 594 | } | ||
| 595 | } tmml; | ||
| 596 | |||
| 597 | union { | ||
| 522 | BitField<28, 1, u64> array; | 598 | BitField<28, 1, u64> array; |
| 523 | BitField<29, 2, TextureType> texture_type; | 599 | BitField<29, 2, TextureType> texture_type; |
| 524 | BitField<56, 2, u64> component; | 600 | BitField<56, 2, u64> component; |
| @@ -670,11 +746,13 @@ public: | |||
| 670 | LDG, // Load from global memory | 746 | LDG, // Load from global memory |
| 671 | STG, // Store in global memory | 747 | STG, // Store in global memory |
| 672 | TEX, | 748 | TEX, |
| 673 | TEXQ, // Texture Query | 749 | TXQ, // Texture Query |
| 674 | TEXS, // Texture Fetch with scalar/non-vec4 source/destinations | 750 | TEXS, // Texture Fetch with scalar/non-vec4 source/destinations |
| 675 | TLDS, // Texture Load with scalar/non-vec4 source/destinations | 751 | TLDS, // Texture Load with scalar/non-vec4 source/destinations |
| 676 | TLD4, // Texture Load 4 | 752 | TLD4, // Texture Load 4 |
| 677 | TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations | 753 | TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations |
| 754 | TMML_B, // Texture Mip Map Level | ||
| 755 | TMML, // Texture Mip Map Level | ||
| 678 | EXIT, | 756 | EXIT, |
| 679 | IPA, | 757 | IPA, |
| 680 | FFMA_IMM, // Fused Multiply and Add | 758 | FFMA_IMM, // Fused Multiply and Add |
| @@ -699,6 +777,11 @@ public: | |||
| 699 | ISCADD_C, // Scale and Add | 777 | ISCADD_C, // Scale and Add |
| 700 | ISCADD_R, | 778 | ISCADD_R, |
| 701 | ISCADD_IMM, | 779 | ISCADD_IMM, |
| 780 | LEA_R1, | ||
| 781 | LEA_R2, | ||
| 782 | LEA_RZ, | ||
| 783 | LEA_IMM, | ||
| 784 | LEA_HI, | ||
| 702 | POPC_C, | 785 | POPC_C, |
| 703 | POPC_R, | 786 | POPC_R, |
| 704 | POPC_IMM, | 787 | POPC_IMM, |
| @@ -757,6 +840,7 @@ public: | |||
| 757 | ISET_C, | 840 | ISET_C, |
| 758 | ISET_IMM, | 841 | ISET_IMM, |
| 759 | PSETP, | 842 | PSETP, |
| 843 | PSET, | ||
| 760 | XMAD_IMM, | 844 | XMAD_IMM, |
| 761 | XMAD_CR, | 845 | XMAD_CR, |
| 762 | XMAD_RC, | 846 | XMAD_RC, |
| @@ -780,6 +864,7 @@ public: | |||
| 780 | IntegerSet, | 864 | IntegerSet, |
| 781 | IntegerSetPredicate, | 865 | IntegerSetPredicate, |
| 782 | PredicateSetPredicate, | 866 | PredicateSetPredicate, |
| 867 | PredicateSetRegister, | ||
| 783 | Conversion, | 868 | Conversion, |
| 784 | Xmad, | 869 | Xmad, |
| 785 | Unknown, | 870 | Unknown, |
| @@ -894,11 +979,13 @@ private: | |||
| 894 | INST("1110111011010---", Id::LDG, Type::Memory, "LDG"), | 979 | INST("1110111011010---", Id::LDG, Type::Memory, "LDG"), |
| 895 | INST("1110111011011---", Id::STG, Type::Memory, "STG"), | 980 | INST("1110111011011---", Id::STG, Type::Memory, "STG"), |
| 896 | INST("110000----111---", Id::TEX, Type::Memory, "TEX"), | 981 | INST("110000----111---", Id::TEX, Type::Memory, "TEX"), |
| 897 | INST("1101111101001---", Id::TEXQ, Type::Memory, "TEXQ"), | 982 | INST("1101111101001---", Id::TXQ, Type::Memory, "TXQ"), |
| 898 | INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"), | 983 | INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"), |
| 899 | INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"), | 984 | INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"), |
| 900 | INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"), | 985 | INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"), |
| 901 | INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"), | 986 | INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"), |
| 987 | INST("110111110110----", Id::TMML_B, Type::Memory, "TMML_B"), | ||
| 988 | INST("1101111101011---", Id::TMML, Type::Memory, "TMML"), | ||
| 902 | INST("111000110000----", Id::EXIT, Type::Trivial, "EXIT"), | 989 | INST("111000110000----", Id::EXIT, Type::Trivial, "EXIT"), |
| 903 | INST("11100000--------", Id::IPA, Type::Trivial, "IPA"), | 990 | INST("11100000--------", Id::IPA, Type::Trivial, "IPA"), |
| 904 | INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"), | 991 | INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"), |
| @@ -929,6 +1016,11 @@ private: | |||
| 929 | INST("0100110010100---", Id::SEL_C, Type::ArithmeticInteger, "SEL_C"), | 1016 | INST("0100110010100---", Id::SEL_C, Type::ArithmeticInteger, "SEL_C"), |
| 930 | INST("0101110010100---", Id::SEL_R, Type::ArithmeticInteger, "SEL_R"), | 1017 | INST("0101110010100---", Id::SEL_R, Type::ArithmeticInteger, "SEL_R"), |
| 931 | INST("0011100-10100---", Id::SEL_IMM, Type::ArithmeticInteger, "SEL_IMM"), | 1018 | INST("0011100-10100---", Id::SEL_IMM, Type::ArithmeticInteger, "SEL_IMM"), |
| 1019 | INST("0101101111011---", Id::LEA_R2, Type::ArithmeticInteger, "LEA_R2"), | ||
| 1020 | INST("0101101111010---", Id::LEA_R1, Type::ArithmeticInteger, "LEA_R1"), | ||
| 1021 | INST("001101101101----", Id::LEA_IMM, Type::ArithmeticInteger, "LEA_IMM"), | ||
| 1022 | INST("010010111101----", Id::LEA_RZ, Type::ArithmeticInteger, "LEA_RZ"), | ||
| 1023 | INST("00011000--------", Id::LEA_HI, Type::ArithmeticInteger, "LEA_HI"), | ||
| 932 | INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), | 1024 | INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), |
| 933 | INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), | 1025 | INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), |
| 934 | INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), | 1026 | INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), |
| @@ -983,6 +1075,7 @@ private: | |||
| 983 | INST("010110110101----", Id::ISET_R, Type::IntegerSet, "ISET_R"), | 1075 | INST("010110110101----", Id::ISET_R, Type::IntegerSet, "ISET_R"), |
| 984 | INST("010010110101----", Id::ISET_C, Type::IntegerSet, "ISET_C"), | 1076 | INST("010010110101----", Id::ISET_C, Type::IntegerSet, "ISET_C"), |
| 985 | INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"), | 1077 | INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"), |
| 1078 | INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"), | ||
| 986 | INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), | 1079 | INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), |
| 987 | INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"), | 1080 | INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"), |
| 988 | INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"), | 1081 | INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"), |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index e6d8e65c6..86a809f86 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -66,6 +66,7 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { | |||
| 66 | case RenderTargetFormat::RGBA8_UINT: | 66 | case RenderTargetFormat::RGBA8_UINT: |
| 67 | case RenderTargetFormat::RGB10_A2_UNORM: | 67 | case RenderTargetFormat::RGB10_A2_UNORM: |
| 68 | case RenderTargetFormat::BGRA8_UNORM: | 68 | case RenderTargetFormat::BGRA8_UNORM: |
| 69 | case RenderTargetFormat::BGRA8_SRGB: | ||
| 69 | case RenderTargetFormat::RG16_UNORM: | 70 | case RenderTargetFormat::RG16_UNORM: |
| 70 | case RenderTargetFormat::RG16_SNORM: | 71 | case RenderTargetFormat::RG16_SNORM: |
| 71 | case RenderTargetFormat::RG16_UINT: | 72 | case RenderTargetFormat::RG16_UINT: |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index d29f31f52..589a59b4f 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <memory> | 8 | #include <memory> |
| 9 | #include <vector> | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "core/hle/service/nvflinger/buffer_queue.h" | 11 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 11 | #include "video_core/memory_manager.h" | 12 | #include "video_core/memory_manager.h" |
| @@ -26,6 +27,7 @@ enum class RenderTargetFormat : u32 { | |||
| 26 | RG32_FLOAT = 0xCB, | 27 | RG32_FLOAT = 0xCB, |
| 27 | RG32_UINT = 0xCD, | 28 | RG32_UINT = 0xCD, |
| 28 | BGRA8_UNORM = 0xCF, | 29 | BGRA8_UNORM = 0xCF, |
| 30 | BGRA8_SRGB = 0xD0, | ||
| 29 | RGB10_A2_UNORM = 0xD1, | 31 | RGB10_A2_UNORM = 0xD1, |
| 30 | RGBA8_UNORM = 0xD5, | 32 | RGBA8_UNORM = 0xD5, |
| 31 | RGBA8_SRGB = 0xD6, | 33 | RGBA8_SRGB = 0xD6, |
| @@ -67,6 +69,7 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format); | |||
| 67 | /// Returns the number of bytes per pixel of each depth format. | 69 | /// Returns the number of bytes per pixel of each depth format. |
| 68 | u32 DepthFormatBytesPerPixel(DepthFormat format); | 70 | u32 DepthFormatBytesPerPixel(DepthFormat format); |
| 69 | 71 | ||
| 72 | struct CommandListHeader; | ||
| 70 | class DebugContext; | 73 | class DebugContext; |
| 71 | 74 | ||
| 72 | /** | 75 | /** |
| @@ -115,7 +118,7 @@ public: | |||
| 115 | ~GPU(); | 118 | ~GPU(); |
| 116 | 119 | ||
| 117 | /// Processes a command list stored at the specified address in GPU memory. | 120 | /// Processes a command list stored at the specified address in GPU memory. |
| 118 | void ProcessCommandList(GPUVAddr address, u32 size); | 121 | void ProcessCommandLists(const std::vector<CommandListHeader>& commands); |
| 119 | 122 | ||
| 120 | /// Returns a reference to the Maxwell3D GPU engine. | 123 | /// Returns a reference to the Maxwell3D GPU engine. |
| 121 | Engines::Maxwell3D& Maxwell3D(); | 124 | Engines::Maxwell3D& Maxwell3D(); |
| @@ -130,9 +133,6 @@ public: | |||
| 130 | const Tegra::MemoryManager& MemoryManager() const; | 133 | const Tegra::MemoryManager& MemoryManager() const; |
| 131 | 134 | ||
| 132 | private: | 135 | private: |
| 133 | /// Writes a single register in the engine bound to the specified subchannel | ||
| 134 | void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params); | ||
| 135 | |||
| 136 | std::unique_ptr<Tegra::MemoryManager> memory_manager; | 136 | std::unique_ptr<Tegra::MemoryManager> memory_manager; |
| 137 | 137 | ||
| 138 | /// Mapping of command subchannels to their bound engine ids. | 138 | /// Mapping of command subchannels to their bound engine ids. |
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 9d78e8b6b..cd819d69f 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h | |||
| @@ -20,9 +20,6 @@ public: | |||
| 20 | /// Clear the current framebuffer | 20 | /// Clear the current framebuffer |
| 21 | virtual void Clear() = 0; | 21 | virtual void Clear() = 0; |
| 22 | 22 | ||
| 23 | /// Notify rasterizer that the specified Maxwell register has been changed | ||
| 24 | virtual void NotifyMaxwellRegisterChanged(u32 method) = 0; | ||
| 25 | |||
| 26 | /// Notify rasterizer that all caches should be flushed to Switch memory | 23 | /// Notify rasterizer that all caches should be flushed to Switch memory |
| 27 | virtual void FlushAll() = 0; | 24 | virtual void FlushAll() = 0; |
| 28 | 25 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e6d6917fa..c59f3af1b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -294,61 +294,80 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { | |||
| 294 | cached_pages.add({pages_interval, delta}); | 294 | cached_pages.add({pages_interval, delta}); |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, | 297 | void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb, |
| 298 | bool using_depth_fb, | 298 | bool preserve_contents, |
| 299 | bool preserve_contents) { | 299 | boost::optional<size_t> single_color_target) { |
| 300 | MICROPROFILE_SCOPE(OpenGL_Framebuffer); | 300 | MICROPROFILE_SCOPE(OpenGL_Framebuffer); |
| 301 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 301 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |
| 302 | 302 | ||
| 303 | if (regs.rt[0].format == Tegra::RenderTargetFormat::NONE) { | 303 | Surface depth_surface; |
| 304 | LOG_ERROR(HW_GPU, "RenderTargetFormat is not configured"); | 304 | if (using_depth_fb) { |
| 305 | using_color_fb = false; | 305 | depth_surface = res_cache.GetDepthBufferSurface(preserve_contents); |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | const bool has_stencil = regs.stencil_enable; | 308 | // TODO(bunnei): Figure out how the below register works. According to envytools, this should be |
| 309 | const bool write_color_fb = | 309 | // used to enable multiple render targets. However, it is left unset on all games that I have |
| 310 | state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE || | 310 | // tested. |
| 311 | state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE; | 311 | ASSERT_MSG(regs.rt_separate_frag_data == 0, "Unimplemented"); |
| 312 | |||
| 313 | const bool write_depth_fb = | ||
| 314 | (state.depth.test_enabled && state.depth.write_mask == GL_TRUE) || | ||
| 315 | (has_stencil && (state.stencil.front.write_mask || state.stencil.back.write_mask)); | ||
| 316 | 312 | ||
| 317 | Surface color_surface; | 313 | // Bind the framebuffer surfaces |
| 318 | Surface depth_surface; | 314 | state.draw.draw_framebuffer = framebuffer.handle; |
| 319 | MathUtil::Rectangle<u32> surfaces_rect; | 315 | state.Apply(); |
| 320 | std::tie(color_surface, depth_surface, surfaces_rect) = | ||
| 321 | res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, preserve_contents); | ||
| 322 | 316 | ||
| 323 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; | 317 | if (using_color_fb) { |
| 324 | const MathUtil::Rectangle<u32> draw_rect{ | 318 | if (single_color_target) { |
| 325 | static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left, | 319 | // Used when just a single color attachment is enabled, e.g. for clearing a color buffer |
| 326 | surfaces_rect.left, surfaces_rect.right)), // Left | 320 | Surface color_surface = |
| 327 | static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.top, | 321 | res_cache.GetColorBufferSurface(*single_color_target, preserve_contents); |
| 328 | surfaces_rect.bottom, surfaces_rect.top)), // Top | 322 | glFramebufferTexture2D( |
| 329 | static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.right, | 323 | GL_DRAW_FRAMEBUFFER, |
| 330 | surfaces_rect.left, surfaces_rect.right)), // Right | 324 | GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(*single_color_target), GL_TEXTURE_2D, |
| 331 | static_cast<u32>( | 325 | color_surface != nullptr ? color_surface->Texture().handle : 0, 0); |
| 332 | std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.bottom, | 326 | glDrawBuffer(GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(*single_color_target)); |
| 333 | surfaces_rect.bottom, surfaces_rect.top))}; // Bottom | 327 | } else { |
| 328 | // Multiple color attachments are enabled | ||
| 329 | std::array<GLenum, Maxwell::NumRenderTargets> buffers; | ||
| 330 | for (size_t index = 0; index < Maxwell::NumRenderTargets; ++index) { | ||
| 331 | Surface color_surface = res_cache.GetColorBufferSurface(index, preserve_contents); | ||
| 332 | buffers[index] = GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index); | ||
| 333 | glFramebufferTexture2D( | ||
| 334 | GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index), | ||
| 335 | GL_TEXTURE_2D, color_surface != nullptr ? color_surface->Texture().handle : 0, | ||
| 336 | 0); | ||
| 337 | } | ||
| 338 | glDrawBuffers(regs.rt_control.count, buffers.data()); | ||
| 339 | } | ||
| 340 | } else { | ||
| 341 | // No color attachments are enabled - zero out all of them | ||
| 342 | for (size_t index = 0; index < Maxwell::NumRenderTargets; ++index) { | ||
| 343 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, | ||
| 344 | GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index), GL_TEXTURE_2D, | ||
| 345 | 0, 0); | ||
| 346 | } | ||
| 347 | glDrawBuffer(GL_NONE); | ||
| 348 | } | ||
| 334 | 349 | ||
| 335 | // Bind the framebuffer surfaces | 350 | if (depth_surface) { |
| 336 | BindFramebufferSurfaces(color_surface, depth_surface, has_stencil); | 351 | if (regs.stencil_enable) { |
| 352 | // Attach both depth and stencil | ||
| 353 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, | ||
| 354 | depth_surface->Texture().handle, 0); | ||
| 355 | } else { | ||
| 356 | // Attach depth | ||
| 357 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, | ||
| 358 | depth_surface->Texture().handle, 0); | ||
| 359 | // Clear stencil attachment | ||
| 360 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); | ||
| 361 | } | ||
| 362 | } else { | ||
| 363 | // Clear both depth and stencil attachment | ||
| 364 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, | ||
| 365 | 0); | ||
| 366 | } | ||
| 337 | 367 | ||
| 338 | SyncViewport(surfaces_rect); | 368 | SyncViewport(); |
| 339 | 369 | ||
| 340 | // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable | ||
| 341 | // scissor test to prevent drawing outside of the framebuffer region | ||
| 342 | state.scissor.enabled = true; | ||
| 343 | state.scissor.x = draw_rect.left; | ||
| 344 | state.scissor.y = draw_rect.bottom; | ||
| 345 | state.scissor.width = draw_rect.GetWidth(); | ||
| 346 | state.scissor.height = draw_rect.GetHeight(); | ||
| 347 | state.Apply(); | 370 | state.Apply(); |
| 348 | |||
| 349 | // Only return the surface to be marked as dirty if writing to it is enabled. | ||
| 350 | return std::make_pair(write_color_fb ? color_surface : nullptr, | ||
| 351 | write_depth_fb ? depth_surface : nullptr); | ||
| 352 | } | 371 | } |
| 353 | 372 | ||
| 354 | void RasterizerOpenGL::Clear() { | 373 | void RasterizerOpenGL::Clear() { |
| @@ -356,8 +375,9 @@ void RasterizerOpenGL::Clear() { | |||
| 356 | SCOPE_EXIT({ prev_state.Apply(); }); | 375 | SCOPE_EXIT({ prev_state.Apply(); }); |
| 357 | 376 | ||
| 358 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 377 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |
| 359 | bool use_color_fb = false; | 378 | bool use_color{}; |
| 360 | bool use_depth_fb = false; | 379 | bool use_depth{}; |
| 380 | bool use_stencil{}; | ||
| 361 | 381 | ||
| 362 | OpenGLState clear_state; | 382 | OpenGLState clear_state; |
| 363 | clear_state.draw.draw_framebuffer = state.draw.draw_framebuffer; | 383 | clear_state.draw.draw_framebuffer = state.draw.draw_framebuffer; |
| @@ -366,22 +386,13 @@ void RasterizerOpenGL::Clear() { | |||
| 366 | clear_state.color_mask.blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE; | 386 | clear_state.color_mask.blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE; |
| 367 | clear_state.color_mask.alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE; | 387 | clear_state.color_mask.alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE; |
| 368 | 388 | ||
| 369 | GLbitfield clear_mask{}; | ||
| 370 | if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || | 389 | if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || |
| 371 | regs.clear_buffers.A) { | 390 | regs.clear_buffers.A) { |
| 372 | if (regs.clear_buffers.RT == 0) { | 391 | use_color = true; |
| 373 | // We only support clearing the first color attachment for now | ||
| 374 | clear_mask |= GL_COLOR_BUFFER_BIT; | ||
| 375 | use_color_fb = true; | ||
| 376 | } else { | ||
| 377 | // TODO(subv): Add support for the other color attachments | ||
| 378 | LOG_CRITICAL(HW_GPU, "Clear unimplemented for RT {}", regs.clear_buffers.RT); | ||
| 379 | } | ||
| 380 | } | 392 | } |
| 381 | if (regs.clear_buffers.Z) { | 393 | if (regs.clear_buffers.Z) { |
| 382 | ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!"); | 394 | ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!"); |
| 383 | use_depth_fb = true; | 395 | use_depth = true; |
| 384 | clear_mask |= GL_DEPTH_BUFFER_BIT; | ||
| 385 | 396 | ||
| 386 | // Always enable the depth write when clearing the depth buffer. The depth write mask is | 397 | // Always enable the depth write when clearing the depth buffer. The depth write mask is |
| 387 | // ignored when clearing the buffer in the Switch, but OpenGL obeys it so we set it to true. | 398 | // ignored when clearing the buffer in the Switch, but OpenGL obeys it so we set it to true. |
| @@ -390,34 +401,33 @@ void RasterizerOpenGL::Clear() { | |||
| 390 | } | 401 | } |
| 391 | if (regs.clear_buffers.S) { | 402 | if (regs.clear_buffers.S) { |
| 392 | ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear stencil but buffer is not enabled!"); | 403 | ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear stencil but buffer is not enabled!"); |
| 393 | use_depth_fb = true; | 404 | use_stencil = true; |
| 394 | clear_mask |= GL_STENCIL_BUFFER_BIT; | ||
| 395 | clear_state.stencil.test_enabled = true; | 405 | clear_state.stencil.test_enabled = true; |
| 396 | } | 406 | } |
| 397 | 407 | ||
| 398 | if (!use_color_fb && !use_depth_fb) { | 408 | if (!use_color && !use_depth && !use_stencil) { |
| 399 | // No color surface nor depth/stencil surface are enabled | 409 | // No color surface nor depth/stencil surface are enabled |
| 400 | return; | 410 | return; |
| 401 | } | 411 | } |
| 402 | 412 | ||
| 403 | if (clear_mask == 0) { | ||
| 404 | // No clear mask is enabled | ||
| 405 | return; | ||
| 406 | } | ||
| 407 | |||
| 408 | ScopeAcquireGLContext acquire_context{emu_window}; | 413 | ScopeAcquireGLContext acquire_context{emu_window}; |
| 409 | 414 | ||
| 410 | auto [dirty_color_surface, dirty_depth_surface] = | 415 | ConfigureFramebuffers(use_color, use_depth || use_stencil, false, |
| 411 | ConfigureFramebuffers(use_color_fb, use_depth_fb, false); | 416 | regs.clear_buffers.RT.Value()); |
| 412 | 417 | ||
| 413 | clear_state.Apply(); | 418 | clear_state.Apply(); |
| 414 | 419 | ||
| 415 | glClearColor(regs.clear_color[0], regs.clear_color[1], regs.clear_color[2], | 420 | if (use_color) { |
| 416 | regs.clear_color[3]); | 421 | glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color); |
| 417 | glClearDepth(regs.clear_depth); | 422 | } |
| 418 | glClearStencil(regs.clear_stencil); | ||
| 419 | 423 | ||
| 420 | glClear(clear_mask); | 424 | if (use_depth && use_stencil) { |
| 425 | glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil); | ||
| 426 | } else if (use_depth) { | ||
| 427 | glClearBufferfv(GL_DEPTH, 0, ®s.clear_depth); | ||
| 428 | } else if (use_stencil) { | ||
| 429 | glClearBufferiv(GL_STENCIL, 0, ®s.clear_stencil); | ||
| 430 | } | ||
| 421 | } | 431 | } |
| 422 | 432 | ||
| 423 | void RasterizerOpenGL::DrawArrays() { | 433 | void RasterizerOpenGL::DrawArrays() { |
| @@ -430,8 +440,7 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 430 | 440 | ||
| 431 | ScopeAcquireGLContext acquire_context{emu_window}; | 441 | ScopeAcquireGLContext acquire_context{emu_window}; |
| 432 | 442 | ||
| 433 | const auto [dirty_color_surface, dirty_depth_surface] = | 443 | ConfigureFramebuffers(); |
| 434 | ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0, true); | ||
| 435 | 444 | ||
| 436 | SyncDepthTestState(); | 445 | SyncDepthTestState(); |
| 437 | SyncStencilTestState(); | 446 | SyncStencilTestState(); |
| @@ -525,8 +534,6 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 525 | state.Apply(); | 534 | state.Apply(); |
| 526 | } | 535 | } |
| 527 | 536 | ||
| 528 | void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 method) {} | ||
| 529 | |||
| 530 | void RasterizerOpenGL::FlushAll() {} | 537 | void RasterizerOpenGL::FlushAll() {} |
| 531 | 538 | ||
| 532 | void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) {} | 539 | void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) {} |
| @@ -729,38 +736,12 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, | |||
| 729 | return current_unit + static_cast<u32>(entries.size()); | 736 | return current_unit + static_cast<u32>(entries.size()); |
| 730 | } | 737 | } |
| 731 | 738 | ||
| 732 | void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface, | 739 | void RasterizerOpenGL::SyncViewport() { |
| 733 | const Surface& depth_surface, bool has_stencil) { | ||
| 734 | state.draw.draw_framebuffer = framebuffer.handle; | ||
| 735 | state.Apply(); | ||
| 736 | |||
| 737 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, | ||
| 738 | color_surface != nullptr ? color_surface->Texture().handle : 0, 0); | ||
| 739 | if (depth_surface != nullptr) { | ||
| 740 | if (has_stencil) { | ||
| 741 | // attach both depth and stencil | ||
| 742 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, | ||
| 743 | depth_surface->Texture().handle, 0); | ||
| 744 | } else { | ||
| 745 | // attach depth | ||
| 746 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, | ||
| 747 | depth_surface->Texture().handle, 0); | ||
| 748 | // clear stencil attachment | ||
| 749 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); | ||
| 750 | } | ||
| 751 | } else { | ||
| 752 | // clear both depth and stencil attachment | ||
| 753 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, | ||
| 754 | 0); | ||
| 755 | } | ||
| 756 | } | ||
| 757 | |||
| 758 | void RasterizerOpenGL::SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect) { | ||
| 759 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 740 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |
| 760 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; | 741 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; |
| 761 | 742 | ||
| 762 | state.viewport.x = static_cast<GLint>(surfaces_rect.left) + viewport_rect.left; | 743 | state.viewport.x = viewport_rect.left; |
| 763 | state.viewport.y = static_cast<GLint>(surfaces_rect.bottom) + viewport_rect.bottom; | 744 | state.viewport.y = viewport_rect.bottom; |
| 764 | state.viewport.width = static_cast<GLsizei>(viewport_rect.GetWidth()); | 745 | state.viewport.width = static_cast<GLsizei>(viewport_rect.GetWidth()); |
| 765 | state.viewport.height = static_cast<GLsizei>(viewport_rect.GetHeight()); | 746 | state.viewport.height = static_cast<GLsizei>(viewport_rect.GetHeight()); |
| 766 | } | 747 | } |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index c6bb1516b..745c3dc0c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <vector> | 13 | #include <vector> |
| 14 | 14 | ||
| 15 | #include <boost/icl/interval_map.hpp> | 15 | #include <boost/icl/interval_map.hpp> |
| 16 | #include <boost/optional.hpp> | ||
| 16 | #include <boost/range/iterator_range.hpp> | 17 | #include <boost/range/iterator_range.hpp> |
| 17 | #include <glad/glad.h> | 18 | #include <glad/glad.h> |
| 18 | 19 | ||
| @@ -45,7 +46,6 @@ public: | |||
| 45 | 46 | ||
| 46 | void DrawArrays() override; | 47 | void DrawArrays() override; |
| 47 | void Clear() override; | 48 | void Clear() override; |
| 48 | void NotifyMaxwellRegisterChanged(u32 method) override; | ||
| 49 | void FlushAll() override; | 49 | void FlushAll() override; |
| 50 | void FlushRegion(VAddr addr, u64 size) override; | 50 | void FlushRegion(VAddr addr, u64 size) override; |
| 51 | void InvalidateRegion(VAddr addr, u64 size) override; | 51 | void InvalidateRegion(VAddr addr, u64 size) override; |
| @@ -97,14 +97,16 @@ private: | |||
| 97 | GLvec4 border_color; | 97 | GLvec4 border_color; |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | /// Configures the color and depth framebuffer states and returns the dirty <Color, Depth> | 100 | /** |
| 101 | /// surfaces if writing was enabled. | 101 | * Configures the color and depth framebuffer states. |
| 102 | std::pair<Surface, Surface> ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb, | 102 | * @param use_color_fb If true, configure color framebuffers. |
| 103 | bool preserve_contents); | 103 | * @param using_depth_fb If true, configure the depth/stencil framebuffer. |
| 104 | 104 | * @param preserve_contents If true, tries to preserve data from a previously used framebuffer. | |
| 105 | /// Binds the framebuffer color and depth surface | 105 | * @param single_color_target Specifies if a single color buffer target should be used. |
| 106 | void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface, | 106 | */ |
| 107 | bool has_stencil); | 107 | void ConfigureFramebuffers(bool use_color_fb = true, bool using_depth_fb = true, |
| 108 | bool preserve_contents = true, | ||
| 109 | boost::optional<size_t> single_color_target = {}); | ||
| 108 | 110 | ||
| 109 | /* | 111 | /* |
| 110 | * Configures the current constbuffers to use for the draw command. | 112 | * Configures the current constbuffers to use for the draw command. |
| @@ -127,7 +129,7 @@ private: | |||
| 127 | u32 current_unit); | 129 | u32 current_unit); |
| 128 | 130 | ||
| 129 | /// Syncs the viewport to match the guest state | 131 | /// Syncs the viewport to match the guest state |
| 130 | void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect); | 132 | void SyncViewport(); |
| 131 | 133 | ||
| 132 | /// Syncs the clip enabled status to match the guest state | 134 | /// Syncs the clip enabled status to match the guest state |
| 133 | void SyncClipEnabled(); | 135 | void SyncClipEnabled(); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 360fb0cd5..fb56decc0 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -52,17 +52,31 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 52 | params.type = GetFormatType(params.pixel_format); | 52 | params.type = GetFormatType(params.pixel_format); |
| 53 | params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format)); | 53 | params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format)); |
| 54 | params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); | 54 | params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); |
| 55 | params.depth = config.tic.Depth(); | ||
| 56 | params.unaligned_height = config.tic.Height(); | 55 | params.unaligned_height = config.tic.Height(); |
| 57 | params.size_in_bytes = params.SizeInBytes(); | ||
| 58 | params.cache_width = Common::AlignUp(params.width, 8); | ||
| 59 | params.cache_height = Common::AlignUp(params.height, 8); | ||
| 60 | params.target = SurfaceTargetFromTextureType(config.tic.texture_type); | 56 | params.target = SurfaceTargetFromTextureType(config.tic.texture_type); |
| 57 | |||
| 58 | switch (params.target) { | ||
| 59 | case SurfaceTarget::Texture1D: | ||
| 60 | case SurfaceTarget::Texture2D: | ||
| 61 | params.depth = 1; | ||
| 62 | break; | ||
| 63 | case SurfaceTarget::Texture3D: | ||
| 64 | case SurfaceTarget::Texture2DArray: | ||
| 65 | params.depth = config.tic.Depth(); | ||
| 66 | break; | ||
| 67 | default: | ||
| 68 | LOG_CRITICAL(HW_GPU, "Unknown depth for target={}", static_cast<u32>(params.target)); | ||
| 69 | UNREACHABLE(); | ||
| 70 | params.depth = 1; | ||
| 71 | break; | ||
| 72 | } | ||
| 73 | |||
| 74 | params.size_in_bytes = params.SizeInBytes(); | ||
| 61 | return params; | 75 | return params; |
| 62 | } | 76 | } |
| 63 | 77 | ||
| 64 | /*static*/ SurfaceParams SurfaceParams::CreateForFramebuffer( | 78 | /*static*/ SurfaceParams SurfaceParams::CreateForFramebuffer(size_t index) { |
| 65 | const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config) { | 79 | const auto& config{Core::System::GetInstance().GPU().Maxwell3D().regs.rt[index]}; |
| 66 | SurfaceParams params{}; | 80 | SurfaceParams params{}; |
| 67 | params.addr = TryGetCpuAddr(config.Address()); | 81 | params.addr = TryGetCpuAddr(config.Address()); |
| 68 | params.is_tiled = true; | 82 | params.is_tiled = true; |
| @@ -72,12 +86,10 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 72 | params.type = GetFormatType(params.pixel_format); | 86 | params.type = GetFormatType(params.pixel_format); |
| 73 | params.width = config.width; | 87 | params.width = config.width; |
| 74 | params.height = config.height; | 88 | params.height = config.height; |
| 75 | params.depth = 1; | ||
| 76 | params.unaligned_height = config.height; | 89 | params.unaligned_height = config.height; |
| 77 | params.size_in_bytes = params.SizeInBytes(); | ||
| 78 | params.cache_width = Common::AlignUp(params.width, 8); | ||
| 79 | params.cache_height = Common::AlignUp(params.height, 8); | ||
| 80 | params.target = SurfaceTarget::Texture2D; | 90 | params.target = SurfaceTarget::Texture2D; |
| 91 | params.depth = 1; | ||
| 92 | params.size_in_bytes = params.SizeInBytes(); | ||
| 81 | return params; | 93 | return params; |
| 82 | } | 94 | } |
| 83 | 95 | ||
| @@ -93,12 +105,10 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 93 | params.type = GetFormatType(params.pixel_format); | 105 | params.type = GetFormatType(params.pixel_format); |
| 94 | params.width = zeta_width; | 106 | params.width = zeta_width; |
| 95 | params.height = zeta_height; | 107 | params.height = zeta_height; |
| 96 | params.depth = 1; | ||
| 97 | params.unaligned_height = zeta_height; | 108 | params.unaligned_height = zeta_height; |
| 98 | params.size_in_bytes = params.SizeInBytes(); | ||
| 99 | params.cache_width = Common::AlignUp(params.width, 8); | ||
| 100 | params.cache_height = Common::AlignUp(params.height, 8); | ||
| 101 | params.target = SurfaceTarget::Texture2D; | 109 | params.target = SurfaceTarget::Texture2D; |
| 110 | params.depth = 1; | ||
| 111 | params.size_in_bytes = params.SizeInBytes(); | ||
| 102 | return params; | 112 | return params; |
| 103 | } | 113 | } |
| 104 | 114 | ||
| @@ -461,30 +471,27 @@ CachedSurface::CachedSurface(const SurfaceParams& params) | |||
| 461 | // Only pre-create the texture for non-compressed textures. | 471 | // Only pre-create the texture for non-compressed textures. |
| 462 | switch (params.target) { | 472 | switch (params.target) { |
| 463 | case SurfaceParams::SurfaceTarget::Texture1D: | 473 | case SurfaceParams::SurfaceTarget::Texture1D: |
| 464 | glTexImage1D(SurfaceTargetToGL(params.target), 0, format_tuple.internal_format, | 474 | glTexStorage1D(SurfaceTargetToGL(params.target), 1, format_tuple.internal_format, |
| 465 | rect.GetWidth(), 0, format_tuple.format, format_tuple.type, nullptr); | 475 | rect.GetWidth()); |
| 466 | break; | 476 | break; |
| 467 | case SurfaceParams::SurfaceTarget::Texture2D: | 477 | case SurfaceParams::SurfaceTarget::Texture2D: |
| 468 | glTexImage2D(SurfaceTargetToGL(params.target), 0, format_tuple.internal_format, | 478 | glTexStorage2D(SurfaceTargetToGL(params.target), 1, format_tuple.internal_format, |
| 469 | rect.GetWidth(), rect.GetHeight(), 0, format_tuple.format, | 479 | rect.GetWidth(), rect.GetHeight()); |
| 470 | format_tuple.type, nullptr); | ||
| 471 | break; | 480 | break; |
| 472 | case SurfaceParams::SurfaceTarget::Texture3D: | 481 | case SurfaceParams::SurfaceTarget::Texture3D: |
| 473 | case SurfaceParams::SurfaceTarget::Texture2DArray: | 482 | case SurfaceParams::SurfaceTarget::Texture2DArray: |
| 474 | glTexImage3D(SurfaceTargetToGL(params.target), 0, format_tuple.internal_format, | 483 | glTexStorage3D(SurfaceTargetToGL(params.target), 1, format_tuple.internal_format, |
| 475 | rect.GetWidth(), rect.GetHeight(), params.depth, 0, format_tuple.format, | 484 | rect.GetWidth(), rect.GetHeight(), params.depth); |
| 476 | format_tuple.type, nullptr); | ||
| 477 | break; | 485 | break; |
| 478 | default: | 486 | default: |
| 479 | LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", | 487 | LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", |
| 480 | static_cast<u32>(params.target)); | 488 | static_cast<u32>(params.target)); |
| 481 | UNREACHABLE(); | 489 | UNREACHABLE(); |
| 482 | glTexImage2D(GL_TEXTURE_2D, 0, format_tuple.internal_format, rect.GetWidth(), | 490 | glTexStorage2D(GL_TEXTURE_2D, 1, format_tuple.internal_format, rect.GetWidth(), |
| 483 | rect.GetHeight(), 0, format_tuple.format, format_tuple.type, nullptr); | 491 | rect.GetHeight()); |
| 484 | } | 492 | } |
| 485 | } | 493 | } |
| 486 | 494 | ||
| 487 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAX_LEVEL, 0); | ||
| 488 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 495 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 489 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 496 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 490 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 497 | glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| @@ -505,7 +512,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) { | |||
| 505 | 512 | ||
| 506 | S8Z24 input_pixel{}; | 513 | S8Z24 input_pixel{}; |
| 507 | Z24S8 output_pixel{}; | 514 | Z24S8 output_pixel{}; |
| 508 | const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::S8Z24)}; | 515 | constexpr auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::S8Z24)}; |
| 509 | for (size_t y = 0; y < height; ++y) { | 516 | for (size_t y = 0; y < height; ++y) { |
| 510 | for (size_t x = 0; x < width; ++x) { | 517 | for (size_t x = 0; x < width; ++x) { |
| 511 | const size_t offset{bpp * (y * width + x)}; | 518 | const size_t offset{bpp * (y * width + x)}; |
| @@ -518,7 +525,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) { | |||
| 518 | } | 525 | } |
| 519 | 526 | ||
| 520 | static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) { | 527 | static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) { |
| 521 | const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8U)}; | 528 | constexpr auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8U)}; |
| 522 | for (size_t y = 0; y < height; ++y) { | 529 | for (size_t y = 0; y < height; ++y) { |
| 523 | for (size_t x = 0; x < width; ++x) { | 530 | for (size_t x = 0; x < width; ++x) { |
| 524 | const size_t offset{bpp * (y * width + x)}; | 531 | const size_t offset{bpp * (y * width + x)}; |
| @@ -584,12 +591,13 @@ void CachedSurface::LoadGLBuffer() { | |||
| 584 | UNREACHABLE(); | 591 | UNREACHABLE(); |
| 585 | } | 592 | } |
| 586 | 593 | ||
| 587 | gl_buffer.resize(params.depth * copy_size); | 594 | gl_buffer.resize(static_cast<size_t>(params.depth) * copy_size); |
| 588 | morton_to_gl_fns[static_cast<size_t>(params.pixel_format)]( | 595 | morton_to_gl_fns[static_cast<size_t>(params.pixel_format)]( |
| 589 | params.width, params.block_height, params.height, gl_buffer.data(), copy_size, | 596 | params.width, params.block_height, params.height, gl_buffer.data(), copy_size, |
| 590 | params.addr); | 597 | params.addr); |
| 591 | } else { | 598 | } else { |
| 592 | const u8* const texture_src_data_end{texture_src_data + (params.depth * copy_size)}; | 599 | const u8* const texture_src_data_end{texture_src_data + |
| 600 | (static_cast<size_t>(params.depth) * copy_size)}; | ||
| 593 | gl_buffer.assign(texture_src_data, texture_src_data_end); | 601 | gl_buffer.assign(texture_src_data, texture_src_data_end); |
| 594 | } | 602 | } |
| 595 | 603 | ||
| @@ -608,18 +616,20 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||
| 608 | 616 | ||
| 609 | MICROPROFILE_SCOPE(OpenGL_TextureUL); | 617 | MICROPROFILE_SCOPE(OpenGL_TextureUL); |
| 610 | 618 | ||
| 611 | ASSERT(gl_buffer.size() == | 619 | ASSERT(gl_buffer.size() == static_cast<size_t>(params.width) * params.height * |
| 612 | params.width * params.height * GetGLBytesPerPixel(params.pixel_format) * params.depth); | 620 | GetGLBytesPerPixel(params.pixel_format) * params.depth); |
| 613 | 621 | ||
| 614 | const auto& rect{params.GetRect()}; | 622 | const auto& rect{params.GetRect()}; |
| 615 | 623 | ||
| 616 | // Load data from memory to the surface | 624 | // Load data from memory to the surface |
| 617 | GLint x0 = static_cast<GLint>(rect.left); | 625 | const GLint x0 = static_cast<GLint>(rect.left); |
| 618 | GLint y0 = static_cast<GLint>(rect.bottom); | 626 | const GLint y0 = static_cast<GLint>(rect.bottom); |
| 619 | size_t buffer_offset = (y0 * params.width + x0) * GetGLBytesPerPixel(params.pixel_format); | 627 | const size_t buffer_offset = |
| 628 | static_cast<size_t>(static_cast<size_t>(y0) * params.width + static_cast<size_t>(x0)) * | ||
| 629 | GetGLBytesPerPixel(params.pixel_format); | ||
| 620 | 630 | ||
| 621 | const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); | 631 | const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); |
| 622 | GLuint target_tex = texture.handle; | 632 | const GLuint target_tex = texture.handle; |
| 623 | OpenGLState cur_state = OpenGLState::GetCurState(); | 633 | OpenGLState cur_state = OpenGLState::GetCurState(); |
| 624 | 634 | ||
| 625 | const auto& old_tex = cur_state.texture_units[0]; | 635 | const auto& old_tex = cur_state.texture_units[0]; |
| @@ -705,62 +715,34 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu | |||
| 705 | return GetSurface(SurfaceParams::CreateForTexture(config)); | 715 | return GetSurface(SurfaceParams::CreateForTexture(config)); |
| 706 | } | 716 | } |
| 707 | 717 | ||
| 708 | SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(bool using_color_fb, | 718 | Surface RasterizerCacheOpenGL::GetDepthBufferSurface(bool preserve_contents) { |
| 709 | bool using_depth_fb, | 719 | const auto& regs{Core::System::GetInstance().GPU().Maxwell3D().regs}; |
| 710 | bool preserve_contents) { | 720 | if (!regs.zeta.Address() || !regs.zeta_enable) { |
| 711 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 721 | return {}; |
| 722 | } | ||
| 712 | 723 | ||
| 713 | // TODO(bunnei): This is hard corded to use just the first render buffer | 724 | SurfaceParams depth_params{SurfaceParams::CreateForDepthBuffer( |
| 714 | LOG_TRACE(Render_OpenGL, "hard-coded for render target 0!"); | 725 | regs.zeta_width, regs.zeta_height, regs.zeta.Address(), regs.zeta.format)}; |
| 715 | 726 | ||
| 716 | // get color and depth surfaces | 727 | return GetSurface(depth_params, preserve_contents); |
| 717 | SurfaceParams color_params{}; | 728 | } |
| 718 | SurfaceParams depth_params{}; | ||
| 719 | 729 | ||
| 720 | if (using_color_fb) { | 730 | Surface RasterizerCacheOpenGL::GetColorBufferSurface(size_t index, bool preserve_contents) { |
| 721 | color_params = SurfaceParams::CreateForFramebuffer(regs.rt[0]); | 731 | const auto& regs{Core::System::GetInstance().GPU().Maxwell3D().regs}; |
| 722 | } | ||
| 723 | 732 | ||
| 724 | if (using_depth_fb) { | 733 | ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets); |
| 725 | depth_params = SurfaceParams::CreateForDepthBuffer(regs.zeta_width, regs.zeta_height, | ||
| 726 | regs.zeta.Address(), regs.zeta.format); | ||
| 727 | } | ||
| 728 | 734 | ||
| 729 | MathUtil::Rectangle<u32> color_rect{}; | 735 | if (index >= regs.rt_control.count) { |
| 730 | Surface color_surface; | 736 | return {}; |
| 731 | if (using_color_fb) { | ||
| 732 | color_surface = GetSurface(color_params, preserve_contents); | ||
| 733 | if (color_surface) { | ||
| 734 | color_rect = color_surface->GetSurfaceParams().GetRect(); | ||
| 735 | } | ||
| 736 | } | 737 | } |
| 737 | 738 | ||
| 738 | MathUtil::Rectangle<u32> depth_rect{}; | 739 | if (regs.rt[index].Address() == 0 || regs.rt[index].format == Tegra::RenderTargetFormat::NONE) { |
| 739 | Surface depth_surface; | 740 | return {}; |
| 740 | if (using_depth_fb) { | ||
| 741 | depth_surface = GetSurface(depth_params, preserve_contents); | ||
| 742 | if (depth_surface) { | ||
| 743 | depth_rect = depth_surface->GetSurfaceParams().GetRect(); | ||
| 744 | } | ||
| 745 | } | 741 | } |
| 746 | 742 | ||
| 747 | MathUtil::Rectangle<u32> fb_rect{}; | 743 | const SurfaceParams color_params{SurfaceParams::CreateForFramebuffer(index)}; |
| 748 | if (color_surface && depth_surface) { | ||
| 749 | fb_rect = color_rect; | ||
| 750 | // Color and Depth surfaces must have the same dimensions and offsets | ||
| 751 | if (color_rect.bottom != depth_rect.bottom || color_rect.top != depth_rect.top || | ||
| 752 | color_rect.left != depth_rect.left || color_rect.right != depth_rect.right) { | ||
| 753 | color_surface = GetSurface(color_params); | ||
| 754 | depth_surface = GetSurface(depth_params); | ||
| 755 | fb_rect = color_surface->GetSurfaceParams().GetRect(); | ||
| 756 | } | ||
| 757 | } else if (color_surface) { | ||
| 758 | fb_rect = color_rect; | ||
| 759 | } else if (depth_surface) { | ||
| 760 | fb_rect = depth_rect; | ||
| 761 | } | ||
| 762 | 744 | ||
| 763 | return std::make_tuple(color_surface, depth_surface, fb_rect); | 745 | return GetSurface(color_params, preserve_contents); |
| 764 | } | 746 | } |
| 765 | 747 | ||
| 766 | void RasterizerCacheOpenGL::LoadSurface(const Surface& surface) { | 748 | void RasterizerCacheOpenGL::LoadSurface(const Surface& surface) { |
| @@ -826,16 +808,20 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, | |||
| 826 | // Get a new surface with the new parameters, and blit the previous surface to it | 808 | // Get a new surface with the new parameters, and blit the previous surface to it |
| 827 | Surface new_surface{GetUncachedSurface(new_params)}; | 809 | Surface new_surface{GetUncachedSurface(new_params)}; |
| 828 | 810 | ||
| 829 | // If format is unchanged, we can do a faster blit without reinterpreting pixel data | 811 | if (params.pixel_format == new_params.pixel_format || |
| 830 | if (params.pixel_format == new_params.pixel_format) { | 812 | !Settings::values.use_accurate_framebuffers) { |
| 813 | // If the format is the same, just do a framebuffer blit. This is significantly faster than | ||
| 814 | // using PBOs. The is also likely less accurate, as textures will be converted rather than | ||
| 815 | // reinterpreted. | ||
| 816 | |||
| 831 | BlitTextures(surface->Texture().handle, params.GetRect(), new_surface->Texture().handle, | 817 | BlitTextures(surface->Texture().handle, params.GetRect(), new_surface->Texture().handle, |
| 832 | params.GetRect(), params.type, read_framebuffer.handle, | 818 | params.GetRect(), params.type, read_framebuffer.handle, |
| 833 | draw_framebuffer.handle); | 819 | draw_framebuffer.handle); |
| 834 | return new_surface; | 820 | } else { |
| 835 | } | 821 | // When use_accurate_framebuffers setting is enabled, perform a more accurate surface copy, |
| 822 | // where pixels are reinterpreted as a new format (without conversion). This code path uses | ||
| 823 | // OpenGL PBOs and is quite slow. | ||
| 836 | 824 | ||
| 837 | // When using accurate framebuffers, always copy old data to new surface, regardless of format | ||
| 838 | if (Settings::values.use_accurate_framebuffers) { | ||
| 839 | auto source_format = GetFormatTuple(params.pixel_format, params.component_type); | 825 | auto source_format = GetFormatTuple(params.pixel_format, params.component_type); |
| 840 | auto dest_format = GetFormatTuple(new_params.pixel_format, new_params.component_type); | 826 | auto dest_format = GetFormatTuple(new_params.pixel_format, new_params.component_type); |
| 841 | 827 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 8312b2c7a..57ea8593b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -297,6 +297,7 @@ struct SurfaceParams { | |||
| 297 | return PixelFormat::ABGR8S; | 297 | return PixelFormat::ABGR8S; |
| 298 | case Tegra::RenderTargetFormat::RGBA8_UINT: | 298 | case Tegra::RenderTargetFormat::RGBA8_UINT: |
| 299 | return PixelFormat::ABGR8UI; | 299 | return PixelFormat::ABGR8UI; |
| 300 | case Tegra::RenderTargetFormat::BGRA8_SRGB: | ||
| 300 | case Tegra::RenderTargetFormat::BGRA8_UNORM: | 301 | case Tegra::RenderTargetFormat::BGRA8_UNORM: |
| 301 | return PixelFormat::BGRA8; | 302 | return PixelFormat::BGRA8; |
| 302 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: | 303 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: |
| @@ -569,6 +570,7 @@ struct SurfaceParams { | |||
| 569 | case Tegra::RenderTargetFormat::RGBA8_UNORM: | 570 | case Tegra::RenderTargetFormat::RGBA8_UNORM: |
| 570 | case Tegra::RenderTargetFormat::RGBA8_SRGB: | 571 | case Tegra::RenderTargetFormat::RGBA8_SRGB: |
| 571 | case Tegra::RenderTargetFormat::BGRA8_UNORM: | 572 | case Tegra::RenderTargetFormat::BGRA8_UNORM: |
| 573 | case Tegra::RenderTargetFormat::BGRA8_SRGB: | ||
| 572 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: | 574 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: |
| 573 | case Tegra::RenderTargetFormat::R8_UNORM: | 575 | case Tegra::RenderTargetFormat::R8_UNORM: |
| 574 | case Tegra::RenderTargetFormat::RG16_UNORM: | 576 | case Tegra::RenderTargetFormat::RG16_UNORM: |
| @@ -669,8 +671,7 @@ struct SurfaceParams { | |||
| 669 | static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config); | 671 | static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config); |
| 670 | 672 | ||
| 671 | /// Creates SurfaceParams from a framebuffer configuration | 673 | /// Creates SurfaceParams from a framebuffer configuration |
| 672 | static SurfaceParams CreateForFramebuffer( | 674 | static SurfaceParams CreateForFramebuffer(size_t index); |
| 673 | const Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig& config); | ||
| 674 | 675 | ||
| 675 | /// Creates SurfaceParams for a depth buffer configuration | 676 | /// Creates SurfaceParams for a depth buffer configuration |
| 676 | static SurfaceParams CreateForDepthBuffer(u32 zeta_width, u32 zeta_height, | 677 | static SurfaceParams CreateForDepthBuffer(u32 zeta_width, u32 zeta_height, |
| @@ -679,8 +680,8 @@ struct SurfaceParams { | |||
| 679 | 680 | ||
| 680 | /// Checks if surfaces are compatible for caching | 681 | /// Checks if surfaces are compatible for caching |
| 681 | bool IsCompatibleSurface(const SurfaceParams& other) const { | 682 | bool IsCompatibleSurface(const SurfaceParams& other) const { |
| 682 | return std::tie(pixel_format, type, cache_width, cache_height) == | 683 | return std::tie(pixel_format, type, width, height) == |
| 683 | std::tie(other.pixel_format, other.type, other.cache_width, other.cache_height); | 684 | std::tie(other.pixel_format, other.type, other.width, other.height); |
| 684 | } | 685 | } |
| 685 | 686 | ||
| 686 | VAddr addr; | 687 | VAddr addr; |
| @@ -695,10 +696,6 @@ struct SurfaceParams { | |||
| 695 | u32 unaligned_height; | 696 | u32 unaligned_height; |
| 696 | size_t size_in_bytes; | 697 | size_t size_in_bytes; |
| 697 | SurfaceTarget target; | 698 | SurfaceTarget target; |
| 698 | |||
| 699 | // Parameters used for caching only | ||
| 700 | u32 cache_width; | ||
| 701 | u32 cache_height; | ||
| 702 | }; | 699 | }; |
| 703 | 700 | ||
| 704 | }; // namespace OpenGL | 701 | }; // namespace OpenGL |
| @@ -774,9 +771,11 @@ public: | |||
| 774 | /// Get a surface based on the texture configuration | 771 | /// Get a surface based on the texture configuration |
| 775 | Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config); | 772 | Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config); |
| 776 | 773 | ||
| 777 | /// Get the color and depth surfaces based on the framebuffer configuration | 774 | /// Get the depth surface based on the framebuffer configuration |
| 778 | SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb, | 775 | Surface GetDepthBufferSurface(bool preserve_contents); |
| 779 | bool preserve_contents); | 776 | |
| 777 | /// Get the color surface based on the framebuffer configuration and the specified render target | ||
| 778 | Surface GetColorBufferSurface(size_t index, bool preserve_contents); | ||
| 780 | 779 | ||
| 781 | /// Flushes the surface to Switch memory | 780 | /// Flushes the surface to Switch memory |
| 782 | void FlushSurface(const Surface& surface); | 781 | void FlushSurface(const Surface& surface); |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 7e4b85ac3..61080f5cc 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -13,8 +13,8 @@ namespace OpenGL { | |||
| 13 | 13 | ||
| 14 | /// Gets the address for the specified shader stage program | 14 | /// Gets the address for the specified shader stage program |
| 15 | static VAddr GetShaderAddress(Maxwell::ShaderProgram program) { | 15 | static VAddr GetShaderAddress(Maxwell::ShaderProgram program) { |
| 16 | auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); | 16 | const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); |
| 17 | auto& shader_config = gpu.regs.shader_config[static_cast<size_t>(program)]; | 17 | const auto& shader_config = gpu.regs.shader_config[static_cast<size_t>(program)]; |
| 18 | return *gpu.memory_manager.GpuToCpuAddress(gpu.regs.code_address.CodeAddress() + | 18 | return *gpu.memory_manager.GpuToCpuAddress(gpu.regs.code_address.CodeAddress() + |
| 19 | shader_config.offset); | 19 | shader_config.offset); |
| 20 | } | 20 | } |
| @@ -86,7 +86,7 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type) | |||
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) { | 88 | GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) { |
| 89 | auto search{resource_cache.find(buffer.GetHash())}; | 89 | const auto search{resource_cache.find(buffer.GetHash())}; |
| 90 | if (search == resource_cache.end()) { | 90 | if (search == resource_cache.end()) { |
| 91 | const GLuint index{ | 91 | const GLuint index{ |
| 92 | glGetProgramResourceIndex(program.handle, GL_UNIFORM_BLOCK, buffer.GetName().c_str())}; | 92 | glGetProgramResourceIndex(program.handle, GL_UNIFORM_BLOCK, buffer.GetName().c_str())}; |
| @@ -98,7 +98,7 @@ GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& b | |||
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | GLint CachedShader::GetUniformLocation(const GLShader::SamplerEntry& sampler) { | 100 | GLint CachedShader::GetUniformLocation(const GLShader::SamplerEntry& sampler) { |
| 101 | auto search{uniform_cache.find(sampler.GetHash())}; | 101 | const auto search{uniform_cache.find(sampler.GetHash())}; |
| 102 | if (search == uniform_cache.end()) { | 102 | if (search == uniform_cache.end()) { |
| 103 | const GLint index{glGetUniformLocation(program.handle, sampler.GetName().c_str())}; | 103 | const GLint index{glGetUniformLocation(program.handle, sampler.GetName().c_str())}; |
| 104 | uniform_cache[sampler.GetHash()] = index; | 104 | uniform_cache[sampler.GetHash()] = index; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 172ba8335..582c811e0 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -113,7 +113,7 @@ private: | |||
| 113 | 113 | ||
| 114 | /// Scans a range of code for labels and determines the exit method. | 114 | /// Scans a range of code for labels and determines the exit method. |
| 115 | ExitMethod Scan(u32 begin, u32 end, std::set<u32>& labels) { | 115 | ExitMethod Scan(u32 begin, u32 end, std::set<u32>& labels) { |
| 116 | auto [iter, inserted] = | 116 | const auto [iter, inserted] = |
| 117 | exit_method_map.emplace(std::make_pair(begin, end), ExitMethod::Undetermined); | 117 | exit_method_map.emplace(std::make_pair(begin, end), ExitMethod::Undetermined); |
| 118 | ExitMethod& exit_method = iter->second; | 118 | ExitMethod& exit_method = iter->second; |
| 119 | if (!inserted) | 119 | if (!inserted) |
| @@ -131,22 +131,22 @@ private: | |||
| 131 | if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) { | 131 | if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) { |
| 132 | return exit_method = ExitMethod::AlwaysEnd; | 132 | return exit_method = ExitMethod::AlwaysEnd; |
| 133 | } else { | 133 | } else { |
| 134 | ExitMethod not_met = Scan(offset + 1, end, labels); | 134 | const ExitMethod not_met = Scan(offset + 1, end, labels); |
| 135 | return exit_method = ParallelExit(ExitMethod::AlwaysEnd, not_met); | 135 | return exit_method = ParallelExit(ExitMethod::AlwaysEnd, not_met); |
| 136 | } | 136 | } |
| 137 | } | 137 | } |
| 138 | case OpCode::Id::BRA: { | 138 | case OpCode::Id::BRA: { |
| 139 | u32 target = offset + instr.bra.GetBranchTarget(); | 139 | const u32 target = offset + instr.bra.GetBranchTarget(); |
| 140 | labels.insert(target); | 140 | labels.insert(target); |
| 141 | ExitMethod no_jmp = Scan(offset + 1, end, labels); | 141 | const ExitMethod no_jmp = Scan(offset + 1, end, labels); |
| 142 | ExitMethod jmp = Scan(target, end, labels); | 142 | const ExitMethod jmp = Scan(target, end, labels); |
| 143 | return exit_method = ParallelExit(no_jmp, jmp); | 143 | return exit_method = ParallelExit(no_jmp, jmp); |
| 144 | } | 144 | } |
| 145 | case OpCode::Id::SSY: { | 145 | case OpCode::Id::SSY: { |
| 146 | // The SSY instruction uses a similar encoding as the BRA instruction. | 146 | // The SSY instruction uses a similar encoding as the BRA instruction. |
| 147 | ASSERT_MSG(instr.bra.constant_buffer == 0, | 147 | ASSERT_MSG(instr.bra.constant_buffer == 0, |
| 148 | "Constant buffer SSY is not supported"); | 148 | "Constant buffer SSY is not supported"); |
| 149 | u32 target = offset + instr.bra.GetBranchTarget(); | 149 | const u32 target = offset + instr.bra.GetBranchTarget(); |
| 150 | labels.insert(target); | 150 | labels.insert(target); |
| 151 | // Continue scanning for an exit method. | 151 | // Continue scanning for an exit method. |
| 152 | break; | 152 | break; |
| @@ -346,8 +346,8 @@ public: | |||
| 346 | */ | 346 | */ |
| 347 | void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute, | 347 | void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute, |
| 348 | const Tegra::Shader::IpaMode& input_mode) { | 348 | const Tegra::Shader::IpaMode& input_mode) { |
| 349 | std::string dest = GetRegisterAsFloat(reg); | 349 | const std::string dest = GetRegisterAsFloat(reg); |
| 350 | std::string src = GetInputAttribute(attribute, input_mode) + GetSwizzle(elem); | 350 | const std::string src = GetInputAttribute(attribute, input_mode) + GetSwizzle(elem); |
| 351 | shader.AddLine(dest + " = " + src + ';'); | 351 | shader.AddLine(dest + " = " + src + ';'); |
| 352 | } | 352 | } |
| 353 | 353 | ||
| @@ -359,8 +359,8 @@ public: | |||
| 359 | * @param reg The register to use as the source value. | 359 | * @param reg The register to use as the source value. |
| 360 | */ | 360 | */ |
| 361 | void SetOutputAttributeToRegister(Attribute::Index attribute, u64 elem, const Register& reg) { | 361 | void SetOutputAttributeToRegister(Attribute::Index attribute, u64 elem, const Register& reg) { |
| 362 | std::string dest = GetOutputAttribute(attribute); | 362 | const std::string dest = GetOutputAttribute(attribute); |
| 363 | std::string src = GetRegisterAsFloat(reg); | 363 | const std::string src = GetRegisterAsFloat(reg); |
| 364 | 364 | ||
| 365 | if (!dest.empty()) { | 365 | if (!dest.empty()) { |
| 366 | // Can happen with unknown/unimplemented output attributes, in which case we ignore the | 366 | // Can happen with unknown/unimplemented output attributes, in which case we ignore the |
| @@ -393,9 +393,9 @@ public: | |||
| 393 | GLSLRegister::Type type) { | 393 | GLSLRegister::Type type) { |
| 394 | declr_const_buffers[cbuf_index].MarkAsUsedIndirect(cbuf_index, stage); | 394 | declr_const_buffers[cbuf_index].MarkAsUsedIndirect(cbuf_index, stage); |
| 395 | 395 | ||
| 396 | std::string final_offset = fmt::format("({} + {})", index_str, offset / 4); | 396 | const std::string final_offset = fmt::format("({} + {})", index_str, offset / 4); |
| 397 | std::string value = 'c' + std::to_string(cbuf_index) + '[' + final_offset + " / 4][" + | 397 | const std::string value = 'c' + std::to_string(cbuf_index) + '[' + final_offset + " / 4][" + |
| 398 | final_offset + " % 4]"; | 398 | final_offset + " % 4]"; |
| 399 | 399 | ||
| 400 | if (type == GLSLRegister::Type::Float) { | 400 | if (type == GLSLRegister::Type::Float) { |
| 401 | return value; | 401 | return value; |
| @@ -468,10 +468,10 @@ public: | |||
| 468 | /// necessary. | 468 | /// necessary. |
| 469 | std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type, | 469 | std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type, |
| 470 | bool is_array) { | 470 | bool is_array) { |
| 471 | size_t offset = static_cast<size_t>(sampler.index.Value()); | 471 | const size_t offset = static_cast<size_t>(sampler.index.Value()); |
| 472 | 472 | ||
| 473 | // If this sampler has already been used, return the existing mapping. | 473 | // If this sampler has already been used, return the existing mapping. |
| 474 | auto itr = | 474 | const auto itr = |
| 475 | std::find_if(used_samplers.begin(), used_samplers.end(), | 475 | std::find_if(used_samplers.begin(), used_samplers.end(), |
| 476 | [&](const SamplerEntry& entry) { return entry.GetOffset() == offset; }); | 476 | [&](const SamplerEntry& entry) { return entry.GetOffset() == offset; }); |
| 477 | 477 | ||
| @@ -481,8 +481,8 @@ public: | |||
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | // Otherwise create a new mapping for this sampler | 483 | // Otherwise create a new mapping for this sampler |
| 484 | size_t next_index = used_samplers.size(); | 484 | const size_t next_index = used_samplers.size(); |
| 485 | SamplerEntry entry{stage, offset, next_index, type, is_array}; | 485 | const SamplerEntry entry{stage, offset, next_index, type, is_array}; |
| 486 | used_samplers.emplace_back(entry); | 486 | used_samplers.emplace_back(entry); |
| 487 | return entry.GetName(); | 487 | return entry.GetName(); |
| 488 | } | 488 | } |
| @@ -699,7 +699,7 @@ private: | |||
| 699 | }; | 699 | }; |
| 700 | 700 | ||
| 701 | bool IsColorComponentOutputEnabled(u32 render_target, u32 component) const { | 701 | bool IsColorComponentOutputEnabled(u32 render_target, u32 component) const { |
| 702 | u32 bit = render_target * 4 + component; | 702 | const u32 bit = render_target * 4 + component; |
| 703 | return enabled_color_outputs & (1 << bit); | 703 | return enabled_color_outputs & (1 << bit); |
| 704 | } | 704 | } |
| 705 | }; | 705 | }; |
| @@ -707,7 +707,7 @@ private: | |||
| 707 | 707 | ||
| 708 | /// Gets the Subroutine object corresponding to the specified address. | 708 | /// Gets the Subroutine object corresponding to the specified address. |
| 709 | const Subroutine& GetSubroutine(u32 begin, u32 end) const { | 709 | const Subroutine& GetSubroutine(u32 begin, u32 end) const { |
| 710 | auto iter = subroutines.find(Subroutine{begin, end, suffix}); | 710 | const auto iter = subroutines.find(Subroutine{begin, end, suffix}); |
| 711 | ASSERT(iter != subroutines.end()); | 711 | ASSERT(iter != subroutines.end()); |
| 712 | return *iter; | 712 | return *iter; |
| 713 | } | 713 | } |
| @@ -752,7 +752,7 @@ private: | |||
| 752 | // Can't assign to the constant predicate. | 752 | // Can't assign to the constant predicate. |
| 753 | ASSERT(pred != static_cast<u64>(Pred::UnusedIndex)); | 753 | ASSERT(pred != static_cast<u64>(Pred::UnusedIndex)); |
| 754 | 754 | ||
| 755 | std::string variable = 'p' + std::to_string(pred) + '_' + suffix; | 755 | const std::string variable = 'p' + std::to_string(pred) + '_' + suffix; |
| 756 | shader.AddLine(variable + " = " + value + ';'); | 756 | shader.AddLine(variable + " = " + value + ';'); |
| 757 | declr_predicates.insert(std::move(variable)); | 757 | declr_predicates.insert(std::move(variable)); |
| 758 | } | 758 | } |
| @@ -1023,7 +1023,7 @@ private: | |||
| 1023 | // TODO(Subv): Figure out how dual-source blending is configured in the Switch. | 1023 | // TODO(Subv): Figure out how dual-source blending is configured in the Switch. |
| 1024 | for (u32 component = 0; component < 4; ++component) { | 1024 | for (u32 component = 0; component < 4; ++component) { |
| 1025 | if (header.IsColorComponentOutputEnabled(render_target, component)) { | 1025 | if (header.IsColorComponentOutputEnabled(render_target, component)) { |
| 1026 | shader.AddLine(fmt::format("color[{}][{}] = {};", render_target, component, | 1026 | shader.AddLine(fmt::format("FragColor{}[{}] = {};", render_target, component, |
| 1027 | regs.GetRegisterAsFloat(current_reg))); | 1027 | regs.GetRegisterAsFloat(current_reg))); |
| 1028 | ++current_reg; | 1028 | ++current_reg; |
| 1029 | } | 1029 | } |
| @@ -1033,7 +1033,11 @@ private: | |||
| 1033 | if (header.writes_depth) { | 1033 | if (header.writes_depth) { |
| 1034 | // The depth output is always 2 registers after the last color output, and current_reg | 1034 | // The depth output is always 2 registers after the last color output, and current_reg |
| 1035 | // already contains one past the last color register. | 1035 | // already contains one past the last color register. |
| 1036 | shader.AddLine("gl_FragDepth = " + regs.GetRegisterAsFloat(current_reg + 1) + ';'); | 1036 | |
| 1037 | shader.AddLine( | ||
| 1038 | "gl_FragDepth = " + | ||
| 1039 | regs.GetRegisterAsFloat(static_cast<Tegra::Shader::Register>(current_reg) + 1) + | ||
| 1040 | ';'); | ||
| 1037 | } | 1041 | } |
| 1038 | } | 1042 | } |
| 1039 | 1043 | ||
| @@ -1435,7 +1439,7 @@ private: | |||
| 1435 | if (instr.alu_integer.negate_b) | 1439 | if (instr.alu_integer.negate_b) |
| 1436 | op_b = "-(" + op_b + ')'; | 1440 | op_b = "-(" + op_b + ')'; |
| 1437 | 1441 | ||
| 1438 | std::string shift = std::to_string(instr.alu_integer.shift_amount.Value()); | 1442 | const std::string shift = std::to_string(instr.alu_integer.shift_amount.Value()); |
| 1439 | 1443 | ||
| 1440 | regs.SetRegisterToInteger(instr.gpr0, true, 0, | 1444 | regs.SetRegisterToInteger(instr.gpr0, true, 0, |
| 1441 | "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); | 1445 | "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); |
| @@ -1453,7 +1457,7 @@ private: | |||
| 1453 | case OpCode::Id::SEL_C: | 1457 | case OpCode::Id::SEL_C: |
| 1454 | case OpCode::Id::SEL_R: | 1458 | case OpCode::Id::SEL_R: |
| 1455 | case OpCode::Id::SEL_IMM: { | 1459 | case OpCode::Id::SEL_IMM: { |
| 1456 | std::string condition = | 1460 | const std::string condition = |
| 1457 | GetPredicateCondition(instr.sel.pred, instr.sel.neg_pred != 0); | 1461 | GetPredicateCondition(instr.sel.pred, instr.sel.neg_pred != 0); |
| 1458 | regs.SetRegisterToInteger(instr.gpr0, true, 0, | 1462 | regs.SetRegisterToInteger(instr.gpr0, true, 0, |
| 1459 | '(' + condition + ") ? " + op_a + " : " + op_b, 1, 1); | 1463 | '(' + condition + ") ? " + op_a + " : " + op_b, 1, 1); |
| @@ -1475,8 +1479,9 @@ private: | |||
| 1475 | case OpCode::Id::LOP3_C: | 1479 | case OpCode::Id::LOP3_C: |
| 1476 | case OpCode::Id::LOP3_R: | 1480 | case OpCode::Id::LOP3_R: |
| 1477 | case OpCode::Id::LOP3_IMM: { | 1481 | case OpCode::Id::LOP3_IMM: { |
| 1478 | std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); | 1482 | const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); |
| 1479 | std::string lut; | 1483 | std::string lut; |
| 1484 | |||
| 1480 | if (opcode->GetId() == OpCode::Id::LOP3_R) { | 1485 | if (opcode->GetId() == OpCode::Id::LOP3_R) { |
| 1481 | lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')'; | 1486 | lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')'; |
| 1482 | } else { | 1487 | } else { |
| @@ -1491,15 +1496,82 @@ private: | |||
| 1491 | case OpCode::Id::IMNMX_IMM: { | 1496 | case OpCode::Id::IMNMX_IMM: { |
| 1492 | ASSERT_MSG(instr.imnmx.exchange == Tegra::Shader::IMinMaxExchange::None, | 1497 | ASSERT_MSG(instr.imnmx.exchange == Tegra::Shader::IMinMaxExchange::None, |
| 1493 | "Unimplemented"); | 1498 | "Unimplemented"); |
| 1494 | std::string condition = | 1499 | const std::string condition = |
| 1495 | GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0); | 1500 | GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0); |
| 1496 | std::string parameters = op_a + ',' + op_b; | 1501 | const std::string parameters = op_a + ',' + op_b; |
| 1497 | regs.SetRegisterToInteger(instr.gpr0, instr.imnmx.is_signed, 0, | 1502 | regs.SetRegisterToInteger(instr.gpr0, instr.imnmx.is_signed, 0, |
| 1498 | '(' + condition + ") ? min(" + parameters + ") : max(" + | 1503 | '(' + condition + ") ? min(" + parameters + ") : max(" + |
| 1499 | parameters + ')', | 1504 | parameters + ')', |
| 1500 | 1, 1); | 1505 | 1, 1); |
| 1501 | break; | 1506 | break; |
| 1502 | } | 1507 | } |
| 1508 | case OpCode::Id::LEA_R2: | ||
| 1509 | case OpCode::Id::LEA_R1: | ||
| 1510 | case OpCode::Id::LEA_IMM: | ||
| 1511 | case OpCode::Id::LEA_RZ: | ||
| 1512 | case OpCode::Id::LEA_HI: { | ||
| 1513 | std::string op_a; | ||
| 1514 | std::string op_b; | ||
| 1515 | std::string op_c; | ||
| 1516 | |||
| 1517 | switch (opcode->GetId()) { | ||
| 1518 | case OpCode::Id::LEA_R2: { | ||
| 1519 | op_a = regs.GetRegisterAsInteger(instr.gpr20); | ||
| 1520 | op_b = regs.GetRegisterAsInteger(instr.gpr39); | ||
| 1521 | op_c = std::to_string(instr.lea.r2.entry_a); | ||
| 1522 | break; | ||
| 1523 | } | ||
| 1524 | |||
| 1525 | case OpCode::Id::LEA_R1: { | ||
| 1526 | const bool neg = instr.lea.r1.neg != 0; | ||
| 1527 | op_a = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 1528 | if (neg) | ||
| 1529 | op_a = "-(" + op_a + ')'; | ||
| 1530 | op_b = regs.GetRegisterAsInteger(instr.gpr20); | ||
| 1531 | op_c = std::to_string(instr.lea.r1.entry_a); | ||
| 1532 | break; | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | case OpCode::Id::LEA_IMM: { | ||
| 1536 | const bool neg = instr.lea.imm.neg != 0; | ||
| 1537 | op_b = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 1538 | if (neg) | ||
| 1539 | op_b = "-(" + op_b + ')'; | ||
| 1540 | op_a = std::to_string(instr.lea.imm.entry_a); | ||
| 1541 | op_c = std::to_string(instr.lea.imm.entry_b); | ||
| 1542 | break; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | case OpCode::Id::LEA_RZ: { | ||
| 1546 | const bool neg = instr.lea.rz.neg != 0; | ||
| 1547 | op_b = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 1548 | if (neg) | ||
| 1549 | op_b = "-(" + op_b + ')'; | ||
| 1550 | op_a = regs.GetUniform(instr.lea.rz.cb_index, instr.lea.rz.cb_offset, | ||
| 1551 | GLSLRegister::Type::Integer); | ||
| 1552 | op_c = std::to_string(instr.lea.rz.entry_a); | ||
| 1553 | |||
| 1554 | break; | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | case OpCode::Id::LEA_HI: | ||
| 1558 | default: { | ||
| 1559 | op_b = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 1560 | op_a = std::to_string(instr.lea.imm.entry_a); | ||
| 1561 | op_c = std::to_string(instr.lea.imm.entry_b); | ||
| 1562 | LOG_CRITICAL(HW_GPU, "Unhandled LEA subinstruction: {}", opcode->GetName()); | ||
| 1563 | UNREACHABLE(); | ||
| 1564 | } | ||
| 1565 | } | ||
| 1566 | if (instr.lea.pred48 != static_cast<u64>(Pred::UnusedIndex)) { | ||
| 1567 | LOG_ERROR(HW_GPU, "Unhandled LEA Predicate"); | ||
| 1568 | UNREACHABLE(); | ||
| 1569 | } | ||
| 1570 | const std::string value = '(' + op_a + " + (" + op_b + "*(1 << " + op_c + ")))"; | ||
| 1571 | regs.SetRegisterToInteger(instr.gpr0, true, 0, value, 1, 1); | ||
| 1572 | |||
| 1573 | break; | ||
| 1574 | } | ||
| 1503 | default: { | 1575 | default: { |
| 1504 | LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", | 1576 | LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", |
| 1505 | opcode->GetName()); | 1577 | opcode->GetName()); |
| @@ -1510,7 +1582,7 @@ private: | |||
| 1510 | break; | 1582 | break; |
| 1511 | } | 1583 | } |
| 1512 | case OpCode::Type::Ffma: { | 1584 | case OpCode::Type::Ffma: { |
| 1513 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | 1585 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); |
| 1514 | std::string op_b = instr.ffma.negate_b ? "-" : ""; | 1586 | std::string op_b = instr.ffma.negate_b ? "-" : ""; |
| 1515 | std::string op_c = instr.ffma.negate_c ? "-" : ""; | 1587 | std::string op_c = instr.ffma.negate_c ? "-" : ""; |
| 1516 | 1588 | ||
| @@ -1720,7 +1792,7 @@ private: | |||
| 1720 | shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + | 1792 | shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + |
| 1721 | " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);"); | 1793 | " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);"); |
| 1722 | 1794 | ||
| 1723 | std::string op_a = | 1795 | const std::string op_a = |
| 1724 | regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, "index", | 1796 | regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, "index", |
| 1725 | GLSLRegister::Type::Float); | 1797 | GLSLRegister::Type::Float); |
| 1726 | 1798 | ||
| @@ -1730,7 +1802,7 @@ private: | |||
| 1730 | break; | 1802 | break; |
| 1731 | 1803 | ||
| 1732 | case Tegra::Shader::UniformType::Double: { | 1804 | case Tegra::Shader::UniformType::Double: { |
| 1733 | std::string op_b = | 1805 | const std::string op_b = |
| 1734 | regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, | 1806 | regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, |
| 1735 | "index", GLSLRegister::Type::Float); | 1807 | "index", GLSLRegister::Type::Float); |
| 1736 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); | 1808 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); |
| @@ -1760,13 +1832,13 @@ private: | |||
| 1760 | 1832 | ||
| 1761 | switch (texture_type) { | 1833 | switch (texture_type) { |
| 1762 | case Tegra::Shader::TextureType::Texture1D: { | 1834 | case Tegra::Shader::TextureType::Texture1D: { |
| 1763 | std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 1835 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 1764 | coord = "float coords = " + x + ';'; | 1836 | coord = "float coords = " + x + ';'; |
| 1765 | break; | 1837 | break; |
| 1766 | } | 1838 | } |
| 1767 | case Tegra::Shader::TextureType::Texture2D: { | 1839 | case Tegra::Shader::TextureType::Texture2D: { |
| 1768 | std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 1840 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 1769 | std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 1841 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 1770 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 1842 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |
| 1771 | break; | 1843 | break; |
| 1772 | } | 1844 | } |
| @@ -1776,8 +1848,8 @@ private: | |||
| 1776 | UNREACHABLE(); | 1848 | UNREACHABLE(); |
| 1777 | 1849 | ||
| 1778 | // Fallback to interpreting as a 2D texture for now | 1850 | // Fallback to interpreting as a 2D texture for now |
| 1779 | std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 1851 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 1780 | std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 1852 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 1781 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 1853 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |
| 1782 | texture_type = Tegra::Shader::TextureType::Texture2D; | 1854 | texture_type = Tegra::Shader::TextureType::Texture2D; |
| 1783 | } | 1855 | } |
| @@ -1811,13 +1883,13 @@ private: | |||
| 1811 | switch (texture_type) { | 1883 | switch (texture_type) { |
| 1812 | case Tegra::Shader::TextureType::Texture2D: { | 1884 | case Tegra::Shader::TextureType::Texture2D: { |
| 1813 | if (is_array) { | 1885 | if (is_array) { |
| 1814 | std::string index = regs.GetRegisterAsInteger(instr.gpr8); | 1886 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); |
| 1815 | std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 1887 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 1816 | std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 1888 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 1817 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; | 1889 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; |
| 1818 | } else { | 1890 | } else { |
| 1819 | std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 1891 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 1820 | std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 1892 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 1821 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 1893 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |
| 1822 | } | 1894 | } |
| 1823 | break; | 1895 | break; |
| @@ -1828,8 +1900,8 @@ private: | |||
| 1828 | UNREACHABLE(); | 1900 | UNREACHABLE(); |
| 1829 | 1901 | ||
| 1830 | // Fallback to interpreting as a 2D texture for now | 1902 | // Fallback to interpreting as a 2D texture for now |
| 1831 | std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 1903 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 1832 | std::string y = regs.GetRegisterAsFloat(instr.gpr20); | 1904 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); |
| 1833 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 1905 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |
| 1834 | texture_type = Tegra::Shader::TextureType::Texture2D; | 1906 | texture_type = Tegra::Shader::TextureType::Texture2D; |
| 1835 | is_array = false; | 1907 | is_array = false; |
| @@ -1850,8 +1922,8 @@ private: | |||
| 1850 | LOG_CRITICAL(HW_GPU, "Unhandled 2d array texture"); | 1922 | LOG_CRITICAL(HW_GPU, "Unhandled 2d array texture"); |
| 1851 | UNREACHABLE(); | 1923 | UNREACHABLE(); |
| 1852 | } else { | 1924 | } else { |
| 1853 | std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 1925 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 1854 | std::string y = regs.GetRegisterAsInteger(instr.gpr20); | 1926 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); |
| 1855 | coord = "ivec2 coords = ivec2(" + x + ", " + y + ");"; | 1927 | coord = "ivec2 coords = ivec2(" + x + ", " + y + ");"; |
| 1856 | } | 1928 | } |
| 1857 | break; | 1929 | break; |
| @@ -1874,8 +1946,8 @@ private: | |||
| 1874 | 1946 | ||
| 1875 | switch (instr.tld4.texture_type) { | 1947 | switch (instr.tld4.texture_type) { |
| 1876 | case Tegra::Shader::TextureType::Texture2D: { | 1948 | case Tegra::Shader::TextureType::Texture2D: { |
| 1877 | std::string x = regs.GetRegisterAsFloat(instr.gpr8); | 1949 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); |
| 1878 | std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 1950 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 1879 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 1951 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; |
| 1880 | break; | 1952 | break; |
| 1881 | } | 1953 | } |
| @@ -1920,6 +1992,74 @@ private: | |||
| 1920 | WriteTexsInstruction(instr, coord, texture); | 1992 | WriteTexsInstruction(instr, coord, texture); |
| 1921 | break; | 1993 | break; |
| 1922 | } | 1994 | } |
| 1995 | case OpCode::Id::TXQ: { | ||
| 1996 | // TODO: the new commits on the texture refactor, change the way samplers work. | ||
| 1997 | // Sadly, not all texture instructions specify the type of texture their sampler | ||
| 1998 | // uses. This must be fixed at a later instance. | ||
| 1999 | const std::string sampler = | ||
| 2000 | GetSampler(instr.sampler, Tegra::Shader::TextureType::Texture2D, false); | ||
| 2001 | switch (instr.txq.query_type) { | ||
| 2002 | case Tegra::Shader::TextureQueryType::Dimension: { | ||
| 2003 | const std::string texture = "textureQueryLevels(" + sampler + ')'; | ||
| 2004 | regs.SetRegisterToInteger(instr.gpr0, true, 0, texture, 1, 1); | ||
| 2005 | break; | ||
| 2006 | } | ||
| 2007 | default: { | ||
| 2008 | LOG_CRITICAL(HW_GPU, "Unhandled texture query type: {}", | ||
| 2009 | static_cast<u32>(instr.txq.query_type.Value())); | ||
| 2010 | UNREACHABLE(); | ||
| 2011 | } | ||
| 2012 | } | ||
| 2013 | break; | ||
| 2014 | } | ||
| 2015 | case OpCode::Id::TMML: { | ||
| 2016 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2017 | const std::string op_b = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2018 | const bool is_array = instr.tmml.array != 0; | ||
| 2019 | auto texture_type = instr.tmml.texture_type.Value(); | ||
| 2020 | const std::string sampler = GetSampler(instr.sampler, texture_type, is_array); | ||
| 2021 | |||
| 2022 | // TODO: add coordinates for different samplers once other texture types are | ||
| 2023 | // implemented. | ||
| 2024 | std::string coord; | ||
| 2025 | switch (texture_type) { | ||
| 2026 | case Tegra::Shader::TextureType::Texture1D: { | ||
| 2027 | std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2028 | coord = "float coords = " + x + ';'; | ||
| 2029 | break; | ||
| 2030 | } | ||
| 2031 | case Tegra::Shader::TextureType::Texture2D: { | ||
| 2032 | std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2033 | std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2034 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2035 | break; | ||
| 2036 | } | ||
| 2037 | default: | ||
| 2038 | LOG_CRITICAL(HW_GPU, "Unhandled texture type {}", | ||
| 2039 | static_cast<u32>(texture_type)); | ||
| 2040 | UNREACHABLE(); | ||
| 2041 | |||
| 2042 | // Fallback to interpreting as a 2D texture for now | ||
| 2043 | std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2044 | std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2045 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2046 | texture_type = Tegra::Shader::TextureType::Texture2D; | ||
| 2047 | } | ||
| 2048 | // Add an extra scope and declare the texture coords inside to prevent | ||
| 2049 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 2050 | shader.AddLine('{'); | ||
| 2051 | ++shader.scope; | ||
| 2052 | shader.AddLine(coord); | ||
| 2053 | const std::string texture = "textureQueryLod(" + sampler + ", coords)"; | ||
| 2054 | const std::string tmp = "vec2 tmp = " + texture + "*vec2(256.0, 256.0);"; | ||
| 2055 | shader.AddLine(tmp); | ||
| 2056 | |||
| 2057 | regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(tmp.y)", 1, 1); | ||
| 2058 | regs.SetRegisterToInteger(instr.gpr0.Value() + 1, false, 0, "uint(tmp.x)", 1, 1); | ||
| 2059 | --shader.scope; | ||
| 2060 | shader.AddLine('}'); | ||
| 2061 | break; | ||
| 2062 | } | ||
| 1923 | default: { | 2063 | default: { |
| 1924 | LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName()); | 2064 | LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName()); |
| 1925 | UNREACHABLE(); | 2065 | UNREACHABLE(); |
| @@ -1959,12 +2099,12 @@ private: | |||
| 1959 | // We can't use the constant predicate as destination. | 2099 | // We can't use the constant predicate as destination. |
| 1960 | ASSERT(instr.fsetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); | 2100 | ASSERT(instr.fsetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); |
| 1961 | 2101 | ||
| 1962 | std::string second_pred = | 2102 | const std::string second_pred = |
| 1963 | GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); | 2103 | GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); |
| 1964 | 2104 | ||
| 1965 | std::string combiner = GetPredicateCombiner(instr.fsetp.op); | 2105 | const std::string combiner = GetPredicateCombiner(instr.fsetp.op); |
| 1966 | 2106 | ||
| 1967 | std::string predicate = GetPredicateComparison(instr.fsetp.cond, op_a, op_b); | 2107 | const std::string predicate = GetPredicateComparison(instr.fsetp.cond, op_a, op_b); |
| 1968 | // Set the primary predicate to the result of Predicate OP SecondPredicate | 2108 | // Set the primary predicate to the result of Predicate OP SecondPredicate |
| 1969 | SetPredicate(instr.fsetp.pred3, | 2109 | SetPredicate(instr.fsetp.pred3, |
| 1970 | '(' + predicate + ") " + combiner + " (" + second_pred + ')'); | 2110 | '(' + predicate + ") " + combiner + " (" + second_pred + ')'); |
| @@ -1978,7 +2118,8 @@ private: | |||
| 1978 | break; | 2118 | break; |
| 1979 | } | 2119 | } |
| 1980 | case OpCode::Type::IntegerSetPredicate: { | 2120 | case OpCode::Type::IntegerSetPredicate: { |
| 1981 | std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.isetp.is_signed); | 2121 | const std::string op_a = |
| 2122 | regs.GetRegisterAsInteger(instr.gpr8, 0, instr.isetp.is_signed); | ||
| 1982 | std::string op_b; | 2123 | std::string op_b; |
| 1983 | 2124 | ||
| 1984 | if (instr.is_b_imm) { | 2125 | if (instr.is_b_imm) { |
| @@ -1995,12 +2136,12 @@ private: | |||
| 1995 | // We can't use the constant predicate as destination. | 2136 | // We can't use the constant predicate as destination. |
| 1996 | ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); | 2137 | ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); |
| 1997 | 2138 | ||
| 1998 | std::string second_pred = | 2139 | const std::string second_pred = |
| 1999 | GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0); | 2140 | GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0); |
| 2000 | 2141 | ||
| 2001 | std::string combiner = GetPredicateCombiner(instr.isetp.op); | 2142 | const std::string combiner = GetPredicateCombiner(instr.isetp.op); |
| 2002 | 2143 | ||
| 2003 | std::string predicate = GetPredicateComparison(instr.isetp.cond, op_a, op_b); | 2144 | const std::string predicate = GetPredicateComparison(instr.isetp.cond, op_a, op_b); |
| 2004 | // Set the primary predicate to the result of Predicate OP SecondPredicate | 2145 | // Set the primary predicate to the result of Predicate OP SecondPredicate |
| 2005 | SetPredicate(instr.isetp.pred3, | 2146 | SetPredicate(instr.isetp.pred3, |
| 2006 | '(' + predicate + ") " + combiner + " (" + second_pred + ')'); | 2147 | '(' + predicate + ") " + combiner + " (" + second_pred + ')'); |
| @@ -2013,21 +2154,45 @@ private: | |||
| 2013 | } | 2154 | } |
| 2014 | break; | 2155 | break; |
| 2015 | } | 2156 | } |
| 2157 | case OpCode::Type::PredicateSetRegister: { | ||
| 2158 | const std::string op_a = | ||
| 2159 | GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0); | ||
| 2160 | const std::string op_b = | ||
| 2161 | GetPredicateCondition(instr.pset.pred29, instr.pset.neg_pred29 != 0); | ||
| 2162 | |||
| 2163 | const std::string second_pred = | ||
| 2164 | GetPredicateCondition(instr.pset.pred39, instr.pset.neg_pred39 != 0); | ||
| 2165 | |||
| 2166 | const std::string combiner = GetPredicateCombiner(instr.pset.op); | ||
| 2167 | |||
| 2168 | const std::string predicate = | ||
| 2169 | '(' + op_a + ") " + GetPredicateCombiner(instr.pset.cond) + " (" + op_b + ')'; | ||
| 2170 | const std::string result = '(' + predicate + ") " + combiner + " (" + second_pred + ')'; | ||
| 2171 | if (instr.pset.bf == 0) { | ||
| 2172 | const std::string value = '(' + result + ") ? 0xFFFFFFFF : 0"; | ||
| 2173 | regs.SetRegisterToInteger(instr.gpr0, false, 0, value, 1, 1); | ||
| 2174 | } else { | ||
| 2175 | const std::string value = '(' + result + ") ? 1.0 : 0.0"; | ||
| 2176 | regs.SetRegisterToFloat(instr.gpr0, 0, value, 1, 1); | ||
| 2177 | } | ||
| 2178 | |||
| 2179 | break; | ||
| 2180 | } | ||
| 2016 | case OpCode::Type::PredicateSetPredicate: { | 2181 | case OpCode::Type::PredicateSetPredicate: { |
| 2017 | std::string op_a = | 2182 | const std::string op_a = |
| 2018 | GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0); | 2183 | GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0); |
| 2019 | std::string op_b = | 2184 | const std::string op_b = |
| 2020 | GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0); | 2185 | GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0); |
| 2021 | 2186 | ||
| 2022 | // We can't use the constant predicate as destination. | 2187 | // We can't use the constant predicate as destination. |
| 2023 | ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); | 2188 | ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); |
| 2024 | 2189 | ||
| 2025 | std::string second_pred = | 2190 | const std::string second_pred = |
| 2026 | GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0); | 2191 | GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0); |
| 2027 | 2192 | ||
| 2028 | std::string combiner = GetPredicateCombiner(instr.psetp.op); | 2193 | const std::string combiner = GetPredicateCombiner(instr.psetp.op); |
| 2029 | 2194 | ||
| 2030 | std::string predicate = | 2195 | const std::string predicate = |
| 2031 | '(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')'; | 2196 | '(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')'; |
| 2032 | 2197 | ||
| 2033 | // Set the primary predicate to the result of Predicate OP SecondPredicate | 2198 | // Set the primary predicate to the result of Predicate OP SecondPredicate |
| @@ -2053,7 +2218,7 @@ private: | |||
| 2053 | std::string op_b = instr.fset.neg_b ? "-" : ""; | 2218 | std::string op_b = instr.fset.neg_b ? "-" : ""; |
| 2054 | 2219 | ||
| 2055 | if (instr.is_b_imm) { | 2220 | if (instr.is_b_imm) { |
| 2056 | std::string imm = GetImmediate19(instr); | 2221 | const std::string imm = GetImmediate19(instr); |
| 2057 | if (instr.fset.neg_imm) | 2222 | if (instr.fset.neg_imm) |
| 2058 | op_b += "(-" + imm + ')'; | 2223 | op_b += "(-" + imm + ')'; |
| 2059 | else | 2224 | else |
| @@ -2073,13 +2238,14 @@ private: | |||
| 2073 | 2238 | ||
| 2074 | // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the | 2239 | // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the |
| 2075 | // condition is true, and to 0 otherwise. | 2240 | // condition is true, and to 0 otherwise. |
| 2076 | std::string second_pred = | 2241 | const std::string second_pred = |
| 2077 | GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); | 2242 | GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); |
| 2078 | 2243 | ||
| 2079 | std::string combiner = GetPredicateCombiner(instr.fset.op); | 2244 | const std::string combiner = GetPredicateCombiner(instr.fset.op); |
| 2080 | 2245 | ||
| 2081 | std::string predicate = "((" + GetPredicateComparison(instr.fset.cond, op_a, op_b) + | 2246 | const std::string predicate = "((" + |
| 2082 | ") " + combiner + " (" + second_pred + "))"; | 2247 | GetPredicateComparison(instr.fset.cond, op_a, op_b) + |
| 2248 | ") " + combiner + " (" + second_pred + "))"; | ||
| 2083 | 2249 | ||
| 2084 | if (instr.fset.bf) { | 2250 | if (instr.fset.bf) { |
| 2085 | regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); | 2251 | regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); |
| @@ -2090,7 +2256,7 @@ private: | |||
| 2090 | break; | 2256 | break; |
| 2091 | } | 2257 | } |
| 2092 | case OpCode::Type::IntegerSet: { | 2258 | case OpCode::Type::IntegerSet: { |
| 2093 | std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.iset.is_signed); | 2259 | const std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.iset.is_signed); |
| 2094 | 2260 | ||
| 2095 | std::string op_b; | 2261 | std::string op_b; |
| 2096 | 2262 | ||
| @@ -2107,13 +2273,14 @@ private: | |||
| 2107 | 2273 | ||
| 2108 | // The iset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the | 2274 | // The iset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the |
| 2109 | // condition is true, and to 0 otherwise. | 2275 | // condition is true, and to 0 otherwise. |
| 2110 | std::string second_pred = | 2276 | const std::string second_pred = |
| 2111 | GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); | 2277 | GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); |
| 2112 | 2278 | ||
| 2113 | std::string combiner = GetPredicateCombiner(instr.iset.op); | 2279 | const std::string combiner = GetPredicateCombiner(instr.iset.op); |
| 2114 | 2280 | ||
| 2115 | std::string predicate = "((" + GetPredicateComparison(instr.iset.cond, op_a, op_b) + | 2281 | const std::string predicate = "((" + |
| 2116 | ") " + combiner + " (" + second_pred + "))"; | 2282 | GetPredicateComparison(instr.iset.cond, op_a, op_b) + |
| 2283 | ") " + combiner + " (" + second_pred + "))"; | ||
| 2117 | 2284 | ||
| 2118 | if (instr.iset.bf) { | 2285 | if (instr.iset.bf) { |
| 2119 | regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); | 2286 | regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); |
| @@ -2263,7 +2430,7 @@ private: | |||
| 2263 | case OpCode::Id::BRA: { | 2430 | case OpCode::Id::BRA: { |
| 2264 | ASSERT_MSG(instr.bra.constant_buffer == 0, | 2431 | ASSERT_MSG(instr.bra.constant_buffer == 0, |
| 2265 | "BRA with constant buffers are not implemented"); | 2432 | "BRA with constant buffers are not implemented"); |
| 2266 | u32 target = offset + instr.bra.GetBranchTarget(); | 2433 | const u32 target = offset + instr.bra.GetBranchTarget(); |
| 2267 | shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); | 2434 | shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); |
| 2268 | break; | 2435 | break; |
| 2269 | } | 2436 | } |
| @@ -2287,7 +2454,7 @@ private: | |||
| 2287 | // has a similar structure to the BRA opcode. | 2454 | // has a similar structure to the BRA opcode. |
| 2288 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); | 2455 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); |
| 2289 | 2456 | ||
| 2290 | u32 target = offset + instr.bra.GetBranchTarget(); | 2457 | const u32 target = offset + instr.bra.GetBranchTarget(); |
| 2291 | EmitPushToSSYStack(target); | 2458 | EmitPushToSSYStack(target); |
| 2292 | break; | 2459 | break; |
| 2293 | } | 2460 | } |
| @@ -2381,10 +2548,10 @@ private: | |||
| 2381 | shader.AddLine("case " + std::to_string(label) + "u: {"); | 2548 | shader.AddLine("case " + std::to_string(label) + "u: {"); |
| 2382 | ++shader.scope; | 2549 | ++shader.scope; |
| 2383 | 2550 | ||
| 2384 | auto next_it = labels.lower_bound(label + 1); | 2551 | const auto next_it = labels.lower_bound(label + 1); |
| 2385 | u32 next_label = next_it == labels.end() ? subroutine.end : *next_it; | 2552 | const u32 next_label = next_it == labels.end() ? subroutine.end : *next_it; |
| 2386 | 2553 | ||
| 2387 | u32 compile_end = CompileRange(label, next_label); | 2554 | const u32 compile_end = CompileRange(label, next_label); |
| 2388 | if (compile_end > next_label && compile_end != PROGRAM_END) { | 2555 | if (compile_end > next_label && compile_end != PROGRAM_END) { |
| 2389 | // This happens only when there is a label inside a IF/LOOP block | 2556 | // This happens only when there is a label inside a IF/LOOP block |
| 2390 | shader.AddLine(" jmp_to = " + std::to_string(compile_end) + "u; break; }"); | 2557 | shader.AddLine(" jmp_to = " + std::to_string(compile_end) + "u; break; }"); |
| @@ -2447,7 +2614,8 @@ boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, | |||
| 2447 | Maxwell3D::Regs::ShaderStage stage, | 2614 | Maxwell3D::Regs::ShaderStage stage, |
| 2448 | const std::string& suffix) { | 2615 | const std::string& suffix) { |
| 2449 | try { | 2616 | try { |
| 2450 | auto subroutines = ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); | 2617 | const auto subroutines = |
| 2618 | ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); | ||
| 2451 | GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix); | 2619 | GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix); |
| 2452 | return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; | 2620 | return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; |
| 2453 | } catch (const DecompileFail& exception) { | 2621 | } catch (const DecompileFail& exception) { |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index e1b1a9d73..b0466c18f 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -88,7 +88,14 @@ ProgramResult GenerateFragmentShader(const ShaderSetup& setup) { | |||
| 88 | .get_value_or({}); | 88 | .get_value_or({}); |
| 89 | out += R"( | 89 | out += R"( |
| 90 | in vec4 position; | 90 | in vec4 position; |
| 91 | layout(location = 0) out vec4 color[8]; | 91 | layout(location = 0) out vec4 FragColor0; |
| 92 | layout(location = 1) out vec4 FragColor1; | ||
| 93 | layout(location = 2) out vec4 FragColor2; | ||
| 94 | layout(location = 3) out vec4 FragColor3; | ||
| 95 | layout(location = 4) out vec4 FragColor4; | ||
| 96 | layout(location = 5) out vec4 FragColor5; | ||
| 97 | layout(location = 6) out vec4 FragColor6; | ||
| 98 | layout(location = 7) out vec4 FragColor7; | ||
| 92 | 99 | ||
| 93 | layout (std140) uniform fs_config { | 100 | layout (std140) uniform fs_config { |
| 94 | vec4 viewport_flip; | 101 | vec4 viewport_flip; |
diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp index 5781d9d16..5f3fe067e 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.cpp +++ b/src/video_core/renderer_opengl/gl_shader_util.cpp | |||
| @@ -25,7 +25,7 @@ GLuint LoadShader(const char* source, GLenum type) { | |||
| 25 | default: | 25 | default: |
| 26 | UNREACHABLE(); | 26 | UNREACHABLE(); |
| 27 | } | 27 | } |
| 28 | GLuint shader_id = glCreateShader(type); | 28 | const GLuint shader_id = glCreateShader(type); |
| 29 | glShaderSource(shader_id, 1, &source, nullptr); | 29 | glShaderSource(shader_id, 1, &source, nullptr); |
| 30 | LOG_DEBUG(Render_OpenGL, "Compiling {} shader...", debug_type); | 30 | LOG_DEBUG(Render_OpenGL, "Compiling {} shader...", debug_type); |
| 31 | glCompileShader(shader_id); | 31 | glCompileShader(shader_id); |
diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.cpp b/src/video_core/renderer_opengl/gl_stream_buffer.cpp index e565afcee..aadf68f16 100644 --- a/src/video_core/renderer_opengl/gl_stream_buffer.cpp +++ b/src/video_core/renderer_opengl/gl_stream_buffer.cpp | |||
| @@ -29,7 +29,7 @@ OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coh | |||
| 29 | if (GLAD_GL_ARB_buffer_storage) { | 29 | if (GLAD_GL_ARB_buffer_storage) { |
| 30 | persistent = true; | 30 | persistent = true; |
| 31 | coherent = prefer_coherent; | 31 | coherent = prefer_coherent; |
| 32 | GLbitfield flags = | 32 | const GLbitfield flags = |
| 33 | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : 0); | 33 | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : 0); |
| 34 | glBufferStorage(gl_target, allocate_size, nullptr, flags); | 34 | glBufferStorage(gl_target, allocate_size, nullptr, flags); |
| 35 | mapped_ptr = static_cast<u8*>(glMapBufferRange( | 35 | mapped_ptr = static_cast<u8*>(glMapBufferRange( |
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index a2b6e984e..f48b69809 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -9,6 +9,8 @@ add_executable(yuzu | |||
| 9 | about_dialog.h | 9 | about_dialog.h |
| 10 | bootmanager.cpp | 10 | bootmanager.cpp |
| 11 | bootmanager.h | 11 | bootmanager.h |
| 12 | compatibility_list.cpp | ||
| 13 | compatibility_list.h | ||
| 12 | configuration/config.cpp | 14 | configuration/config.cpp |
| 13 | configuration/config.h | 15 | configuration/config.h |
| 14 | configuration/configure_audio.cpp | 16 | configuration/configure_audio.cpp |
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 4a60f450a..4e4c108ab 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp | |||
| @@ -112,6 +112,7 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) | |||
| 112 | setWindowTitle(QString::fromStdString(window_title)); | 112 | setWindowTitle(QString::fromStdString(window_title)); |
| 113 | 113 | ||
| 114 | InputCommon::Init(); | 114 | InputCommon::Init(); |
| 115 | InputCommon::StartJoystickEventHandler(); | ||
| 115 | } | 116 | } |
| 116 | 117 | ||
| 117 | GRenderWindow::~GRenderWindow() { | 118 | GRenderWindow::~GRenderWindow() { |
diff --git a/src/yuzu/compatibility_list.cpp b/src/yuzu/compatibility_list.cpp new file mode 100644 index 000000000..2d2cfd03c --- /dev/null +++ b/src/yuzu/compatibility_list.cpp | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | |||
| 7 | #include <fmt/format.h> | ||
| 8 | |||
| 9 | #include "yuzu/compatibility_list.h" | ||
| 10 | |||
| 11 | CompatibilityList::const_iterator FindMatchingCompatibilityEntry( | ||
| 12 | const CompatibilityList& compatibility_list, u64 program_id) { | ||
| 13 | return std::find_if(compatibility_list.begin(), compatibility_list.end(), | ||
| 14 | [program_id](const auto& element) { | ||
| 15 | std::string pid = fmt::format("{:016X}", program_id); | ||
| 16 | return element.first == pid; | ||
| 17 | }); | ||
| 18 | } | ||
diff --git a/src/yuzu/compatibility_list.h b/src/yuzu/compatibility_list.h new file mode 100644 index 000000000..bc0175bd3 --- /dev/null +++ b/src/yuzu/compatibility_list.h | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <string> | ||
| 8 | #include <unordered_map> | ||
| 9 | |||
| 10 | #include <QString> | ||
| 11 | |||
| 12 | #include "common/common_types.h" | ||
| 13 | |||
| 14 | using CompatibilityList = std::unordered_map<std::string, std::pair<QString, QString>>; | ||
| 15 | |||
| 16 | CompatibilityList::const_iterator FindMatchingCompatibilityEntry( | ||
| 17 | const CompatibilityList& compatibility_list, u64 program_id); | ||
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index d8caee1e8..9292d9a42 100644 --- a/src/yuzu/configuration/configure_general.cpp +++ b/src/yuzu/configuration/configure_general.cpp | |||
| @@ -20,7 +20,6 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent) | |||
| 20 | this->setConfiguration(); | 20 | this->setConfiguration(); |
| 21 | 21 | ||
| 22 | ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | 22 | ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); |
| 23 | ui->use_multi_core->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | ||
| 24 | ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | 23 | ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn()); |
| 25 | } | 24 | } |
| 26 | 25 | ||
| @@ -31,7 +30,6 @@ void ConfigureGeneral::setConfiguration() { | |||
| 31 | ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing); | 30 | ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing); |
| 32 | ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme)); | 31 | ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme)); |
| 33 | ui->use_cpu_jit->setChecked(Settings::values.use_cpu_jit); | 32 | ui->use_cpu_jit->setChecked(Settings::values.use_cpu_jit); |
| 34 | ui->use_multi_core->setChecked(Settings::values.use_multi_core); | ||
| 35 | ui->use_docked_mode->setChecked(Settings::values.use_docked_mode); | 33 | ui->use_docked_mode->setChecked(Settings::values.use_docked_mode); |
| 36 | } | 34 | } |
| 37 | 35 | ||
| @@ -46,6 +44,5 @@ void ConfigureGeneral::applyConfiguration() { | |||
| 46 | ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString(); | 44 | ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString(); |
| 47 | 45 | ||
| 48 | Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); | 46 | Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); |
| 49 | Settings::values.use_multi_core = ui->use_multi_core->isChecked(); | ||
| 50 | Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); | 47 | Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); |
| 51 | } | 48 | } |
diff --git a/src/yuzu/configuration/configure_general.ui b/src/yuzu/configuration/configure_general.ui index 233adbe27..1775c4d40 100644 --- a/src/yuzu/configuration/configure_general.ui +++ b/src/yuzu/configuration/configure_general.ui | |||
| @@ -58,13 +58,6 @@ | |||
| 58 | </property> | 58 | </property> |
| 59 | </widget> | 59 | </widget> |
| 60 | </item> | 60 | </item> |
| 61 | <item> | ||
| 62 | <widget class="QCheckBox" name="use_multi_core"> | ||
| 63 | <property name="text"> | ||
| 64 | <string>Enable multi-core</string> | ||
| 65 | </property> | ||
| 66 | </widget> | ||
| 67 | </item> | ||
| 68 | </layout> | 61 | </layout> |
| 69 | </item> | 62 | </item> |
| 70 | </layout> | 63 | </layout> |
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 5e7badedf..d29abb74b 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // Copyright 2016 Citra Emulator Project | 1 | // Copyright 2016 Citra Emulator Project |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| @@ -53,19 +53,18 @@ static QString ButtonToText(const Common::ParamPackage& param) { | |||
| 53 | } else if (param.Get("engine", "") == "keyboard") { | 53 | } else if (param.Get("engine", "") == "keyboard") { |
| 54 | return getKeyName(param.Get("code", 0)); | 54 | return getKeyName(param.Get("code", 0)); |
| 55 | } else if (param.Get("engine", "") == "sdl") { | 55 | } else if (param.Get("engine", "") == "sdl") { |
| 56 | QString text = QString(QObject::tr("Joystick %1")).arg(param.Get("joystick", "").c_str()); | ||
| 57 | if (param.Has("hat")) { | 56 | if (param.Has("hat")) { |
| 58 | text += QString(QObject::tr(" Hat %1 %2")) | 57 | return QString(QObject::tr("Hat %1 %2")) |
| 59 | .arg(param.Get("hat", "").c_str(), param.Get("direction", "").c_str()); | 58 | .arg(param.Get("hat", "").c_str(), param.Get("direction", "").c_str()); |
| 60 | } | 59 | } |
| 61 | if (param.Has("axis")) { | 60 | if (param.Has("axis")) { |
| 62 | text += QString(QObject::tr(" Axis %1%2")) | 61 | return QString(QObject::tr("Axis %1%2")) |
| 63 | .arg(param.Get("axis", "").c_str(), param.Get("direction", "").c_str()); | 62 | .arg(param.Get("axis", "").c_str(), param.Get("direction", "").c_str()); |
| 64 | } | 63 | } |
| 65 | if (param.Has("button")) { | 64 | if (param.Has("button")) { |
| 66 | text += QString(QObject::tr(" Button %1")).arg(param.Get("button", "").c_str()); | 65 | return QString(QObject::tr("Button %1")).arg(param.Get("button", "").c_str()); |
| 67 | } | 66 | } |
| 68 | return text; | 67 | return QString(); |
| 69 | } else { | 68 | } else { |
| 70 | return QObject::tr("[unknown]"); | 69 | return QObject::tr("[unknown]"); |
| 71 | } | 70 | } |
| @@ -81,13 +80,12 @@ static QString AnalogToText(const Common::ParamPackage& param, const std::string | |||
| 81 | return QString(QObject::tr("[unused]")); | 80 | return QString(QObject::tr("[unused]")); |
| 82 | } | 81 | } |
| 83 | 82 | ||
| 84 | QString text = QString(QObject::tr("Joystick %1")).arg(param.Get("joystick", "").c_str()); | ||
| 85 | if (dir == "left" || dir == "right") { | 83 | if (dir == "left" || dir == "right") { |
| 86 | text += QString(QObject::tr(" Axis %1")).arg(param.Get("axis_x", "").c_str()); | 84 | return QString(QObject::tr("Axis %1")).arg(param.Get("axis_x", "").c_str()); |
| 87 | } else if (dir == "up" || dir == "down") { | 85 | } else if (dir == "up" || dir == "down") { |
| 88 | text += QString(QObject::tr(" Axis %1")).arg(param.Get("axis_y", "").c_str()); | 86 | return QString(QObject::tr("Axis %1")).arg(param.Get("axis_y", "").c_str()); |
| 89 | } | 87 | } |
| 90 | return text; | 88 | return QString(); |
| 91 | } else { | 89 | } else { |
| 92 | return QObject::tr("[unknown]"); | 90 | return QObject::tr("[unknown]"); |
| 93 | } | 91 | } |
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 86532e4a9..8c6e16d47 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include "common/file_util.h" | 19 | #include "common/file_util.h" |
| 20 | #include "common/logging/log.h" | 20 | #include "common/logging/log.h" |
| 21 | #include "core/file_sys/patch_manager.h" | 21 | #include "core/file_sys/patch_manager.h" |
| 22 | #include "yuzu/compatibility_list.h" | ||
| 22 | #include "yuzu/game_list.h" | 23 | #include "yuzu/game_list.h" |
| 23 | #include "yuzu/game_list_p.h" | 24 | #include "yuzu/game_list_p.h" |
| 24 | #include "yuzu/game_list_worker.h" | 25 | #include "yuzu/game_list_worker.h" |
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 3fcb298ed..2713e7b54 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h | |||
| @@ -4,8 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <unordered_map> | ||
| 8 | |||
| 9 | #include <QFileSystemWatcher> | 7 | #include <QFileSystemWatcher> |
| 10 | #include <QHBoxLayout> | 8 | #include <QHBoxLayout> |
| 11 | #include <QLabel> | 9 | #include <QLabel> |
| @@ -21,6 +19,7 @@ | |||
| 21 | #include <QWidget> | 19 | #include <QWidget> |
| 22 | 20 | ||
| 23 | #include "common/common_types.h" | 21 | #include "common/common_types.h" |
| 22 | #include "yuzu/compatibility_list.h" | ||
| 24 | 23 | ||
| 25 | class GameListWorker; | 24 | class GameListWorker; |
| 26 | class GMainWindow; | 25 | class GMainWindow; |
| @@ -90,9 +89,8 @@ signals: | |||
| 90 | void GameChosen(QString game_path); | 89 | void GameChosen(QString game_path); |
| 91 | void ShouldCancelWorker(); | 90 | void ShouldCancelWorker(); |
| 92 | void OpenFolderRequested(u64 program_id, GameListOpenTarget target); | 91 | void OpenFolderRequested(u64 program_id, GameListOpenTarget target); |
| 93 | void NavigateToGamedbEntryRequested( | 92 | void NavigateToGamedbEntryRequested(u64 program_id, |
| 94 | u64 program_id, | 93 | const CompatibilityList& compatibility_list); |
| 95 | std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list); | ||
| 96 | 94 | ||
| 97 | private slots: | 95 | private slots: |
| 98 | void onTextChanged(const QString& newText); | 96 | void onTextChanged(const QString& newText); |
| @@ -114,7 +112,7 @@ private: | |||
| 114 | QStandardItemModel* item_model = nullptr; | 112 | QStandardItemModel* item_model = nullptr; |
| 115 | GameListWorker* current_worker = nullptr; | 113 | GameListWorker* current_worker = nullptr; |
| 116 | QFileSystemWatcher* watcher = nullptr; | 114 | QFileSystemWatcher* watcher = nullptr; |
| 117 | std::unordered_map<std::string, std::pair<QString, QString>> compatibility_list; | 115 | CompatibilityList compatibility_list; |
| 118 | }; | 116 | }; |
| 119 | 117 | ||
| 120 | Q_DECLARE_METATYPE(GameListOpenTarget); | 118 | Q_DECLARE_METATYPE(GameListOpenTarget); |
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index 2720bf143..f22e422e5 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h | |||
| @@ -176,14 +176,3 @@ public: | |||
| 176 | return data(SizeRole).toULongLong() < other.data(SizeRole).toULongLong(); | 176 | return data(SizeRole).toULongLong() < other.data(SizeRole).toULongLong(); |
| 177 | } | 177 | } |
| 178 | }; | 178 | }; |
| 179 | |||
| 180 | inline auto FindMatchingCompatibilityEntry( | ||
| 181 | const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list, | ||
| 182 | u64 program_id) { | ||
| 183 | return std::find_if( | ||
| 184 | compatibility_list.begin(), compatibility_list.end(), | ||
| 185 | [program_id](const std::pair<std::string, std::pair<QString, QString>>& element) { | ||
| 186 | std::string pid = fmt::format("{:016X}", program_id); | ||
| 187 | return element.first == pid; | ||
| 188 | }); | ||
| 189 | } | ||
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index 9f26935d6..e228d61bd 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include "core/file_sys/registered_cache.h" | 20 | #include "core/file_sys/registered_cache.h" |
| 21 | #include "core/hle/service/filesystem/filesystem.h" | 21 | #include "core/hle/service/filesystem/filesystem.h" |
| 22 | #include "core/loader/loader.h" | 22 | #include "core/loader/loader.h" |
| 23 | #include "yuzu/compatibility_list.h" | ||
| 23 | #include "yuzu/game_list.h" | 24 | #include "yuzu/game_list.h" |
| 24 | #include "yuzu/game_list_p.h" | 25 | #include "yuzu/game_list_p.h" |
| 25 | #include "yuzu/game_list_worker.h" | 26 | #include "yuzu/game_list_worker.h" |
| @@ -75,9 +76,8 @@ QString FormatPatchNameVersions(const FileSys::PatchManager& patch_manager, bool | |||
| 75 | } | 76 | } |
| 76 | } // Anonymous namespace | 77 | } // Anonymous namespace |
| 77 | 78 | ||
| 78 | GameListWorker::GameListWorker( | 79 | GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs, QString dir_path, bool deep_scan, |
| 79 | FileSys::VirtualFilesystem vfs, QString dir_path, bool deep_scan, | 80 | const CompatibilityList& compatibility_list) |
| 80 | const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list) | ||
| 81 | : vfs(std::move(vfs)), dir_path(std::move(dir_path)), deep_scan(deep_scan), | 81 | : vfs(std::move(vfs)), dir_path(std::move(dir_path)), deep_scan(deep_scan), |
| 82 | compatibility_list(compatibility_list) {} | 82 | compatibility_list(compatibility_list) {} |
| 83 | 83 | ||
diff --git a/src/yuzu/game_list_worker.h b/src/yuzu/game_list_worker.h index 42c93fc31..09d20c42f 100644 --- a/src/yuzu/game_list_worker.h +++ b/src/yuzu/game_list_worker.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <QString> | 16 | #include <QString> |
| 17 | 17 | ||
| 18 | #include "common/common_types.h" | 18 | #include "common/common_types.h" |
| 19 | #include "yuzu/compatibility_list.h" | ||
| 19 | 20 | ||
| 20 | class QStandardItem; | 21 | class QStandardItem; |
| 21 | 22 | ||
| @@ -32,9 +33,8 @@ class GameListWorker : public QObject, public QRunnable { | |||
| 32 | Q_OBJECT | 33 | Q_OBJECT |
| 33 | 34 | ||
| 34 | public: | 35 | public: |
| 35 | GameListWorker( | 36 | GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs, QString dir_path, bool deep_scan, |
| 36 | std::shared_ptr<FileSys::VfsFilesystem> vfs, QString dir_path, bool deep_scan, | 37 | const CompatibilityList& compatibility_list); |
| 37 | const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list); | ||
| 38 | ~GameListWorker() override; | 38 | ~GameListWorker() override; |
| 39 | 39 | ||
| 40 | /// Starts the processing of directory tree information. | 40 | /// Starts the processing of directory tree information. |
| @@ -67,6 +67,6 @@ private: | |||
| 67 | QStringList watch_list; | 67 | QStringList watch_list; |
| 68 | QString dir_path; | 68 | QString dir_path; |
| 69 | bool deep_scan; | 69 | bool deep_scan; |
| 70 | const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list; | 70 | const CompatibilityList& compatibility_list; |
| 71 | std::atomic_bool stop_processing; | 71 | std::atomic_bool stop_processing; |
| 72 | }; | 72 | }; |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 811e7cd3f..05a4a55e8 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | #include "video_core/debug_utils/debug_utils.h" | 47 | #include "video_core/debug_utils/debug_utils.h" |
| 48 | #include "yuzu/about_dialog.h" | 48 | #include "yuzu/about_dialog.h" |
| 49 | #include "yuzu/bootmanager.h" | 49 | #include "yuzu/bootmanager.h" |
| 50 | #include "yuzu/compatibility_list.h" | ||
| 50 | #include "yuzu/configuration/config.h" | 51 | #include "yuzu/configuration/config.h" |
| 51 | #include "yuzu/configuration/configure_dialog.h" | 52 | #include "yuzu/configuration/configure_dialog.h" |
| 52 | #include "yuzu/debugger/console.h" | 53 | #include "yuzu/debugger/console.h" |
| @@ -446,6 +447,8 @@ QStringList GMainWindow::GetUnsupportedGLExtensions() { | |||
| 446 | unsupported_ext.append("ARB_texture_mirror_clamp_to_edge"); | 447 | unsupported_ext.append("ARB_texture_mirror_clamp_to_edge"); |
| 447 | if (!GLAD_GL_ARB_base_instance) | 448 | if (!GLAD_GL_ARB_base_instance) |
| 448 | unsupported_ext.append("ARB_base_instance"); | 449 | unsupported_ext.append("ARB_base_instance"); |
| 450 | if (!GLAD_GL_ARB_texture_storage) | ||
| 451 | unsupported_ext.append("ARB_texture_storage"); | ||
| 449 | 452 | ||
| 450 | // Extensions required to support some texture formats. | 453 | // Extensions required to support some texture formats. |
| 451 | if (!GLAD_GL_EXT_texture_compression_s3tc) | 454 | if (!GLAD_GL_EXT_texture_compression_s3tc) |
| @@ -725,14 +728,11 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target | |||
| 725 | QDesktopServices::openUrl(QUrl::fromLocalFile(qpath)); | 728 | QDesktopServices::openUrl(QUrl::fromLocalFile(qpath)); |
| 726 | } | 729 | } |
| 727 | 730 | ||
| 728 | void GMainWindow::OnGameListNavigateToGamedbEntry( | 731 | void GMainWindow::OnGameListNavigateToGamedbEntry(u64 program_id, |
| 729 | u64 program_id, | 732 | const CompatibilityList& compatibility_list) { |
| 730 | std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list) { | 733 | const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); |
| 731 | |||
| 732 | auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); | ||
| 733 | 734 | ||
| 734 | QString directory; | 735 | QString directory; |
| 735 | |||
| 736 | if (it != compatibility_list.end()) | 736 | if (it != compatibility_list.end()) |
| 737 | directory = it->second.second; | 737 | directory = it->second.second; |
| 738 | 738 | ||
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 089ea2445..552e3e61c 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "core/core.h" | 14 | #include "core/core.h" |
| 15 | #include "ui_main.h" | 15 | #include "ui_main.h" |
| 16 | #include "yuzu/compatibility_list.h" | ||
| 16 | #include "yuzu/hotkeys.h" | 17 | #include "yuzu/hotkeys.h" |
| 17 | 18 | ||
| 18 | class Config; | 19 | class Config; |
| @@ -137,9 +138,8 @@ private slots: | |||
| 137 | /// Called whenever a user selects a game in the game list widget. | 138 | /// Called whenever a user selects a game in the game list widget. |
| 138 | void OnGameListLoadFile(QString game_path); | 139 | void OnGameListLoadFile(QString game_path); |
| 139 | void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target); | 140 | void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target); |
| 140 | void OnGameListNavigateToGamedbEntry( | 141 | void OnGameListNavigateToGamedbEntry(u64 program_id, |
| 141 | u64 program_id, | 142 | const CompatibilityList& compatibility_list); |
| 142 | std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list); | ||
| 143 | void OnMenuLoadFile(); | 143 | void OnMenuLoadFile(); |
| 144 | void OnMenuLoadFolder(); | 144 | void OnMenuLoadFolder(); |
| 145 | void OnMenuInstallToNAND(); | 145 | void OnMenuInstallToNAND(); |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 2f7916256..d213929bd 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include "input_common/keyboard.h" | 16 | #include "input_common/keyboard.h" |
| 17 | #include "input_common/main.h" | 17 | #include "input_common/main.h" |
| 18 | #include "input_common/motion_emu.h" | 18 | #include "input_common/motion_emu.h" |
| 19 | #include "input_common/sdl/sdl.h" | ||
| 19 | #include "yuzu_cmd/emu_window/emu_window_sdl2.h" | 20 | #include "yuzu_cmd/emu_window/emu_window_sdl2.h" |
| 20 | 21 | ||
| 21 | void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { | 22 | void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { |
| @@ -93,6 +94,8 @@ bool EmuWindow_SDL2::SupportsRequiredGLExtensions() { | |||
| 93 | unsupported_ext.push_back("ARB_texture_mirror_clamp_to_edge"); | 94 | unsupported_ext.push_back("ARB_texture_mirror_clamp_to_edge"); |
| 94 | if (!GLAD_GL_ARB_base_instance) | 95 | if (!GLAD_GL_ARB_base_instance) |
| 95 | unsupported_ext.push_back("ARB_base_instance"); | 96 | unsupported_ext.push_back("ARB_base_instance"); |
| 97 | if (!GLAD_GL_ARB_texture_storage) | ||
| 98 | unsupported_ext.push_back("ARB_texture_storage"); | ||
| 96 | 99 | ||
| 97 | // Extensions required to support some texture formats. | 100 | // Extensions required to support some texture formats. |
| 98 | if (!GLAD_GL_EXT_texture_compression_s3tc) | 101 | if (!GLAD_GL_EXT_texture_compression_s3tc) |
| @@ -116,7 +119,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) { | |||
| 116 | SDL_SetMainReady(); | 119 | SDL_SetMainReady(); |
| 117 | 120 | ||
| 118 | // Initialize the window | 121 | // Initialize the window |
| 119 | if (SDL_Init(SDL_INIT_VIDEO) < 0) { | 122 | if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { |
| 120 | LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); | 123 | LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); |
| 121 | exit(1); | 124 | exit(1); |
| 122 | } | 125 | } |
| @@ -176,6 +179,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) { | |||
| 176 | } | 179 | } |
| 177 | 180 | ||
| 178 | EmuWindow_SDL2::~EmuWindow_SDL2() { | 181 | EmuWindow_SDL2::~EmuWindow_SDL2() { |
| 182 | InputCommon::SDL::CloseSDLJoysticks(); | ||
| 179 | SDL_GL_DeleteContext(gl_context); | 183 | SDL_GL_DeleteContext(gl_context); |
| 180 | SDL_Quit(); | 184 | SDL_Quit(); |
| 181 | 185 | ||
| @@ -220,6 +224,9 @@ void EmuWindow_SDL2::PollEvents() { | |||
| 220 | case SDL_QUIT: | 224 | case SDL_QUIT: |
| 221 | is_open = false; | 225 | is_open = false; |
| 222 | break; | 226 | break; |
| 227 | default: | ||
| 228 | InputCommon::SDL::HandleGameControllerEvent(event); | ||
| 229 | break; | ||
| 223 | } | 230 | } |
| 224 | } | 231 | } |
| 225 | } | 232 | } |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 173ac0e0f..b1c364fbb 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -82,6 +82,9 @@ int main(int argc, char** argv) { | |||
| 82 | int option_index = 0; | 82 | int option_index = 0; |
| 83 | bool use_gdbstub = Settings::values.use_gdbstub; | 83 | bool use_gdbstub = Settings::values.use_gdbstub; |
| 84 | u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port); | 84 | u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port); |
| 85 | |||
| 86 | InitializeLogging(); | ||
| 87 | |||
| 85 | char* endarg; | 88 | char* endarg; |
| 86 | #ifdef _WIN32 | 89 | #ifdef _WIN32 |
| 87 | int argc_w; | 90 | int argc_w; |
| @@ -144,8 +147,6 @@ int main(int argc, char** argv) { | |||
| 144 | LocalFree(argv_w); | 147 | LocalFree(argv_w); |
| 145 | #endif | 148 | #endif |
| 146 | 149 | ||
| 147 | InitializeLogging(); | ||
| 148 | |||
| 149 | MicroProfileOnThreadCreate("EmuThread"); | 150 | MicroProfileOnThreadCreate("EmuThread"); |
| 150 | SCOPE_EXIT({ MicroProfileShutdown(); }); | 151 | SCOPE_EXIT({ MicroProfileShutdown(); }); |
| 151 | 152 | ||