From 8d774e7415fac1153d8944baa2cc250cc4831107 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 18 Apr 2022 21:07:21 +0200 Subject: [PATCH] NvDec: Fix regressions. --- .../hle/service/nvdrv/core/syncpoint_manager.cpp | 6 ++++++ .../hle/service/nvdrv/core/syncpoint_manager.h | 5 +++++ .../hle/service/nvdrv/devices/nvhost_gpu.cpp | 1 + .../nvdrv/devices/nvhost_nvdec_common.cpp | 16 ++++++++++++---- .../service/nvdrv/devices/nvhost_nvdec_common.h | 3 +++ src/core/hle/service/nvdrv/nvdrv.cpp | 5 ++++- 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp b/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp index b34481b486..fc4ff3c2fa 100644 --- a/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp +++ b/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp @@ -55,6 +55,12 @@ u32 SyncpointManager::AllocateSyncpoint(bool clientManaged) { return ReserveSyncpoint(FindFreeSyncpoint(), clientManaged); } +void SyncpointManager::FreeSyncpoint(u32 id) { + std::lock_guard lock(reservation_lock); + ASSERT(syncpoints.at(id).reserved); + syncpoints.at(id).reserved = false; +} + bool SyncpointManager::IsSyncpointAllocated(u32 id) { return (id <= SyncpointCount) && syncpoints[id].reserved; } diff --git a/src/core/hle/service/nvdrv/core/syncpoint_manager.h b/src/core/hle/service/nvdrv/core/syncpoint_manager.h index bfc8ba84b0..da456f2062 100644 --- a/src/core/hle/service/nvdrv/core/syncpoint_manager.h +++ b/src/core/hle/service/nvdrv/core/syncpoint_manager.h @@ -84,6 +84,11 @@ public: */ u32 UpdateMin(u32 id); + /** + * @brief Frees the usage of a syncpoint. + */ + void FreeSyncpoint(u32 id); + /** * @return A fence that will be signalled once this syncpoint hits its maximum value */ diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index c2cc09993f..908e60191d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -43,6 +43,7 @@ nvhost_gpu::~nvhost_gpu() { events_interface.FreeEvent(sm_exception_breakpoint_int_report_event); events_interface.FreeEvent(sm_exception_breakpoint_pause_report_event); events_interface.FreeEvent(error_notifier_event); + syncpoint_manager.FreeSyncpoint(channel_syncpoint); } NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector& input, diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index 008092dbb3..fe83423d53 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -51,8 +51,12 @@ std::unordered_map nvhost_nvdec_common::fd_to_id{}; nvhost_nvdec_common::nvhost_nvdec_common(Core::System& system_, NvCore::Container& core_, NvCore::ChannelType channel_type_) : nvdevice{system_}, core{core_}, syncpoint_manager{core.GetSyncpointManager()}, - nvmap{core.GetNvMapFile()}, channel_type{channel_type_} {} -nvhost_nvdec_common::~nvhost_nvdec_common() = default; + nvmap{core.GetNvMapFile()}, channel_type{channel_type_} { + channel_syncpoint = syncpoint_manager.AllocateSyncpoint(false); +} +nvhost_nvdec_common::~nvhost_nvdec_common() { + syncpoint_manager.FreeSyncpoint(channel_syncpoint); +} NvResult nvhost_nvdec_common::SetNVMAPfd(const std::vector& input) { IoctlSetNvmapFD params{}; @@ -117,8 +121,8 @@ NvResult nvhost_nvdec_common::GetSyncpoint(const std::vector& input, std::ve std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); - const u32 id{NvCore::SyncpointManager::channel_syncpoints[static_cast(channel_type)]}; - params.value = id; + // const u32 id{NvCore::SyncpointManager::channel_syncpoints[static_cast(channel_type)]}; + params.value = channel_syncpoint; std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); return NvResult::Success; @@ -176,4 +180,8 @@ Kernel::KEvent* nvhost_nvdec_common::QueryEvent(u32 event_id) { return nullptr; } +void nvhost_nvdec_common::Reset() { + fd_to_id.clear(); +} + } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h index 51bb7c2cb6..4046b0e13f 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h @@ -24,6 +24,8 @@ public: NvCore::ChannelType channel_type); ~nvhost_nvdec_common() override; + static void Reset(); + protected: struct IoctlSetNvmapFD { s32_le nvmap_fd{}; @@ -117,6 +119,7 @@ protected: Kernel::KEvent* QueryEvent(u32 event_id) override; static std::unordered_map fd_to_id; + u32 channel_syncpoint; s32_le nvmap_fd{}; u32_le submit_timeout{}; NvCore::Container& core; diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 1be51e4018..20bf24ec8c 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -18,6 +18,7 @@ #include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" +#include "core/hle/service/nvdrv/devices/nvhost_nvdec_common.h" #include "core/hle/service/nvdrv/devices/nvhost_nvjpg.h" #include "core/hle/service/nvdrv/devices/nvhost_vic.h" #include "core/hle/service/nvdrv/devices/nvmap.h" @@ -101,7 +102,9 @@ Module::Module(Core::System& system) }; } -Module::~Module() = default; +Module::~Module() { + Devices::nvhost_nvdec_common::Reset(); +} NvResult Module::VerifyFD(DeviceFD fd) const { if (fd < 0) {