Compare commits

..

2 Commits

Author SHA1 Message Date
Caio Oliveira
112b14b564 [chore] fix build errors
Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-12-17 21:46:22 -03:00
lizzie
754883db97 [core] pin core threads to logical CPUs 0-3
this basically allows the threads to exist in these logical CPUs, undisturbed, and without trashing each other's cache
this could improve performance, very tricky thing to pull off correctly, but again, this is mostly an experiment
will mainly benefit: Linux, Android, FreeBSD, Windows (not ARM)
Additionally, this means no context trashing :)

Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-12-17 21:23:30 -03:00
52 changed files with 757 additions and 916 deletions

View File

@@ -5,9 +5,11 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <string>
#include <thread>
#include "common/error.h"
#include "common/logging/log.h"
#include "common/assert.h"
#include "common/thread.h"
#ifdef __APPLE__
#include <mach/mach.h>
@@ -18,6 +20,8 @@
#include "common/string_util.h"
#else
#if defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include <sys/cpuset.h>
#include <sys/_cpuset.h>
#include <pthread_np.h>
#endif
#include <pthread.h>
@@ -28,7 +32,7 @@
#endif
#ifdef __FreeBSD__
#define cpu_set_t cpuset_t
# define cpu_set_t cpuset_t
#endif
namespace Common {
@@ -77,22 +81,14 @@ void SetCurrentThreadPriority(ThreadPriority new_priority) {
#endif
}
void SetCurrentThreadName(const char* name) {
#ifdef _MSC_VER
// Sets the debugger-visible name of the current thread.
void SetCurrentThreadName(const char* name) {
static auto pf = (decltype(&SetThreadDescription))(void*)GetProcAddress(GetModuleHandle(TEXT("KernelBase.dll")), "SetThreadDescription");
if (pf)
// Sets the debugger-visible name of the current thread.
if (auto pf = (decltype(&SetThreadDescription))(void*)GetProcAddress(GetModuleHandle(TEXT("KernelBase.dll")), "SetThreadDescription"); pf)
pf(GetCurrentThread(), UTF8ToUTF16W(name).data()); // Windows 10+
}
#else // !MSVC_VER, so must be POSIX threads
// MinGW with the POSIX threading model does not support pthread_setname_np
void SetCurrentThreadName(const char* name) {
// See for reference
// https://gitlab.freedesktop.org/mesa/mesa/-/blame/main/src/util/u_thread.c?ref_type=heads#L75
#ifdef __APPLE__
else
; // No-op
#elif defined(__APPLE__)
pthread_setname_np(name);
#elif defined(__HAIKU__)
rename_thread(find_thread(NULL), name);
@@ -112,13 +108,33 @@ void SetCurrentThreadName(const char* name) {
pthread_setname_np(pthread_self(), buf);
}
#elif defined(_WIN32)
// mingw stub
// MinGW with the POSIX threading model does not support pthread_setname_np
// See for reference
// https://gitlab.freedesktop.org/mesa/mesa/-/blame/main/src/util/u_thread.c?ref_type=heads#L75
(void)name;
#else
pthread_setname_np(pthread_self(), name);
#endif
}
void PinCurrentThreadToPerformanceCore(size_t core_id) {
ASSERT(core_id < 4);
// If we set a flag for a CPU that doesn't exist, the thread may not be allowed to
// run in ANY processor!
auto const total_cores = std::thread::hardware_concurrency();
if (core_id < total_cores) {
#if defined(__linux__) || defined(__FreeBSD__)
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(core_id, &set);
pthread_setaffinity_np(pthread_self(), sizeof(set), &set);
#elif defined(_WIN32)
DWORD set = 1UL << core_id;
SetThreadAffinityMask(GetCurrentThread(), set);
#else
// No pin functionality implemented
#endif
}
}
} // namespace Common

View File

@@ -106,7 +106,7 @@ enum class ThreadPriority : u32 {
};
void SetCurrentThreadPriority(ThreadPriority new_priority);
void SetCurrentThreadName(const char* name);
void PinCurrentThreadToPerformanceCore(size_t core_id);
} // namespace Common

View File

@@ -7,6 +7,7 @@
#include "common/fiber.h"
#include "common/scope_exit.h"
#include "common/thread.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/cpu_manager.h"
@@ -25,11 +26,8 @@ CpuManager::~CpuManager() = default;
void CpuManager::Initialize() {
num_cores = is_multicore ? Core::Hardware::NUM_CPU_CORES : 1;
gpu_barrier = std::make_unique<Common::Barrier>(num_cores + 1);
for (std::size_t core = 0; core < num_cores; core++) {
core_data[core].host_thread =
std::jthread([this, core](std::stop_token token) { RunThread(token, core); });
}
for (std::size_t core = 0; core < num_cores; core++)
core_data[core].host_thread = std::jthread([this, core](std::stop_token token) { RunThread(token, core); });
}
void CpuManager::Shutdown() {
@@ -188,14 +186,10 @@ void CpuManager::ShutdownThread() {
void CpuManager::RunThread(std::stop_token token, std::size_t core) {
/// Initialization
system.RegisterCoreThread(core);
std::string name;
if (is_multicore) {
name = "CPUCore_" + std::to_string(core);
} else {
name = "CPUThread";
}
std::string name = is_multicore ? ("CPUCore_" + std::to_string(core)) : std::string{"CPUThread"};
Common::SetCurrentThreadName(name.c_str());
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
Common::PinCurrentThreadToPerformanceCore(core);
auto& data = core_data[core];
data.host_context = Common::Fiber::ThreadToFiber();

View File

@@ -12,7 +12,7 @@
#include "common/common_types.h"
#include "common/expected.h"
// All the constants in this file come from <http://switchbrew.org/index.php?title=Error_codes>
// All the constants in this file come from http://switchbrew.org/index.php?title=Error_codes
/**
* Identifies the module which caused the error. Error codes can be propagated through a call
@@ -87,7 +87,6 @@ enum class ErrorModule : u32 {
AM = 128,
PlayReport = 129,
AHID = 130,
APPLET = 131,
Qlaunch = 132,
PCV = 133,
USBPD = 134,
@@ -114,8 +113,8 @@ enum class ErrorModule : u32 {
NPNSHTTPSTREAM = 155,
IDLE = 156,
ARP = 157,
UPDATER = 158,
SWKBD = 159,
SWKBD = 158,
BOOT = 159,
NetDiag = 160,
NFCMifare = 161,
UserlandAssert = 162,
@@ -126,8 +125,7 @@ enum class ErrorModule : u32 {
BGTC = 167,
UserlandCrash = 168,
SASBUS = 169,
PL = 170,
CDMSC = 171,
PI = 170,
AudioCtrl = 172,
LBL = 173,
JIT = 175,
@@ -139,30 +137,23 @@ enum class ErrorModule : u32 {
Dauth = 181,
STDFU = 182,
DBG = 183,
CDACM = 184,
TCAP = 185,
DHCPS = 186,
SPI = 187,
AVM = 188,
PWM = 189,
DNSServer = 190,
RTC = 191,
Regulator = 192,
LED = 193,
HTCTool = 194,
SIO = 195,
PCM = 196,
CLKRST = 197,
POWCTL = 198,
HIDDriver = 199,
DMA = 200,
AudioOld = 201,
HID = 202,
LDN = 203,
CS = 204,
Irsensor = 205,
Capture = 206,
MM = 207,
Manu = 208,
ATK = 209,
WEB = 210,
@@ -175,24 +166,19 @@ enum class ErrorModule : u32 {
MigrationLdcServ = 217,
HIDBUS = 218,
ENS = 219,
ND = 220,
NDD = 221,
ToyCon = 222,
WebSocket = 223,
SocketIO = 224,
DCDMTP = 227,
PGL = 228,
Notification = 229,
INS = 230,
LP2P = 231,
RCD = 232,
ICM40607 = 233,
LCM40607 = 233,
PRC = 235,
BridgeCtrl = 237,
ErrContext = 238,
TMAHTC = 237,
ECTX = 238,
MNPP = 239,
HSHL = 240,
RINGCON = 241,
CAPMTP = 242,
DP2HDMI = 244,
Cradle = 245,
@@ -200,8 +186,6 @@ enum class ErrorModule : u32 {
Icm42607p = 248,
NDRM = 250,
Fst2 = 251,
TS = 253,
SPLAY = 260,
Nex = 306,
NPLN = 321,
TSPM = 499,

View File

@@ -88,13 +88,13 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_
{181, nullptr, "UpgradeLaunchRequiredVersion"},
{190, nullptr, "SendServerMaintenanceOverlayNotification"},
{200, nullptr, "GetLastApplicationExitReason"},
{210, D<&IApplicationFunctions::GetLaunchRequiredVersionUpgrade>, "GetLaunchRequiredVersionUpgrade"}, //20.0.0+
{211, nullptr, "GetLaunchRequiredVersionUpgradeStatus"}, //20.0.0+
{220, nullptr, "Unknown220"}, //20.0.0+
{300, nullptr, "CreateMovieWriter"}, //20.0.0+
{310, nullptr, "Unknown310"}, //20.0.0+
{320, nullptr, "Unknown320"}, //20.0.0+
{330, nullptr, "Unknown330"}, //20.0.0+
{210, D<&IApplicationFunctions::GetLaunchRequiredVersionUpgrade>, "GetLaunchRequiredVersionUpgrade"}, // [20.0.0+]
{211, nullptr, "GetLaunchRequiredVersionUpgradeStatus"}, // [20.0.0+]
{220, nullptr, "Unknown220"}, // [20.0.0+]
{300, nullptr, "Unknown300"}, // [20.0.0+]
{310, nullptr, "Unknown310"}, // [20.0.0+]
{320, nullptr, "Unknown320"}, // [20.0.0+]
{330, nullptr, "Unknown330"}, // [20.0.0+]
{500, nullptr, "StartContinuousRecordingFlushForDebug"},
{1000, nullptr, "CreateMovieMaker"},
{1001, D<&IApplicationFunctions::PrepareForJit>, "PrepareForJit"},

View File

@@ -18,7 +18,7 @@ IAudioController::IAudioController(Core::System& system_)
{2, D<&IAudioController::GetLibraryAppletExpectedMasterVolume>, "GetLibraryAppletExpectedMasterVolume"},
{3, D<&IAudioController::ChangeMainAppletMasterVolume>, "ChangeMainAppletMasterVolume"},
{4, D<&IAudioController::SetTransparentVolumeRate>, "SetTransparentVolumeRate"},
{5, nullptr, "Unknown5"}, //20.0.0+
{5, nullptr, "Unknown5"},
};
// clang-format on

View File

@@ -30,7 +30,7 @@ IAudioController::IAudioController(Core::System& system_)
{3, D<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"},
{4, D<&IAudioController::IsTargetMute>, "IsTargetMute"},
{5, D<&IAudioController::SetTargetMute>, "SetTargetMute"},
{6, nullptr, "IsTargetConnected"}, //20.0.0+
{6, nullptr, "IsTargetConnected"},
{7, nullptr, "SetDefaultTarget"},
{8, nullptr, "GetDefaultTarget"},
{9, D<&IAudioController::GetAudioOutputMode>, "GetAudioOutputMode"},
@@ -67,8 +67,7 @@ IAudioController::IAudioController(Core::System& system_)
{40, nullptr, "GetSystemInformationForDebug"},
{41, nullptr, "SetVolumeButtonLongPressTime"},
{42, nullptr, "SetNativeVolumeForDebug"},
{43, nullptr, "Unknown43"}, //21.0.0+
{5000, D<&IAudioController::Unknown5000>, "Unknown5000"}, //19.0.0+
{5000, D<&IAudioController::Unknown5000>, "Unknown5000"},
{10000, nullptr, "NotifyAudioOutputTargetForPlayReport"},
{10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"},
{10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"},
@@ -77,13 +76,13 @@ IAudioController::IAudioController(Core::System& system_)
{10102, nullptr, "BindAudioOutputTargetUpdateEventForPlayReport"},
{10103, nullptr, "GetAudioOutputTargetForPlayReport"},
{10104, nullptr, "GetAudioOutputChannelCountForPlayReport"},
{10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, //14.0.0-19.0.1
{10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"}, //14.0.0-19.0.1
{10200, nullptr, "Unknown10200"}, //20.0.0+
{50000, nullptr, "SetAnalogInputBoostGainForPrototyping"}, //15.0.0-18.1.0
{50001, nullptr, "OverrideDefaultTargetForDebug"}, //19.0.0-19.0.1
{50003, nullptr, "SetForceOverrideExternalDeviceNameForDebug"}, //19.0.0+
{50004, nullptr, "ClearForceOverrideExternalDeviceNameForDebug"} //19.0.0+
{10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
{10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"},
{10200, nullptr, "Unknown10200"}, // [20.0.0+]
{50000, nullptr, "SetAnalogInputBoostGainForPrototyping"},
{50001, nullptr, "OverrideDefaultTargetForDebug"},
{50003, nullptr, "SetForceOverrideExternalDeviceNameForDebug"},
{50004, nullptr, "ClearForceOverrideExternalDeviceNameForDebug"}
};
// clang-format on

View File

@@ -32,13 +32,13 @@ IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u
{12, D<&IAudioDevice::QueryAudioDeviceOutputEvent>, "QueryAudioDeviceOutputEvent"},
{13, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioOutputDeviceName"},
{14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"},
{15, nullptr, "AcquireAudioInputDeviceNotification"}, //17.0.0+
{16, nullptr, "ReleaseAudioInputDeviceNotification"}, //17.0.0+
{17, nullptr, "AcquireAudioOutputDeviceNotification"}, //17.0.0+
{18, nullptr, "ReleaseAudioOutputDeviceNotification"}, //17.0.0+
{19, nullptr, "SetAudioDeviceOutputVolumeAutoTuneEnabled"}, //18.0.0+
{20, nullptr, "IsAudioDeviceOutputVolumeAutoTuneEnabled"}, //18.0.0+
{21, nullptr, "IsActiveOutputDeviceEstimatedLowLatency"} //21.0.0+
{15, nullptr, "AcquireAudioInputDeviceNotification"}, // 17.0.0+
{16, nullptr, "ReleaseAudioInputDeviceNotification"}, // 17.0.0+
{17, nullptr, "AcquireAudioOutputDeviceNotification"}, // 17.0.0+
{18, nullptr, "ReleaseAudioOutputDeviceNotification"}, // 17.0.0+
{19, nullptr, "SetAudioDeviceOutputVolumeAutoTuneEnabled"}, // 18.0.0+
{20, nullptr, "IsAudioDeviceOutputVolumeAutoTuneEnabled"}, // 18.0.0+
{21, nullptr, "IsActiveOutputDeviceEstimatedLowLatency"} // 21.0.0+
};
RegisterHandlers(functions);

View File

@@ -43,21 +43,21 @@ IBcatService::IBcatService(Core::System& system_, BcatBackend& backend_)
{20401, nullptr, "UnregisterSystemApplicationDeliveryTask"},
{20410, nullptr, "SetSystemApplicationDeliveryTaskTimer"},
{30100, D<&IBcatService::SetPassphrase>, "SetPassphrase"},
{30101, nullptr, "Unknown30101"}, //2.0.0-2.3.0
{30102, nullptr, "Unknown30102"}, //2.0.0-2.3.0
{30101, nullptr, "Unknown30101"},
{30102, nullptr, "Unknown30102"},
{30200, nullptr, "RegisterBackgroundDeliveryTask"},
{30201, nullptr, "UnregisterBackgroundDeliveryTask"},
{30202, nullptr, "BlockDeliveryTask"},
{30203, nullptr, "UnblockDeliveryTask"},
{30210, nullptr, "SetDeliveryTaskTimer"},
{30300, D<&IBcatService::RegisterSystemApplicationDeliveryTasks>, "RegisterSystemApplicationDeliveryTasks"},
{90100, nullptr, "GetDeliveryTaskList"},
{90101, nullptr, "GetDeliveryTaskListForSystem"}, //11.0.0+
{90100, nullptr, "EnumerateBackgroundDeliveryTask"},
{90101, nullptr, "Unknown90101"},
{90200, nullptr, "GetDeliveryList"},
{90201, D<&IBcatService::ClearDeliveryCacheStorage>, "ClearDeliveryCacheStorage"},
{90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"},
{90300, nullptr, "GetPushNotificationLog"},
{90301, nullptr, "GetDeliveryCacheStorageUsage"}, //11.0.0+
{90301, nullptr, "Unknown90301"},
};
// clang-format on
RegisterHandlers(functions);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -15,19 +12,19 @@ INewsService::INewsService(Core::System& system_) : ServiceFramework{system_, "I
{10100, D<&INewsService::PostLocalNews>, "PostLocalNews"},
{20100, nullptr, "SetPassphrase"},
{30100, D<&INewsService::GetSubscriptionStatus>, "GetSubscriptionStatus"},
{30101, nullptr, "GetTopicList"}, //3.0.0+
{30110, nullptr, "Unknown30110"}, //6.0.0+
{30101, nullptr, "GetTopicList"},
{30110, nullptr, "Unknown30110"},
{30200, D<&INewsService::IsSystemUpdateRequired>, "IsSystemUpdateRequired"},
{30201, nullptr, "Unknown30201"}, //8.0.0+
{30210, nullptr, "Unknown30210"}, //10.0.0+
{30201, nullptr, "Unknown30201"},
{30210, nullptr, "Unknown30210"},
{30300, nullptr, "RequestImmediateReception"},
{30400, nullptr, "DecodeArchiveFile"}, //3.0.0-18.1.0
{30500, nullptr, "Unknown30500"}, //8.0.0+
{30900, nullptr, "Unknown30900"}, //1.0.0
{30901, nullptr, "Unknown30901"}, //1.0.0
{30902, nullptr, "Unknown30902"}, //1.0.0
{30400, nullptr, "DecodeArchiveFile"},
{30500, nullptr, "Unknown30500"},
{30900, nullptr, "Unknown30900"},
{30901, nullptr, "Unknown30901"},
{30902, nullptr, "Unknown30902"},
{40100, nullptr, "SetSubscriptionStatus"},
{40101, D<&INewsService::RequestAutoSubscription>, "RequestAutoSubscription"}, //3.0.0+
{40101, D<&INewsService::RequestAutoSubscription>, "RequestAutoSubscription"},
{40200, nullptr, "ClearStorage"},
{40201, nullptr, "ClearSubscriptionStatusAll"},
{90100, nullptr, "GetNewsDatabaseDump"},

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -80,33 +77,31 @@ public:
{57, nullptr, "RegisterAppletResourceUserId"},
{58, nullptr, "UnregisterAppletResourceUserId"},
{59, nullptr, "SetAppletResourceUserId"},
{60, nullptr, "AcquireBleConnectionParameterUpdateEvent"}, //8.0.0+
{61, nullptr, "SetCeLength"}, //8.0.0+
{62, nullptr, "EnsureSlotExpansion"}, //9.0.0+
{63, nullptr, "IsSlotExpansionEnsured"}, //9.0.0+
{64, nullptr, "CancelConnectionTrigger"}, //10.0.0+
{65, nullptr, "GetConnectionCapacity"}, //13.0.0+
{66, nullptr, "GetWlanMode"}, //13.0.0+
{67, nullptr, "IsSlotSavingEnabled"}, //13.0.0+
{68, nullptr, "IsSlotSavingForPairingEnabled"}, //13.0.0+
{69, nullptr, "AcquireAudioDeviceConnectionEvent"}, //13.0.0+
{70, nullptr, "GetConnectedAudioDevices"}, //13.0.0+
{71, nullptr, "SetAudioSourceVolume"}, //13.0.0+
{72, nullptr, "GetAudioSourceVolume"}, //13.0.0+
{73, nullptr, "RequestAudioDeviceConnectionRejection"}, //13.0.0+
{74, nullptr, "CancelAudioDeviceConnectionRejection"}, //13.0.0+
{75, nullptr, "GetPairedAudioDevices"}, //13.0.0+
{76, nullptr, "SetWlanModeWithOption"}, //13.1.0+
{100, nullptr, "AcquireConnectionDisallowedEvent"}, //13.0.0+
{101, nullptr, "GetUsecaseViolationFactor"}, //13.0.0+
{110, nullptr, "GetShortenedDeviceInfo"}, //13.0.0+
{111, nullptr, "AcquirePairingCountUpdateEvent"},//13.0.0+
{112, nullptr, "Unknown112"}, //14.0.0-14.1.2
{113, nullptr, "Unknown113"}, //14.0.0-14.1.2
{114, nullptr, "IsFirstAudioControlConnection"}, //14.0.0+
{115, nullptr, "GetShortenedDeviceCondition"}, //14.0.0+
{116, nullptr, "SetAudioSinkVolume"}, //15.0.0+
{117, nullptr, "GetAudioSinkVolume"}, //15.0.0+
{60, nullptr, "Unknown60"},
{61, nullptr, "Unknown61"},
{62, nullptr, "Unknown62"},
{63, nullptr, "Unknown63"},
{64, nullptr, "Unknown64"},
{65, nullptr, "Unknown65"},
{66, nullptr, "Unknown66"},
{67, nullptr, "Unknown67"},
{68, nullptr, "Unknown68"},
{69, nullptr, "Unknown69"},
{70, nullptr, "Unknown70"},
{71, nullptr, "Unknown71"},
{72, nullptr, "Unknown72"},
{73, nullptr, "Unknown73"},
{74, nullptr, "Unknown74"},
{75, nullptr, "Unknown75"},
{76, nullptr, "Unknown76"},
{100, nullptr, "Unknown100"},
{101, nullptr, "Unknown101"},
{110, nullptr, "Unknown110"},
{111, nullptr, "Unknown111"},
{112, nullptr, "Unknown112"},
{113, nullptr, "Unknown113"},
{114, nullptr, "Unknown114"},
{115, nullptr, "Unknown115"},
};
// clang-format on

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -20,15 +17,11 @@ IBtmDebug::IBtmDebug(Core::System& system_) : ServiceFramework{system_, "btm:dbg
{6, nullptr, "SetTsiMode"},
{7, nullptr, "GeneralTest"},
{8, nullptr, "HidConnect"},
{9, nullptr, "GeneralGet"}, //5.0.0+
{10, nullptr, "GetGattClientDisconnectionReason"}, //5.0.0+
{11, nullptr, "GetBleConnectionParameter"}, //5.1.0+
{12, nullptr, "GetBleConnectionParameterRequest"}, //5.1.0+
{13, nullptr, "GetDiscoveredDevice"}, //12.0.0+
{14, nullptr, "SleepAwakeLoopTest"}, //15.0.0+
{15, nullptr, "SleepTest"}, //15.0.0+
{16, nullptr, "MinimumAwakeTest"}, //15.0.0+
{17, nullptr, "ForceEnableBtm"}, //15.0.0+
{9, nullptr, "GeneralGet"},
{10, nullptr, "GetGattClientDisconnectionReason"},
{11, nullptr, "GetBleConnectionParameter"},
{12, nullptr, "GetBleConnectionParameterRequest"},
{13, nullptr, "Unknown13"},
};
// clang-format on

View File

@@ -60,16 +60,6 @@ public:
{38, nullptr, "OwnTicket3"},
{39, nullptr, "DeleteAllInactivePersonalizedTicket"},
{40, nullptr, "DeletePrepurchaseRecordByNintendoAccountId"},
{101, nullptr, "Unknown101"}, //18.0.0+
{102, nullptr, "Unknown102"}, //18.0.0+
{103, nullptr, "Unknown103"}, //18.0.0+
{104, nullptr, "Unknown104"}, //18.0.0+
{105, nullptr, "Unknown105"}, //20.0.0+
{201, nullptr, "Unknown201"}, //18.0.0+
{202, nullptr, "Unknown202"}, //18.0.0+
{203, nullptr, "Unknown203"}, //18.0.0+
{204, nullptr, "Unknown204"}, //18.0.0+
{205, nullptr, "Unknown205"}, //18.0.0+
{501, nullptr, "Unknown501"},
{502, nullptr, "Unknown502"},
{503, nullptr, "GetTitleKey"},

View File

@@ -125,10 +125,13 @@ IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<Resource
{250, nullptr, "IsVirtual"},
{251, nullptr, "GetAnalogStickModuleParam"},
{253, nullptr, "ClearStorageForShipment"}, //19.0.0+
{261, nullptr, "UpdateDesignInfo12"}, //21.0.0+
{262, nullptr, "GetUniquePadButtonCount"}, //21.0.0+
{267, nullptr, "SetAnalogStickCalibration"}, //21.0.0+
{268, nullptr, "ResetAnalogStickCalibration"}, //21.0.0+
{254, nullptr, "Unknown254"},
{255, nullptr, "Unknown255"},
{256, nullptr, "Unknown256"},
{261, nullptr, "UpdateDesignInfo12"},
{262, nullptr, "GetUniquePadButtonCount"},
{267, nullptr, "Unknown267"},
{268, nullptr, "Unknown268"},
{301, nullptr, "GetAbstractedPadHandles"},
{302, nullptr, "GetAbstractedPadState"},
{303, nullptr, "GetAbstractedPadsState"},
@@ -145,8 +148,6 @@ IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<Resource
{331, nullptr, "DetachHdlsVirtualDevice"},
{332, nullptr, "SetHdlsState"},
{350, nullptr, "AddRegisteredDevice"},
{351, nullptr, "GetRegisteredDevicesCountDebug"}, //17.0.0-18.1.0
{352, nullptr, "DeleteRegisteredDevicesDebug"}, //17.0.0-18.1.0
{400, nullptr, "DisableExternalMcuOnNxDevice"},
{401, nullptr, "DisableRailDeviceFiltering"},
{402, nullptr, "EnableWiredPairing"},
@@ -158,30 +159,14 @@ IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<Resource
{551, nullptr, "GetAnalogStickModelData"},
{552, nullptr, "ResetAnalogStickModelData"},
{600, nullptr, "ConvertPadState"},
{601, nullptr, "IsButtonConfigSupported"}, //18.0.0+
{602, nullptr, "IsButtonConfigEmbeddedSupported"}, //18.0.0+
{603, nullptr, "DeleteButtonConfig"}, //18.0.0+
{604, nullptr, "DeleteButtonConfigEmbedded"}, //18.0.0+
{605, nullptr, "SetButtonConfigEnabled"}, //18.0.0+
{606, nullptr, "SetButtonConfigEmbeddedEnabled"}, //18.0.0+
{607, nullptr, "IsButtonConfigEnabled"}, //18.0.0+
{608, nullptr, "IsButtonConfigEmbeddedEnabled"}, //18.0.0+
{609, nullptr, "SetButtonConfigEmbedded"}, //18.0.0+
{610, nullptr, "SetButtonConfigFull"}, //18.0.0+
{611, nullptr, "SetButtonConfigLeft"}, //18.0.0+
{612, nullptr, "SetButtonConfigRight"}, //18.0.0+
{613, nullptr, "GetButtonConfigEmbedded"}, //18.0.0+
{614, nullptr, "GetButtonConfigFull"}, //18.0.0+
{615, nullptr, "GetButtonConfigLeft"}, //18.0.0+
{616, nullptr, "GetButtonConfigRight"}, //18.0.0+
{650, nullptr, "AddButtonPlayData"},
{651, nullptr, "StartButtonPlayData"},
{652, nullptr, "StopButtonPlayData"},
{700, nullptr, "GetRailAttachEventCount"}, //21.0.0+
{700, nullptr, "Unknown700"},
{2000, nullptr, "DeactivateDigitizer"},
{2001, nullptr, "SetDigitizerAutoPilotState"},
{2002, nullptr, "UnsetDigitizerAutoPilotState"},
{3000, nullptr, "ReloadFirmwareDebugSettings"},
{2002, nullptr, "ReloadFirmwareDebugSettings"},
};
// clang-format on

View File

@@ -70,9 +70,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{328, nullptr, "AttachAbstractedPadToNpad"},
{329, nullptr, "DetachAbstractedPadAll"},
{330, nullptr, "CheckAbstractedPadConnection"},
{332, nullptr, "ConvertAppletDetailedUiTypeFromPlayReportType"}, //19.0.0+
{333, nullptr, "SetNpadUserSpgApplet"}, //20.0.0+
{334, nullptr, "AcquireUniquePadButtonStateChangedEventHandle"}, //20.0.0+
{500, nullptr, "SetAppletResourceUserId"},
{501, &IHidSystemServer::RegisterAppletResourceUserId, "RegisterAppletResourceUserId"},
{502, &IHidSystemServer::UnregisterAppletResourceUserId, "UnregisterAppletResourceUserId"},
{503, &IHidSystemServer::EnableAppletToGetInput, "EnableAppletToGetInput"},
@@ -101,7 +99,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{547, nullptr, "GetAllowedBluetoothLinksCount"},
{548, &IHidSystemServer::GetRegisteredDevices, "GetRegisteredDevices"},
{549, nullptr, "GetConnectableRegisteredDevices"},
{551, nullptr, "GetRegisteredDevicesForControllerSupport"}, //20.0.0+
{551, nullptr, "GetRegisteredDevicesForControllerSupport"},
{700, nullptr, "ActivateUniquePad"},
{702, &IHidSystemServer::AcquireUniquePadConnectionEventHandle, "AcquireUniquePadConnectionEventHandle"},
{703, &IHidSystemServer::GetUniquePadIds, "GetUniquePadIds"},
@@ -121,7 +119,6 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{810, nullptr, "GetUniquePadControllerNumber"},
{811, nullptr, "GetSixAxisSensorUserCalibrationStage"},
{812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"},
{813, nullptr, "GetDeviceType"},
{821, nullptr, "StartAnalogStickManualCalibration"},
{822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"},
{823, nullptr, "CancelAnalogStickManualCalibration"},
@@ -152,7 +149,6 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{1009, nullptr, "AcquireAudioControlEventHandle"},
{1010, nullptr, "GetAudioControlStates"},
{1011, nullptr, "DeactivateAudioControl"},
{1012, nullptr, "GetFirmwareVersionStringForUserSupportPage"},
{1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"},
{1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"},
{1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
@@ -173,8 +169,6 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{1155, &IHidSystemServer::SetForceHandheldStyleVibration, "SetForceHandheldStyleVibration"},
{1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"},
{1157, nullptr, "CancelConnectionTrigger"},
{1158, nullptr, "SetConnectionLimitForSplay"}, //20.1.0+
{1159, nullptr, "ClearConnectionLimitForSplay"}, //20.1.0+
{1200, nullptr, "IsButtonConfigSupported"},
{1201, nullptr, "IsButtonConfigEmbeddedSupported"},
{1202, nullptr, "DeleteButtonConfig"},
@@ -233,17 +227,16 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{1289, nullptr, "SetButtonConfigStorageFull"},
{1290, nullptr, "DeleteButtonConfigStorageRight"},
{1291, nullptr, "DeleteButtonConfigStorageRight"},
{1308, nullptr, "SetButtonConfigVisible"}, //18.0.0+
{1309, nullptr, "IsButtonConfigVisible"}, //18.0.0+
{1320, nullptr, "WakeTouchScreenUp"}, //17.0.0+
{1321, nullptr, "PutTouchScreenToSleep"}, //17.0.0+
{1322, nullptr, "AcquireTouchScreenAsyncWakeCompletedEvent"}, //20.0.0+
{1323, nullptr, "StartTouchScreenAutoTuneForSystemSettings"}, //21.0.0+
{1324, nullptr, "AcquireTouchScreenAutoTuneCompletedEvent"}, //21.0.0+
{1325, nullptr, "IsTouchScreenAutoTuneRequiredForRepairProviderReplacement"}, //21.0.0+
{1326, nullptr, "SetTouchScreenOffset"}, //21.0.0+
{1420, nullptr, "GetAppletResourceProperty"}, //19.0.0+
{12010, nullptr, "SetButtonConfigLeft"} //11.0.0-17.0.1
{1308, nullptr, "SetButtonConfigVisible"}, // 18.0.0+
{1309, nullptr, "IsButtonConfigVisible"}, // 18.0.0+
{1320, nullptr, "WakeTouchScreenUp"}, // 17.0.0+
{1321, nullptr, "PutTouchScreenToSleep"}, // 17.0.0+
{1322, nullptr, "AcquireTouchScreenAsyncWakeCompletedEvent"}, // 20.0.0+
{1323, nullptr, "StartTouchScreenAutoTuneForSystemSettings"}, // 21.0.0+
{1324, nullptr, "AcquireTouchScreenAutoTuneCompletedEvent"}, // 21.0.0+
{1325, nullptr, "IsTouchScreenAutoTuneRequiredForRepairProviderReplacement"}, // 21.0.0+
{1326, nullptr, "Unknown1326"}, // 21.0.0+
{1420, nullptr, "GetAppletResourceProperty"}, // 19.0.0+
};
// clang-format on

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -17,42 +14,17 @@ public:
explicit MIG_USR(Core::System& system_) : ServiceFramework{system_, "mig:usr"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Unknown0"}, //19.0.0+
{1, nullptr, "Unknown1"}, //20.0.0+
{2, nullptr, "Unknown2"}, //20.0.0+
{10, nullptr, "TryGetLastMigrationInfo"},
{11, nullptr, "Unknown11"}, //20.0.0+
{100, nullptr, "CreateUserMigrationServer"}, //7.0.0+
{101, nullptr, "ResumeUserMigrationServer"}, //7.0.0+
{200, nullptr, "CreateUserMigrationClient"}, //7.0.0+
{201, nullptr, "ResumeUserMigrationClient"}, //7.0.0+
{1001, nullptr, "GetSaveDataMigrationPolicyInfoAsync"}, //8.0.0-20.5.0
{1010, nullptr, "TryGetLastSaveDataMigrationInfo"}, //7.0.0+
{1100, nullptr, "CreateSaveDataMigrationServer"}, //7.0.0-19.0.1
{1101, nullptr, "ResumeSaveDataMigrationServer"}, //7.0.0+
{1110, nullptr, "Unknown1101"}, //17.0.0+
{1200, nullptr, "CreateSaveDataMigrationClient"}, //7.0.0+
{1201, nullptr, "ResumeSaveDataMigrationClient"}, //7.0.0+
{2001, nullptr, "Unknown2001"}, //20.0.0+
{2010, nullptr, "Unknown2010"}, //20.0.0+
{2100, nullptr, "Unknown2100"}, //20.0.0+
{2110, nullptr, "Unknown2110"}, //20.0.0+
{2200, nullptr, "Unknown2200"}, //20.0.0+
{2210, nullptr, "Unknown2210"}, //20.0.0+
{2220, nullptr, "Unknown2220"}, //20.0.0+
{2230, nullptr, "Unknown2230"}, //20.0.0+
{2231, nullptr, "Unknown2231"}, //20.0.0+
{2232, nullptr, "Unknown2232"}, //20.0.0+
{2233, nullptr, "Unknown2233"}, //20.0.0+
{2234, nullptr, "Unknown2234"}, //20.0.0+
{2250, nullptr, "Unknown2250"}, //20.0.0+
{2260, nullptr, "Unknown2260"}, //20.0.0+
{2270, nullptr, "Unknown2270"}, //20.0.0+
{2280, nullptr, "Unknown2280"}, //20.0.0+
{2300, nullptr, "Unknown2300"}, //20.0.0+
{2310, nullptr, "Unknown2310"}, //20.0.0+
{2400, nullptr, "Unknown2400"}, //20.0.0+
{2420, nullptr, "Unknown2420"}, //20.0.0+
{100, nullptr, "CreateServer"},
{101, nullptr, "ResumeServer"},
{200, nullptr, "CreateClient"},
{201, nullptr, "ResumeClient"},
{1001, nullptr, "Unknown1001"},
{1010, nullptr, "Unknown1010"},
{1100, nullptr, "Unknown1100"},
{1101, nullptr, "Unknown1101"},
{1200, nullptr, "Unknown1200"},
{1201, nullptr, "Unknown1201"}
};
// clang-format on

View File

@@ -167,146 +167,57 @@ public:
{81, nullptr, "ListLocalCommunicationSendSystemUpdateTask"},
{82, nullptr, "GetReceivedSystemDataPath"},
{83, nullptr, "CalculateApplyDeltaTaskOccupiedSize"},
{84, nullptr, "ReloadErrorSimulation"},
{84, nullptr, "Unknown84"},
{85, nullptr, "ListNetworkInstallTaskContentMetaFromInstallMeta"},
{86, nullptr, "ListNetworkInstallTaskOccupiedSize"},
{87, nullptr, "RequestQueryAvailableELicenses"},
{88, nullptr, "RequestAssignELicenses"},
{89, nullptr, "RequestExtendELicenses"},
{90, nullptr, "RequestSyncELicenses"},
{91, nullptr, "Unknown91"}, //6.0.0-14.1.2
{92, nullptr, "Unknown92"}, //21.0.0+
{93, nullptr, "RequestReportActiveELicenses"},
{94, nullptr, "RequestReportActiveELicensesPassively"},
{95, nullptr, "RequestRegisterDynamicRightsNotificationToken"},
{96, nullptr, "RequestAssignAllDeviceLinkedELicenses"},
{97, nullptr, "RequestRevokeAllELicenses"},
{98, nullptr, "RequestPrefetchForDynamicRights"},
{99, nullptr, "CreateNetworkInstallTask"},
{100, nullptr, "ListNetworkInstallTaskRightsIds"},
{101, nullptr, "RequestDownloadETickets"},
{102, nullptr, "RequestQueryDownloadableContents"},
{103, nullptr, "DeleteNetworkInstallTaskContentMeta"},
{104, nullptr, "RequestIssueEdgeTokenForDebug"},
{105, nullptr, "RequestQueryAvailableELicenses2"},
{106, nullptr, "RequestAssignELicenses2"},
{107, nullptr, "GetNetworkInstallTaskStateCounter"},
{108, nullptr, "InvalidateDynamicRightsNaIdTokenCacheForDebug"},
{109, nullptr, "ListNetworkInstallTaskPartialInstallContentMeta"},
{110, nullptr, "ListNetworkInstallTaskRightsIdsFromIndex"},
{111, nullptr, "AddNetworkInstallTaskContentMetaForUser"},
{112, nullptr, "RequestAssignELicensesAndDownloadETickets"},
{113, nullptr, "RequestQueryAvailableCommonELicenses"},
{114, nullptr, "SetNetworkInstallTaskExtendedAttribute"},
{115, nullptr, "GetNetworkInstallTaskExtendedAttribute"},
{116, nullptr, "GetAllocatorInfo"},
{117, nullptr, "RequestQueryDownloadableContentsByApplicationId"},
{118, nullptr, "MarkNoDownloadRightsErrorResolved"},
{119, nullptr, "GetApplyDeltaTaskAllAppliedContentMeta"},
{120, nullptr, "PrioritizeNetworkInstallTask"},
{121, nullptr, "RequestQueryAvailableCommonELicenses2"},
{122, nullptr, "RequestAssignCommonELicenses"},
{123, nullptr, "RequestAssignCommonELicenses2"},
{124, nullptr, "IsNetworkInstallTaskFrontOfQueue"},
{125, nullptr, "PrioritizeApplyDeltaTask"},
{126, nullptr, "RerouteDownloadingPatch"},
{127, nullptr, "UnmarkNoDownloadRightsErrorResolved"},
{128, nullptr, "RequestContentsSize"},
{129, nullptr, "RequestContentsAuthorizationToken"},
{130, nullptr, "RequestCdnVendorDiscovery"},
{131, nullptr, "RefreshDebugAvailability"},
{132, nullptr, "ClearResponseSimulationEntry"},
{133, nullptr, "RegisterResponseSimulationEntry"},
{134, nullptr, "GetProcessedCdnVendors"},
{135, nullptr, "RefreshRuntimeBehaviorsForDebug"},
{136, nullptr, "RequestOnlineSubscriptionFreeTrialAvailability"},
{137, nullptr, "GetNetworkInstallTaskContentMetaCount"},
{138, nullptr, "RequestRevokeELicenses"},
{139, nullptr, "EnableNetworkConnectionToUseApplicationCore"},
{140, nullptr, "DisableNetworkConnectionToUseApplicationCore"},
{141, nullptr, "IsNetworkConnectionEnabledToUseApplicationCore"},
{142, nullptr, "RequestCheckSafeSystemVersion"},
{143, nullptr, "RequestApplicationIcon"},
{144, nullptr, "RequestDownloadIdbeIconFile"},
{147, nullptr, "Unknown147"}, //18.0.0+
{148, nullptr, "Unknown148"}, //18.0.0+
{150, nullptr, "Unknown150"}, //19.0.0+
{151, nullptr, "Unknown151"}, //20.0.0+
{152, nullptr, "Unknown152"}, //20.0.0+
{153, nullptr, "Unknown153"}, //20.0.0+
{154, nullptr, "Unknown154"}, //20.0.0+
{155, nullptr, "Unknown155"}, //20.0.0+
{156, nullptr, "Unknown156"}, //20.0.0+
{157, nullptr, "Unknown157"}, //20.0.0+
{158, nullptr, "Unknown158"}, //20.0.0+
{159, nullptr, "Unknown159"}, //20.0.0+
{160, nullptr, "Unknown160"}, //20.0.0+
{161, nullptr, "Unknown161"}, //20.0.0+
{162, nullptr, "Unknown162"}, //20.0.0+
{163, nullptr, "Unknown163"}, //20.0.0+
{164, nullptr, "Unknown164"}, //20.0.0+
{165, nullptr, "Unknown165"}, //20.0.0+
{166, nullptr, "Unknown166"}, //20.0.0+
{167, nullptr, "Unknown167"}, //20.0.0+
{168, nullptr, "Unknown168"}, //20.0.0+
{169, nullptr, "Unknown169"}, //20.0.0+
{170, nullptr, "Unknown170"}, //20.0.0+
{171, nullptr, "Unknown171"}, //20.0.0+
{172, nullptr, "Unknown172"}, //20.0.0+
{173, nullptr, "Unknown173"}, //20.0.0+
{174, nullptr, "Unknown174"}, //20.0.0+
{175, nullptr, "Unknown175"}, //20.0.0+
{176, nullptr, "Unknown176"}, //20.0.0+
{177, nullptr, "Unknown177"}, //20.0.0+
{2000, nullptr, "Unknown2000"}, //20.0.0+
{2001, nullptr, "Unknown2001"}, //20.0.0+
{2002, nullptr, "Unknown2002"}, //20.0.0+
{2003, nullptr, "Unknown2003"}, //20.0.0+
{2004, nullptr, "Unknown2004"}, //20.0.0+
{2007, nullptr, "Unknown2007"}, //20.0.0+
{2011, nullptr, "Unknown2011"}, //20.0.0+
{2012, nullptr, "Unknown2012"}, //20.0.0+
{2013, nullptr, "Unknown2013"}, //20.0.0+
{2014, nullptr, "Unknown2014"}, //20.0.0+
{2015, nullptr, "Unknown2015"}, //20.0.0+
{2016, nullptr, "Unknown2016"}, //20.0.0+
{2017, nullptr, "Unknown2017"}, //20.0.0+
{2018, nullptr, "Unknown2018"}, //20.0.0+
{2019, nullptr, "Unknown2019"}, //20.0.0+
{2020, nullptr, "Unknown2020"}, //20.0.0+
{2021, nullptr, "Unknown2021"}, //20.0.0+
{2022, nullptr, "Unknown2022"}, //20.0.0+
{2023, nullptr, "Unknown2023"}, //20.0.0+
{2024, nullptr, "Unknown2024"}, //20.0.0+
{2025, nullptr, "Unknown2025"}, //20.0.0+
{2026, nullptr, "Unknown2026"}, //20.0.0+
{2027, nullptr, "Unknown2027"}, //20.0.0+
{2028, nullptr, "Unknown2028"}, //20.0.0+
{2029, nullptr, "Unknown2029"}, //20.0.0+
{2030, nullptr, "Unknown2030"}, //20.0.0+
{2031, nullptr, "Unknown2031"}, //20.0.0+
{2032, nullptr, "Unknown2032"}, //20.0.0+
{2033, nullptr, "Unknown2033"}, //20.0.0+
{2034, nullptr, "Unknown2034"}, //20.0.0+
{2035, nullptr, "Unknown2035"}, //20.0.0+
{2036, nullptr, "Unknown2036"}, //20.0.0+
{2037, nullptr, "Unknown2037"}, //20.0.0+
{2038, nullptr, "Unknown2038"}, //20.0.0+
{2039, nullptr, "Unknown2039"}, //20.0.0+
{2040, nullptr, "Unknown2040"}, //20.0.0+
{2041, nullptr, "Unknown2041"}, //20.0.0+
{2042, nullptr, "Unknown2042"}, //20.0.0+
{2043, nullptr, "Unknown2043"}, //20.0.0+
{2044, nullptr, "Unknown2044"}, //20.0.0+
{2045, nullptr, "Unknown2045"}, //20.0.0+
{2046, nullptr, "Unknown2046"}, //20.0.0+
{2047, nullptr, "Unknown2047"}, //20.0.0+
{2048, nullptr, "Unknown2048"}, //20.0.0+
{2049, nullptr, "Unknown2049"}, //20.0.0+
{2050, nullptr, "Unknown2050"}, //20.0.0+
{2051, nullptr, "Unknown2051"}, //20.0.0+
{3000, nullptr, "RequestLatestApplicationIcon"}, //17.0.0+
{3001, nullptr, "RequestDownloadIdbeLatestIconFile"}, //17.0.0+
{87, nullptr, "Unknown87"},
{88, nullptr, "Unknown88"},
{89, nullptr, "Unknown89"},
{90, nullptr, "Unknown90"},
{91, nullptr, "Unknown91"},
{92, nullptr, "Unknown92"},
{93, nullptr, "Unknown93"},
{94, nullptr, "Unknown94"},
{95, nullptr, "Unknown95"},
{96, nullptr, "Unknown96"},
{97, nullptr, "Unknown97"},
{98, nullptr, "Unknown98"},
{99, nullptr, "Unknown99"},
{100, nullptr, "Unknown100"},
{101, nullptr, "Unknown101"},
{102, nullptr, "Unknown102"},
{103, nullptr, "Unknown103"},
{104, nullptr, "Unknown104"},
{105, nullptr, "Unknown105"},
{106, nullptr, "Unknown106"},
{107, nullptr, "Unknown107"},
{108, nullptr, "Unknown108"},
{109, nullptr, "Unknown109"},
{110, nullptr, "Unknown110"},
{111, nullptr, "Unknown111"},
{112, nullptr, "Unknown112"},
{113, nullptr, "Unknown113"},
{114, nullptr, "Unknown114"},
{115, nullptr, "Unknown115"},
{116, nullptr, "Unknown116"},
{117, nullptr, "Unknown117"},
{118, nullptr, "Unknown118"},
{119, nullptr, "Unknown119"},
{120, nullptr, "Unknown120"},
{121, nullptr, "Unknown121"},
{122, nullptr, "Unknown122"},
{123, nullptr, "Unknown123"},
{124, nullptr, "Unknown124"},
{125, nullptr, "Unknown125"},
{126, nullptr, "Unknown126"},
{127, nullptr, "Unknown127"},
{128, nullptr, "Unknown128"},
{129, nullptr, "Unknown129"},
{130, nullptr, "Unknown130"},
{131, nullptr, "Unknown131"},
{132, nullptr, "Unknown132"},
{133, nullptr, "Unknown133"},
{134, nullptr, "Unknown134"},
};
// clang-format on

View File

@@ -134,26 +134,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{406, nullptr, "GetApplicationControlProperty"},
{407, nullptr, "ListApplicationTitle"},
{408, nullptr, "ListApplicationIcon"},
{411, nullptr, "Unknown411"}, //19.0.0+
{412, nullptr, "Unknown412"}, //19.0.0+
{413, nullptr, "Unknown413"}, //19.0.0+
{414, nullptr, "Unknown414"}, //19.0.0+
{415, nullptr, "Unknown415"}, //19.0.0+
{416, nullptr, "Unknown416"}, //19.0.0+
{417, nullptr, "InvalidateAllApplicationControlCacheOfTheStage"}, //19.0.0+
{418, nullptr, "InvalidateApplicationControlCacheOfTheStage"}, //19.0.0+
{419, D<&IApplicationManagerInterface::RequestDownloadApplicationControlDataInBackground>, "RequestDownloadApplicationControlDataInBackground"},
{420, nullptr, "CloneApplicationControlDataCacheForDebug"},
{421, nullptr, "Unknown421"}, //20.0.0+
{422, nullptr, "Unknown422"}, //20.0.0+
{423, nullptr, "Unknown423"}, //20.0.0+
{424, nullptr, "Unknown424"}, //20.0.0+
{425, nullptr, "Unknown425"}, //20.0.0+
{426, nullptr, "Unknown426"}, //20.0.0+
{427, nullptr, "Unknown427"}, //20.0.0+
{428, nullptr, "Unknown428"}, //21.0.0+
{429, nullptr, "Unknown429"}, //21.0.0+
{430, nullptr, "Unknown430"}, //21.0.0+
{502, nullptr, "RequestCheckGameCardRegistration"},
{503, nullptr, "RequestGameCardRegistrationGoldPoint"},
{504, nullptr, "RequestRegisterGameCard"},
@@ -165,13 +146,6 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{510, nullptr, "GetGameCardPlatformRegion"},
{511, D<&IApplicationManagerInterface::GetGameCardWakenReadyEvent>, "GetGameCardWakenReadyEvent"},
{512, D<&IApplicationManagerInterface::IsGameCardApplicationRunning>, "IsGameCardApplicationRunning"},
{513, nullptr, "Unknown513"}, //20.0.0+
{514, nullptr, "Unknown514"}, //20.0.0+
{515, nullptr, "Unknown515"}, //20.0.0+
{516, nullptr, "Unknown516"}, //21.0.0+
{517, nullptr, "Unknown517"}, //21.0.0+
{518, nullptr, "Unknown518"}, //21.0.0+
{519, nullptr, "Unknown519"}, //21.0.0+
{600, nullptr, "CountApplicationContentMeta"},
{601, nullptr, "ListApplicationContentMetaStatus"},
{602, nullptr, "ListAvailableAddOnContent"},
@@ -209,22 +183,6 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{914, nullptr, "HideApplicationRecord"},
{915, nullptr, "ShowApplicationRecord"},
{916, nullptr, "IsApplicationAutoDeleteDisabled"},
{916, nullptr, "Unknown916"}, //20.0.0+
{917, nullptr, "Unknown917"}, //20.0.0+
{918, nullptr, "Unknown918"}, //20.0.0+
{919, nullptr, "Unknown919"}, //20.0.0+
{920, nullptr, "Unknown920"}, //20.0.0+
{921, nullptr, "Unknown921"}, //20.0.0+
{922, nullptr, "Unknown922"}, //20.0.0+
{923, nullptr, "Unknown923"}, //20.0.0+
{928, nullptr, "Unknown928"}, //20.0.0+
{929, nullptr, "Unknown929"}, //20.0.0+
{930, nullptr, "Unknown930"}, //20.0.0+
{931, nullptr, "Unknown931"}, //20.0.0+
{933, nullptr, "Unknown933"}, //20.0.0+
{934, nullptr, "Unknown934"}, //20.0.0+
{935, nullptr, "Unknown935"}, //20.0.0+
{936, nullptr, "Unknown936"}, //20.0.0+
{1000, nullptr, "RequestVerifyApplicationDeprecated"},
{1001, nullptr, "CorruptApplicationForDebug"},
{1002, nullptr, "RequestVerifyAddOnContentsRights"},
@@ -253,11 +211,6 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{1504, nullptr, "InsertSdCard"},
{1505, nullptr, "RemoveSdCard"},
{1506, nullptr, "GetSdCardStartupStatus"},
{1508, nullptr, "Unknown1508"}, //20.0.0+
{1509, nullptr, "Unknown1509"}, //20.0.0+
{1510, nullptr, "Unknown1510"}, //20.0.0+
{1511, nullptr, "Unknown1511"}, //20.0.0+
{1512, nullptr, "Unknown1512"}, //20.0.0+
{1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
{1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
{1700, nullptr, "ListApplicationDownloadingContentMeta"},
@@ -294,11 +247,8 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{2016, nullptr, "ListNotCommittedContentMeta"},
{2017, nullptr, "CreateDownloadTask"},
{2018, nullptr, "GetApplicationDeliveryInfoHash"},
{2019, nullptr, "Unknown2019"}, //20.0.0+
{2050, D<&IApplicationManagerInterface::GetApplicationRightsOnClient>, "GetApplicationRightsOnClient"},
{2051, nullptr, "InvalidateRightsIdCache"},
{2052, nullptr, "Unknown2052"}, //20.0.0+
{2053, nullptr, "Unknown2053"}, //20.0.0+
{2100, D<&IApplicationManagerInterface::GetApplicationTerminateResult>, "GetApplicationTerminateResult"},
{2101, nullptr, "GetRawApplicationTerminateResult"},
{2150, nullptr, "CreateRightsEnvironment"},
@@ -315,7 +265,6 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{2180, nullptr, "RequestExtendRightsInRightsEnvironment"},
{2181, nullptr, "GetResultOfExtendRightsInRightsEnvironment"},
{2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"},
{2183, nullptr, "Unknown2183"}, //20.1.0+
{2190, nullptr, "GetRightsEnvironmentHandleForApplication"},
{2199, nullptr, "GetRightsEnvironmentCountForDebug"},
{2200, nullptr, "GetGameCardApplicationCopyIdentifier"},
@@ -332,16 +281,6 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{2357, nullptr, "EnableMultiCoreDownload"},
{2358, nullptr, "DisableMultiCoreDownload"},
{2359, nullptr, "IsMultiCoreDownloadEnabled"},
{2360, nullptr, "GetApplicationDownloadTaskCount"}, //19.0.0+
{2361, nullptr, "GetMaxApplicationDownloadTaskCount"}, //19.0.0+
{2362, nullptr, "Unknown2362"}, //20.0.0+
{2363, nullptr, "Unknown2363"}, //20.0.0+
{2364, nullptr, "Unknown2364"}, //20.0.0+
{2365, nullptr, "Unknown2365"}, //20.0.0+
{2366, nullptr, "Unknown2366"}, //20.0.0+
{2367, nullptr, "Unknown2367"}, //20.0.0+
{2368, nullptr, "Unknown2368"}, //20.0.0+
{2369, nullptr, "Unknown2369"}, //21.0.0+
{2400, nullptr, "GetPromotionInfo"},
{2401, nullptr, "CountPromotionInfo"},
{2402, nullptr, "ListPromotionInfo"},
@@ -360,9 +299,6 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{2520, nullptr, "IsQualificationTransitionSupportedByProcessId"},
{2521, nullptr, "GetRightsUserChangedEvent"},
{2522, nullptr, "IsRomRedirectionAvailable"},
{2523, nullptr, "GetProgramId"}, //17.0.0+
{2524, nullptr, "Unknown2524"}, //19.0.0+
{2525, nullptr, "Unknown2525"}, //20.0.0+
{2800, nullptr, "GetApplicationIdOfPreomia"},
{3000, nullptr, "RegisterDeviceLockKey"},
{3001, nullptr, "UnregisterDeviceLockKey"},
@@ -380,99 +316,11 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{3013, nullptr, "IsGameCardEnabled"},
{3014, nullptr, "IsLocalContentShareEnabled"},
{3050, nullptr, "ListAssignELicenseTaskResult"},
{3104, nullptr, "GetApplicationNintendoLogo"}, //18.0.0+
{3105, nullptr, "GetApplicationStartupMovie"}, //18.0.0+
{4000, nullptr, "Unknown4000"}, //20.0.0+
{4004, nullptr, "Unknown4004"}, //20.0.0+
{4006, nullptr, "Unknown4006"}, //20.0.0+
{4007, nullptr, "Unknown4007"}, //20.0.0+
{4008, nullptr, "Unknown4008"}, //20.0.0+
{4009, nullptr, "Unknown4009"}, //20.0.0+
{4010, nullptr, "Unknown4010"}, //20.0.0+
{4011, nullptr, "Unknown4011"}, //20.0.0+
{4012, nullptr, "Unknown4012"}, //20.0.0+
{4013, nullptr, "Unknown4013"}, //20.0.0+
{4015, nullptr, "Unknown4015"}, //20.0.0+
{4017, nullptr, "Unknown4017"}, //20.0.0+
{4019, nullptr, "Unknown4019"}, //20.0.0+
{4020, nullptr, "Unknown4020"}, //20.0.0+
{4021, nullptr, "Unknown4021"}, //20.0.0+
{4022, D<&IApplicationManagerInterface::Unknown4022>, "Unknown4022"}, //20.0.0+
{4023, D<&IApplicationManagerInterface::Unknown4023>, "Unknown4023"}, //20.0.0+
{4024, nullptr, "Unknown4024"}, //20.0.0+
{4025, nullptr, "Unknown4025"}, //20.0.0+
{4026, nullptr, "Unknown4026"}, //20.0.0+
{4027, nullptr, "Unknown4027"}, //20.0.0+
{4028, nullptr, "Unknown4028"}, //20.0.0+
{4029, nullptr, "Unknown4029"}, //20.0.0+
{4030, nullptr, "Unknown4030"}, //20.0.0+
{4031, nullptr, "Unknown4031"}, //20.0.0+
{4032, nullptr, "Unknown4032"}, //20.0.0+
{4033, nullptr, "Unknown4033"}, //20.0.0+
{4034, nullptr, "Unknown4034"}, //20.0.0+
{4035, nullptr, "Unknown4035"}, //20.0.0+
{4037, nullptr, "Unknown4037"}, //20.0.0+
{4038, nullptr, "Unknown4038"}, //20.0.0+
{4039, nullptr, "Unknown4039"}, //20.0.0+
{4040, nullptr, "Unknown4040"}, //20.0.0+
{4041, nullptr, "Unknown4041"}, //20.0.0+
{4042, nullptr, "Unknown4042"}, //20.0.0+
{4043, nullptr, "Unknown4043"}, //20.0.0+
{4044, nullptr, "Unknown4044"}, //20.0.0+
{4045, nullptr, "Unknown4045"}, //20.0.0+
{4046, nullptr, "Unknown4046"}, //20.0.0+
{4049, nullptr, "Unknown4049"}, //20.0.0+
{4050, nullptr, "Unknown4050"}, //20.0.0+
{4051, nullptr, "Unknown4051"}, //20.0.0+
{4052, nullptr, "Unknown4052"}, //20.0.0+
{4053, D<&IApplicationManagerInterface::Unknown4053>, "Unknown4053"}, //20.0.0+
{4054, nullptr, "Unknown4054"}, //20.0.0+
{4055, nullptr, "Unknown4055"}, //20.0.0+
{4056, nullptr, "Unknown4056"}, //20.0.0+
{4057, nullptr, "Unknown4057"}, //20.0.0+
{4058, nullptr, "Unknown4058"}, //20.0.0+
{4059, nullptr, "Unknown4059"}, //20.0.0+
{4060, nullptr, "Unknown4060"}, //20.0.0+
{4061, nullptr, "Unknown4061"}, //20.0.0+
{4062, nullptr, "Unknown4062"}, //20.0.0+
{4063, nullptr, "Unknown4063"}, //20.0.0+
{4064, nullptr, "Unknown4064"}, //20.0.0+
{4065, nullptr, "Unknown4065"}, //20.0.0+
{4066, nullptr, "Unknown4066"}, //20.0.0+
{4067, nullptr, "Unknown4067"}, //20.0.0+
{4068, nullptr, "Unknown4068"}, //20.0.0+
{4069, nullptr, "Unknown4069"}, //20.0.0+
{4070, nullptr, "Unknown4070"}, //20.0.0+
{4071, nullptr, "Unknown4071"}, //20.0.0+
{4072, nullptr, "Unknown4072"}, //20.0.0+
{4073, nullptr, "Unknown4073"}, //20.0.0+
{4074, nullptr, "Unknown4074"}, //20.0.0+
{4075, nullptr, "Unknown4075"}, //20.0.0+
{4076, nullptr, "Unknown4076"}, //20.0.0+
{4077, nullptr, "Unknown4077"}, //20.0.0+
{4078, nullptr, "Unknown4078"}, //20.0.0+
{4079, nullptr, "Unknown4079"}, //20.0.0+
{4080, nullptr, "Unknown4080"}, //20.0.0+
{4081, nullptr, "Unknown4081"}, //20.0.0+
{4083, nullptr, "Unknown4083"}, //20.0.0+
{4084, nullptr, "Unknown4084"}, //20.0.0+
{4085, nullptr, "Unknown4085"}, //20.0.0+
{4086, nullptr, "Unknown4086"}, //20.0.0+
{4087, nullptr, "Unknown4087"}, //20.0.0+
{4088, D<&IApplicationManagerInterface::Unknown4022>, "Unknown4088"}, //20.0.0+
{4089, nullptr, "Unknown4089"}, //20.0.0+
{4090, nullptr, "Unknown4090"}, //20.0.0+
{4091, nullptr, "Unknown4091"}, //20.0.0+
{4092, nullptr, "Unknown4092"}, //20.0.0+
{4093, nullptr, "Unknown4093"}, //20.0.0+
{4094, nullptr, "Unknown4094"}, //20.0.0+
{4095, nullptr, "Unknown4095"}, //20.0.0+
{4096, nullptr, "Unknown4096"}, //20.0.0+
{4097, nullptr, "Unknown4097"}, //20.0.0+
{4099, nullptr, "Unknown4099"}, //21.0.0+
{5000, nullptr, "Unknown5000"}, //18.0.0+
{5001, nullptr, "Unknown5001"}, //18.0.0+
{9999, nullptr, "GetApplicationCertificate"}, //10.0.0-10.2.0
{4022, D<&IApplicationManagerInterface::Unknown4022>, "Unknown4022"},
{4023, D<&IApplicationManagerInterface::Unknown4023>, "Unknown4023"},
{4088, D<&IApplicationManagerInterface::Unknown4022>, "Unknown4088"},
{4053, D<&IApplicationManagerInterface::Unknown4053>, "Unknown4053"},
{9999, nullptr, "GetApplicationCertificate"},
};
// clang-format on

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -25,7 +22,6 @@ IContentManagementInterface::IContentManagementInterface(Core::System& system_)
{601, nullptr, "ListApplicationContentMetaStatus"},
{605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
{607, nullptr, "IsAnyApplicationRunning"},
{608, nullptr, "Unknown608"}, //21.0.0+
};
// clang-format on

View File

@@ -37,11 +37,7 @@ IDynamicRightsInterface::IDynamicRightsInterface(Core::System& system_)
{23, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"},
{24, nullptr, "NotifyLimitedApplicationLicenseUpgradableEventForDebug"},
{25, nullptr, "RequestProceedDynamicRightsState"},
{26, D<&IDynamicRightsInterface::HasAccountRestrictedRightsInRunningApplications>, "HasAccountRestrictedRightsInRunningApplications"},
{27, nullptr, "Unknown27"}, //20.0.0+
{28, nullptr, "Unknown28"}, //20.0.0+
{29, nullptr, "Unknown29"}, //21.0.0+
{30, nullptr, "Unknown30"}, //21.0.0+
{26, D<&IDynamicRightsInterface::HasAccountRestrictedRightsInRunningApplications>, "HasAccountRestrictedRightsInRunningApplications"}
};
// clang-format on

View File

@@ -16,67 +16,64 @@ IOlscServiceForSystemService::IOlscServiceForSystemService(Core::System& system_
: ServiceFramework{system_, "olsc:s"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&IOlscServiceForSystemService::GetTransferTaskListController>, "GetTransferTaskListController"},
{1, D<&IOlscServiceForSystemService::GetRemoteStorageController>, "GetRemoteStorageController"},
{2, D<&IOlscServiceForSystemService::GetDaemonController>, "GetDaemonController"},
{10, nullptr, "PrepareDeleteUserProperty"},
{11, nullptr, "DeleteUserSaveDataProperty"},
{12, nullptr, "InvalidateMountCache"},
{13, nullptr, "DeleteDeviceSaveDataProperty"},
{0, D<&IOlscServiceForSystemService::OpenTransferTaskListController>, "OpenTransferTaskListController"},
{1, D<&IOlscServiceForSystemService::OpenRemoteStorageController>, "OpenRemoteStorageController"},
{2, D<&IOlscServiceForSystemService::OpenDaemonController>, "OpenDaemonController"},
{10, nullptr, "Unknown10"},
{11, nullptr, "Unknown11"},
{12, nullptr, "Unknown12"},
{13, nullptr, "Unknown13"},
{100, nullptr, "ListLastTransferTaskErrorInfo"},
{101, nullptr, "GetLastErrorInfoCount"},
{102, nullptr, "RemoveLastErrorInfoOld"},
{103, nullptr, "GetLastErrorInfo"},
{104, nullptr, "GetLastErrorEventHolder"},
{105, nullptr, "GetLastTransferTaskErrorInfo"},
{200, D<&IOlscServiceForSystemService::GetDataTransferPolicy>, "GetDataTransferPolicy"},
{201, nullptr, "DeleteDataTransferPolicyCache"},
{202, nullptr, "Unknown202"},
{203, nullptr, "RequestUpdateDataTransferPolicyCacheAsync"},
{204, nullptr, "ClearDataTransferPolicyCache"},
{205, nullptr, "RequestGetDataTransferPolicyAsync"},
{206, nullptr, "Unknown206"}, //21.0.0+
{300, nullptr, "GetUserSaveDataProperty"},
{301, nullptr, "SetUserSaveDataProperty"},
{302, nullptr, "Unknown302"}, //21.0.0+
{400, nullptr, "CleanupSaveDataBackupContextForSpecificApplications"},
{900, nullptr, "DeleteAllTransferTask"},
{902, nullptr, "DeleteAllSeriesInfo"},
{903, nullptr, "DeleteAllSdaInfoCache"},
{904, nullptr, "DeleteAllApplicationSetting"},
{905, nullptr, "DeleteAllTransferTaskErrorInfo"},
{906, nullptr, "RegisterTransferTaskErrorInfo"},
{907, nullptr, "AddSaveDataArchiveInfoCache"},
{908, nullptr, "DeleteSeriesInfo"},
{909, nullptr, "GetSeriesInfo"},
{910, nullptr, "RemoveTransferTaskErrorInfo"},
{911, nullptr, "DeleteAllSeriesInfoForSaveDataBackup"},
{912, nullptr, "DeleteSeriesInfoForSaveDataBackup"},
{913, nullptr, "GetSeriesInfoForSaveDataBackup"},
{914, nullptr, "Unknown914"}, //20.2.0+
{200, D<&IOlscServiceForSystemService::GetDataTransferPolicyInfo>, "GetDataTransferPolicyInfo"},
{201, nullptr, "RemoveDataTransferPolicyInfo"},
{202, nullptr, "UpdateDataTransferPolicyOld"},
{203, nullptr, "UpdateDataTransferPolicy"},
{204, nullptr, "CleanupDataTransferPolicyInfo"},
{205, nullptr, "RequestDataTransferPolicy"},
{300, nullptr, "GetAutoTransferSeriesInfo"},
{301, nullptr, "UpdateAutoTransferSeriesInfo"},
{400, nullptr, "CleanupSaveDataArchiveInfoType1"},
{900, nullptr, "CleanupTransferTask"},
{902, nullptr, "CleanupSeriesInfoType0"},
{903, nullptr, "CleanupSaveDataArchiveInfoType0"},
{904, nullptr, "CleanupApplicationAutoTransferSetting"},
{905, nullptr, "CleanupErrorHistory"},
{906, nullptr, "SetLastError"},
{907, nullptr, "AddSaveDataArchiveInfoType0"},
{908, nullptr, "RemoveSeriesInfoType0"},
{909, nullptr, "GetSeriesInfoType0"},
{910, nullptr, "RemoveLastErrorInfo"},
{911, nullptr, "CleanupSeriesInfoType1"},
{912, nullptr, "RemoveSeriesInfoType1"},
{913, nullptr, "GetSeriesInfoType1"},
{1000, nullptr, "UpdateIssueOld"},
{1010, nullptr, "Unknown1010"},
{1011, nullptr, "Unknown1011"},
{1012, nullptr, "Unknown1012"},
{1013, nullptr, "Unkown1013"},
{1014, nullptr, "Unknown1014"},
{1020, nullptr, "Unknown1020"},
{1021, nullptr, "Unknown1021"},
{1022, nullptr, "Unknown1022"},
{1023, nullptr, "Unknown1023"},
{1011, nullptr, "ListIssueInfoOld"},
{1012, nullptr, "GetIssueOld"},
{1013, nullptr, "GetIssue2Old"},
{1014, nullptr, "GetIssue3Old"},
{1020, nullptr, "RepairIssueOld"},
{1021, nullptr, "RepairIssueWithUserIdOld"},
{1022, nullptr, "RepairIssue2Old"},
{1023, nullptr, "RepairIssue3Old"},
{1024, nullptr, "Unknown1024"},
{1100, nullptr, "RepairUpdateIssueInfoCacheAync"},
{1110, nullptr, "RepairGetIssueInfo"},
{1111, nullptr, "RepairListIssueInfo"},
{1112, nullptr, "RepairListOperationPermissionInfo"},
{1113, nullptr, "RepairListDataInfoForRepairedSaveDataDownload"},
{1114, nullptr, "RepairListDataInfoForOriginalSaveDataDownload"},
{1120, nullptr, "RepairUploadSaveDataAsync"},
{1121, nullptr, "RepairUploadSaveDataAsync1"},
{1122, nullptr, "RepairDownloadRepairedSaveDataAsync"},
{1123, nullptr, "RepairDownloadOriginalSaveDataAsync"},
{1124, nullptr, "RepairGetOperationProgressInfo"},
{10000, D<&IOlscServiceForSystemService::GetOlscServiceForSystemService>, "GetOlscServiceForSystemService"},
{1100, nullptr, "UpdateIssue"},
{1110, nullptr, "Unknown1110"},
{1111, nullptr, "ListIssueInfo"},
{1112, nullptr, "GetIssue"},
{1113, nullptr, "GetIssue2"},
{1114, nullptr, "GetIssue3"},
{1120, nullptr, "RepairIssue"},
{1121, nullptr, "RepairIssueWithUserId"},
{1122, nullptr, "RepairIssue2"},
{1123, nullptr, "RepairIssue3"},
{1124, nullptr, "Unknown1124"},
{10000, D<&IOlscServiceForSystemService::CloneService>, "CloneService"},
};
// clang-format on
@@ -85,38 +82,38 @@ IOlscServiceForSystemService::IOlscServiceForSystemService(Core::System& system_
IOlscServiceForSystemService::~IOlscServiceForSystemService() = default;
Result IOlscServiceForSystemService::GetTransferTaskListController(
Result IOlscServiceForSystemService::OpenTransferTaskListController(
Out<SharedPointer<ITransferTaskListController>> out_interface) {
LOG_INFO(Service_OLSC, "called");
*out_interface = std::make_shared<ITransferTaskListController>(system);
R_SUCCEED();
}
Result IOlscServiceForSystemService::GetRemoteStorageController(
Result IOlscServiceForSystemService::OpenRemoteStorageController(
Out<SharedPointer<IRemoteStorageController>> out_interface) {
LOG_INFO(Service_OLSC, "called");
*out_interface = std::make_shared<IRemoteStorageController>(system);
R_SUCCEED();
}
Result IOlscServiceForSystemService::GetDaemonController(
Result IOlscServiceForSystemService::OpenDaemonController(
Out<SharedPointer<IDaemonController>> out_interface) {
LOG_INFO(Service_OLSC, "called");
*out_interface = std::make_shared<IDaemonController>(system);
R_SUCCEED();
}
Result IOlscServiceForSystemService::GetDataTransferPolicy(
Out<DataTransferPolicy> out_policy, u64 application_id) {
Result IOlscServiceForSystemService::GetDataTransferPolicyInfo(
Out<DataTransferPolicy> out_policy_info, u64 application_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
DataTransferPolicy policy{};
policy.upload_policy = 0;
policy.download_policy = 0;
*out_policy = policy;
*out_policy_info = policy;
R_SUCCEED();
}
Result IOlscServiceForSystemService::GetOlscServiceForSystemService(
Result IOlscServiceForSystemService::CloneService(
Out<SharedPointer<IOlscServiceForSystemService>> out_interface) {
LOG_INFO(Service_OLSC, "called");
*out_interface = std::static_pointer_cast<IOlscServiceForSystemService>(shared_from_this());

View File

@@ -24,12 +24,12 @@ public:
~IOlscServiceForSystemService() override;
private:
Result GetTransferTaskListController(
Result OpenTransferTaskListController(
Out<SharedPointer<ITransferTaskListController>> out_interface);
Result GetRemoteStorageController(Out<SharedPointer<IRemoteStorageController>> out_interface);
Result GetDaemonController(Out<SharedPointer<IDaemonController>> out_interface);
Result GetDataTransferPolicy(Out<DataTransferPolicy> out_policy, u64 application_id);
Result GetOlscServiceForSystemService(Out<SharedPointer<IOlscServiceForSystemService>> out_interface);
Result OpenRemoteStorageController(Out<SharedPointer<IRemoteStorageController>> out_interface);
Result OpenDaemonController(Out<SharedPointer<IDaemonController>> out_interface);
Result GetDataTransferPolicyInfo(Out<DataTransferPolicy> out_policy_info, u64 application_id);
Result CloneService(Out<SharedPointer<IOlscServiceForSystemService>> out_interface);
};
} // namespace Service::OLSC

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -14,37 +11,32 @@ ITransferTaskListController::ITransferTaskListController(Core::System& system_)
: ServiceFramework{system_, "ITransferTaskListController"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetTransferTaskCountForOcean"},
{1, nullptr, "GetTransferTaskInfoForOcean"},
{2, nullptr, "ListTransferTaskInfoForOcean"},
{3, nullptr, "DeleteTransferTaskForOcean"},
{4, nullptr, "RaiseTransferTaskPriorityForOcean"},
{5, D<&ITransferTaskListController::GetTransferTaskEndEventNativeHandleHolder>, "GetTransferTaskEndEventNativeHandleHolder"},
{6, nullptr, "GetTransferTaskProgressForOcean"},
{7, nullptr, "GetTransferTaskLastResultForOcean"},
{8, nullptr, "StopNextTransferTaskExecution"},
{9, D<&ITransferTaskListController::GetTransferTaskStartEventNativeHandleHolder>, "GetTransferTaskStartEventNativeHandleHolder"},
{10, nullptr, "SuspendTransferTaskForOcean"},
{11, nullptr, "GetCurrentTransferTaskInfoForOcean"},
{12, nullptr, "FindTransferTaskInfoForOcean"},
{13, nullptr, "CancelCurrentRepairTransferTask"},
{14, nullptr, "GetRepairTransferTaskProgress"},
{15, nullptr, "EnsureExecutableForRepairTransferTask"},
{16, nullptr, "GetTransferTaskCount"},
{17, nullptr, "GetTransferTaskInfo"},
{18, nullptr, "ListTransferTaskInfo"},
{19, nullptr, "DeleteTransferTask"},
{20, nullptr, "RaiseTransferTaskPriority"},
{21, nullptr, "GetTransferTaskProgress"},
{22, nullptr, "GetTransferTaskLastResult"},
{23, nullptr, "SuspendTransferTask"},
{24, nullptr, "GetCurrentTransferTaskInfo"},
{25, nullptr, "Unknown25"}, //20.1.0+
{26, nullptr, "Unknown26"}, //20.1.0+
{27, nullptr, "Unknown27"}, //20.1.0+
{28, nullptr, "Unknown28"}, //20.1.0+
{29, nullptr, "Unknown29"}, //20.1.0+
{30, nullptr, "Unknown30"}, //20.1.0+
{0, nullptr, "Unknown0"},
{1, nullptr, "Unknown1"},
{2, nullptr, "Unknown2"},
{3, nullptr, "Unknown3"},
{4, nullptr, "Unknown4"},
{5, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder"},
{6, nullptr, "Unknown6"},
{7, nullptr, "Unknown7"},
{8, nullptr, "GetRemoteStorageController"},
{9, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder2"},
{10, nullptr, "Unknown10"},
{11, nullptr, "Unknown11"},
{12, nullptr, "Unknown12"},
{13, nullptr, "Unknown13"},
{14, nullptr, "Unknown14"},
{15, nullptr, "Unknown15"},
{16, nullptr, "Unknown16"},
{17, nullptr, "Unknown17"},
{18, nullptr, "Unknown18"},
{19, nullptr, "Unknown19"},
{20, nullptr, "Unknown20"},
{21, nullptr, "Unknown21"},
{22, nullptr, "Unknown22"},
{23, nullptr, "Unknown23"},
{24, nullptr, "Unknown24"},
{25, nullptr, "Unknown25"},
};
// clang-format on
@@ -53,14 +45,7 @@ ITransferTaskListController::ITransferTaskListController(Core::System& system_)
ITransferTaskListController::~ITransferTaskListController() = default;
Result ITransferTaskListController::GetTransferTaskEndEventNativeHandleHolder(
Out<SharedPointer<INativeHandleHolder>> out_holder) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
*out_holder = std::make_shared<INativeHandleHolder>(system);
R_SUCCEED();
}
Result ITransferTaskListController::GetTransferTaskStartEventNativeHandleHolder(
Result ITransferTaskListController::GetNativeHandleHolder(
Out<SharedPointer<INativeHandleHolder>> out_holder) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
*out_holder = std::make_shared<INativeHandleHolder>(system);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -17,8 +14,7 @@ public:
~ITransferTaskListController() override;
private:
Result GetTransferTaskEndEventNativeHandleHolder(Out<SharedPointer<INativeHandleHolder>> out_holder);
Result GetTransferTaskStartEventNativeHandleHolder(Out<SharedPointer<INativeHandleHolder>> out_holder);
Result GetNativeHandleHolder(Out<SharedPointer<INativeHandleHolder>> out_holder);
};
} // namespace Service::OLSC

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -37,10 +34,10 @@ public:
{17, nullptr, "AcquireIrq"},
{18, nullptr, "ReleaseIrq"},
{19, nullptr, "SetIrqEnable"},
{20, nullptr, "GetIrqEvent"},
{21, nullptr, "SetAspmEnable"},
{22, nullptr, "SetResetUponResumeEnable"},
{23, nullptr, "ResetFunction"},
{20, nullptr, "SetAspmEnable"},
{21, nullptr, "SetResetUponResumeEnable"},
{22, nullptr, "ResetFunction"},
{23, nullptr, "Unknown23"},
};
// clang-format on

View File

@@ -39,9 +39,6 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili
{1017, D<&IParentalControlService::EndFreeCommunication>, "EndFreeCommunication"},
{1018, D<&IParentalControlService::IsFreeCommunicationAvailable>, "IsFreeCommunicationAvailable"},
{1019, D<&IParentalControlService::ConfirmLaunchApplicationPermission>, "ConfirmLaunchApplicationPermission"},
{1020, nullptr, "ConfirmLaunchSharedApplicationPermission"}, //20.0.0+
{1021, nullptr, "TryBeginFreeCommunicationForStreamPlay"}, //21.0.0+
{1022, nullptr, "EndFreeCommunicationForStreamPlay"}, //21.0.0+
{1031, D<&IParentalControlService::IsRestrictionEnabled>, "IsRestrictionEnabled"},
{1032, D<&IParentalControlService::GetSafetyLevel>, "GetSafetyLevel"},
{1033, nullptr, "SetSafetyLevel"},
@@ -59,8 +56,6 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili
{1047, nullptr, "NotifyApplicationDownloadStarted"},
{1048, nullptr, "NotifyNetworkProfileCreated"},
{1049, nullptr, "ResetFreeCommunicationApplicationList"},
{1050, nullptr, "AddToFreeCommunicationApplicationList"}, //20.0.0+
{1051, nullptr, "NotifyApplicationDownloadStarted"}, //20.0.0+
{1061, D<&IParentalControlService::ConfirmStereoVisionRestrictionConfigurable>, "ConfirmStereoVisionRestrictionConfigurable"},
{1062, D<&IParentalControlService::GetStereoVisionRestriction>, "GetStereoVisionRestriction"},
{1063, D<&IParentalControlService::SetStereoVisionRestriction>, "SetStereoVisionRestriction"},
@@ -131,17 +126,8 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili
{2013, nullptr, "SynchronizeParentalControlSettingsAsync"},
{2014, nullptr, "FinishSynchronizeParentalControlSettings"},
{2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"},
{2016, nullptr, "RequestUpdateExemptionListAsync"}, //5.0.0+
{145601, D<&IParentalControlService::GetPlayTimerSettings>, "GetPlayTimerSettings"}, // 18.0.0+
{2017, nullptr, "AuthorizePairingAsync"}, //19.0.0+
{2019, nullptr, "RequestUpdateDeviceUsersBackground"}, //19.0.0+
{2021, nullptr, "RequestCopyPairingAsync"}, //20.0.0+
{2022, nullptr, "FinishRequestCopyPairing"}, //20.0.0+
{2023, nullptr, "IsFromPairingActiveDevice"}, //20.0.0+
{2024, nullptr, "RollbackCopyPairing"}, //21.0.0+
{3001, nullptr, "GetErrorContextChangedEvent"}, //20.0.0+
{145601, D<&IParentalControlService::GetPlayTimerSettings>, "GetPlayTimerSettings"}, // 18.0.0+
{195101, D<&IParentalControlService::SetPlayTimerSettings>, "SetPlayTimerSettingsForDebug"}, //18.0.0+
{2016, nullptr, "RequestUpdateExemptionListAsync"},
{145601, D<&IParentalControlService::GetPlayTimerSettings>, "GetPlayTimerSettings"} // 18.0.0+
};
// clang-format on
RegisterHandlers(functions);
@@ -407,21 +393,16 @@ Result IParentalControlService::IsRestrictedByPlayTimer(Out<bool> out_is_restric
}
Result IParentalControlService::GetPlayTimerSettingsOld(
Out<PlayTimerSettingsOld> out_play_timer_settings) {
Out<PlayTimerSettings> out_play_timer_settings) {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
*out_play_timer_settings = {};
R_SUCCEED();
}
Result IParentalControlService::GetPlayTimerSettings(Out<PlayTimerSettings> out_play_timer_settings) {
Result IParentalControlService::GetPlayTimerSettings(
Out<PlayTimerSettings> out_play_timer_settings) {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
*out_play_timer_settings = raw_play_timer_settings;
R_SUCCEED();
}
Result IParentalControlService::SetPlayTimerSettings(PlayTimerSettings play_timer_settings) {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
raw_play_timer_settings = play_timer_settings;
*out_play_timer_settings = {};
R_SUCCEED();
}

View File

@@ -51,7 +51,7 @@ private:
Result IsPlayTimerEnabled(Out<bool> out_is_play_timer_enabled);
Result GetPlayTimerRemainingTime(Out<s32> out_remaining_time);
Result IsRestrictedByPlayTimer(Out<bool> out_is_restricted_by_play_timer);
Result GetPlayTimerSettingsOld(Out<PlayTimerSettingsOld> out_play_timer_settings);
Result GetPlayTimerSettingsOld(Out<PlayTimerSettings> out_play_timer_settings);
Result GetPlayTimerEventToRequestSuspension(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result IsPlayTimerAlarmDisabled(Out<bool> out_play_timer_alarm_disabled);
Result GetPlayTimerRemainingTimeDisplayInfo();
@@ -60,7 +60,6 @@ private:
Result SetStereoVisionRestriction(bool stereo_vision_restriction);
Result ResetConfirmedStereoVisionPermission();
Result GetPlayTimerSettings(Out<PlayTimerSettings> out_play_timer_settings);
Result SetPlayTimerSettings(PlayTimerSettings out_play_timer_settings);
struct States {
u64 current_tid{};
@@ -84,8 +83,6 @@ private:
RestrictionSettings restriction_settings{};
std::array<char, 8> pin_code{};
Capability capability{};
// TODO: this is RAW as fuck
PlayTimerSettings raw_play_timer_settings{};
KernelHelpers::ServiceContext service_context;
Event synchronization_event;

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -37,16 +34,10 @@ struct RestrictionSettings {
};
static_assert(sizeof(RestrictionSettings) == 0x3, "RestrictionSettings has incorrect size.");
// This is nn::pctl::PlayTimerSettingsOld
struct PlayTimerSettingsOld {
std::array<u32, 13> settings;
};
static_assert(sizeof(PlayTimerSettingsOld) == 0x34, "PlayTimerSettingsOld has incorrect size.");
// This is nn::pctl::PlayTimerSettings
struct PlayTimerSettings {
std::array<u32, 17> settings; //21.0.0+ now takes 0x44
std::array<u32, 13> settings;
};
static_assert(sizeof(PlayTimerSettings) == 0x44, "PlayTimerSettings has incorrect size.");
static_assert(sizeof(PlayTimerSettings) == 0x34, "PlayTimerSettings has incorrect size.");
} // namespace Service::PCTL

View File

@@ -34,9 +34,9 @@ public:
{10300, &PlayReport::GetTransmissionStatus, "GetTransmissionStatus"},
{10400, &PlayReport::GetSystemSessionId, "GetSystemSessionId"},
{20100, &PlayReport::SaveSystemReportOld, "SaveSystemReport"},
{20101, &PlayReport::SaveSystemReportWithUserOld, "SaveSystemReportWithUser"},
{20102, &PlayReport::SaveSystemReport, "SaveSystemReport"},
{20103, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"},
{20101, &PlayReport::SaveSystemReportWithUserOld, "SaveSystemReportWithUser"},
{20102, &PlayReport::SaveSystemReport, "SaveSystemReport"},
{20103, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"},
{20200, nullptr, "SetOperationMode"},
{30100, nullptr, "ClearStorage"},
{30200, nullptr, "ClearStatistics"},

View File

@@ -18,43 +18,49 @@
namespace Service {
/// @brief Creates a function string for logging, complete with the name (or header code, depending
/// on what's passed in) the port name, and all the cmd_buff arguments.
[[maybe_unused]] static std::string MakeFunctionString(std::string_view name, std::string_view port_name, const u32* cmd_buff) {
/**
* Creates a function string for logging, complete with the name (or header code, depending
* on what's passed in) the port name, and all the cmd_buff arguments.
*/
[[maybe_unused]] static std::string MakeFunctionString(std::string_view name,
std::string_view port_name,
const u32* cmd_buff) {
// Number of params == bits 0-5 + bits 6-11
int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F);
std::string function_string = fmt::format("function '{}': port={}", name, port_name);
for (int i = 1; i <= num_params; ++i)
for (int i = 1; i <= num_params; ++i) {
function_string += fmt::format(", cmd_buff[{}]={:#X}", i, cmd_buff[i]);
}
return function_string;
}
ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_,
u32 max_sessions_, InvokerFn* handler_invoker_)
: SessionRequestHandler(system_.Kernel(), service_name_), system{system_},
service_name{service_name_}, handler_invoker{handler_invoker_}, max_sessions{max_sessions_} {}
service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {}
ServiceFrameworkBase::~ServiceFrameworkBase() {
// Wait for other threads to release access before destroying
const auto guard = ServiceFrameworkBase::LockService();
const auto guard = LockService();
}
void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) {
// Usually this array is sorted by id already, so hint to insert at the end
handlers.reserve(handlers.size() + n);
for (std::size_t i = 0; i < n; ++i)
for (std::size_t i = 0; i < n; ++i) {
// Usually this array is sorted by id already, so hint to insert at the end
handlers.emplace_hint(handlers.cend(), functions[i].expected_header, functions[i]);
}
}
void ServiceFrameworkBase::RegisterHandlersBaseTipc(const FunctionInfoBase* functions, std::size_t n) {
// Usually this array is sorted by id already, so hint to insert at the end
void ServiceFrameworkBase::RegisterHandlersBaseTipc(const FunctionInfoBase* functions,
std::size_t n) {
handlers_tipc.reserve(handlers_tipc.size() + n);
for (std::size_t i = 0; i < n; ++i)
for (std::size_t i = 0; i < n; ++i) {
// Usually this array is sorted by id already, so hint to insert at the end
handlers_tipc.emplace_hint(handlers_tipc.cend(), functions[i].expected_header,
functions[i]);
}
}
void ServiceFrameworkBase::ReportUnimplementedFunction(HLERequestContext& ctx,
@@ -63,12 +69,15 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(HLERequestContext& ctx,
std::string function_name = info == nullptr ? "<unknown>" : info->name;
fmt::memory_buffer buf;
fmt::format_to(std::back_inserter(buf), "function '{}({})': port='{}' cmd_buf={{[0]={:#X}", ctx.GetCommand(), function_name, service_name, cmd_buf[0]);
for (int i = 1; i <= 8; ++i)
fmt::format_to(std::back_inserter(buf), "function '{}({})': port='{}' cmd_buf={{[0]={:#X}",
ctx.GetCommand(), function_name, service_name, cmd_buf[0]);
for (int i = 1; i <= 8; ++i) {
fmt::format_to(std::back_inserter(buf), ", [{}]={:#X}", i, cmd_buf[i]);
}
buf.push_back('}');
system.GetReporter().SaveUnimplementedFunctionReport(ctx, ctx.GetCommand(), function_name, service_name);
system.GetReporter().SaveUnimplementedFunctionReport(ctx, ctx.GetCommand(), function_name,
service_name);
UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf));
if (Settings::values.use_auto_stub) {
LOG_WARNING(Service, "Using auto stub fallback!");
@@ -78,20 +87,25 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(HLERequestContext& ctx,
}
void ServiceFrameworkBase::InvokeRequest(HLERequestContext& ctx) {
auto it = handlers.find(ctx.GetCommand());
FunctionInfoBase const* info = it == handlers.end() ? nullptr : &it->second;
if (info == nullptr || info->handler_callback == nullptr)
auto itr = handlers.find(ctx.GetCommand());
const FunctionInfoBase* info = itr == handlers.end() ? nullptr : &itr->second;
if (info == nullptr || info->handler_callback == nullptr) {
return ReportUnimplementedFunction(ctx, info);
}
LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName(), ctx.CommandBuffer()));
handler_invoker(this, info->handler_callback, ctx);
}
void ServiceFrameworkBase::InvokeRequestTipc(HLERequestContext& ctx) {
auto it = handlers_tipc.find(ctx.GetCommand());
FunctionInfoBase const* info = it == handlers_tipc.end() ? nullptr : &it->second;
if (info == nullptr || info->handler_callback == nullptr)
boost::container::flat_map<u32, FunctionInfoBase>::iterator itr;
itr = handlers_tipc.find(ctx.GetCommand());
const FunctionInfoBase* info = itr == handlers_tipc.end() ? nullptr : &itr->second;
if (info == nullptr || info->handler_callback == nullptr) {
return ReportUnimplementedFunction(ctx, info);
}
LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName(), ctx.CommandBuffer()));
handler_invoker(this, info->handler_callback, ctx);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -50,23 +47,25 @@ static_assert(ServerSessionCountMax == 0x40,
class ServiceFrameworkBase : public SessionRequestHandler {
public:
/// Returns the string identifier used to connect to the service.
[[nodiscard]] std::string_view GetServiceName() const noexcept {
std::string GetServiceName() const {
return service_name;
}
/// @brief Returns the maximum number of sessions that can be connected to this service at the same
/// time.
u32 GetMaxSessions() const noexcept {
/**
* Returns the maximum number of sessions that can be connected to this service at the same
* time.
*/
u32 GetMaxSessions() const {
return max_sessions;
}
/// @brief Invokes a service request routine using the HIPC protocol.
/// Invokes a service request routine using the HIPC protocol.
void InvokeRequest(HLERequestContext& ctx);
/// @brief Invokes a service request routine using the HIPC protocol.
/// Invokes a service request routine using the HIPC protocol.
void InvokeRequestTipc(HLERequestContext& ctx);
/// @brief Handles a synchronization request for the service.
/// Handles a synchronization request for the service.
Result HandleSyncRequest(Kernel::KServerSession& session, HLERequestContext& context) override;
protected:
@@ -75,7 +74,7 @@ protected:
using HandlerFnP = void (Self::*)(HLERequestContext&);
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
[[nodiscard]] virtual std::unique_lock<std::mutex> LockService() noexcept {
[[nodiscard]] virtual std::unique_lock<std::mutex> LockService() {
return std::unique_lock{lock_service};
}
@@ -106,19 +105,20 @@ private:
void RegisterHandlersBaseTipc(const FunctionInfoBase* functions, std::size_t n);
void ReportUnimplementedFunction(HLERequestContext& ctx, const FunctionInfoBase* info);
boost::container::flat_map<u32, FunctionInfoBase> handlers;
boost::container::flat_map<u32, FunctionInfoBase> handlers_tipc;
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
std::mutex lock_service;
/// Function used to safely up-cast pointers to the derived class before invoking a handler.
InvokerFn* handler_invoker;
/// Maximum number of concurrent sessions that this service can handle.
u32 max_sessions;
/// Flag to store if a port was already create/installed to detect multiple install attempts,
/// which is not supported.
bool service_registered = false;
/// Function used to safely up-cast pointers to the derived class before invoking a handler.
InvokerFn* handler_invoker;
boost::container::flat_map<u32, FunctionInfoBase> handlers;
boost::container::flat_map<u32, FunctionInfoBase> handlers_tipc;
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
std::mutex lock_service;
};
/**
@@ -142,12 +142,20 @@ protected:
// TODO(yuriks): This function could be constexpr, but clang is the only compiler that
// doesn't emit an ICE or a wrong diagnostic because of the static_cast.
/// @brief Constructs a FunctionInfo for a function.
/// @param expected_header_ request header in the command buffer which will trigger dispatch to this handler
/// @param handler_callback_ member function in this service which will be called to handle the request
/// @param name_ human-friendly name for the request. Used mostly for logging purposes.
constexpr FunctionInfoTyped(u32 expected_header_, HandlerFnP<T> handler_callback_, const char* name_)
: FunctionInfoBase{expected_header_, HandlerFnP<ServiceFrameworkBase>(handler_callback_), name_} {}
/**
* Constructs a FunctionInfo for a function.
*
* @param expected_header_ request header in the command buffer which will trigger dispatch
* to this handler
* @param handler_callback_ member function in this service which will be called to handle
* the request
* @param name_ human-friendly name for the request. Used mostly for logging purposes.
*/
FunctionInfoTyped(u32 expected_header_, HandlerFnP<T> handler_callback_, const char* name_)
: FunctionInfoBase{
expected_header_,
// Type-erase member function pointer by casting it down to the base class.
static_cast<HandlerFnP<ServiceFrameworkBase>>(handler_callback_), name_} {}
};
using FunctionInfo = FunctionInfoTyped<Self>;

View File

@@ -1082,7 +1082,8 @@ BSD::~BSD() {
}
}
std::unique_lock<std::mutex> BSD::LockService() noexcept {
std::unique_lock<std::mutex> BSD::LockService() {
// Do not lock socket IClient instances.
return {};
}

View File

@@ -188,7 +188,7 @@ private:
Network::RoomMember::CallbackHandle<Network::ProxyPacket> proxy_packet_received;
protected:
std::unique_lock<std::mutex> LockService() noexcept override;
virtual std::unique_lock<std::mutex> LockService() override;
};
class BSDCFG final : public ServiceFramework<BSDCFG> {

View File

@@ -10,7 +10,6 @@
#include <mutex>
#include <span>
#include <thread>
#include <type_traits>
#include <vector>
#include "common/assert.h"
@@ -682,17 +681,22 @@ struct Memory::Impl {
}
}
template<typename F, typename G>
[[nodiscard]] u8* GetPointerImpl(u64 vaddr, F&& on_unmapped, G&& on_rasterizer) const {
[[nodiscard]] u8* GetPointerImpl(u64 vaddr, auto on_unmapped, auto on_rasterizer) const {
// AARCH64 masks the upper 16 bit of all memory accesses
vaddr &= 0xffffffffffffULL;
if (AddressSpaceContains(*current_page_table, vaddr, 1)) [[likely]] {
vaddr = vaddr & 0xffffffffffffULL;
if (!AddressSpaceContains(*current_page_table, vaddr, 1)) [[unlikely]] {
on_unmapped();
return nullptr;
} else {
// Avoid adding any extra logic to this fast-path block
const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw();
if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) [[likely]] {
if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
return reinterpret_cast<u8*>(pointer + vaddr);
} else {
switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
case Common::PageType::Unmapped:
on_unmapped();
return nullptr;
case Common::PageType::Memory:
ASSERT_MSG(false, "Mapped memory page without a pointer @ 0x{:016X}", vaddr);
return nullptr;
@@ -703,18 +707,11 @@ struct Memory::Impl {
on_rasterizer();
return host_ptr;
}
case Common::PageType::Unmapped: [[unlikely]] {
on_unmapped();
return nullptr;
}
default:
UNREACHABLE();
}
return nullptr;
}
} else {
on_unmapped();
return nullptr;
}
}
@@ -732,38 +729,172 @@ struct Memory::Impl {
GetInteger(vaddr), []() {}, []() {});
}
/// @brief Reads a particular data type out of memory at the given virtual address.
/// @param vaddr The virtual address to read the data type from.
/// @tparam T The data type to read out of memory.
/// @returns The instance of T read from the specified virtual address.
/**
* Reads a particular data type out of memory at the given virtual address.
*
* @param vaddr The virtual address to read the data type from.
*
* @tparam T The data type to read out of memory. This type *must* be
* trivially copyable, otherwise the behavior of this function
* is undefined.
*
* @returns The instance of T read from the specified virtual address.
*/
template <typename T>
inline T Read(Common::ProcessAddress vaddr) noexcept requires(std::is_trivially_copyable_v<T>) {
T Read(Common::ProcessAddress vaddr) {
// Fast path for aligned reads of common sizes
const u64 addr = GetInteger(vaddr);
if (auto const ptr = GetPointerImpl(addr, [addr]() {
LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8, addr);
}, [&]() {
HandleRasterizerDownload(addr, sizeof(T));
}); ptr) [[likely]] {
// It may be tempting to rewrite this particular section to use "reinterpret_cast";
// afterall, it's trivially copyable so surely it can be copied ov- Alignment.
// Remember, alignment. memcpy() will deal with all the alignment extremely fast.
T result{};
std::memcpy(&result, ptr, sizeof(T));
return result;
if constexpr (std::is_same_v<T, u8> || std::is_same_v<T, s8>) {
// 8-bit reads are always aligned
const u8* const ptr = GetPointerImpl(
addr,
[addr]() {
LOG_ERROR(HW_Memory, "Unmapped Read8 @ 0x{:016X}", addr);
},
[&]() { HandleRasterizerDownload(addr, sizeof(T)); });
if (ptr) {
return static_cast<T>(*ptr);
}
return 0;
} else if constexpr (std::is_same_v<T, u16_le> || std::is_same_v<T, s16_le>) {
// Check alignment for 16-bit reads
if ((addr & 1) == 0) {
const u8* const ptr = GetPointerImpl(
addr,
[addr]() {
LOG_ERROR(HW_Memory, "Unmapped Read16 @ 0x{:016X}", addr);
},
[&]() { HandleRasterizerDownload(addr, sizeof(T)); });
if (ptr) {
return static_cast<T>(*reinterpret_cast<const u16*>(ptr));
}
}
} else if constexpr (std::is_same_v<T, u32_le> || std::is_same_v<T, s32_le>) {
// Check alignment for 32-bit reads
if ((addr & 3) == 0) {
const u8* const ptr = GetPointerImpl(
addr,
[addr]() {
LOG_ERROR(HW_Memory, "Unmapped Read32 @ 0x{:016X}", addr);
},
[&]() { HandleRasterizerDownload(addr, sizeof(T)); });
if (ptr) {
return static_cast<T>(*reinterpret_cast<const u32*>(ptr));
}
}
} else if constexpr (std::is_same_v<T, u64_le> || std::is_same_v<T, s64_le>) {
// Check alignment for 64-bit reads
if ((addr & 7) == 0) {
const u8* const ptr = GetPointerImpl(
addr,
[addr]() {
LOG_ERROR(HW_Memory, "Unmapped Read64 @ 0x{:016X}", addr);
},
[&]() { HandleRasterizerDownload(addr, sizeof(T)); });
if (ptr) {
return static_cast<T>(*reinterpret_cast<const u64*>(ptr));
}
}
}
return T{};
// Fall back to the general case for other types or unaligned access
T result = 0;
const u8* const ptr = GetPointerImpl(
addr,
[addr]() {
LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8, addr);
},
[&]() { HandleRasterizerDownload(addr, sizeof(T)); });
if (ptr) {
std::memcpy(&result, ptr, sizeof(T));
}
return result;
}
/// @brief Writes a particular data type to memory at the given virtual address.
/// @param vaddr The virtual address to write the data type to.
/// @tparam T The data type to write to memory.
/**
* Writes a particular data type to memory at the given virtual address.
*
* @param vaddr The virtual address to write the data type to.
*
* @tparam T The data type to write to memory. This type *must* be
* trivially copyable, otherwise the behavior of this function
* is undefined.
*/
template <typename T>
inline void Write(Common::ProcessAddress vaddr, const T data) noexcept requires(std::is_trivially_copyable_v<T>) {
void Write(Common::ProcessAddress vaddr, const T data) {
// Fast path for aligned writes of common sizes
const u64 addr = GetInteger(vaddr);
if (auto const ptr = GetPointerImpl(addr, [addr, data]() {
LOG_ERROR(HW_Memory, "Unmapped Write{} @ 0x{:016X} = 0x{:016X}", sizeof(T) * 8, addr, u64(data));
}, [&]() { HandleRasterizerWrite(addr, sizeof(T)); }); ptr) [[likely]]
if constexpr (std::is_same_v<T, u8> || std::is_same_v<T, s8>) {
// 8-bit writes are always aligned
u8* const ptr = GetPointerImpl(
addr,
[addr, data]() {
LOG_ERROR(HW_Memory, "Unmapped Write8 @ 0x{:016X} = 0x{:02X}", addr,
static_cast<u8>(data));
},
[&]() { HandleRasterizerWrite(addr, sizeof(T)); });
if (ptr) {
*ptr = static_cast<u8>(data);
}
return;
} else if constexpr (std::is_same_v<T, u16_le> || std::is_same_v<T, s16_le>) {
// Check alignment for 16-bit writes
if ((addr & 1) == 0) {
u8* const ptr = GetPointerImpl(
addr,
[addr, data]() {
LOG_ERROR(HW_Memory, "Unmapped Write16 @ 0x{:016X} = 0x{:04X}", addr,
static_cast<u16>(data));
},
[&]() { HandleRasterizerWrite(addr, sizeof(T)); });
if (ptr) {
*reinterpret_cast<u16*>(ptr) = static_cast<u16>(data);
return;
}
}
} else if constexpr (std::is_same_v<T, u32_le> || std::is_same_v<T, s32_le>) {
// Check alignment for 32-bit writes
if ((addr & 3) == 0) {
u8* const ptr = GetPointerImpl(
addr,
[addr, data]() {
LOG_ERROR(HW_Memory, "Unmapped Write32 @ 0x{:016X} = 0x{:08X}", addr,
static_cast<u32>(data));
},
[&]() { HandleRasterizerWrite(addr, sizeof(T)); });
if (ptr) {
*reinterpret_cast<u32*>(ptr) = static_cast<u32>(data);
return;
}
}
} else if constexpr (std::is_same_v<T, u64_le> || std::is_same_v<T, s64_le>) {
// Check alignment for 64-bit writes
if ((addr & 7) == 0) {
u8* const ptr = GetPointerImpl(
addr,
[addr, data]() {
LOG_ERROR(HW_Memory, "Unmapped Write64 @ 0x{:016X} = 0x{:016X}", addr,
static_cast<u64>(data));
},
[&]() { HandleRasterizerWrite(addr, sizeof(T)); });
if (ptr) {
*reinterpret_cast<u64*>(ptr) = static_cast<u64>(data);
return;
}
}
}
// Fall back to the general case for other types or unaligned access
u8* const ptr = GetPointerImpl(
addr,
[addr, data]() {
LOG_ERROR(HW_Memory, "Unmapped Write{} @ 0x{:016X} = 0x{:016X}", sizeof(T) * 8,
addr, static_cast<u64>(data));
},
[&]() { HandleRasterizerWrite(addr, sizeof(T)); });
if (ptr) {
std::memcpy(ptr, &data, sizeof(T));
}
}
template <typename T>

View File

@@ -14,7 +14,7 @@
#include "input_common/drivers/mouse.h"
namespace InputCommon {
constexpr int update_time = 10;
constexpr int update_time = 250; // 4 TPS
constexpr float default_panning_sensitivity = 0.0010f;
constexpr float default_stick_sensitivity = 0.0006f;
constexpr float default_deadzone_counterweight = 0.01f;

View File

@@ -1049,7 +1049,7 @@ void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRend
VkShaderModule frag_shader = *convert_float_to_depth_frag;
const std::array stages = MakeStages(*full_screen_vert, frag_shader);
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
pipeline = device.GetLogical().CreateGraphicsPipeline({
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
@@ -1079,7 +1079,7 @@ void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRend
VkShaderModule frag_shader = *convert_depth_to_float_frag;
const std::array stages = MakeStages(*full_screen_vert, frag_shader);
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
pipeline = device.GetLogical().CreateGraphicsPipeline({
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
@@ -1110,7 +1110,7 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass ren
}
const std::array stages = MakeStages(*full_screen_vert, *module);
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
pipeline = device.GetLogical().CreateGraphicsPipeline({
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
@@ -1152,7 +1152,7 @@ void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass rende
is_target_depth ? *convert_float_to_depth_frag : *convert_depth_to_float_frag;
const std::array stages = MakeStages(*full_screen_vert, frag_shader);
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
pipeline = device.GetLogical().CreateGraphicsPipeline({
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,

View File

@@ -137,8 +137,14 @@ try
memory_allocator,
scheduler,
swapchain,
#ifdef ANDROID
surface)
,
#else
*surface)
, blit_swapchain(device_memory,
,
#endif
blit_swapchain(device_memory,
device,
memory_allocator,
present_manager,

View File

@@ -284,7 +284,7 @@ ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool,
.requiredSubgroupSize = optional_subgroup_size ? *optional_subgroup_size : 32U,
};
bool use_setup_size = device.IsExtSubgroupSizeControlSupported() && optional_subgroup_size;
pipeline = device.GetLogical().CreateComputePipeline(VkComputePipelineCreateInfo{
pipeline = device.GetLogical().CreateComputePipeline({
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
@@ -298,7 +298,7 @@ ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool,
.pSpecializationInfo = nullptr,
},
.layout = *layout,
.basePipelineHandle = {},
.basePipelineHandle = nullptr,
.basePipelineIndex = 0,
});
}
@@ -653,7 +653,7 @@ MSAACopyPass::MSAACopyPass(const Device& device_, Scheduler& scheduler_,
.codeSize = static_cast<u32>(code.size_bytes()),
.pCode = code.data(),
});
pipelines[i] = device.GetLogical().CreateComputePipeline(VkComputePipelineCreateInfo{
pipelines[i] = device.GetLogical().CreateComputePipeline({
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
@@ -667,7 +667,7 @@ MSAACopyPass::MSAACopyPass(const Device& device_, Scheduler& scheduler_,
.pSpecializationInfo = nullptr,
},
.layout = *layout,
.basePipelineHandle = {},
.basePipelineHandle = nullptr,
.basePipelineIndex = 0,
});
};

View File

@@ -61,24 +61,26 @@ ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipel
if (device.IsKhrPipelineExecutablePropertiesEnabled() && Settings::values.renderer_debug.GetValue()) {
flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
}
pipeline = device.GetLogical().CreateComputePipeline(VkComputePipelineCreateInfo{
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.flags = flags,
.stage{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext =
device.IsExtSubgroupSizeControlSupported() ? &subgroup_size_ci : nullptr,
.flags = 0,
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
.module = *spv_module,
.pName = "main",
.pSpecializationInfo = nullptr,
pipeline = device.GetLogical().CreateComputePipeline(
{
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.flags = flags,
.stage{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext =
device.IsExtSubgroupSizeControlSupported() ? &subgroup_size_ci : nullptr,
.flags = 0,
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
.module = *spv_module,
.pName = "main",
.pSpecializationInfo = nullptr,
},
.layout = *pipeline_layout,
.basePipelineHandle = 0,
.basePipelineIndex = 0,
},
.layout = *pipeline_layout,
.basePipelineHandle = 0,
.basePipelineIndex = 0,
}, *pipeline_cache);
*pipeline_cache);
if (pipeline_statistics) {
pipeline_statistics->Collect(*pipeline);

View File

@@ -936,27 +936,29 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
}
pipeline = device.GetLogical().CreateGraphicsPipeline({
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.flags = flags,
.stageCount = static_cast<u32>(shader_stages.size()),
.pStages = shader_stages.data(),
.pVertexInputState = &vertex_input_ci,
.pInputAssemblyState = &input_assembly_ci,
.pTessellationState = &tessellation_ci,
.pViewportState = &viewport_ci,
.pRasterizationState = &rasterization_ci,
.pMultisampleState = &multisample_ci,
.pDepthStencilState = &depth_stencil_ci,
.pColorBlendState = &color_blend_ci,
.pDynamicState = &dynamic_state_ci,
.layout = *pipeline_layout,
.renderPass = render_pass,
.subpass = 0,
.basePipelineHandle = {},
.basePipelineIndex = 0,
}, *pipeline_cache);
pipeline = device.GetLogical().CreateGraphicsPipeline(
{
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.flags = flags,
.stageCount = static_cast<u32>(shader_stages.size()),
.pStages = shader_stages.data(),
.pVertexInputState = &vertex_input_ci,
.pInputAssemblyState = &input_assembly_ci,
.pTessellationState = &tessellation_ci,
.pViewportState = &viewport_ci,
.pRasterizationState = &rasterization_ci,
.pMultisampleState = &multisample_ci,
.pDepthStencilState = &depth_stencil_ci,
.pColorBlendState = &color_blend_ci,
.pDynamicState = &dynamic_state_ci,
.layout = *pipeline_layout,
.renderPass = render_pass,
.subpass = 0,
.basePipelineHandle = nullptr,
.basePipelineIndex = 0,
},
*pipeline_cache);
}
void GraphicsPipeline::Validate() {

View File

@@ -101,14 +101,22 @@ PresentManager::PresentManager(const vk::Instance& instance_,
MemoryAllocator& memory_allocator_,
Scheduler& scheduler_,
Swapchain& swapchain_,
VkSurfaceKHR_T* surface_)
#ifdef ANDROID
vk::SurfaceKHR& surface_)
#else
VkSurfaceKHR_T* surface_handle_)
#endif
: instance{instance_}
, render_window{render_window_}
, device{device_}
, memory_allocator{memory_allocator_}
, scheduler{scheduler_}
, swapchain{swapchain_}
#ifdef ANDROID
, surface{surface_}
#else
, surface_handle{surface_handle_}
#endif
, blit_supported{CanBlitToSwapchain(device.GetPhysical(), swapchain.GetImageViewFormat())}
, use_present_thread{Settings::values.async_presentation.GetValue()}
{
@@ -138,7 +146,7 @@ PresentManager::PresentManager(const vk::Instance& instance_,
.pNext = nullptr,
.flags = VK_FENCE_CREATE_SIGNALED_BIT,
});
free_queue.push_back(&frame);
free_queue.push(&frame);
}
if (use_present_thread) {
@@ -156,7 +164,7 @@ Frame* PresentManager::GetRenderFrame() {
// Take the frame from the queue
Frame* frame = free_queue.front();
free_queue.pop_front();
free_queue.pop();
// Wait for the presentation to be finished so all frame resources are free
frame->present_done.Wait();
@@ -166,17 +174,18 @@ Frame* PresentManager::GetRenderFrame() {
}
void PresentManager::Present(Frame* frame) {
if (use_present_thread) {
scheduler.Record([this, frame](vk::CommandBuffer) {
std::unique_lock lock{queue_mutex};
present_queue.push_back(frame);
frame_cv.notify_one();
});
} else {
if (!use_present_thread) {
scheduler.WaitWorker();
CopyToSwapchain(frame);
free_queue.push_back(frame);
free_queue.push(frame);
return;
}
scheduler.Record([this, frame](vk::CommandBuffer) {
std::unique_lock lock{queue_mutex};
present_queue.push(frame);
frame_cv.notify_one();
});
}
void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat image_view_format,
@@ -268,30 +277,38 @@ void PresentManager::PresentThread(std::stop_token token) {
Common::SetCurrentThreadName("VulkanPresent");
while (!token.stop_requested()) {
std::unique_lock lock{queue_mutex};
// Wait for presentation frames
frame_cv.wait(lock, token, [this] { return !present_queue.empty(); });
if (!token.stop_requested()) {
// Take the frame and notify anyone waiting
Frame* frame = present_queue.front();
present_queue.pop_front();
frame_cv.notify_one();
// By exchanging the lock ownership we take the swapchain lock
// before the queue lock goes out of scope. This way the swapchain
// lock in WaitPresent is guaranteed to occur after here.
std::exchange(lock, std::unique_lock{swapchain_mutex});
CopyToSwapchain(frame);
// Free the frame for reuse
std::scoped_lock fl{free_mutex};
free_queue.push_back(frame);
free_cv.notify_one();
if (token.stop_requested()) {
return;
}
// Take the frame and notify anyone waiting
Frame* frame = present_queue.front();
present_queue.pop();
frame_cv.notify_one();
// By exchanging the lock ownership we take the swapchain lock
// before the queue lock goes out of scope. This way the swapchain
// lock in WaitPresent is guaranteed to occur after here.
std::exchange(lock, std::unique_lock{swapchain_mutex});
CopyToSwapchain(frame);
// Free the frame for reuse
std::scoped_lock fl{free_mutex};
free_queue.push(frame);
free_cv.notify_one();
}
}
void PresentManager::RecreateSwapchain(Frame* frame) {
swapchain.Create(surface, frame->width, frame->height); // Pass raw pointer
#ifndef ANDROID
swapchain.Create(surface_handle, frame->width, frame->height); // Pass raw pointer
#else
swapchain.Create(*surface, frame->width, frame->height); // Pass raw pointer
#endif
SetImageCount();
}
@@ -310,7 +327,7 @@ void PresentManager::CopyToSwapchain(Frame* frame) {
// Recreate surface and swapchain if needed.
if (requires_recreation) {
#ifdef ANDROID
surface = reinterpret_cast<VkSurfaceKHR_T*>(CreateSurface(instance, render_window.GetWindowInfo()).address());
surface = CreateSurface(instance, render_window.GetWindowInfo());
#endif
RecreateSwapchain(frame);
}

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -8,13 +5,15 @@
#include <condition_variable>
#include <mutex>
#include <boost/container/deque.hpp>
#include <queue>
#include "common/common_types.h"
#include "common/polyfill_thread.h"
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
struct VkSurfaceKHR_T;
namespace Core::Frontend {
class EmuWindow;
} // namespace Core::Frontend
@@ -44,7 +43,11 @@ public:
MemoryAllocator& memory_allocator,
Scheduler& scheduler,
Swapchain& swapchain,
VkSurfaceKHR_T* surface);
#ifdef ANDROID
vk::SurfaceKHR& surface);
#else
VkSurfaceKHR_T* surface_handle);
#endif
~PresentManager();
/// Returns the last used presentation frame
@@ -78,11 +81,15 @@ private:
MemoryAllocator& memory_allocator;
Scheduler& scheduler;
Swapchain& swapchain;
VkSurfaceKHR_T* surface;
#ifdef ANDROID
vk::SurfaceKHR& surface;
#else
VkSurfaceKHR_T* surface_handle;
#endif
vk::CommandPool cmdpool;
std::vector<Frame> frames;
boost::container::deque<Frame*> present_queue;
boost::container::deque<Frame*> free_queue;
std::queue<Frame*> present_queue;
std::queue<Frame*> free_queue;
std::condition_variable_any frame_cv;
std::condition_variable free_cv;
std::mutex swapchain_mutex;

View File

@@ -1278,7 +1278,7 @@ void QueryCacheRuntime::EndHostConditionalRendering() {
PauseHostConditionalRendering();
impl->hcr_is_set = false;
impl->is_hcr_running = false;
impl->hcr_buffer = VkBuffer{};
impl->hcr_buffer = nullptr;
impl->hcr_offset = 0;
}

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -38,7 +35,7 @@ public:
~QueryCacheRuntime();
template <typename SyncValuesType>
void SyncValues(std::span<SyncValuesType> values, VkBuffer base_src_buffer = VkBuffer{});
void SyncValues(std::span<SyncValuesType> values, VkBuffer base_src_buffer = nullptr);
void Barriers(bool is_prebarrier);

View File

@@ -342,7 +342,7 @@ void Scheduler::EndRenderPass()
);
});
state.renderpass = VkRenderPass{};
state.renderpass = nullptr;
num_renderpass_images = 0;
}

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -43,10 +40,10 @@ public:
~Scheduler();
/// Sends the current execution context to the GPU.
u64 Flush(VkSemaphore signal_semaphore = {}, VkSemaphore wait_semaphore = {});
u64 Flush(VkSemaphore signal_semaphore = nullptr, VkSemaphore wait_semaphore = nullptr);
/// Sends the current execution context to the GPU and waits for it to complete.
void Finish(VkSemaphore signal_semaphore = {}, VkSemaphore wait_semaphore = {});
void Finish(VkSemaphore signal_semaphore = nullptr, VkSemaphore wait_semaphore = nullptr);
/// Waits for the worker thread to finish executing everything. After this function returns it's
/// safe to touch worker resources.
@@ -211,8 +208,8 @@ private:
};
struct State {
VkRenderPass renderpass{};
VkFramebuffer framebuffer{};
VkRenderPass renderpass = nullptr;
VkFramebuffer framebuffer = nullptr;
VkExtent2D render_area = {0, 0};
GraphicsPipeline* graphics_pipeline = nullptr;
bool is_rescaling = false;

View File

@@ -109,22 +109,38 @@ VkCompositeAlphaFlagBitsKHR ChooseAlphaFlags(const VkSurfaceCapabilitiesKHR& cap
} // Anonymous namespace
Swapchain::Swapchain(
VkSurfaceKHR_T* surface_,
#ifdef ANDROID
VkSurfaceKHR surface_,
#else
VkSurfaceKHR_T* surface_handle_,
#endif
const Device& device_,
Scheduler& scheduler_,
u32 width_,
u32 height_)
#ifdef ANDROID
: surface(surface_)
#else
: surface_handle{surface_handle_}
#endif
, device{device_}
, scheduler{scheduler_}
{
#ifdef ANDROID
Create(surface, width_, height_);
#else
Create(surface_handle, width_, height_);
#endif
}
Swapchain::~Swapchain() = default;
void Swapchain::Create(
VkSurfaceKHR_T* surface_,
#ifdef ANDROID
VkSurfaceKHR surface_,
#else
VkSurfaceKHR_T* surface_handle_,
#endif
u32 width_,
u32 height_)
{
@@ -132,10 +148,18 @@ void Swapchain::Create(
is_suboptimal = false;
width = width_;
height = height_;
#ifdef ANDROID
surface = surface_;
#else
surface_handle = surface_handle_;
#endif
const auto physical_device = device.GetPhysical();
const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(VkSurfaceKHR(surface))};
#ifdef ANDROID
const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)};
#else
const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface_handle)};
#endif
if (capabilities.maxImageExtent.width == 0 || capabilities.maxImageExtent.height == 0) {
return;
}
@@ -213,8 +237,14 @@ void Swapchain::Present(VkSemaphore render_semaphore) {
void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities) {
const auto physical_device{device.GetPhysical()};
const auto formats{physical_device.GetSurfaceFormatsKHR(VkSurfaceKHR(surface))};
const auto present_modes = physical_device.GetSurfacePresentModesKHR(VkSurfaceKHR(surface));
#ifdef ANDROID
const auto formats{physical_device.GetSurfaceFormatsKHR(surface)};
const auto present_modes = physical_device.GetSurfacePresentModesKHR(surface);
#else
const auto formats{physical_device.GetSurfaceFormatsKHR(surface_handle)};
const auto present_modes = physical_device.GetSurfacePresentModesKHR(surface_handle);
#endif
has_mailbox = std::find(present_modes.begin(), present_modes.end(), VK_PRESENT_MODE_MAILBOX_KHR)
!= present_modes.end();
@@ -243,7 +273,11 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities) {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.pNext = nullptr,
.flags = 0,
.surface = VkSurfaceKHR(surface),
#ifdef ANDROID
.surface = surface,
#else
.surface = surface_handle,
#endif
.minImageCount = requested_image_count,
.imageFormat = surface_format.format,
.imageColorSpace = surface_format.colorSpace,
@@ -262,7 +296,7 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities) {
.compositeAlpha = alpha_flags,
.presentMode = present_mode,
.clipped = VK_FALSE,
.oldSwapchain = VkSwapchainKHR{},
.oldSwapchain = nullptr,
};
const u32 graphics_family{device.GetGraphicsFamily()};
const u32 present_family{device.GetPresentFamily()};
@@ -284,7 +318,11 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities) {
swapchain_ci.flags |= VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR;
}
// Request the size again to reduce the possibility of a TOCTOU race condition.
const auto updated_capabilities = physical_device.GetSurfaceCapabilitiesKHR(VkSurfaceKHR(surface));
#ifdef ANDROID
const auto updated_capabilities = physical_device.GetSurfaceCapabilitiesKHR(surface);
#else
const auto updated_capabilities = physical_device.GetSurfaceCapabilitiesKHR(surface_handle);
#endif
swapchain_ci.imageExtent = ChooseSwapExtent(updated_capabilities, width, height);
// Don't add code within this and the swapchain creation.
swapchain = device.GetLogical().CreateSwapchainKHR(swapchain_ci);

View File

@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -11,6 +8,8 @@
#include "common/common_types.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
struct VkSurfaceKHR_T;
namespace Layout {
struct FramebufferLayout;
}
@@ -23,7 +22,11 @@ class Scheduler;
class Swapchain {
public:
explicit Swapchain(
VkSurfaceKHR_T* surface,
#ifdef ANDROID
VkSurfaceKHR surface,
#else
VkSurfaceKHR_T* surface_handle,
#endif
const Device& device,
Scheduler& scheduler,
u32 width,
@@ -32,7 +35,11 @@ public:
/// Creates (or recreates) the swapchain with a given size.
void Create(
VkSurfaceKHR_T* surface,
#ifdef ANDROID
VkSurfaceKHR surface,
#else
VkSurfaceKHR_T* surface_handle,
#endif
u32 width,
u32 height);
@@ -118,7 +125,11 @@ private:
bool NeedsPresentModeUpdate() const;
VkSurfaceKHR_T* surface;
#ifdef ANDROID
VkSurfaceKHR surface;
#else
VkSurfaceKHR_T* surface_handle;
#endif
const Device& device;
Scheduler& scheduler;

View File

@@ -29,6 +29,3 @@
#undef False
#undef None
#undef True
// "Catch-all" handle for both Android and.. the rest of platforms
struct VkSurfaceKHR_T;

View File

@@ -413,7 +413,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
: instance{instance_}, dld{dld_}, physical{physical_},
format_properties(GetFormatProperties(physical)) {
// Get suitability and device properties.
const bool is_suitable = GetSuitability(surface != VkSurfaceKHR{});
const bool is_suitable = GetSuitability(surface != nullptr);
const VkDriverId driver_id = properties.driver.driverID;
const auto device_id = properties.properties.deviceID;

View File

@@ -15,7 +15,7 @@ vk::SurfaceKHR CreateSurface(
const vk::Instance& instance,
[[maybe_unused]] const Core::Frontend::EmuWindow::WindowSystemInfo& window_info) {
[[maybe_unused]] const vk::InstanceDispatch& dld = instance.Dispatch();
VkSurfaceKHR unsafe_surface = VkSurfaceKHR{};
VkSurfaceKHR unsafe_surface = nullptr;
#ifdef _WIN32
if (window_info.type == Core::Frontend::WindowSystemType::Windows) {

View File

@@ -399,13 +399,13 @@ public:
/// Construct a handle transferring the ownership from another handle.
Handle(Handle&& rhs) noexcept
: handle{std::exchange(rhs.handle, Type{})}, owner{rhs.owner}, dld{rhs.dld} {}
: handle{std::exchange(rhs.handle, nullptr)}, owner{rhs.owner}, dld{rhs.dld} {}
/// Assign the current handle transferring the ownership from another handle.
/// Destroys any previously held object.
Handle& operator=(Handle&& rhs) noexcept {
Release();
handle = std::exchange(rhs.handle, Type{});
handle = std::exchange(rhs.handle, nullptr);
owner = rhs.owner;
dld = rhs.dld;
return *this;
@@ -419,7 +419,7 @@ public:
/// Destroys any held object.
void reset() noexcept {
Release();
handle = Type{};
handle = nullptr;
}
/// Returns the address of the held object.
@@ -435,7 +435,7 @@ public:
/// Returns true when there's a held object.
explicit operator bool() const noexcept {
return handle != Type{};
return handle != nullptr;
}
#ifndef ANDROID
@@ -450,7 +450,7 @@ public:
#endif
protected:
Type handle{};
Type handle = nullptr;
OwnerType owner = nullptr;
const Dispatch* dld = nullptr;
@@ -458,7 +458,7 @@ private:
/// Destroys the held object if it exists.
void Release() noexcept {
if (handle) {
Destroy(OwnerType(owner), Type(handle), *dld);
Destroy(owner, handle, *dld);
}
}
};
@@ -501,7 +501,7 @@ public:
/// Destroys any held object.
void reset() noexcept {
Release();
handle = {};
handle = nullptr;
}
/// Returns the address of the held object.
@@ -517,7 +517,7 @@ public:
/// Returns true when there's a held object.
explicit operator bool() const noexcept {
return handle != Type{};
return handle != nullptr;
}
#ifndef ANDROID
@@ -532,7 +532,7 @@ public:
#endif
protected:
Type handle{};
Type handle = nullptr;
const Dispatch* dld = nullptr;
private:
@@ -602,7 +602,7 @@ private:
std::unique_ptr<AllocationType[]> allocations;
std::size_t num = 0;
VkDevice device = nullptr;
PoolType pool{};
PoolType pool = nullptr;
const DeviceDispatch* dld = nullptr;
};
@@ -664,12 +664,12 @@ public:
Image& operator=(const Image&) = delete;
Image(Image&& rhs) noexcept
: handle{std::exchange(rhs.handle, VkImage{})}, usage{rhs.usage}, owner{rhs.owner},
: handle{std::exchange(rhs.handle, nullptr)}, usage{rhs.usage}, owner{rhs.owner},
allocator{rhs.allocator}, allocation{rhs.allocation}, dld{rhs.dld} {}
Image& operator=(Image&& rhs) noexcept {
Release();
handle = std::exchange(rhs.handle, VkImage{});
handle = std::exchange(rhs.handle, nullptr);
usage = rhs.usage;
owner = rhs.owner;
allocator = rhs.allocator;
@@ -688,11 +688,11 @@ public:
void reset() noexcept {
Release();
handle = VkImage{};
handle = nullptr;
}
explicit operator bool() const noexcept {
return handle != VkImage{};
return handle != nullptr;
}
void SetObjectNameEXT(const char* name) const;
@@ -704,7 +704,7 @@ public:
private:
void Release() const noexcept;
VkImage handle{};
VkImage handle = nullptr;
VkImageUsageFlags usage{};
VkDevice owner = nullptr;
VmaAllocator allocator = nullptr;
@@ -725,13 +725,13 @@ public:
Buffer& operator=(const Buffer&) = delete;
Buffer(Buffer&& rhs) noexcept
: handle{std::exchange(rhs.handle, VkBuffer{})}, owner{rhs.owner}, allocator{rhs.allocator},
: handle{std::exchange(rhs.handle, nullptr)}, owner{rhs.owner}, allocator{rhs.allocator},
allocation{rhs.allocation}, mapped{rhs.mapped},
is_coherent{rhs.is_coherent}, dld{rhs.dld} {}
Buffer& operator=(Buffer&& rhs) noexcept {
Release();
handle = std::exchange(rhs.handle, VkBuffer{});
handle = std::exchange(rhs.handle, nullptr);
owner = rhs.owner;
allocator = rhs.allocator;
allocation = rhs.allocation;
@@ -751,11 +751,11 @@ public:
void reset() noexcept {
Release();
handle = VkBuffer{};
handle = nullptr;
}
explicit operator bool() const noexcept {
return handle != VkBuffer{};
return handle != nullptr;
}
/// Returns the host mapped memory, an empty span otherwise.
@@ -781,7 +781,7 @@ public:
private:
void Release() const noexcept;
VkBuffer handle{};
VkBuffer handle = nullptr;
VkDevice owner = nullptr;
VmaAllocator allocator = nullptr;
VmaAllocation allocation = nullptr;
@@ -1015,10 +1015,10 @@ public:
[[nodiscard]] PipelineLayout CreatePipelineLayout(const VkPipelineLayoutCreateInfo& ci) const;
[[nodiscard]] Pipeline CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& ci,
VkPipelineCache cache = {}) const;
VkPipelineCache cache = nullptr) const;
[[nodiscard]] Pipeline CreateComputePipeline(const VkComputePipelineCreateInfo& ci,
VkPipelineCache cache = {}) const;
VkPipelineCache cache = nullptr) const;
[[nodiscard]] Sampler CreateSampler(const VkSamplerCreateInfo& ci) const;