Эх сурвалжийг харах

apm: Add Controller class to manage speed data and application

Zach Hilman 7 жил өмнө
parent
commit
65eb9cbb28

+ 2 - 0
src/core/CMakeLists.txt

@@ -207,6 +207,8 @@ add_library(core STATIC
     hle/service/aoc/aoc_u.h
     hle/service/apm/apm.cpp
     hle/service/apm/apm.h
+    hle/service/apm/controller.cpp
+    hle/service/apm/controller.h
     hle/service/apm/interface.cpp
     hle/service/apm/interface.h
     hle/service/audio/audctl.cpp

+ 68 - 0
src/core/hle/service/apm/controller.cpp

@@ -0,0 +1,68 @@
+// Copyright 2019 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/logging/log.h"
+#include "core/core_timing.h"
+#include "core/hle/service/apm/controller.h"
+#include "core/settings.h"
+
+namespace Service::APM {
+
+constexpr PerformanceConfiguration DEFAULT_PERFORMANCE_CONFIGURATION =
+    PerformanceConfiguration::Config7;
+
+Controller::Controller(Core::Timing::CoreTiming& core_timing)
+    : core_timing(core_timing), configs{
+                                    {PerformanceMode::Handheld, DEFAULT_PERFORMANCE_CONFIGURATION},
+                                    {PerformanceMode::Docked, DEFAULT_PERFORMANCE_CONFIGURATION},
+                                } {}
+
+Controller::~Controller() = default;
+
+void Controller::SetPerformanceConfiguration(PerformanceMode mode,
+                                             PerformanceConfiguration config) {
+    static const std::map<PerformanceConfiguration, u32> PCONFIG_TO_SPEED_MAP{
+        {PerformanceConfiguration::Config1, 1020},  {PerformanceConfiguration::Config2, 1020},
+        {PerformanceConfiguration::Config3, 1224},  {PerformanceConfiguration::Config4, 1020},
+        {PerformanceConfiguration::Config5, 1020},  {PerformanceConfiguration::Config6, 1224},
+        {PerformanceConfiguration::Config7, 1020},  {PerformanceConfiguration::Config8, 1020},
+        {PerformanceConfiguration::Config9, 1020},  {PerformanceConfiguration::Config10, 1020},
+        {PerformanceConfiguration::Config11, 1020}, {PerformanceConfiguration::Config12, 1020},
+        {PerformanceConfiguration::Config13, 1785}, {PerformanceConfiguration::Config14, 1785},
+        {PerformanceConfiguration::Config15, 1020}, {PerformanceConfiguration::Config16, 1020},
+    };
+
+    SetClockSpeed(PCONFIG_TO_SPEED_MAP.find(config)->second);
+    configs.insert_or_assign(mode, config);
+}
+
+void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
+    constexpr std::array<PerformanceConfiguration, 3> BOOST_MODE_TO_CONFIG_MAP{{
+        PerformanceConfiguration::Config7,
+        PerformanceConfiguration::Config13,
+        PerformanceConfiguration::Config15,
+    }};
+
+    SetPerformanceConfiguration(PerformanceMode::Docked,
+                                BOOST_MODE_TO_CONFIG_MAP.at(static_cast<u32>(mode)));
+}
+
+PerformanceMode Controller::GetCurrentPerformanceMode() {
+    return Settings::values.use_docked_mode ? PerformanceMode::Docked : PerformanceMode::Handheld;
+}
+
+PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) {
+    if (configs.find(mode) == configs.end()) {
+        configs.insert_or_assign(mode, DEFAULT_PERFORMANCE_CONFIGURATION);
+    }
+
+    return configs[mode];
+}
+
+void Controller::SetClockSpeed(u32 mhz) {
+    LOG_INFO(Service_APM, "called, mhz={:08X}", mhz);
+    // TODO(DarkLordZach): Actually signal core_timing to change clock speed.
+}
+
+} // namespace Service::APM

+ 70 - 0
src/core/hle/service/apm/controller.h

@@ -0,0 +1,70 @@
+// Copyright 2019 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <map>
+#include "common/common_types.h"
+
+namespace Core::Timing {
+class CoreTiming;
+}
+
+namespace Service::APM {
+
+enum class PerformanceConfiguration : u32 {
+    Config1 = 0x00010000,
+    Config2 = 0x00010001,
+    Config3 = 0x00010002,
+    Config4 = 0x00020000,
+    Config5 = 0x00020001,
+    Config6 = 0x00020002,
+    Config7 = 0x00020003,
+    Config8 = 0x00020004,
+    Config9 = 0x00020005,
+    Config10 = 0x00020006,
+    Config11 = 0x92220007,
+    Config12 = 0x92220008,
+    Config13 = 0x92220009,
+    Config14 = 0x9222000A,
+    Config15 = 0x9222000B,
+    Config16 = 0x9222000C,
+};
+
+enum class CpuBoostMode : u32 {
+    Disabled = 0,
+    Full = 1,    // CPU + GPU -> Config 13, 14, 15, or 16
+    Partial = 2, // GPU Only -> Config 15 or 16
+};
+
+enum class PerformanceMode : u8 {
+    Handheld = 0,
+    Docked = 1,
+};
+
+// Class to manage the state and change of the emulated system performance.
+// Specifically, this deals with PerformanceMode, which corresponds to the system being docked or
+// undocked, and PerformanceConfig which specifies the exact CPU, GPU, and Memory clocks to operate
+// at. Additionally, this manages 'Boost Mode', which allows games to temporarily overclock the
+// system during times of high load -- this simply maps to different PerformanceConfigs to use.
+class Controller {
+public:
+    Controller(Core::Timing::CoreTiming& core_timing);
+    ~Controller();
+
+    void SetPerformanceConfiguration(PerformanceMode mode, PerformanceConfiguration config);
+    void SetFromCpuBoostMode(CpuBoostMode mode);
+
+    PerformanceMode GetCurrentPerformanceMode();
+    PerformanceConfiguration GetCurrentPerformanceConfiguration(PerformanceMode mode);
+
+private:
+    void SetClockSpeed(u32 mhz);
+
+    std::map<PerformanceMode, PerformanceConfiguration> configs;
+
+    Core::Timing::CoreTiming& core_timing;
+};
+
+} // namespace Service::APM