From 929994132a4f39ca4ab2975caf47a2a99a19b518 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 28 Jun 2021 14:38:14 -0700 Subject: hle: kernel: Provide methods for tracking dangling kernel objects. --- src/core/hle/kernel/k_auto_object.cpp | 9 +++++++++ src/core/hle/kernel/k_auto_object.h | 12 ++++++++++-- src/core/hle/kernel/kernel.cpp | 16 ++++++++++++++++ src/core/hle/kernel/kernel.h | 8 ++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/kernel/k_auto_object.cpp b/src/core/hle/kernel/k_auto_object.cpp index dbe237f09..c99a9ebb7 100644 --- a/src/core/hle/kernel/k_auto_object.cpp +++ b/src/core/hle/kernel/k_auto_object.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/kernel/k_auto_object.h" +#include "core/hle/kernel/kernel.h" namespace Kernel { @@ -11,4 +12,12 @@ KAutoObject* KAutoObject::Create(KAutoObject* obj) { return obj; } +void KAutoObject::RegisterWithKernel() { + kernel.RegisterKernelObject(this); +} + +void KAutoObject::UnregisterWithKernel() { + kernel.UnregisterKernelObject(this); +} + } // namespace Kernel diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index 88a052f65..e4fcdbc67 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h @@ -85,8 +85,12 @@ private: KERNEL_AUTOOBJECT_TRAITS(KAutoObject, KAutoObject); public: - explicit KAutoObject(KernelCore& kernel_) : kernel(kernel_) {} - virtual ~KAutoObject() = default; + explicit KAutoObject(KernelCore& kernel_) : kernel(kernel_) { + RegisterWithKernel(); + } + virtual ~KAutoObject() { + UnregisterWithKernel(); + } static KAutoObject* Create(KAutoObject* ptr); @@ -166,6 +170,10 @@ public: } } +private: + void RegisterWithKernel(); + void UnregisterWithKernel(); + protected: KernelCore& kernel; std::string name; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 64bd0c494..ee60072c2 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -142,6 +142,13 @@ struct KernelCore::Impl { // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others next_host_thread_id = Core::Hardware::NUM_CPU_CORES; + + // Track kernel objects that were not freed on shutdown + if (registered_objects.size()) { + LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!", + registered_objects.size()); + registered_objects.clear(); + } } void InitializePhysicalCores() { @@ -656,6 +663,7 @@ struct KernelCore::Impl { /// the ConnectToPort SVC. std::unordered_map service_interface_factory; NamedPortTable named_ports; + std::unordered_set registered_objects; std::unique_ptr exclusive_monitor; std::vector cores; @@ -852,6 +860,14 @@ KClientPort* KernelCore::CreateNamedServicePort(std::string name) { return &search->second(impl->system.ServiceManager(), impl->system); } +void KernelCore::RegisterKernelObject(KAutoObject* object) { + impl->registered_objects.insert(object); +} + +void KernelCore::UnregisterKernelObject(KAutoObject* object) { + impl->registered_objects.erase(object); +} + bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { return port != impl->named_ports.cend(); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 2d01e1ae0..b669ca74e 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -185,6 +185,14 @@ public: /// Opens a port to a service previously registered with RegisterNamedService. KClientPort* CreateNamedServicePort(std::string name); + /// Registers all kernel objects with the global emulation state, this is purely for tracking + /// leaks after emulation has been shutdown. + void RegisterKernelObject(KAutoObject* object); + + /// Unregisters a kernel object previously registered with RegisterKernelObject when it was + /// destroyed during the current emulation session. + void UnregisterKernelObject(KAutoObject* object); + /// Determines whether or not the given port is a valid named port. bool IsValidNamedPort(NamedPortTable::const_iterator port) const; -- cgit v1.2.3 From 015058fadf8dbc72c186e833512e7189c625474b Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 28 Jun 2021 14:41:24 -0700 Subject: hle: service: Add a helper module for managing kernel objects. --- src/core/CMakeLists.txt | 2 + src/core/hle/service/hid/controllers/npad.cpp | 12 ++--- src/core/hle/service/hid/controllers/npad.h | 8 +++- src/core/hle/service/hid/hid.cpp | 14 +++--- src/core/hle/service/hid/hid.h | 13 +++++- src/core/hle/service/kernel_helpers.cpp | 64 +++++++++++++++++++++++++++ src/core/hle/service/kernel_helpers.h | 35 +++++++++++++++ src/core/hle/service/nvdrv/nvdrv.cpp | 10 ++--- src/core/hle/service/nvdrv/nvdrv.h | 3 ++ src/core/hle/service/service.h | 5 ++- 10 files changed, 146 insertions(+), 20 deletions(-) create mode 100644 src/core/hle/service/kernel_helpers.cpp create mode 100644 src/core/hle/service/kernel_helpers.h (limited to 'src/core') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c7b899131..5c99c00f5 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -517,6 +517,8 @@ add_library(core STATIC hle/service/psc/psc.h hle/service/ptm/psm.cpp hle/service/ptm/psm.h + hle/service/kernel_helpers.cpp + hle/service/kernel_helpers.h hle/service/service.cpp hle/service/service.h hle/service/set/set.cpp diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 6ce1360e3..95d4f9588 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -18,6 +18,7 @@ #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" #include "core/hle/service/hid/controllers/npad.h" +#include "core/hle/service/kernel_helpers.h" namespace Service::HID { constexpr s32 HID_JOYSTICK_MAX = 0x7fff; @@ -147,7 +148,9 @@ bool Controller_NPad::IsDeviceHandleValid(const DeviceHandle& device_handle) { device_handle.device_index < DeviceIndex::MaxDeviceIndex; } -Controller_NPad::Controller_NPad(Core::System& system_) : ControllerBase{system_} { +Controller_NPad::Controller_NPad(Core::System& system_, + KernelHelpers::ServiceContext& service_context_) + : ControllerBase{system_}, service_context{service_context_} { latest_vibration_values.fill({DEFAULT_VIBRATION_VALUE, DEFAULT_VIBRATION_VALUE}); } @@ -253,8 +256,8 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { void Controller_NPad::OnInit() { auto& kernel = system.Kernel(); for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { - styleset_changed_events[i] = Kernel::KEvent::Create(kernel); - styleset_changed_events[i]->Initialize(fmt::format("npad:NpadStyleSetChanged_{}", i)); + styleset_changed_events[i] = + service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i)); } if (!IsControllerActivated()) { @@ -344,8 +347,7 @@ void Controller_NPad::OnRelease() { } for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { - styleset_changed_events[i]->Close(); - styleset_changed_events[i] = nullptr; + service_context.CloseEvent(styleset_changed_events[i]); } } diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 1409d82a2..4fcc6f93a 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -20,6 +20,10 @@ class KEvent; class KReadableEvent; } // namespace Kernel +namespace Service::KernelHelpers { +class ServiceContext; +} + namespace Service::HID { constexpr u32 NPAD_HANDHELD = 32; @@ -27,7 +31,8 @@ constexpr u32 NPAD_UNKNOWN = 16; // TODO(ogniK): What is this? class Controller_NPad final : public ControllerBase { public: - explicit Controller_NPad(Core::System& system_); + explicit Controller_NPad(Core::System& system_, + KernelHelpers::ServiceContext& service_context_); ~Controller_NPad() override; // Called when the controller is initialized @@ -566,6 +571,7 @@ private: std::array, Settings::NativeMotion::NUM_MOTIONS_HID>, 10>; + KernelHelpers::ServiceContext& service_context; std::mutex mutex; ButtonArray buttons; StickArray sticks; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index d68b023d0..b8b80570d 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -46,8 +46,9 @@ constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz) constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; -IAppletResource::IAppletResource(Core::System& system_) - : ServiceFramework{system_, "IAppletResource"} { +IAppletResource::IAppletResource(Core::System& system_, + KernelHelpers::ServiceContext& service_context_) + : ServiceFramework{system_, "IAppletResource"}, service_context{service_context_} { static const FunctionInfo functions[] = { {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, }; @@ -63,7 +64,7 @@ IAppletResource::IAppletResource(Core::System& system_) MakeController(HidController::CaptureButton); MakeController(HidController::InputDetector); MakeController(HidController::UniquePad); - MakeController(HidController::NPad); + MakeControllerWithServiceContext(HidController::NPad); MakeController(HidController::Gesture); MakeController(HidController::ConsoleSixAxisSensor); @@ -191,13 +192,14 @@ private: std::shared_ptr Hid::GetAppletResource() { if (applet_resource == nullptr) { - applet_resource = std::make_shared(system); + applet_resource = std::make_shared(system, service_context); } return applet_resource; } -Hid::Hid(Core::System& system_) : ServiceFramework{system_, "hid"} { +Hid::Hid(Core::System& system_) + : ServiceFramework{system_, "hid"}, service_context{system_, service_name} { // clang-format off static const FunctionInfo functions[] = { {0, &Hid::CreateAppletResource, "CreateAppletResource"}, @@ -347,7 +349,7 @@ void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); if (applet_resource == nullptr) { - applet_resource = std::make_shared(system); + applet_resource = std::make_shared(system, service_context); } IPC::ResponseBuilder rb{ctx, 2, 0, 1}; diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 83fc2ea1d..9c5c7f252 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -7,6 +7,7 @@ #include #include "core/hle/service/hid/controllers/controller_base.h" +#include "core/hle/service/kernel_helpers.h" #include "core/hle/service/service.h" namespace Core::Timing { @@ -39,7 +40,8 @@ enum class HidController : std::size_t { class IAppletResource final : public ServiceFramework { public: - explicit IAppletResource(Core::System& system_); + explicit IAppletResource(Core::System& system_, + KernelHelpers::ServiceContext& service_context_); ~IAppletResource() override; void ActivateController(HidController controller); @@ -60,11 +62,18 @@ private: void MakeController(HidController controller) { controllers[static_cast(controller)] = std::make_unique(system); } + template + void MakeControllerWithServiceContext(HidController controller) { + controllers[static_cast(controller)] = + std::make_unique(system, service_context); + } void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); + KernelHelpers::ServiceContext& service_context; + std::shared_ptr pad_update_event; std::shared_ptr motion_update_event; @@ -176,6 +185,8 @@ private: static_assert(sizeof(VibrationDeviceInfo) == 0x8, "VibrationDeviceInfo has incorrect size."); std::shared_ptr applet_resource; + + KernelHelpers::ServiceContext service_context; }; /// Reload input devices. Used when input configuration changed diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp new file mode 100644 index 000000000..895294c9f --- /dev/null +++ b/src/core/hle/service/kernel_helpers.cpp @@ -0,0 +1,64 @@ +// Copyright 2021 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/core.h" +#include "core/hle/kernel/k_event.h" +#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/k_readable_event.h" +#include "core/hle/kernel/k_resource_limit.h" +#include "core/hle/kernel/k_scoped_resource_reservation.h" +#include "core/hle/kernel/k_writable_event.h" +#include "core/hle/service/kernel_helpers.h" + +namespace Service::KernelHelpers { + +ServiceContext::ServiceContext(Core::System& system_, std::string name_) + : kernel(system_.Kernel()) { + process = Kernel::KProcess::Create(kernel); + ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_), + Kernel::KProcess::ProcessType::Userland) + .IsSuccess()); +} + +ServiceContext::~ServiceContext() { + process->Close(); + process = nullptr; +} + +Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) { + // Reserve a new event from the process resource limit + Kernel::KScopedResourceReservation event_reservation(process, + Kernel::LimitableResource::Events); + if (!event_reservation.Succeeded()) { + LOG_CRITICAL(Service, "Resource limit reached!"); + return {}; + } + + // Create a new event. + auto* event = Kernel::KEvent::Create(kernel); + if (!event) { + LOG_CRITICAL(Service, "Unable to create event!"); + return {}; + } + + // Initialize the event. + event->Initialize(std::move(name)); + + // Commit the thread reservation. + event_reservation.Commit(); + + // Register the event. + Kernel::KEvent::Register(kernel, event); + + return event; +} + +void ServiceContext::CloseEvent(Kernel::KEvent* event) { + event->GetReadableEvent().Close(); + event->GetWritableEvent().Close(); +} + +} // namespace Service::KernelHelpers diff --git a/src/core/hle/service/kernel_helpers.h b/src/core/hle/service/kernel_helpers.h new file mode 100644 index 000000000..4f3e95f67 --- /dev/null +++ b/src/core/hle/service/kernel_helpers.h @@ -0,0 +1,35 @@ +// Copyright 2021 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +namespace Core { +class System; +} + +namespace Kernel { +class KernelCore; +class KEvent; +class KProcess; +} // namespace Kernel + +namespace Service::KernelHelpers { + +class ServiceContext { +public: + ServiceContext(Core::System& system_, std::string name_); + ~ServiceContext(); + + Kernel::KEvent* CreateEvent(std::string&& name); + + void CloseEvent(Kernel::KEvent* event); + +private: + Kernel::KernelCore& kernel; + Kernel::KProcess* process{}; +}; + +} // namespace Service::KernelHelpers diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 03992af5e..5600ea126 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -39,11 +39,12 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger nvflinger.SetNVDrvInstance(module_); } -Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} { +Module::Module(Core::System& system) + : syncpoint_manager{system.GPU()}, service_context{system, "nvdrv"} { auto& kernel = system.Kernel(); for (u32 i = 0; i < MaxNvEvents; i++) { - events_interface.events[i].event = Kernel::KEvent::Create(kernel); - events_interface.events[i].event->Initialize(fmt::format("NVDRV::NvEvent_{}", i)); + events_interface.events[i].event = + service_context.CreateEvent(fmt::format("NVDRV::NvEvent_{}", i)); events_interface.status[i] = EventState::Free; events_interface.registered[i] = false; } @@ -65,8 +66,7 @@ Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} { Module::~Module() { for (u32 i = 0; i < MaxNvEvents; i++) { - events_interface.events[i].event->Close(); - events_interface.events[i].event = nullptr; + service_context.CloseEvent(events_interface.events[i].event); } } diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index a43ceb7ae..e2a1dde5b 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -9,6 +9,7 @@ #include #include "common/common_types.h" +#include "core/hle/service/kernel_helpers.h" #include "core/hle/service/nvdrv/nvdata.h" #include "core/hle/service/nvdrv/syncpoint_manager.h" #include "core/hle/service/service.h" @@ -154,6 +155,8 @@ private: std::unordered_map> devices; EventInterface events_interface; + + KernelHelpers::ServiceContext service_context; }; /// Registers all NVDRV services with the specified service manager. diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index e078ac176..632ce9252 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -96,6 +96,9 @@ protected: /// System context that the service operates under. Core::System& system; + /// Identifier string used to connect to the service. + std::string service_name; + private: template friend class ServiceFramework; @@ -117,8 +120,6 @@ private: void RegisterHandlersBaseTipc(const FunctionInfoBase* functions, std::size_t n); void ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, const FunctionInfoBase* info); - /// Identifier string used to connect to the service. - std::string service_name; /// Maximum number of concurrent sessions that this service can handle. u32 max_sessions; -- cgit v1.2.3 From fe402d350650de50bf9a0aa70c04bec986863978 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 28 Jun 2021 16:38:13 -0700 Subject: hle: kernel: Ensure global handle table is initialized. --- src/core/hle/kernel/kernel.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index ee60072c2..e180db791 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -61,6 +61,7 @@ struct KernelCore::Impl { void Initialize(KernelCore& kernel) { global_scheduler_context = std::make_unique(kernel); global_handle_table = std::make_unique(kernel); + global_handle_table->Initialize(KHandleTable::MaxTableSize); is_phantom_mode_for_singlecore = false; -- cgit v1.2.3 From 6020723e77585835eddcc5675385f5e7dd3072ac Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 28 Jun 2021 16:58:40 -0700 Subject: hle: kernel: k_process: Close main thread reference after it is inserted into handle table. --- src/core/hle/kernel/k_process.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/core') diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index d1bd98051..c309ae563 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -10,6 +10,7 @@ #include "common/alignment.h" #include "common/assert.h" #include "common/logging/log.h" +#include "common/scope_exit.h" #include "common/settings.h" #include "core/core.h" #include "core/device_memory.h" @@ -43,6 +44,8 @@ void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); KThread* thread = KThread::Create(system.Kernel()); + SCOPE_EXIT({ thread->Close(); }); + ASSERT(KThread::InitializeUserThread(system, thread, entry_point, 0, stack_top, priority, owner_process.GetIdealCoreId(), &owner_process) .IsSuccess()); -- cgit v1.2.3 From b119363fc27994a4eb68405011235c4a1b3cdf8f Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 28 Jun 2021 16:59:49 -0700 Subject: hle: kernel: k_process: Close the handle table on shutdown. --- src/core/hle/kernel/k_process.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/core') diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index c309ae563..87171b1c8 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -409,6 +409,9 @@ void KProcess::Finalize() { resource_limit->Close(); } + // Finalize the handle table and close any open handles. + handle_table.Finalize(); + // Perform inherited finalization. KAutoObjectWithSlabHeapAndContainer::Finalize(); } -- cgit v1.2.3 From 7bd020e0307c6a870707440f99bf6bb8b513306f Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 30 Jun 2021 18:06:47 -0700 Subject: hle: service: sm: Refactor to better manage ports. --- src/core/hle/service/service.cpp | 11 ++++--- src/core/hle/service/service.h | 2 +- src/core/hle/service/sm/sm.cpp | 65 +++++++++++++++++++++------------------- src/core/hle/service/sm/sm.h | 14 ++++----- 4 files changed, 47 insertions(+), 45 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index e6fba88b2..b3e50433b 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -104,23 +104,22 @@ ServiceFrameworkBase::~ServiceFrameworkBase() { void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) { const auto guard = LockService(); - ASSERT(!port_installed); + ASSERT(!service_registered); - auto port = service_manager.RegisterService(service_name, max_sessions).Unwrap(); - port->SetSessionHandler(shared_from_this()); - port_installed = true; + service_manager.RegisterService(service_name, max_sessions, shared_from_this()); + service_registered = true; } Kernel::KClientPort& ServiceFrameworkBase::CreatePort() { const auto guard = LockService(); - ASSERT(!port_installed); + ASSERT(!service_registered); auto* port = Kernel::KPort::Create(kernel); port->Initialize(max_sessions, false, service_name); port->GetServerPort().SetSessionHandler(shared_from_this()); - port_installed = true; + service_registered = true; return port->GetClientPort(); } diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 632ce9252..c9d6b879d 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -125,7 +125,7 @@ private: /// Flag to store if a port was already create/installed to detect multiple install attempts, /// which is not supported. - bool port_installed = false; + bool service_registered = false; /// Function used to safely up-cast pointers to the derived class before invoking a handler. InvokerFn* handler_invoker; diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 15034abed..ae4dc4a75 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -4,6 +4,7 @@ #include #include "common/assert.h" +#include "common/scope_exit.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/k_client_port.h" @@ -40,17 +41,13 @@ static ResultCode ValidateServiceName(const std::string& name) { } Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core::System& system) { - ASSERT(self.sm_interface.expired()); - - auto sm = std::make_shared(self, system); - self.sm_interface = sm; + self.sm_interface = std::make_shared(self, system); self.controller_interface = std::make_unique(system); - - return sm->CreatePort(); + return self.sm_interface->CreatePort(); } -ResultVal ServiceManager::RegisterService(std::string name, - u32 max_sessions) { +ResultCode ServiceManager::RegisterService(std::string name, u32 max_sessions, + Kernel::SessionRequestHandlerPtr handler) { CASCADE_CODE(ValidateServiceName(name)); @@ -59,12 +56,9 @@ ResultVal ServiceManager::RegisterService(std::string name return ERR_ALREADY_REGISTERED; } - auto* port = Kernel::KPort::Create(kernel); - port->Initialize(max_sessions, false, name); + registered_services.emplace(std::move(name), handler); - registered_services.emplace(std::move(name), port); - - return MakeResult(&port->GetServerPort()); + return ResultSuccess; } ResultCode ServiceManager::UnregisterService(const std::string& name) { @@ -76,14 +70,11 @@ ResultCode ServiceManager::UnregisterService(const std::string& name) { return ERR_SERVICE_NOT_REGISTERED; } - iter->second->Close(); - registered_services.erase(iter); return ResultSuccess; } ResultVal ServiceManager::GetServicePort(const std::string& name) { - CASCADE_CODE(ValidateServiceName(name)); auto it = registered_services.find(name); if (it == registered_services.end()) { @@ -91,10 +82,13 @@ ResultVal ServiceManager::GetServicePort(const std::string& name return ERR_SERVICE_NOT_REGISTERED; } - return MakeResult(it->second); -} + auto* port = Kernel::KPort::Create(kernel); + port->Initialize(ServerSessionCountMax, false, name); + auto handler = it->second; + port->GetServerPort().SetSessionHandler(std::move(handler)); -SM::~SM() = default; + return MakeResult(port); +} /** * SM::Initialize service function @@ -156,11 +150,15 @@ ResultVal SM::GetServiceImpl(Kernel::HLERequestContext& LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw); return port_result.Code(); } - auto& port = port_result.Unwrap()->GetClientPort(); + auto& port = port_result.Unwrap(); + SCOPE_EXIT({ port->GetClientPort().Close(); }); + + server_ports.emplace_back(&port->GetServerPort()); // Create a new session. Kernel::KClientSession* session{}; - if (const auto result = port.CreateSession(std::addressof(session)); result.IsError()) { + if (const auto result = port->GetClientPort().CreateSession(std::addressof(session)); + result.IsError()) { LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); return result; } @@ -180,20 +178,21 @@ void SM::RegisterService(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_SM, "called with name={}, max_session_count={}, is_light={}", name, max_session_count, is_light); - auto handle = service_manager.RegisterService(name, max_session_count); - if (handle.Failed()) { - LOG_ERROR(Service_SM, "failed to register service with error_code={:08X}", - handle.Code().raw); + if (const auto result = service_manager.RegisterService(name, max_session_count, nullptr); + result.IsError()) { + LOG_ERROR(Service_SM, "failed to register service with error_code={:08X}", result.raw); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(handle.Code()); + rb.Push(result); return; } - IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; - rb.Push(handle.Code()); + auto* port = Kernel::KPort::Create(kernel); + port->Initialize(ServerSessionCountMax, is_light, name); + SCOPE_EXIT({ port->GetClientPort().Close(); }); - auto server_port = handle.Unwrap(); - rb.PushMoveObjects(server_port); + IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; + rb.Push(ResultSuccess); + rb.PushMoveObjects(port->GetServerPort()); } void SM::UnregisterService(Kernel::HLERequestContext& ctx) { @@ -225,4 +224,10 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_) }); } +SM::~SM() { + for (auto& server_port : server_ports) { + server_port->Close(); + } +} + } // namespace Service::SM diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index ea37f11d4..068c78588 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -49,6 +49,7 @@ private: ServiceManager& service_manager; bool is_initialized{}; Kernel::KernelCore& kernel; + std::vector server_ports; }; class ServiceManager { @@ -58,7 +59,8 @@ public: explicit ServiceManager(Kernel::KernelCore& kernel_); ~ServiceManager(); - ResultVal RegisterService(std::string name, u32 max_sessions); + ResultCode RegisterService(std::string name, u32 max_sessions, + Kernel::SessionRequestHandlerPtr handler); ResultCode UnregisterService(const std::string& name); ResultVal GetServicePort(const std::string& name); @@ -69,21 +71,17 @@ public: LOG_DEBUG(Service, "Can't find service: {}", service_name); return nullptr; } - auto* port = service->second; - if (port == nullptr) { - return nullptr; - } - return std::static_pointer_cast(port->GetServerPort().GetSessionRequestHandler()); + return std::static_pointer_cast(service->second); } void InvokeControlRequest(Kernel::HLERequestContext& context); private: - std::weak_ptr sm_interface; + std::shared_ptr sm_interface; std::unique_ptr controller_interface; /// Map of registered services, retrieved using GetServicePort. - std::unordered_map registered_services; + std::unordered_map registered_services; /// Kernel context Kernel::KernelCore& kernel; -- cgit v1.2.3 From 24540e0ad9b81092aa3f60fa843bfe45ebd25b8b Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 1 Jul 2021 20:05:10 -0700 Subject: kernel: svc: ConnectToNamedPort: Close extra reference to port. --- src/core/hle/kernel/svc.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 8339e11a0..e1e556370 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -298,6 +298,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out, VAddr po // Create a session. KClientSession* session{}; R_TRY(port->CreateSession(std::addressof(session))); + port->Close(); // Register the session in the table, close the extra reference. handle_table.Register(*out, session); -- cgit v1.2.3 From ecf36534446df97bbe18042a098f25069dfd8648 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 1 Jul 2021 21:44:50 -0700 Subject: hle: kernel: Ensure global handle table is finalized before closing. --- src/core/hle/kernel/kernel.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index e180db791..b7f9eb5c1 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -117,6 +117,7 @@ struct KernelCore::Impl { current_process = nullptr; } + global_handle_table->Finalize(); global_handle_table.reset(); preemption_event = nullptr; -- cgit v1.2.3 From 854c7a3c2826b769d9d41c79570c4dae57e0b3eb Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 1 Jul 2021 21:50:42 -0700 Subject: hle: kernel: Ensure current running process is closed. --- src/core/hle/kernel/kernel.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b7f9eb5c1..2d5525839 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -91,6 +91,12 @@ struct KernelCore::Impl { } void Shutdown() { + if (current_process) { + current_process->Finalize(); + current_process->Close(); + current_process = nullptr; + } + process_list.clear(); // Ensures all service threads gracefully shutdown @@ -112,11 +118,6 @@ struct KernelCore::Impl { cores.clear(); - if (current_process) { - current_process->Close(); - current_process = nullptr; - } - global_handle_table->Finalize(); global_handle_table.reset(); -- cgit v1.2.3 From 8d755147d8fbe664d78b3e78514b64804505d6d7 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 2 Jul 2021 15:04:08 -0700 Subject: hle: kernel: KProcess: Change process termination assert to a warning. - Since we do not implement multiprocess right now, this should not be a crashing assert. --- src/core/hle/kernel/k_process.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 87171b1c8..8ead1a769 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -165,7 +165,7 @@ void KProcess::DecrementThreadCount() { ASSERT(num_threads > 0); if (const auto count = --num_threads; count == 0) { - UNIMPLEMENTED_MSG("Process termination is not implemented!"); + LOG_WARNING(Kernel, "Process termination is not fully implemented."); } } -- cgit v1.2.3 From 52caa52cc2e47d426b5af38fd8439da237836e0e Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 2 Jul 2021 15:19:04 -0700 Subject: hle: kernel: Track and release server sessions, and protect methods with locks. --- src/core/hle/kernel/hle_ipc.cpp | 3 ++ src/core/hle/kernel/k_server_session.cpp | 5 +- src/core/hle/kernel/kernel.cpp | 78 +++++++++++++++++++++++++++----- src/core/hle/kernel/kernel.h | 9 ++++ 4 files changed, 82 insertions(+), 13 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 28ed6265a..ca68fc325 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -58,6 +58,9 @@ bool SessionRequestManager::HasSessionRequestHandler(const HLERequestContext& co void SessionRequestHandler::ClientConnected(KServerSession* session) { session->ClientConnected(shared_from_this()); + + // Ensure our server session is tracked globally. + kernel.RegisterServerSession(session); } void SessionRequestHandler::ClientDisconnected(KServerSession* session) { diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 5c3c13ce6..b9f24475c 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -28,7 +28,10 @@ namespace Kernel { KServerSession::KServerSession(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} -KServerSession::~KServerSession() {} +KServerSession::~KServerSession() { + // Ensure that the global list tracking server sessions does not hold on to a reference. + kernel.UnregisterServerSession(this); +} void KServerSession::Initialize(KSession* parent_session_, std::string&& name_, std::shared_ptr manager_) { diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2d5525839..92fbc5532 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -91,15 +91,39 @@ struct KernelCore::Impl { } void Shutdown() { + // Shutdown all processes. if (current_process) { current_process->Finalize(); current_process->Close(); current_process = nullptr; } - process_list.clear(); - // Ensures all service threads gracefully shutdown + // Close all open server ports. + std::unordered_set server_ports_; + { + std::lock_guard lk(server_ports_lock); + server_ports_ = server_ports; + server_ports.clear(); + } + for (auto* server_port : server_ports_) { + server_port->Close(); + } + // Close all open server sessions. + std::unordered_set server_sessions_; + { + std::lock_guard lk(server_sessions_lock); + server_sessions_ = server_sessions; + server_sessions.clear(); + } + for (auto* server_session : server_sessions_) { + server_session->Close(); + } + + // Ensure that the object list container is finalized and properly shutdown. + object_list_container.Finalize(); + + // Ensures all service threads gracefully shutdown. service_threads.clear(); next_object_id = 0; @@ -147,10 +171,13 @@ struct KernelCore::Impl { next_host_thread_id = Core::Hardware::NUM_CPU_CORES; // Track kernel objects that were not freed on shutdown - if (registered_objects.size()) { - LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!", - registered_objects.size()); - registered_objects.clear(); + { + std::lock_guard lk(registered_objects_lock); + if (registered_objects.size()) { + LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!", + registered_objects.size()); + registered_objects.clear(); + } } } @@ -640,6 +667,21 @@ struct KernelCore::Impl { user_slab_heap_size); } + KClientPort* CreateNamedServicePort(std::string name) { + auto search = service_interface_factory.find(name); + if (search == service_interface_factory.end()) { + UNIMPLEMENTED(); + return {}; + } + + KClientPort* port = &search->second(system.ServiceManager(), system); + { + std::lock_guard lk(server_ports_lock); + server_ports.insert(&port->GetParent()->GetServerPort()); + } + return port; + } + std::atomic next_object_id{0}; std::atomic next_kernel_process_id{KProcess::InitialKIPIDMin}; std::atomic next_user_process_id{KProcess::ProcessIDMin}; @@ -666,7 +708,12 @@ struct KernelCore::Impl { /// the ConnectToPort SVC. std::unordered_map service_interface_factory; NamedPortTable named_ports; + std::unordered_set server_ports; + std::unordered_set server_sessions; std::unordered_set registered_objects; + std::mutex server_ports_lock; + std::mutex server_sessions_lock; + std::mutex registered_objects_lock; std::unique_ptr exclusive_monitor; std::vector cores; @@ -855,19 +902,26 @@ void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory& } KClientPort* KernelCore::CreateNamedServicePort(std::string name) { - auto search = impl->service_interface_factory.find(name); - if (search == impl->service_interface_factory.end()) { - UNIMPLEMENTED(); - return {}; - } - return &search->second(impl->system.ServiceManager(), impl->system); + return impl->CreateNamedServicePort(std::move(name)); +} + +void KernelCore::RegisterServerSession(KServerSession* server_session) { + std::lock_guard lk(impl->server_sessions_lock); + impl->server_sessions.insert(server_session); +} + +void KernelCore::UnregisterServerSession(KServerSession* server_session) { + std::lock_guard lk(impl->server_sessions_lock); + impl->server_sessions.erase(server_session); } void KernelCore::RegisterKernelObject(KAutoObject* object) { + std::lock_guard lk(impl->registered_objects_lock); impl->registered_objects.insert(object); } void KernelCore::UnregisterKernelObject(KAutoObject* object) { + std::lock_guard lk(impl->registered_objects_lock); impl->registered_objects.erase(object); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index b669ca74e..3a6db0b1c 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -45,6 +45,7 @@ class KPort; class KProcess; class KResourceLimit; class KScheduler; +class KServerSession; class KSession; class KSharedMemory; class KThread; @@ -185,6 +186,14 @@ public: /// Opens a port to a service previously registered with RegisterNamedService. KClientPort* CreateNamedServicePort(std::string name); + /// Registers a server session with the gobal emulation state, to be freed on shutdown. This is + /// necessary because we do not emulate processes for HLE sessions. + void RegisterServerSession(KServerSession* server_session); + + /// Unregisters a server session previously registered with RegisterServerSession when it was + /// destroyed during the current emulation session. + void UnregisterServerSession(KServerSession* server_session); + /// Registers all kernel objects with the global emulation state, this is purely for tracking /// leaks after emulation has been shutdown. void RegisterKernelObject(KAutoObject* object); -- cgit v1.2.3 From 6c6e730e9a7d88184b807b97ce88da907f36d7e3 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 3 Jul 2021 02:34:40 -0700 Subject: hle: service: hid: npad: Remove unused kernel reference. --- src/core/hle/service/hid/controllers/npad.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core') diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 95d4f9588..b7f551e40 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -254,7 +254,6 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { } void Controller_NPad::OnInit() { - auto& kernel = system.Kernel(); for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { styleset_changed_events[i] = service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i)); -- cgit v1.2.3 From 185b19fd5b5c9cec1db860fc15d23bec4ba0647a Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 3 Jul 2021 12:02:47 -0700 Subject: hle: service: nvdrv: Remove unused kernel reference. --- src/core/hle/service/nvdrv/nvdrv.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core') diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 5600ea126..ff405099a 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -41,7 +41,6 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger Module::Module(Core::System& system) : syncpoint_manager{system.GPU()}, service_context{system, "nvdrv"} { - auto& kernel = system.Kernel(); for (u32 i = 0; i < MaxNvEvents; i++) { events_interface.events[i].event = service_context.CreateEvent(fmt::format("NVDRV::NvEvent_{}", i)); -- cgit v1.2.3 From f3db3dcc8d5941bf09d682c9d22c865701e8160f Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Jul 2021 18:53:43 -0700 Subject: hle: kernel: svc: Remove part of ExitProcess. - ExitProcess is not actually implemented either way, and this needs more work before we implement. --- src/core/hle/kernel/svc.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index e1e556370..2eb532472 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1440,11 +1440,6 @@ static void ExitProcess(Core::System& system) { LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, "Process has already exited"); - - current_process->PrepareForTermination(); - - // Kill the current thread - system.Kernel().CurrentScheduler()->GetCurrentThread()->Exit(); } static void ExitProcess32(Core::System& system) { -- cgit v1.2.3 From 346bfb6c47096239e1997e348c76aeadbe05294d Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Jul 2021 18:54:35 -0700 Subject: hle: service: kernel_helpers: Remove unnecessary pragma once. --- src/core/hle/service/kernel_helpers.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/core') diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp index 895294c9f..62f4cdfb2 100644 --- a/src/core/hle/service/kernel_helpers.cpp +++ b/src/core/hle/service/kernel_helpers.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma once - #include "core/core.h" #include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_process.h" -- cgit v1.2.3 From 1152d66ddd4e7b29b53e01990fef77e4cff20e24 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Thu, 8 Jul 2021 17:28:48 -0400 Subject: general: Add setting shader_backend GLASM is getting good enough that we can move it out of advanced graphics settings. This removes the setting `use_assembly_shaders`, opting for a enum class `shader_backend`. This comes with the benefits that it is extensible for additional shader backends besides GLSL and GLASM, and this will work better with a QComboBox. Qt removes the related assembly shader setting from the Advanced Graphics section and places it as a new QComboBox in the API Settings group. This will replace the Vulkan device selector when OpenGL is selected. Additionally, mark all of the custom anisotropic filtering settings as "WILL BREAK THINGS", as that is the case with a select few games. --- src/core/telemetry_session.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 066cb23e4..422de3a7d 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -233,8 +233,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader, Settings::values.use_nvdec_emulation.GetValue()); AddField(field_type, "Renderer_AccelerateASTC", Settings::values.accelerate_astc.GetValue()); AddField(field_type, "Renderer_UseVsync", Settings::values.use_vsync.GetValue()); - AddField(field_type, "Renderer_UseAssemblyShaders", - Settings::values.use_assembly_shaders.GetValue()); + AddField(field_type, "Renderer_ShaderBackend", + static_cast(Settings::values.shader_backend.GetValue())); AddField(field_type, "Renderer_UseAsynchronousShaders", Settings::values.use_asynchronous_shaders.GetValue()); AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode.GetValue()); -- cgit v1.2.3 From 4a82450c8139ee751f23f2d50bec6e748e7c9637 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 18 Jul 2021 20:56:50 -0300 Subject: cmake: Remove shader cache version --- src/core/reporter.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core') diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index cfaf50105..365b8f906 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -62,7 +62,6 @@ json GetYuzuVersionData() { {"build_date", std::string(Common::g_build_date)}, {"build_fullname", std::string(Common::g_build_fullname)}, {"build_version", std::string(Common::g_build_version)}, - {"shader_cache_version", std::string(Common::g_shader_cache_version)}, }; } -- cgit v1.2.3