diff options
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/nvdrv.cpp | 53 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/nvdrv.h | 9 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/nvdrv_interface.cpp | 6 |
4 files changed, 40 insertions, 32 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 9b393521a..55acd4f78 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -125,8 +125,10 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector } }(); + must_unmark_fail = true; + const auto check_failing = [&]() { - if (events_interface.fails[slot] > 1) { + if (events_interface.fails[slot] > 2) { { auto lk = system.StallProcesses(); gpu.WaitFence(fence_id, target_value); diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 7c0f89c12..df4656240 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -29,6 +29,29 @@ namespace Service::Nvidia { +EventInterface::EventInterface(Module& module_) : module{module_} { + events_mask = 0; + for (u32 i = 0; i < MaxNvEvents; i++) { + status[i] = EventState::Available; + events[i] = nullptr; + registered[i] = false; + } +} + +EventInterface::~EventInterface() { + auto lk = Lock(); + for (u32 i = 0; i < MaxNvEvents; i++) { + if (registered[i]) { + module.service_context.CloseEvent(events[i]); + events[i] = nullptr; + registered[i] = false; + } + } + for (auto* event : basic_events) { + module.service_context.CloseEvent(event); + } +} + std::unique_lock<std::mutex> EventInterface::Lock() { return std::unique_lock<std::mutex>(events_mutex); } @@ -45,27 +68,25 @@ void EventInterface::Create(u32 event_id) { ASSERT(!events[event_id]); ASSERT(!registered[event_id]); ASSERT(!IsBeingUsed(event_id)); - events[event_id] = backup[event_id]; + events[event_id] = + module.service_context.CreateEvent(fmt::format("NVDRV::NvEvent_{}", event_id)); status[event_id] = EventState::Available; registered[event_id] = true; const u64 mask = 1ULL << event_id; fails[event_id] = 0; events_mask |= mask; - LOG_CRITICAL(Service_NVDRV, "Created Event {}", event_id); } void EventInterface::Free(u32 event_id) { ASSERT(events[event_id]); ASSERT(registered[event_id]); ASSERT(!IsBeingUsed(event_id)); - - backup[event_id]->GetWritableEvent().Clear(); + module.service_context.CloseEvent(events[event_id]); events[event_id] = nullptr; status[event_id] = EventState::Available; registered[event_id] = false; const u64 mask = ~(1ULL << event_id); events_mask &= mask; - LOG_CRITICAL(Service_NVDRV, "Freed Event {}", event_id); } u32 EventInterface::FindFreeEvent(u32 syncpoint_id) { @@ -114,15 +135,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger } Module::Module(Core::System& system) - : syncpoint_manager{system.GPU()}, events_interface{*this}, service_context{system, "nvdrv"} { - events_interface.events_mask = 0; - for (u32 i = 0; i < MaxNvEvents; i++) { - events_interface.status[i] = EventState::Available; - events_interface.events[i] = nullptr; - events_interface.registered[i] = false; - events_interface.backup[i] = - service_context.CreateEvent(fmt::format("NVDRV::NvEvent_{}", i)); - } + : syncpoint_manager{system.GPU()}, service_context{system, "nvdrv"}, events_interface{*this} { auto nvmap_dev = std::make_shared<Devices::nvmap>(system); devices["/dev/nvhost-as-gpu"] = std::make_shared<Devices::nvhost_as_gpu>(system, nvmap_dev); devices["/dev/nvhost-gpu"] = std::make_shared<Devices::nvhost_gpu>( @@ -140,15 +153,7 @@ Module::Module(Core::System& system) std::make_shared<Devices::nvhost_vic>(system, nvmap_dev, syncpoint_manager); } -Module::~Module() { - auto lock = events_interface.Lock(); - for (u32 i = 0; i < MaxNvEvents; i++) { - if (events_interface.registered[i]) { - events_interface.Free(i); - } - service_context.CloseEvent(events_interface.backup[i]); - } -} +Module::~Module() = default; NvResult Module::VerifyFD(DeviceFD fd) const { if (fd < 0) { @@ -255,7 +260,7 @@ void Module::SignalSyncpt(const u32 syncpoint_id, const u32 value) { const u32 max = MaxNvEvents - std::countl_zero(events_interface.events_mask); const u32 min = std::countr_zero(events_interface.events_mask); for (u32 i = min; i < max; i++) { - if (events_interface.registered[i] && events_interface.assigned_syncpt[i] == syncpoint_id && + if (events_interface.assigned_syncpt[i] == syncpoint_id && events_interface.assigned_value[i] == value) { events_interface.Signal(i); } diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index be8813c97..d24b57539 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -41,14 +41,13 @@ class Module; class EventInterface { public: - EventInterface(Module& module_) : module{module_} {} + EventInterface(Module& module_); + ~EventInterface(); // Mask representing registered events u64 events_mask{}; // Each kernel event associated to an NV event std::array<Kernel::KEvent*, MaxNvEvents> events{}; - // Backup NV event - std::array<Kernel::KEvent*, MaxNvEvents> backup{}; // The status of the current NVEvent std::array<std::atomic<EventState>, MaxNvEvents> status{}; // Tells if an NVEvent is registered or not @@ -139,10 +138,10 @@ private: /// Mapping of device node names to their implementation. std::unordered_map<std::string, std::shared_ptr<Devices::nvdevice>> devices; - EventInterface events_interface; - KernelHelpers::ServiceContext service_context; + EventInterface events_interface; + void CreateEvent(u32 event_id); void FreeEvent(u32 event_id); }; diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp index 81ee28f31..bd41205b8 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp @@ -1,5 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2021 yuzu emulator team and Skyline Team and Contributors +// (https://github.com/skyline-emu/) +// SPDX-License-Identifier: GPL-3.0-or-later Licensed under GPLv3 +// or any later version Refer to the license.txt file included. #include <cinttypes> #include "common/logging/log.h" |