Compare commits
41 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4ae449f73 | ||
|
|
b81f6f67f5 | ||
|
|
0b3901bdd0 | ||
|
|
502358ab05 | ||
|
|
fd066ffbce | ||
|
|
7fb7054bc8 | ||
|
|
93eaea109d | ||
|
|
463af08bed | ||
|
|
d707a12b9a | ||
|
|
206ec29f17 | ||
|
|
55245b6183 | ||
|
|
f2e5c19520 | ||
|
|
05d55b0fd7 | ||
|
|
0330f5d6f8 | ||
|
|
c04785c928 | ||
|
|
618d8446ab | ||
|
|
6c3cceafdc | ||
|
|
5234e08a0d | ||
|
|
e3d000a7e6 | ||
|
|
7b28f954c9 | ||
|
|
8f5aae3074 | ||
|
|
8070cb3f6b | ||
|
|
be020f7621 | ||
|
|
cbdd6cd1c0 | ||
|
|
4b27680639 | ||
|
|
86a874a2fc | ||
|
|
a4ef86a021 | ||
|
|
b82b5e46e7 | ||
|
|
472210bf72 | ||
|
|
7e5d7773cc | ||
|
|
e2ad3e1fb0 | ||
|
|
e52306ca60 | ||
|
|
1c6e6305ea | ||
|
|
9175b00e7d | ||
|
|
65eb9cbb28 | ||
|
|
d40f38967e | ||
|
|
554e2f2f98 | ||
|
|
db2fdd0352 | ||
|
|
bce4bfffb6 | ||
|
|
354c254cde | ||
|
|
49af3bcdcb |
19
.ci/yuzu-mainline.yml
Normal file
19
.ci/yuzu-mainline.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
# Starter pipeline
|
||||
# Start with a minimal pipeline that you can customize to build and deploy your code.
|
||||
# Add steps that build, run tests, deploy, and more:
|
||||
# https://aka.ms/yaml
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- script: echo Hello, world!
|
||||
displayName: 'Run a one-line script'
|
||||
|
||||
- script: |
|
||||
echo Add other tasks to build, test, and deploy your project.
|
||||
echo See https://aka.ms/yaml
|
||||
displayName: 'Run a multi-line script'
|
||||
19
.ci/yuzu-patreon.yml
Normal file
19
.ci/yuzu-patreon.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
# Starter pipeline
|
||||
# Start with a minimal pipeline that you can customize to build and deploy your code.
|
||||
# Add steps that build, run tests, deploy, and more:
|
||||
# https://aka.ms/yaml
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- script: echo Hello, world!
|
||||
displayName: 'Run a one-line script'
|
||||
|
||||
- script: |
|
||||
echo Add other tasks to build, test, and deploy your project.
|
||||
echo See https://aka.ms/yaml
|
||||
displayName: 'Run a multi-line script'
|
||||
19
.ci/yuzu-repo-sync.yml
Normal file
19
.ci/yuzu-repo-sync.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
trigger:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
- job: copy
|
||||
displayName: 'Sync Repository'
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- script: echo 'https://$(GitUsername):$(GitAccessToken)@dev.azure.com' > $HOME/.git-credentials
|
||||
displayName: 'Load Credentials'
|
||||
- script: git config --global credential.helper store
|
||||
displayName: 'Register Credential Helper'
|
||||
- script: git remote add other $(GitRepoPushChangesURL)
|
||||
displayName: 'Register Repository'
|
||||
- script: git push --force other HEAD:$(GitPushBranch)
|
||||
displayName: 'Update Code'
|
||||
- script: rm -rf $HOME/.git-credentials
|
||||
displayName: 'Clear Cached Credentials'
|
||||
19
.ci/yuzu.yml
Normal file
19
.ci/yuzu.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
# Starter pipeline
|
||||
# Start with a minimal pipeline that you can customize to build and deploy your code.
|
||||
# Add steps that build, run tests, deploy, and more:
|
||||
# https://aka.ms/yaml
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- script: echo Hello, world!
|
||||
displayName: 'Run a one-line script'
|
||||
|
||||
- script: |
|
||||
echo Add other tasks to build, test, and deploy your project.
|
||||
echo See https://aka.ms/yaml
|
||||
displayName: 'Run a multi-line script'
|
||||
@@ -217,13 +217,15 @@ std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_co
|
||||
if (offset == samples.size()) {
|
||||
offset = 0;
|
||||
|
||||
if (!wave_buffer.is_looping) {
|
||||
if (!wave_buffer.is_looping && wave_buffer.buffer_sz) {
|
||||
SetWaveIndex(wave_index + 1);
|
||||
}
|
||||
|
||||
out_status.wave_buffer_consumed++;
|
||||
if (wave_buffer.buffer_sz) {
|
||||
out_status.wave_buffer_consumed++;
|
||||
}
|
||||
|
||||
if (wave_buffer.end_of_stream) {
|
||||
if (wave_buffer.end_of_stream || wave_buffer.buffer_sz == 0) {
|
||||
info.play_state = PlayState::Paused;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,6 +208,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
|
||||
@@ -293,6 +295,7 @@ add_library(core STATIC
|
||||
hle/service/hid/irs.h
|
||||
hle/service/hid/xcd.cpp
|
||||
hle/service/hid/xcd.h
|
||||
hle/service/hid/errors.h
|
||||
hle/service/hid/controllers/controller_base.cpp
|
||||
hle/service/hid/controllers/controller_base.h
|
||||
hle/service/hid/controllers/debug_pad.cpp
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "core/hle/kernel/scheduler.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
#include "core/hle/service/am/applets/applets.h"
|
||||
#include "core/hle/service/apm/controller.h"
|
||||
#include "core/hle/service/glue/manager.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
@@ -143,7 +144,7 @@ struct System::Impl {
|
||||
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
||||
service_manager = std::make_shared<Service::SM::ServiceManager>();
|
||||
|
||||
Service::Init(service_manager, system, *virtual_filesystem);
|
||||
Service::Init(service_manager, system);
|
||||
GDBStub::Init();
|
||||
|
||||
renderer = VideoCore::CreateRenderer(emu_window, system);
|
||||
@@ -306,6 +307,9 @@ struct System::Impl {
|
||||
/// Frontend applets
|
||||
Service::AM::Applets::AppletManager applet_manager;
|
||||
|
||||
/// APM (Performance) services
|
||||
Service::APM::Controller apm_controller{core_timing};
|
||||
|
||||
/// Glue services
|
||||
Service::Glue::ARPManager arp_manager;
|
||||
|
||||
@@ -568,6 +572,14 @@ const Service::Glue::ARPManager& System::GetARPManager() const {
|
||||
return impl->arp_manager;
|
||||
}
|
||||
|
||||
Service::APM::Controller& System::GetAPMController() {
|
||||
return impl->apm_controller;
|
||||
}
|
||||
|
||||
const Service::APM::Controller& System::GetAPMController() const {
|
||||
return impl->apm_controller;
|
||||
}
|
||||
|
||||
System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) {
|
||||
return impl->Init(*this, emu_window);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ struct AppletFrontendSet;
|
||||
class AppletManager;
|
||||
} // namespace AM::Applets
|
||||
|
||||
namespace APM {
|
||||
class Controller;
|
||||
}
|
||||
|
||||
namespace Glue {
|
||||
class ARPManager;
|
||||
}
|
||||
@@ -296,6 +300,10 @@ public:
|
||||
|
||||
const Service::Glue::ARPManager& GetARPManager() const;
|
||||
|
||||
Service::APM::Controller& GetAPMController();
|
||||
|
||||
const Service::APM::Controller& GetAPMController() const;
|
||||
|
||||
private:
|
||||
System();
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ const std::array<const char*, 15> LANGUAGE_NAMES{{
|
||||
"Korean",
|
||||
"Taiwanese",
|
||||
"Chinese",
|
||||
"Czech", //Again not sure
|
||||
}};
|
||||
|
||||
std::string LanguageEntry::GetApplicationName() const {
|
||||
|
||||
@@ -88,9 +88,7 @@ enum class Language : u8 {
|
||||
Korean = 12,
|
||||
Taiwanese = 13,
|
||||
Chinese = 14,
|
||||
|
||||
Czech = 17, // not sure
|
||||
|
||||
|
||||
Default = 255,
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
#include "core/hle/service/am/omm.h"
|
||||
#include "core/hle/service/am/spsm.h"
|
||||
#include "core/hle/service/am/tcap.h"
|
||||
#include "core/hle/service/apm/apm.h"
|
||||
#include "core/hle/service/apm/controller.h"
|
||||
#include "core/hle/service/apm/interface.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/hle/service/ns/ns.h"
|
||||
#include "core/hle/service/nvflinger/nvflinger.h"
|
||||
@@ -265,8 +266,8 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
|
||||
{65, nullptr, "ReportUserIsActive"},
|
||||
{66, nullptr, "GetCurrentIlluminance"},
|
||||
{67, nullptr, "IsIlluminanceAvailable"},
|
||||
{68, nullptr, "SetAutoSleepDisabled"},
|
||||
{69, nullptr, "IsAutoSleepDisabled"},
|
||||
{68, &ISelfController::SetAutoSleepDisabled, "SetAutoSleepDisabled"},
|
||||
{69, &ISelfController::IsAutoSleepDisabled, "IsAutoSleepDisabled"},
|
||||
{70, nullptr, "ReportMultimediaError"},
|
||||
{71, nullptr, "GetCurrentIlluminanceEx"},
|
||||
{80, nullptr, "SetWirelessPriorityMode"},
|
||||
@@ -453,6 +454,34 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
|
||||
rb.Push<u32>(idle_time_detection_extension);
|
||||
}
|
||||
|
||||
void ISelfController::SetAutoSleepDisabled(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
is_auto_sleep_disabled = rp.Pop<bool>();
|
||||
|
||||
// On the system itself, if the previous state of is_auto_sleep_disabled
|
||||
// differed from the current value passed in, it'd signify the internal
|
||||
// window manager to update (and also increment some statistics like update counts)
|
||||
//
|
||||
// It'd also indicate this change to an idle handling context.
|
||||
//
|
||||
// However, given we're emulating this behavior, most of this can be ignored
|
||||
// and it's sufficient to simply set the member variable for querying via
|
||||
// IsAutoSleepDisabled().
|
||||
|
||||
LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", is_auto_sleep_disabled);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void ISelfController::IsAutoSleepDisabled(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_AM, "called.");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(is_auto_sleep_disabled);
|
||||
}
|
||||
|
||||
void ISelfController::GetAccumulatedSuspendedTickValue(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_AM, "called.");
|
||||
|
||||
@@ -520,8 +549,9 @@ void AppletMessageQueue::OperationModeChanged() {
|
||||
on_operation_mode_changed.writable->Signal();
|
||||
}
|
||||
|
||||
ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue)
|
||||
: ServiceFramework("ICommonStateGetter"), msg_queue(std::move(msg_queue)) {
|
||||
ICommonStateGetter::ICommonStateGetter(Core::System& system,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue)
|
||||
: ServiceFramework("ICommonStateGetter"), system(system), msg_queue(std::move(msg_queue)) {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
|
||||
@@ -554,7 +584,7 @@ ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_q
|
||||
{63, nullptr, "GetHdcpAuthenticationStateChangeEvent"},
|
||||
{64, nullptr, "SetTvPowerStateMatchingMode"},
|
||||
{65, nullptr, "GetApplicationIdByContentActionName"},
|
||||
{66, nullptr, "SetCpuBoostMode"},
|
||||
{66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"},
|
||||
{80, nullptr, "PerformSystemButtonPressingIfInFocus"},
|
||||
{90, nullptr, "SetPerformanceConfigurationChangedNotification"},
|
||||
{91, nullptr, "GetCurrentPerformanceConfiguration"},
|
||||
@@ -635,6 +665,16 @@ void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext&
|
||||
}
|
||||
}
|
||||
|
||||
void ICommonStateGetter::SetCpuBoostMode(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_AM, "called, forwarding to APM:SYS");
|
||||
|
||||
const auto& sm = system.ServiceManager();
|
||||
const auto apm_sys = sm.GetService<APM::APM_Sys>("apm:sys");
|
||||
ASSERT(apm_sys != nullptr);
|
||||
|
||||
apm_sys->SetCpuBoostMode(ctx);
|
||||
}
|
||||
|
||||
IStorage::IStorage(std::vector<u8> buffer)
|
||||
: ServiceFramework("IStorage"), buffer(std::move(buffer)) {
|
||||
// clang-format off
|
||||
@@ -663,13 +703,11 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
|
||||
const bool use_docked_mode{Settings::values.use_docked_mode};
|
||||
LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode);
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
|
||||
: APM::PerformanceMode::Handheld));
|
||||
rb.PushEnum(system.GetAPMController().GetCurrentPerformanceMode());
|
||||
}
|
||||
|
||||
class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
|
||||
|
||||
@@ -36,7 +36,6 @@ enum SystemLanguage {
|
||||
// 4.0.0+
|
||||
SimplifiedChinese = 15,
|
||||
TraditionalChinese = 16,
|
||||
Czech = 17,//cs-CZ
|
||||
};
|
||||
|
||||
class AppletMessageQueue {
|
||||
@@ -134,6 +133,8 @@ private:
|
||||
void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx);
|
||||
void SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
|
||||
void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
|
||||
void SetAutoSleepDisabled(Kernel::HLERequestContext& ctx);
|
||||
void IsAutoSleepDisabled(Kernel::HLERequestContext& ctx);
|
||||
void GetAccumulatedSuspendedTickValue(Kernel::HLERequestContext& ctx);
|
||||
void GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx);
|
||||
|
||||
@@ -143,11 +144,13 @@ private:
|
||||
|
||||
u32 idle_time_detection_extension = 0;
|
||||
u64 num_fatal_sections_entered = 0;
|
||||
bool is_auto_sleep_disabled = false;
|
||||
};
|
||||
|
||||
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
|
||||
public:
|
||||
explicit ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue);
|
||||
explicit ICommonStateGetter(Core::System& system,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue);
|
||||
~ICommonStateGetter() override;
|
||||
|
||||
private:
|
||||
@@ -169,7 +172,9 @@ private:
|
||||
void GetPerformanceMode(Kernel::HLERequestContext& ctx);
|
||||
void GetBootMode(Kernel::HLERequestContext& ctx);
|
||||
void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
|
||||
void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
|
||||
|
||||
Core::System& system;
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
|
||||
rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue);
|
||||
}
|
||||
|
||||
void GetSelfController(Kernel::HLERequestContext& ctx) {
|
||||
@@ -146,7 +146,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
|
||||
rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue);
|
||||
}
|
||||
|
||||
void GetSelfController(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
@@ -80,7 +80,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
|
||||
rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue);
|
||||
}
|
||||
|
||||
void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/apm/apm.h"
|
||||
#include "core/hle/service/apm/interface.h"
|
||||
@@ -12,11 +11,15 @@ namespace Service::APM {
|
||||
Module::Module() = default;
|
||||
Module::~Module() = default;
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
void InstallInterfaces(Core::System& system) {
|
||||
auto module_ = std::make_shared<Module>();
|
||||
std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager);
|
||||
std::make_shared<APM>(module_, "apm:p")->InstallAsService(service_manager);
|
||||
std::make_shared<APM_Sys>()->InstallAsService(service_manager);
|
||||
std::make_shared<APM>(module_, system.GetAPMController(), "apm")
|
||||
->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<APM>(module_, system.GetAPMController(), "apm:p")
|
||||
->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<APM>(module_, system.GetAPMController(), "apm:am")
|
||||
->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<APM_Sys>(system.GetAPMController())->InstallAsService(system.ServiceManager());
|
||||
}
|
||||
|
||||
} // namespace Service::APM
|
||||
|
||||
@@ -8,11 +8,6 @@
|
||||
|
||||
namespace Service::APM {
|
||||
|
||||
enum class PerformanceMode : u8 {
|
||||
Handheld = 0,
|
||||
Docked = 1,
|
||||
};
|
||||
|
||||
class Module final {
|
||||
public:
|
||||
Module();
|
||||
@@ -20,6 +15,6 @@ public:
|
||||
};
|
||||
|
||||
/// Registers all AM services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
void InstallInterfaces(Core::System& system);
|
||||
|
||||
} // namespace Service::APM
|
||||
|
||||
68
src/core/hle/service/apm/controller.cpp
Normal file
68
src/core/hle/service/apm/controller.cpp
Normal file
@@ -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
src/core/hle/service/apm/controller.h
Normal file
70
src/core/hle/service/apm/controller.h
Normal file
@@ -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
|
||||
@@ -5,43 +5,32 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/apm/apm.h"
|
||||
#include "core/hle/service/apm/controller.h"
|
||||
#include "core/hle/service/apm/interface.h"
|
||||
|
||||
namespace Service::APM {
|
||||
|
||||
class ISession final : public ServiceFramework<ISession> {
|
||||
public:
|
||||
ISession() : ServiceFramework("ISession") {
|
||||
ISession(Controller& controller) : ServiceFramework("ISession"), controller(controller) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
|
||||
{1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
|
||||
{2, nullptr, "SetCpuOverclockEnabled"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
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,
|
||||
};
|
||||
|
||||
void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
|
||||
u32 config = rp.Pop<u32>();
|
||||
LOG_WARNING(Service_APM, "(STUBBED) called mode={} config={}", static_cast<u32>(mode),
|
||||
config);
|
||||
const auto mode = rp.PopEnum<PerformanceMode>();
|
||||
const auto config = rp.PopEnum<PerformanceConfiguration>();
|
||||
LOG_DEBUG(Service_APM, "called mode={} config={}", static_cast<u32>(mode),
|
||||
static_cast<u32>(config));
|
||||
|
||||
controller.SetPerformanceConfiguration(mode, config);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -50,20 +39,23 @@ private:
|
||||
void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
|
||||
LOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode));
|
||||
const auto mode = rp.PopEnum<PerformanceMode>();
|
||||
LOG_DEBUG(Service_APM, "called mode={}", static_cast<u32>(mode));
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(static_cast<u32>(PerformanceConfiguration::Config1));
|
||||
rb.PushEnum(controller.GetCurrentPerformanceConfiguration(mode));
|
||||
}
|
||||
|
||||
Controller& controller;
|
||||
};
|
||||
|
||||
APM::APM(std::shared_ptr<Module> apm, const char* name)
|
||||
: ServiceFramework(name), apm(std::move(apm)) {
|
||||
APM::APM(std::shared_ptr<Module> apm, Controller& controller, const char* name)
|
||||
: ServiceFramework(name), apm(std::move(apm)), controller(controller) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &APM::OpenSession, "OpenSession"},
|
||||
{1, nullptr, "GetPerformanceMode"},
|
||||
{1, &APM::GetPerformanceMode, "GetPerformanceMode"},
|
||||
{6, nullptr, "IsCpuOverclockEnabled"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
@@ -75,10 +67,17 @@ void APM::OpenSession(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISession>();
|
||||
rb.PushIpcInterface<ISession>(controller);
|
||||
}
|
||||
|
||||
APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} {
|
||||
void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_APM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.PushEnum(controller.GetCurrentPerformanceMode());
|
||||
}
|
||||
|
||||
APM_Sys::APM_Sys(Controller& controller) : ServiceFramework{"apm:sys"}, controller(controller) {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestPerformanceMode"},
|
||||
@@ -87,8 +86,8 @@ APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} {
|
||||
{3, nullptr, "GetLastThrottlingState"},
|
||||
{4, nullptr, "ClearLastThrottlingState"},
|
||||
{5, nullptr, "LoadAndApplySettings"},
|
||||
{6, nullptr, "SetCpuBoostMode"},
|
||||
{7, nullptr, "GetCurrentPerformanceConfiguration"},
|
||||
{6, &APM_Sys::SetCpuBoostMode, "SetCpuBoostMode"},
|
||||
{7, &APM_Sys::GetCurrentPerformanceConfiguration, "GetCurrentPerformanceConfiguration"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -102,7 +101,28 @@ void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISession>();
|
||||
rb.PushIpcInterface<ISession>(controller);
|
||||
}
|
||||
|
||||
void APM_Sys::SetCpuBoostMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto mode = rp.PopEnum<CpuBoostMode>();
|
||||
|
||||
LOG_DEBUG(Service_APM, "called, mode={:08X}", static_cast<u32>(mode));
|
||||
|
||||
controller.SetFromCpuBoostMode(mode);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void APM_Sys::GetCurrentPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_APM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushEnum(
|
||||
controller.GetCurrentPerformanceConfiguration(controller.GetCurrentPerformanceMode()));
|
||||
}
|
||||
|
||||
} // namespace Service::APM
|
||||
|
||||
@@ -8,24 +8,34 @@
|
||||
|
||||
namespace Service::APM {
|
||||
|
||||
class Controller;
|
||||
class Module;
|
||||
|
||||
class APM final : public ServiceFramework<APM> {
|
||||
public:
|
||||
explicit APM(std::shared_ptr<Module> apm, const char* name);
|
||||
explicit APM(std::shared_ptr<Module> apm, Controller& controller, const char* name);
|
||||
~APM() override;
|
||||
|
||||
private:
|
||||
void OpenSession(Kernel::HLERequestContext& ctx);
|
||||
void GetPerformanceMode(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<Module> apm;
|
||||
Controller& controller;
|
||||
};
|
||||
|
||||
class APM_Sys final : public ServiceFramework<APM_Sys> {
|
||||
public:
|
||||
explicit APM_Sys();
|
||||
explicit APM_Sys(Controller& controller);
|
||||
~APM_Sys() override;
|
||||
|
||||
void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
|
||||
|
||||
private:
|
||||
void GetPerformanceEvent(Kernel::HLERequestContext& ctx);
|
||||
void GetCurrentPerformanceConfiguration(Kernel::HLERequestContext& ctx);
|
||||
|
||||
Controller& controller;
|
||||
};
|
||||
|
||||
} // namespace Service::APM
|
||||
|
||||
@@ -472,12 +472,12 @@ void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) {
|
||||
}
|
||||
}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager, FileSys::VfsFilesystem& vfs) {
|
||||
void InstallInterfaces(Core::System& system) {
|
||||
romfs_factory = nullptr;
|
||||
CreateFactories(vfs, false);
|
||||
std::make_shared<FSP_LDR>()->InstallAsService(service_manager);
|
||||
std::make_shared<FSP_PR>()->InstallAsService(service_manager);
|
||||
std::make_shared<FSP_SRV>()->InstallAsService(service_manager);
|
||||
CreateFactories(*system.GetFilesystem(), false);
|
||||
std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<FSP_SRV>(system.GetReporter())->InstallAsService(system.ServiceManager());
|
||||
}
|
||||
|
||||
} // namespace Service::FileSystem
|
||||
|
||||
@@ -65,7 +65,7 @@ FileSys::VirtualDir GetModificationDumpRoot(u64 title_id);
|
||||
// above is called.
|
||||
void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true);
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager, FileSys::VfsFilesystem& vfs);
|
||||
void InstallInterfaces(Core::System& system);
|
||||
|
||||
// A class that wraps a VfsDirectory with methods that return ResultVal and ResultCode instead of
|
||||
// pointers and booleans. This makes using a VfsDirectory with switch services much easier and
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/hle/service/filesystem/fsp_srv.h"
|
||||
#include "core/reporter.h"
|
||||
|
||||
namespace Service::FileSystem {
|
||||
|
||||
@@ -613,7 +614,7 @@ private:
|
||||
u64 next_entry_index = 0;
|
||||
};
|
||||
|
||||
FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
|
||||
FSP_SRV::FSP_SRV(const Core::Reporter& reporter) : ServiceFramework("fsp-srv"), reporter(reporter) {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "OpenFileSystem"},
|
||||
@@ -710,14 +711,14 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
|
||||
{1001, nullptr, "SetSaveDataSize"},
|
||||
{1002, nullptr, "SetSaveDataRootPath"},
|
||||
{1003, nullptr, "DisableAutoSaveDataCreation"},
|
||||
{1004, nullptr, "SetGlobalAccessLogMode"},
|
||||
{1004, &FSP_SRV::SetGlobalAccessLogMode, "SetGlobalAccessLogMode"},
|
||||
{1005, &FSP_SRV::GetGlobalAccessLogMode, "GetGlobalAccessLogMode"},
|
||||
{1006, nullptr, "OutputAccessLogToSdCard"},
|
||||
{1006, &FSP_SRV::OutputAccessLogToSdCard, "OutputAccessLogToSdCard"},
|
||||
{1007, nullptr, "RegisterUpdatePartition"},
|
||||
{1008, nullptr, "OpenRegisteredUpdatePartition"},
|
||||
{1009, nullptr, "GetAndClearMemoryReportInfo"},
|
||||
{1010, nullptr, "SetDataStorageRedirectTarget"},
|
||||
{1011, nullptr, "OutputAccessLogToSdCard2"},
|
||||
{1011, &FSP_SRV::GetAccessLogVersionInfo, "GetAccessLogVersionInfo"},
|
||||
{1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
|
||||
{1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
|
||||
{1200, nullptr, "OpenMultiCommitManager"},
|
||||
@@ -814,21 +815,22 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext&
|
||||
rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space));
|
||||
}
|
||||
|
||||
void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
log_mode = rp.PopEnum<LogMode>();
|
||||
|
||||
LOG_DEBUG(Service_FS, "called, log_mode={:08X}", static_cast<u32>(log_mode));
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_FS, "called");
|
||||
|
||||
enum class LogMode : u32 {
|
||||
Off,
|
||||
Log,
|
||||
RedirectToSdCard,
|
||||
LogToSdCard = Log | RedirectToSdCard,
|
||||
};
|
||||
|
||||
// Given we always want to receive logging information,
|
||||
// we always specify logging as enabled.
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushEnum(LogMode::Log);
|
||||
rb.PushEnum(log_mode);
|
||||
}
|
||||
|
||||
void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
|
||||
@@ -902,4 +904,26 @@ void FSP_SRV::OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ct
|
||||
rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND);
|
||||
}
|
||||
|
||||
void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) {
|
||||
const auto raw = ctx.ReadBuffer();
|
||||
auto log = Common::StringFromFixedZeroTerminatedBuffer(
|
||||
reinterpret_cast<const char*>(raw.data()), raw.size());
|
||||
|
||||
LOG_DEBUG(Service_FS, "called, log='{}'", log);
|
||||
|
||||
reporter.SaveFilesystemAccessReport(log_mode, std::move(log));
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_FS, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushEnum(AccessLogVersion::Latest);
|
||||
rb.Push(access_log_program_index);
|
||||
}
|
||||
|
||||
} // namespace Service::FileSystem
|
||||
|
||||
@@ -7,15 +7,32 @@
|
||||
#include <memory>
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class Reporter;
|
||||
}
|
||||
|
||||
namespace FileSys {
|
||||
class FileSystemBackend;
|
||||
}
|
||||
|
||||
namespace Service::FileSystem {
|
||||
|
||||
enum class AccessLogVersion : u32 {
|
||||
V7_0_0 = 2,
|
||||
|
||||
Latest = V7_0_0,
|
||||
};
|
||||
|
||||
enum class LogMode : u32 {
|
||||
Off,
|
||||
Log,
|
||||
RedirectToSdCard,
|
||||
LogToSdCard = Log | RedirectToSdCard,
|
||||
};
|
||||
|
||||
class FSP_SRV final : public ServiceFramework<FSP_SRV> {
|
||||
public:
|
||||
explicit FSP_SRV();
|
||||
explicit FSP_SRV(const Core::Reporter& reporter);
|
||||
~FSP_SRV() override;
|
||||
|
||||
private:
|
||||
@@ -26,13 +43,20 @@ private:
|
||||
void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx);
|
||||
void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx);
|
||||
void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx);
|
||||
void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
|
||||
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
|
||||
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
|
||||
void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx);
|
||||
void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
|
||||
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
|
||||
void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
|
||||
|
||||
FileSys::VirtualFile romfs;
|
||||
u64 current_process_id = 0;
|
||||
u32 access_log_program_index = 0;
|
||||
LogMode log_mode = LogMode::LogToSdCard;
|
||||
|
||||
const Core::Reporter& reporter;
|
||||
};
|
||||
|
||||
} // namespace Service::FileSystem
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
{0, nullptr, "GetCompletionEvent"},
|
||||
{1, nullptr, "Cancel"},
|
||||
{10100, nullptr, "GetFriendListIds"},
|
||||
{10101, nullptr, "GetFriendList"},
|
||||
{10101, &IFriendService::GetFriendList, "GetFriendList"},
|
||||
{10102, nullptr, "UpdateFriendInfo"},
|
||||
{10110, nullptr, "GetFriendProfileImage"},
|
||||
{10200, nullptr, "SendFriendRequestForApplication"},
|
||||
@@ -99,6 +99,23 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
enum class PresenceFilter : u32 {
|
||||
None = 0,
|
||||
Online = 1,
|
||||
OnlinePlay = 2,
|
||||
OnlineOrOnlinePlay = 3,
|
||||
};
|
||||
|
||||
struct SizedFriendFilter {
|
||||
PresenceFilter presence;
|
||||
u8 is_favorite;
|
||||
u8 same_app;
|
||||
u8 same_app_played;
|
||||
u8 arbitary_app_played;
|
||||
u64 group_id;
|
||||
};
|
||||
static_assert(sizeof(SizedFriendFilter) == 0x10, "SizedFriendFilter is an invalid size");
|
||||
|
||||
void DeclareCloseOnlinePlaySession(Kernel::HLERequestContext& ctx) {
|
||||
// Stub used by Splatoon 2
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
@@ -112,6 +129,22 @@ private:
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void GetFriendList(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto friend_offset = rp.Pop<u32>();
|
||||
const auto uuid = rp.PopRaw<Common::UUID>();
|
||||
[[maybe_unused]] const auto filter = rp.PopRaw<SizedFriendFilter>();
|
||||
const auto pid = rp.Pop<u64>();
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called, offset={}, uuid={}, pid={}", friend_offset,
|
||||
uuid.Format(), pid);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
rb.Push<u32>(0); // Friend count
|
||||
// TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId"
|
||||
}
|
||||
};
|
||||
|
||||
class INotificationService final : public ServiceFramework<INotificationService> {
|
||||
|
||||
@@ -548,6 +548,37 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) {
|
||||
connected_controllers[NPadIdToIndex(npad_id)].is_connected = false;
|
||||
}
|
||||
|
||||
void Controller_NPad::StartLRAssignmentMode() {
|
||||
// Nothing internally is used for lr assignment mode. Since we have the ability to set the
|
||||
// controller types from boot, it doesn't really matter about showing a selection screen
|
||||
is_in_lr_assignment_mode = true;
|
||||
}
|
||||
|
||||
void Controller_NPad::StopLRAssignmentMode() {
|
||||
is_in_lr_assignment_mode = false;
|
||||
}
|
||||
|
||||
bool Controller_NPad::SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2) {
|
||||
if (npad_id_1 == NPAD_HANDHELD || npad_id_2 == NPAD_HANDHELD || npad_id_1 == NPAD_UNKNOWN ||
|
||||
npad_id_2 == NPAD_UNKNOWN) {
|
||||
return true;
|
||||
}
|
||||
const auto npad_index_1 = NPadIdToIndex(npad_id_1);
|
||||
const auto npad_index_2 = NPadIdToIndex(npad_id_2);
|
||||
|
||||
if (!IsControllerSupported(connected_controllers[npad_index_1].type) ||
|
||||
!IsControllerSupported(connected_controllers[npad_index_2].type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::swap(connected_controllers[npad_index_1].type, connected_controllers[npad_index_2].type);
|
||||
|
||||
InitNewlyAddedControler(npad_index_1);
|
||||
InitNewlyAddedControler(npad_index_2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller_NPad::IsControllerSupported(NPadControllerType controller) {
|
||||
if (controller == NPadControllerType::Handheld) {
|
||||
// Handheld is not even a supported type, lets stop here
|
||||
|
||||
@@ -124,6 +124,10 @@ public:
|
||||
void ConnectAllDisconnectedControllers();
|
||||
void ClearAllControllers();
|
||||
|
||||
void StartLRAssignmentMode();
|
||||
void StopLRAssignmentMode();
|
||||
bool SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2);
|
||||
|
||||
// Logical OR for all buttons presses on all controllers
|
||||
// Specifically for cheat engine and other features.
|
||||
u32 GetAndResetPressState();
|
||||
@@ -321,5 +325,6 @@ private:
|
||||
void RequestPadStateUpdate(u32 npad_id);
|
||||
std::array<ControllerPad, 10> npad_pad_states{};
|
||||
bool IsControllerSupported(NPadControllerType controller);
|
||||
bool is_in_lr_assignment_mode{false};
|
||||
};
|
||||
} // namespace Service::HID
|
||||
|
||||
13
src/core/hle/service/hid/errors.h
Normal file
13
src/core/hle/service/hid/errors.h
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2019 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
constexpr ResultCode ERR_NPAD_NOT_CONNECTED{ErrorModule::HID, 710};
|
||||
|
||||
} // namespace Service::HID
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "core/hle/kernel/readable_event.h"
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
#include "core/hle/kernel/writable_event.h"
|
||||
#include "core/hle/service/hid/errors.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/hid/irs.h"
|
||||
#include "core/hle/service/hid/xcd.h"
|
||||
@@ -202,11 +203,11 @@ Hid::Hid() : ServiceFramework("hid") {
|
||||
{123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
|
||||
{124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
|
||||
{125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
|
||||
{126, nullptr, "StartLrAssignmentMode"},
|
||||
{127, nullptr, "StopLrAssignmentMode"},
|
||||
{126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"},
|
||||
{127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"},
|
||||
{128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
|
||||
{129, nullptr, "GetNpadHandheldActivationMode"},
|
||||
{130, nullptr, "SwapNpadAssignment"},
|
||||
{130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
|
||||
{131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
|
||||
{132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
|
||||
{133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
|
||||
@@ -733,6 +734,49 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
controller.StartLRAssignmentMode();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
controller.StopLRAssignmentMode();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto npad_1{rp.Pop<u32>()};
|
||||
const auto npad_2{rp.Pop<u32>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
|
||||
applet_resource_user_id, npad_1, npad_2);
|
||||
|
||||
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
if (controller.SwapNpadAssignment(npad_1, npad_2)) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
} else {
|
||||
LOG_ERROR(Service_HID, "Npads are not connected!");
|
||||
rb.Push(ERR_NPAD_NOT_CONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
class HidDbg final : public ServiceFramework<HidDbg> {
|
||||
public:
|
||||
explicit HidDbg() : ServiceFramework{"hid:dbg"} {
|
||||
|
||||
@@ -119,6 +119,9 @@ private:
|
||||
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
|
||||
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
|
||||
void StartLrAssignmentMode(Kernel::HLERequestContext& ctx);
|
||||
void StopLrAssignmentMode(Kernel::HLERequestContext& ctx);
|
||||
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<IAppletResource> applet_resource;
|
||||
};
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
{19, nullptr, "Export"},
|
||||
{20, nullptr, "IsBrokenDatabaseWithClearFlag"},
|
||||
{21, &IDatabaseService::GetIndex, "GetIndex"},
|
||||
{22, nullptr, "SetInterfaceVersion"},
|
||||
{22, &IDatabaseService::SetInterfaceVersion, "SetInterfaceVersion"},
|
||||
{23, nullptr, "Convert"},
|
||||
};
|
||||
// clang-format on
|
||||
@@ -350,8 +350,22 @@ private:
|
||||
rb.Push(index);
|
||||
}
|
||||
|
||||
void SetInterfaceVersion(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
current_interface_version = rp.PopRaw<u32>();
|
||||
|
||||
LOG_DEBUG(Service_Mii, "called, interface_version={:08X}", current_interface_version);
|
||||
|
||||
UNIMPLEMENTED_IF(current_interface_version != 1);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
MiiManager db;
|
||||
|
||||
u32 current_interface_version = 0;
|
||||
|
||||
// Last read offsets of Get functions
|
||||
std::array<u32, 4> offsets{};
|
||||
};
|
||||
|
||||
@@ -23,7 +23,6 @@ constexpr ApplicationLanguagePriorityList priority_list_american_english = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_british_english = {{
|
||||
@@ -42,7 +41,6 @@ constexpr ApplicationLanguagePriorityList priority_list_british_english = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_japanese = {{
|
||||
@@ -61,7 +59,6 @@ constexpr ApplicationLanguagePriorityList priority_list_japanese = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_french = {{
|
||||
@@ -80,7 +77,6 @@ constexpr ApplicationLanguagePriorityList priority_list_french = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_german = {{
|
||||
@@ -99,7 +95,6 @@ constexpr ApplicationLanguagePriorityList priority_list_german = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_latin_american_spanish = {{
|
||||
@@ -118,7 +113,6 @@ constexpr ApplicationLanguagePriorityList priority_list_latin_american_spanish =
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_spanish = {{
|
||||
@@ -137,7 +131,6 @@ constexpr ApplicationLanguagePriorityList priority_list_spanish = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_italian = {{
|
||||
@@ -156,7 +149,6 @@ constexpr ApplicationLanguagePriorityList priority_list_italian = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_dutch = {{
|
||||
@@ -175,7 +167,6 @@ constexpr ApplicationLanguagePriorityList priority_list_dutch = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_canadian_french = {{
|
||||
@@ -194,7 +185,6 @@ constexpr ApplicationLanguagePriorityList priority_list_canadian_french = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_portuguese = {{
|
||||
@@ -213,7 +203,6 @@ constexpr ApplicationLanguagePriorityList priority_list_portuguese = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_russian = {{
|
||||
@@ -232,7 +221,6 @@ constexpr ApplicationLanguagePriorityList priority_list_russian = {{
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_korean = {{
|
||||
@@ -251,7 +239,6 @@ constexpr ApplicationLanguagePriorityList priority_list_korean = {{
|
||||
ApplicationLanguage::Japanese,
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_traditional_chinese = {{
|
||||
@@ -270,7 +257,6 @@ constexpr ApplicationLanguagePriorityList priority_list_traditional_chinese = {{
|
||||
ApplicationLanguage::Portuguese,
|
||||
ApplicationLanguage::Russian,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{
|
||||
@@ -289,28 +275,8 @@ constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{
|
||||
ApplicationLanguage::Portuguese,
|
||||
ApplicationLanguage::Russian,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Czech,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_czech = {{
|
||||
ApplicationLanguage::Czech,
|
||||
ApplicationLanguage::AmericanEnglish,
|
||||
ApplicationLanguage::BritishEnglish,
|
||||
ApplicationLanguage::LatinAmericanSpanish,
|
||||
ApplicationLanguage::CanadianFrench,
|
||||
ApplicationLanguage::French,
|
||||
ApplicationLanguage::German,
|
||||
ApplicationLanguage::Spanish,
|
||||
ApplicationLanguage::Italian,
|
||||
ApplicationLanguage::Dutch,
|
||||
ApplicationLanguage::Portuguese,
|
||||
ApplicationLanguage::Russian,
|
||||
ApplicationLanguage::Japanese,
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
}};
|
||||
|
||||
const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
|
||||
const ApplicationLanguage lang) {
|
||||
switch (lang) {
|
||||
@@ -344,8 +310,6 @@ const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
|
||||
return &priority_list_traditional_chinese;
|
||||
case ApplicationLanguage::SimplifiedChinese:
|
||||
return &priority_list_simplified_chinese;
|
||||
case ApplicationLanguage::Czech:
|
||||
return &priority_list_czech;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
@@ -384,8 +348,6 @@ std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
|
||||
return ApplicationLanguage::TraditionalChinese;
|
||||
case Set::LanguageCode::ZH_HANS:
|
||||
return ApplicationLanguage::SimplifiedChinese;
|
||||
case Set::LanguageCode::CZ:
|
||||
return ApplicationLanguage::Czech;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -423,10 +385,8 @@ std::optional<Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage
|
||||
return Set::LanguageCode::ZH_HANT;
|
||||
case ApplicationLanguage::SimplifiedChinese:
|
||||
return Set::LanguageCode::ZH_HANS;
|
||||
case ApplicationLanguage::Czech:
|
||||
return Set::LanguageCode::CZ;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
} // namespace Service::NS
|
||||
} // namespace Service::NS
|
||||
@@ -30,7 +30,6 @@ enum class ApplicationLanguage : u8 {
|
||||
Korean,
|
||||
TraditionalChinese,
|
||||
SimplifiedChinese,
|
||||
Czech,
|
||||
Count
|
||||
};
|
||||
using ApplicationLanguagePriorityList =
|
||||
@@ -43,4 +42,4 @@ constexpr u32 GetSupportedLanguageFlag(const ApplicationLanguage lang) {
|
||||
const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(ApplicationLanguage lang);
|
||||
std::optional<ApplicationLanguage> ConvertToApplicationLanguage(Set::LanguageCode language_code);
|
||||
std::optional<Set::LanguageCode> ConvertToLanguageCode(ApplicationLanguage lang);
|
||||
} // namespace Service::NS
|
||||
} // namespace Service::NS
|
||||
@@ -26,7 +26,6 @@ enum class ApplicationLanguage : u8 {
|
||||
Korean,
|
||||
TraditionalChinese,
|
||||
SimplifiedChinese,
|
||||
Czech,
|
||||
Count
|
||||
};
|
||||
using ApplicationLanguagePriorityList =
|
||||
@@ -40,4 +39,4 @@ const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(Applic
|
||||
std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
|
||||
Service::Set::LanguageCode language_code);
|
||||
std::optional<Service::Set::LanguageCode> ConvertToLanguageCode(ApplicationLanguage lang);
|
||||
} // namespace Service::NS
|
||||
} // namespace Service::NS
|
||||
@@ -3,11 +3,44 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/service/pm/pm.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::PM {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr ResultCode ERROR_PROCESS_NOT_FOUND{ErrorModule::PM, 1};
|
||||
|
||||
constexpr u64 NO_PROCESS_FOUND_PID{0};
|
||||
|
||||
std::optional<Kernel::SharedPtr<Kernel::Process>> SearchProcessList(
|
||||
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list,
|
||||
std::function<bool(const Kernel::SharedPtr<Kernel::Process>&)> predicate) {
|
||||
const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate);
|
||||
|
||||
if (iter == process_list.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return *iter;
|
||||
}
|
||||
|
||||
void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
|
||||
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list) {
|
||||
const auto process = SearchProcessList(process_list, [](const auto& process) {
|
||||
return process->GetProcessID() == Kernel::Process::ProcessIDMin;
|
||||
});
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(process.has_value() ? (*process)->GetProcessID() : NO_PROCESS_FOUND_PID);
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
class BootMode final : public ServiceFramework<BootMode> {
|
||||
public:
|
||||
explicit BootMode() : ServiceFramework{"pm:bm"} {
|
||||
@@ -41,14 +74,15 @@ private:
|
||||
|
||||
class DebugMonitor final : public ServiceFramework<DebugMonitor> {
|
||||
public:
|
||||
explicit DebugMonitor() : ServiceFramework{"pm:dmnt"} {
|
||||
explicit DebugMonitor(const Kernel::KernelCore& kernel)
|
||||
: ServiceFramework{"pm:dmnt"}, kernel(kernel) {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetDebugProcesses"},
|
||||
{1, nullptr, "StartDebugProcess"},
|
||||
{2, nullptr, "GetTitlePid"},
|
||||
{2, &DebugMonitor::GetTitlePid, "GetTitlePid"},
|
||||
{3, nullptr, "EnableDebugForTitleId"},
|
||||
{4, nullptr, "GetApplicationPid"},
|
||||
{4, &DebugMonitor::GetApplicationPid, "GetApplicationPid"},
|
||||
{5, nullptr, "EnableDebugForApplication"},
|
||||
{6, nullptr, "DisableDebug"},
|
||||
};
|
||||
@@ -56,21 +90,77 @@ public:
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetTitlePid(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto title_id = rp.PopRaw<u64>();
|
||||
|
||||
LOG_DEBUG(Service_PM, "called, title_id={:016X}", title_id);
|
||||
|
||||
const auto process =
|
||||
SearchProcessList(kernel.GetProcessList(), [title_id](const auto& process) {
|
||||
return process->GetTitleID() == title_id;
|
||||
});
|
||||
|
||||
if (!process.has_value()) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERROR_PROCESS_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push((*process)->GetProcessID());
|
||||
}
|
||||
|
||||
void GetApplicationPid(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_PM, "called");
|
||||
GetApplicationPidGeneric(ctx, kernel.GetProcessList());
|
||||
}
|
||||
|
||||
const Kernel::KernelCore& kernel;
|
||||
};
|
||||
|
||||
class Info final : public ServiceFramework<Info> {
|
||||
public:
|
||||
explicit Info() : ServiceFramework{"pm:info"} {
|
||||
explicit Info(const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list)
|
||||
: ServiceFramework{"pm:info"}, process_list(process_list) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetTitleId"},
|
||||
{0, &Info::GetTitleId, "GetTitleId"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetTitleId(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto process_id = rp.PopRaw<u64>();
|
||||
|
||||
LOG_DEBUG(Service_PM, "called, process_id={:016X}", process_id);
|
||||
|
||||
const auto process = SearchProcessList(process_list, [process_id](const auto& process) {
|
||||
return process->GetProcessID() == process_id;
|
||||
});
|
||||
|
||||
if (!process.has_value()) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERROR_PROCESS_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push((*process)->GetTitleID());
|
||||
}
|
||||
|
||||
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list;
|
||||
};
|
||||
|
||||
class Shell final : public ServiceFramework<Shell> {
|
||||
public:
|
||||
explicit Shell() : ServiceFramework{"pm:shell"} {
|
||||
explicit Shell(const Kernel::KernelCore& kernel)
|
||||
: ServiceFramework{"pm:shell"}, kernel(kernel) {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "LaunchProcess"},
|
||||
@@ -79,21 +169,31 @@ public:
|
||||
{3, nullptr, "GetProcessEventWaiter"},
|
||||
{4, nullptr, "GetProcessEventType"},
|
||||
{5, nullptr, "NotifyBootFinished"},
|
||||
{6, nullptr, "GetApplicationPid"},
|
||||
{6, &Shell::GetApplicationPid, "GetApplicationPid"},
|
||||
{7, nullptr, "BoostSystemMemoryResourceLimit"},
|
||||
{8, nullptr, "EnableAdditionalSystemThreads"},
|
||||
{9, nullptr, "GetUnimplementedEventHandle"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetApplicationPid(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_PM, "called");
|
||||
GetApplicationPidGeneric(ctx, kernel.GetProcessList());
|
||||
}
|
||||
|
||||
const Kernel::KernelCore& kernel;
|
||||
};
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& sm) {
|
||||
std::make_shared<BootMode>()->InstallAsService(sm);
|
||||
std::make_shared<DebugMonitor>()->InstallAsService(sm);
|
||||
std::make_shared<Info>()->InstallAsService(sm);
|
||||
std::make_shared<Shell>()->InstallAsService(sm);
|
||||
void InstallInterfaces(Core::System& system) {
|
||||
std::make_shared<BootMode>()->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<DebugMonitor>(system.Kernel())->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<Info>(system.Kernel().GetProcessList())
|
||||
->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<Shell>(system.Kernel())->InstallAsService(system.ServiceManager());
|
||||
}
|
||||
|
||||
} // namespace Service::PM
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Service::SM {
|
||||
class ServiceManager;
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::PM {
|
||||
@@ -16,6 +16,6 @@ enum class SystemBootMode {
|
||||
};
|
||||
|
||||
/// Registers all PM services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
void InstallInterfaces(Core::System& system);
|
||||
|
||||
} // namespace Service::PM
|
||||
|
||||
@@ -195,8 +195,7 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
|
||||
// Module interface
|
||||
|
||||
/// Initialize ServiceManager
|
||||
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
|
||||
FileSys::VfsFilesystem& vfs) {
|
||||
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) {
|
||||
// NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
|
||||
// here and pass it into the respective InstallInterfaces functions.
|
||||
auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system.CoreTiming());
|
||||
@@ -206,7 +205,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
|
||||
Account::InstallInterfaces(system);
|
||||
AM::InstallInterfaces(*sm, nv_flinger, system);
|
||||
AOC::InstallInterfaces(*sm);
|
||||
APM::InstallInterfaces(*sm);
|
||||
APM::InstallInterfaces(system);
|
||||
Audio::InstallInterfaces(*sm);
|
||||
BCAT::InstallInterfaces(*sm);
|
||||
BPC::InstallInterfaces(*sm);
|
||||
@@ -218,7 +217,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
|
||||
EUPLD::InstallInterfaces(*sm);
|
||||
Fatal::InstallInterfaces(*sm);
|
||||
FGM::InstallInterfaces(*sm);
|
||||
FileSystem::InstallInterfaces(*sm, vfs);
|
||||
FileSystem::InstallInterfaces(system);
|
||||
Friend::InstallInterfaces(*sm);
|
||||
Glue::InstallInterfaces(system);
|
||||
GRC::InstallInterfaces(*sm);
|
||||
@@ -242,7 +241,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
|
||||
PCTL::InstallInterfaces(*sm);
|
||||
PCV::InstallInterfaces(*sm);
|
||||
PlayReport::InstallInterfaces(*sm);
|
||||
PM::InstallInterfaces(*sm);
|
||||
PM::InstallInterfaces(system);
|
||||
PSC::InstallInterfaces(*sm);
|
||||
PSM::InstallInterfaces(*sm);
|
||||
Set::InstallInterfaces(*sm);
|
||||
|
||||
@@ -182,8 +182,7 @@ private:
|
||||
};
|
||||
|
||||
/// Initialize ServiceManager
|
||||
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
|
||||
FileSys::VfsFilesystem& vfs);
|
||||
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system);
|
||||
|
||||
/// Shutdown ServiceManager
|
||||
void Shutdown();
|
||||
|
||||
@@ -29,7 +29,6 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{
|
||||
LanguageCode::ES_419,
|
||||
LanguageCode::ZH_HANS,
|
||||
LanguageCode::ZH_HANT,
|
||||
LanguageCode::CZ,
|
||||
}};
|
||||
|
||||
constexpr std::size_t pre4_0_0_max_entries = 15;
|
||||
|
||||
@@ -27,7 +27,6 @@ enum class LanguageCode : u64 {
|
||||
ES_419 = 0x00003931342D7365,
|
||||
ZH_HANS = 0x00736E61482D687A,
|
||||
ZH_HANT = 0x00746E61482D687A,
|
||||
CZ = 0x0000000000007a63,
|
||||
};
|
||||
LanguageCode GetLanguageCodeFromIndex(std::size_t idx);
|
||||
|
||||
|
||||
@@ -350,6 +350,24 @@ void Reporter::SaveErrorReport(u64 title_id, ResultCode result,
|
||||
SaveToFile(std::move(out), GetPath("error_report", title_id, timestamp));
|
||||
}
|
||||
|
||||
void Reporter::SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode,
|
||||
std::string log_message) const {
|
||||
if (!IsReportingEnabled())
|
||||
return;
|
||||
|
||||
const auto timestamp = GetTimestamp();
|
||||
const auto title_id = system.CurrentProcess()->GetTitleID();
|
||||
json out;
|
||||
|
||||
out["yuzu_version"] = GetYuzuVersionData();
|
||||
out["report_common"] = GetReportCommonData(title_id, RESULT_SUCCESS, timestamp);
|
||||
|
||||
out["log_mode"] = fmt::format("{:08X}", static_cast<u32>(log_mode));
|
||||
out["log_message"] = std::move(log_message);
|
||||
|
||||
SaveToFile(std::move(out), GetPath("filesystem_access_report", title_id, timestamp));
|
||||
}
|
||||
|
||||
void Reporter::SaveUserReport() const {
|
||||
if (!IsReportingEnabled()) {
|
||||
return;
|
||||
|
||||
@@ -16,6 +16,10 @@ namespace Kernel {
|
||||
class HLERequestContext;
|
||||
} // namespace Kernel
|
||||
|
||||
namespace Service::FileSystem {
|
||||
enum class LogMode : u32;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
|
||||
class System;
|
||||
@@ -49,6 +53,9 @@ public:
|
||||
std::optional<std::string> custom_text_main = {},
|
||||
std::optional<std::string> custom_text_detail = {}) const;
|
||||
|
||||
void SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode,
|
||||
std::string log_message) const;
|
||||
|
||||
void SaveUserReport() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -98,17 +98,19 @@ private:
|
||||
|
||||
/**
|
||||
* Configures the color and depth framebuffer states.
|
||||
* @param must_reconfigure If true, tells the framebuffer to skip the cache and reconfigure
|
||||
* again. Used by the texture cache to solve texception conflicts
|
||||
* @param use_color_fb If true, configure color framebuffers.
|
||||
* @param using_depth_fb If true, configure the depth/stencil framebuffer.
|
||||
* @param preserve_contents If true, tries to preserve data from a previously used framebuffer.
|
||||
*
|
||||
* @param current_state The current OpenGL state.
|
||||
* @param using_color_fb If true, configure color framebuffers.
|
||||
* @param using_depth_fb If true, configure the depth/stencil framebuffer.
|
||||
* @param preserve_contents If true, tries to preserve data from a previously used
|
||||
* framebuffer.
|
||||
* @param single_color_target Specifies if a single color buffer target should be used.
|
||||
*
|
||||
* @returns If depth (first) or stencil (second) are being stored in the bound zeta texture
|
||||
* (requires using_depth_fb to be true)
|
||||
* (requires using_depth_fb to be true)
|
||||
*/
|
||||
std::pair<bool, bool> ConfigureFramebuffers(
|
||||
OpenGLState& current_state, bool use_color_fb = true, bool using_depth_fb = true,
|
||||
OpenGLState& current_state, bool using_color_fb = true, bool using_depth_fb = true,
|
||||
bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
|
||||
|
||||
/// Configures the current constbuffers to use for the draw command.
|
||||
|
||||
@@ -17,9 +17,9 @@ public:
|
||||
~SamplerCacheOpenGL();
|
||||
|
||||
protected:
|
||||
OGLSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const;
|
||||
OGLSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const override;
|
||||
|
||||
GLuint ToSamplerType(const OGLSampler& sampler) const;
|
||||
GLuint ToSamplerType(const OGLSampler& sampler) const override;
|
||||
};
|
||||
|
||||
} // namespace OpenGL
|
||||
|
||||
@@ -109,8 +109,8 @@ void VKBufferCache::Reserve(std::size_t max_size) {
|
||||
}
|
||||
}
|
||||
|
||||
VKExecutionContext VKBufferCache::Send(VKExecutionContext exctx) {
|
||||
return stream_buffer->Send(exctx, buffer_offset - buffer_offset_base);
|
||||
void VKBufferCache::Send() {
|
||||
stream_buffer->Send(buffer_offset - buffer_offset_base);
|
||||
}
|
||||
|
||||
void VKBufferCache::AlignBuffer(std::size_t alignment) {
|
||||
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
void Reserve(std::size_t max_size);
|
||||
|
||||
/// Ensures that the set data is sent to the device.
|
||||
[[nodiscard]] VKExecutionContext Send(VKExecutionContext exctx);
|
||||
void Send();
|
||||
|
||||
/// Returns the buffer cache handle.
|
||||
vk::Buffer GetBuffer() const {
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/renderer_vulkan/declarations.h"
|
||||
#include "video_core/sampler_cache.h"
|
||||
#include "video_core/textures/texture.h"
|
||||
@@ -21,9 +18,9 @@ public:
|
||||
~VKSamplerCache();
|
||||
|
||||
protected:
|
||||
UniqueSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const;
|
||||
UniqueSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const override;
|
||||
|
||||
vk::Sampler ToSamplerType(const UniqueSampler& sampler) const;
|
||||
vk::Sampler ToSamplerType(const UniqueSampler& sampler) const override;
|
||||
|
||||
private:
|
||||
const VKDevice& device;
|
||||
|
||||
@@ -19,23 +19,19 @@ VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_man
|
||||
|
||||
VKScheduler::~VKScheduler() = default;
|
||||
|
||||
VKExecutionContext VKScheduler::GetExecutionContext() const {
|
||||
return VKExecutionContext(current_fence, current_cmdbuf);
|
||||
}
|
||||
|
||||
VKExecutionContext VKScheduler::Flush(vk::Semaphore semaphore) {
|
||||
void VKScheduler::Flush(bool release_fence, vk::Semaphore semaphore) {
|
||||
SubmitExecution(semaphore);
|
||||
current_fence->Release();
|
||||
if (release_fence)
|
||||
current_fence->Release();
|
||||
AllocateNewContext();
|
||||
return GetExecutionContext();
|
||||
}
|
||||
|
||||
VKExecutionContext VKScheduler::Finish(vk::Semaphore semaphore) {
|
||||
void VKScheduler::Finish(bool release_fence, vk::Semaphore semaphore) {
|
||||
SubmitExecution(semaphore);
|
||||
current_fence->Wait();
|
||||
current_fence->Release();
|
||||
if (release_fence)
|
||||
current_fence->Release();
|
||||
AllocateNewContext();
|
||||
return GetExecutionContext();
|
||||
}
|
||||
|
||||
void VKScheduler::SubmitExecution(vk::Semaphore semaphore) {
|
||||
|
||||
@@ -10,10 +10,43 @@
|
||||
namespace Vulkan {
|
||||
|
||||
class VKDevice;
|
||||
class VKExecutionContext;
|
||||
class VKFence;
|
||||
class VKResourceManager;
|
||||
|
||||
class VKFenceView {
|
||||
public:
|
||||
VKFenceView() = default;
|
||||
VKFenceView(VKFence* const& fence) : fence{fence} {}
|
||||
|
||||
VKFence* operator->() const noexcept {
|
||||
return fence;
|
||||
}
|
||||
|
||||
operator VKFence&() const noexcept {
|
||||
return *fence;
|
||||
}
|
||||
|
||||
private:
|
||||
VKFence* const& fence;
|
||||
};
|
||||
|
||||
class VKCommandBufferView {
|
||||
public:
|
||||
VKCommandBufferView() = default;
|
||||
VKCommandBufferView(const vk::CommandBuffer& cmdbuf) : cmdbuf{cmdbuf} {}
|
||||
|
||||
const vk::CommandBuffer* operator->() const noexcept {
|
||||
return &cmdbuf;
|
||||
}
|
||||
|
||||
operator vk::CommandBuffer() const noexcept {
|
||||
return cmdbuf;
|
||||
}
|
||||
|
||||
private:
|
||||
const vk::CommandBuffer& cmdbuf;
|
||||
};
|
||||
|
||||
/// The scheduler abstracts command buffer and fence management with an interface that's able to do
|
||||
/// OpenGL-like operations on Vulkan command buffers.
|
||||
class VKScheduler {
|
||||
@@ -21,16 +54,21 @@ public:
|
||||
explicit VKScheduler(const VKDevice& device, VKResourceManager& resource_manager);
|
||||
~VKScheduler();
|
||||
|
||||
/// Gets the current execution context.
|
||||
[[nodiscard]] VKExecutionContext GetExecutionContext() const;
|
||||
/// Gets a reference to the current fence.
|
||||
VKFenceView GetFence() const {
|
||||
return current_fence;
|
||||
}
|
||||
|
||||
/// Sends the current execution context to the GPU. It invalidates the current execution context
|
||||
/// and returns a new one.
|
||||
VKExecutionContext Flush(vk::Semaphore semaphore = nullptr);
|
||||
/// Gets a reference to the current command buffer.
|
||||
VKCommandBufferView GetCommandBuffer() const {
|
||||
return current_cmdbuf;
|
||||
}
|
||||
|
||||
/// Sends the current execution context to the GPU and waits for it to complete. It invalidates
|
||||
/// the current execution context and returns a new one.
|
||||
VKExecutionContext Finish(vk::Semaphore semaphore = nullptr);
|
||||
/// Sends the current execution context to the GPU.
|
||||
void Flush(bool release_fence = true, vk::Semaphore semaphore = nullptr);
|
||||
|
||||
/// Sends the current execution context to the GPU and waits for it to complete.
|
||||
void Finish(bool release_fence = true, vk::Semaphore semaphore = nullptr);
|
||||
|
||||
private:
|
||||
void SubmitExecution(vk::Semaphore semaphore);
|
||||
@@ -44,26 +82,4 @@ private:
|
||||
VKFence* next_fence = nullptr;
|
||||
};
|
||||
|
||||
class VKExecutionContext {
|
||||
friend class VKScheduler;
|
||||
|
||||
public:
|
||||
VKExecutionContext() = default;
|
||||
|
||||
VKFence& GetFence() const {
|
||||
return *fence;
|
||||
}
|
||||
|
||||
vk::CommandBuffer GetCommandBuffer() const {
|
||||
return cmdbuf;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit VKExecutionContext(VKFence* fence, vk::CommandBuffer cmdbuf)
|
||||
: fence{fence}, cmdbuf{cmdbuf} {}
|
||||
|
||||
VKFence* fence{};
|
||||
vk::CommandBuffer cmdbuf;
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -46,12 +46,12 @@ std::tuple<u8*, u64, bool> VKStreamBuffer::Reserve(u64 size) {
|
||||
return {mapped_pointer + offset, offset, invalidation_mark.has_value()};
|
||||
}
|
||||
|
||||
VKExecutionContext VKStreamBuffer::Send(VKExecutionContext exctx, u64 size) {
|
||||
void VKStreamBuffer::Send(u64 size) {
|
||||
ASSERT_MSG(size <= mapped_size, "Reserved size is too small");
|
||||
|
||||
if (invalidation_mark) {
|
||||
// TODO(Rodrigo): Find a better way to invalidate than waiting for all watches to finish.
|
||||
exctx = scheduler.Flush();
|
||||
scheduler.Flush();
|
||||
std::for_each(watches.begin(), watches.begin() + *invalidation_mark,
|
||||
[&](auto& resource) { resource->Wait(); });
|
||||
invalidation_mark = std::nullopt;
|
||||
@@ -62,11 +62,9 @@ VKExecutionContext VKStreamBuffer::Send(VKExecutionContext exctx, u64 size) {
|
||||
ReserveWatches(WATCHES_RESERVE_CHUNK);
|
||||
}
|
||||
// Add a watch for this allocation.
|
||||
watches[used_watches++]->Watch(exctx.GetFence());
|
||||
watches[used_watches++]->Watch(scheduler.GetFence());
|
||||
|
||||
offset += size;
|
||||
|
||||
return exctx;
|
||||
}
|
||||
|
||||
void VKStreamBuffer::CreateBuffers(VKMemoryManager& memory_manager, vk::BufferUsageFlags usage) {
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
std::tuple<u8*, u64, bool> Reserve(u64 size);
|
||||
|
||||
/// Ensures that "size" bytes of memory are available to the GPU, potentially recording a copy.
|
||||
[[nodiscard]] VKExecutionContext Send(VKExecutionContext exctx, u64 size);
|
||||
void Send(u64 size);
|
||||
|
||||
vk::Buffer GetBuffer() const {
|
||||
return *buffer;
|
||||
|
||||
@@ -126,11 +126,6 @@
|
||||
<string>Traditional Chinese (正體中文)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Czech (Čeština)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
|
||||
@@ -204,7 +204,7 @@ username = yuzu
|
||||
# Sets the systems language index
|
||||
# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
|
||||
# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
|
||||
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Czech
|
||||
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese
|
||||
language_index =
|
||||
|
||||
# The system region that yuzu will use during emulation
|
||||
|
||||
@@ -109,7 +109,7 @@ username = yuzu
|
||||
# Sets the systems language index
|
||||
# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
|
||||
# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
|
||||
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Czech
|
||||
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese
|
||||
language_index =
|
||||
|
||||
# The system region that yuzu will use during emulation
|
||||
|
||||
Reference in New Issue
Block a user