diff options
37 files changed, 260 insertions, 100 deletions
diff --git a/src/core/hle/service/hle_ipc.h b/src/core/hle/service/hle_ipc.h index 440737db5..d550a11b7 100644 --- a/src/core/hle/service/hle_ipc.h +++ b/src/core/hle/service/hle_ipc.h | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #include "core/hle/ipc.h" | 19 | #include "core/hle/ipc.h" |
| 20 | #include "core/hle/kernel/k_handle_table.h" | 20 | #include "core/hle/kernel/k_handle_table.h" |
| 21 | #include "core/hle/kernel/svc_common.h" | 21 | #include "core/hle/kernel/svc_common.h" |
| 22 | #include "core/hle/kernel/k_auto_object.h" | ||
| 23 | #include "core/hle/kernel/k_handle_table.h" | ||
| 22 | 24 | ||
| 23 | union Result; | 25 | union Result; |
| 24 | 26 | ||
| @@ -41,6 +43,8 @@ class KernelCore; | |||
| 41 | class KHandleTable; | 43 | class KHandleTable; |
| 42 | class KProcess; | 44 | class KProcess; |
| 43 | class KServerSession; | 45 | class KServerSession; |
| 46 | template <typename T> | ||
| 47 | class KScopedAutoObject; | ||
| 44 | class KThread; | 48 | class KThread; |
| 45 | } // namespace Kernel | 49 | } // namespace Kernel |
| 46 | 50 | ||
| @@ -373,6 +377,10 @@ public: | |||
| 373 | return nullptr; | 377 | return nullptr; |
| 374 | } | 378 | } |
| 375 | 379 | ||
| 380 | Kernel::KScopedAutoObject<Kernel::KAutoObject> GetObjectFromHandle(u32 handle) { | ||
| 381 | return GetClientHandleTable().GetObjectForIpc(handle, thread); | ||
| 382 | } | ||
| 383 | |||
| 376 | [[nodiscard]] std::shared_ptr<SessionRequestManager> GetManager() const { | 384 | [[nodiscard]] std::shared_ptr<SessionRequestManager> GetManager() const { |
| 377 | return manager.lock(); | 385 | return manager.lock(); |
| 378 | } | 386 | } |
diff --git a/src/core/hle/service/nvdrv/core/container.cpp b/src/core/hle/service/nvdrv/core/container.cpp index 37ca24f5d..7c2231fe6 100644 --- a/src/core/hle/service/nvdrv/core/container.cpp +++ b/src/core/hle/service/nvdrv/core/container.cpp | |||
| @@ -2,19 +2,30 @@ | |||
| 2 | // SPDX-FileCopyrightText: 2022 Skyline Team and Contributors | 2 | // SPDX-FileCopyrightText: 2022 Skyline Team and Contributors |
| 3 | // SPDX-License-Identifier: GPL-3.0-or-later | 3 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 4 | 4 | ||
| 5 | #include <atomic> | ||
| 6 | #include <deque> | ||
| 7 | #include <mutex> | ||
| 8 | |||
| 9 | #include "core/hle/kernel/k_process.h" | ||
| 5 | #include "core/hle/service/nvdrv/core/container.h" | 10 | #include "core/hle/service/nvdrv/core/container.h" |
| 6 | #include "core/hle/service/nvdrv/core/nvmap.h" | 11 | #include "core/hle/service/nvdrv/core/nvmap.h" |
| 7 | #include "core/hle/service/nvdrv/core/syncpoint_manager.h" | 12 | #include "core/hle/service/nvdrv/core/syncpoint_manager.h" |
| 13 | #include "core/memory.h" | ||
| 8 | #include "video_core/host1x/host1x.h" | 14 | #include "video_core/host1x/host1x.h" |
| 9 | 15 | ||
| 10 | namespace Service::Nvidia::NvCore { | 16 | namespace Service::Nvidia::NvCore { |
| 11 | 17 | ||
| 12 | struct ContainerImpl { | 18 | struct ContainerImpl { |
| 13 | explicit ContainerImpl(Tegra::Host1x::Host1x& host1x_) | 19 | explicit ContainerImpl(Tegra::Host1x::Host1x& host1x_) |
| 14 | : file{host1x_}, manager{host1x_}, device_file_data{} {} | 20 | : host1x{host1x_}, file{host1x_}, manager{host1x_}, device_file_data{} {} |
| 21 | Tegra::Host1x::Host1x& host1x; | ||
| 15 | NvMap file; | 22 | NvMap file; |
| 16 | SyncpointManager manager; | 23 | SyncpointManager manager; |
| 17 | Container::Host1xDeviceFileData device_file_data; | 24 | Container::Host1xDeviceFileData device_file_data; |
| 25 | std::deque<Session> sessions; | ||
| 26 | size_t new_ids{}; | ||
| 27 | std::deque<size_t> id_pool; | ||
| 28 | std::mutex session_guard; | ||
| 18 | }; | 29 | }; |
| 19 | 30 | ||
| 20 | Container::Container(Tegra::Host1x::Host1x& host1x_) { | 31 | Container::Container(Tegra::Host1x::Host1x& host1x_) { |
| @@ -23,6 +34,37 @@ Container::Container(Tegra::Host1x::Host1x& host1x_) { | |||
| 23 | 34 | ||
| 24 | Container::~Container() = default; | 35 | Container::~Container() = default; |
| 25 | 36 | ||
| 37 | size_t Container::OpenSession(Kernel::KProcess* process) { | ||
| 38 | std::scoped_lock lk(impl->session_guard); | ||
| 39 | size_t new_id{}; | ||
| 40 | auto* memory_interface = &process->GetMemory(); | ||
| 41 | auto& smmu = impl->host1x.MemoryManager(); | ||
| 42 | auto smmu_id = smmu.RegisterProcess(memory_interface); | ||
| 43 | if (!impl->id_pool.empty()) { | ||
| 44 | new_id = impl->id_pool.front(); | ||
| 45 | impl->id_pool.pop_front(); | ||
| 46 | impl->sessions[new_id] = Session{new_id, process, smmu_id}; | ||
| 47 | } else { | ||
| 48 | impl->sessions.emplace_back(new_id, process, smmu_id); | ||
| 49 | new_id = impl->new_ids++; | ||
| 50 | } | ||
| 51 | LOG_CRITICAL(Debug, "Created Session {}", new_id); | ||
| 52 | return new_id; | ||
| 53 | } | ||
| 54 | |||
| 55 | void Container::CloseSession(size_t id) { | ||
| 56 | std::scoped_lock lk(impl->session_guard); | ||
| 57 | auto& smmu = impl->host1x.MemoryManager(); | ||
| 58 | smmu.UnregisterProcess(impl->sessions[id].smmu_id); | ||
| 59 | impl->id_pool.emplace_front(id); | ||
| 60 | LOG_CRITICAL(Debug, "Closed Session {}", id); | ||
| 61 | } | ||
| 62 | |||
| 63 | Session* Container::GetSession(size_t id) { | ||
| 64 | std::atomic_thread_fence(std::memory_order_acquire); | ||
| 65 | return &impl->sessions[id]; | ||
| 66 | } | ||
| 67 | |||
| 26 | NvMap& Container::GetNvMapFile() { | 68 | NvMap& Container::GetNvMapFile() { |
| 27 | return impl->file; | 69 | return impl->file; |
| 28 | } | 70 | } |
diff --git a/src/core/hle/service/nvdrv/core/container.h b/src/core/hle/service/nvdrv/core/container.h index b4b63ac90..a1fd20199 100644 --- a/src/core/hle/service/nvdrv/core/container.h +++ b/src/core/hle/service/nvdrv/core/container.h | |||
| @@ -10,6 +10,10 @@ | |||
| 10 | 10 | ||
| 11 | #include "core/hle/service/nvdrv/nvdata.h" | 11 | #include "core/hle/service/nvdrv/nvdata.h" |
| 12 | 12 | ||
| 13 | namespace Kernel { | ||
| 14 | class KProcess; | ||
| 15 | } | ||
| 16 | |||
| 13 | namespace Tegra::Host1x { | 17 | namespace Tegra::Host1x { |
| 14 | class Host1x; | 18 | class Host1x; |
| 15 | } // namespace Tegra::Host1x | 19 | } // namespace Tegra::Host1x |
| @@ -21,11 +25,22 @@ class SyncpointManager; | |||
| 21 | 25 | ||
| 22 | struct ContainerImpl; | 26 | struct ContainerImpl; |
| 23 | 27 | ||
| 28 | struct Session { | ||
| 29 | size_t id; | ||
| 30 | Kernel::KProcess* process; | ||
| 31 | size_t smmu_id; | ||
| 32 | }; | ||
| 33 | |||
| 24 | class Container { | 34 | class Container { |
| 25 | public: | 35 | public: |
| 26 | explicit Container(Tegra::Host1x::Host1x& host1x); | 36 | explicit Container(Tegra::Host1x::Host1x& host1x); |
| 27 | ~Container(); | 37 | ~Container(); |
| 28 | 38 | ||
| 39 | size_t OpenSession(Kernel::KProcess* process); | ||
| 40 | void CloseSession(size_t id); | ||
| 41 | |||
| 42 | Session* GetSession(size_t id); | ||
| 43 | |||
| 29 | NvMap& GetNvMapFile(); | 44 | NvMap& GetNvMapFile(); |
| 30 | 45 | ||
| 31 | const NvMap& GetNvMapFile() const; | 46 | const NvMap& GetNvMapFile() const; |
diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp index 0ca05257e..fd6c9aa0c 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.cpp +++ b/src/core/hle/service/nvdrv/core/nvmap.cpp | |||
| @@ -18,8 +18,6 @@ NvMap::Handle::Handle(u64 size_, Id id_) | |||
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) { | 20 | NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) { |
| 21 | std::scoped_lock lock(mutex); | ||
| 22 | |||
| 23 | // Handles cannot be allocated twice | 21 | // Handles cannot be allocated twice |
| 24 | if (allocated) { | 22 | if (allocated) { |
| 25 | return NvResult::AccessDenied; | 23 | return NvResult::AccessDenied; |
| @@ -79,10 +77,11 @@ void NvMap::UnmapHandle(Handle& handle_description) { | |||
| 79 | } | 77 | } |
| 80 | 78 | ||
| 81 | // Free and unmap the handle from the SMMU | 79 | // Free and unmap the handle from the SMMU |
| 82 | host1x.MemoryManager().Unmap(static_cast<GPUVAddr>(handle_description.pin_virt_address), | 80 | auto& smmu = host1x.MemoryManager(); |
| 83 | handle_description.aligned_size); | 81 | smmu.Unmap(static_cast<DAddr>(handle_description.pin_virt_address), |
| 84 | host1x.Allocator().Free(handle_description.pin_virt_address, | 82 | handle_description.aligned_size); |
| 85 | static_cast<u32>(handle_description.aligned_size)); | 83 | smmu.Free(handle_description.pin_virt_address, |
| 84 | static_cast<size_t>(handle_description.aligned_size)); | ||
| 86 | handle_description.pin_virt_address = 0; | 85 | handle_description.pin_virt_address = 0; |
| 87 | } | 86 | } |
| 88 | 87 | ||
| @@ -133,7 +132,32 @@ VAddr NvMap::GetHandleAddress(Handle::Id handle) { | |||
| 133 | } | 132 | } |
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | u32 NvMap::PinHandle(NvMap::Handle::Id handle) { | 135 | NvResult NvMap::AllocateHandle(Handle::Id handle, Handle::Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size_t session_id) { |
| 136 | auto handle_description{GetHandle(handle)}; | ||
| 137 | if (!handle_description) [[unlikely]] { | ||
| 138 | return NvResult::BadParameter; | ||
| 139 | } | ||
| 140 | |||
| 141 | if (handle_description->allocated) [[unlikely]] { | ||
| 142 | return NvResult::InsufficientMemory; | ||
| 143 | } | ||
| 144 | |||
| 145 | std::scoped_lock lock(handle_description->mutex); | ||
| 146 | NvResult result = handle_description->Alloc(pFlags, pAlign, pKind, pAddress); | ||
| 147 | if (result != NvResult::Success) { | ||
| 148 | return result; | ||
| 149 | } | ||
| 150 | auto& smmu = host1x.MemoryManager(); | ||
| 151 | size_t total_size = static_cast<size_t>(handle_description->aligned_size); | ||
| 152 | handle_description->d_address = smmu.Allocate(total_size); | ||
| 153 | if (handle_description->d_address == 0) { | ||
| 154 | return NvResult::InsufficientMemory; | ||
| 155 | } | ||
| 156 | smmu.Map(handle_description->d_address, handle_description->address, total_size, session_id); | ||
| 157 | return NvResult::Success; | ||
| 158 | } | ||
| 159 | |||
| 160 | u32 NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id) { | ||
| 137 | auto handle_description{GetHandle(handle)}; | 161 | auto handle_description{GetHandle(handle)}; |
| 138 | if (!handle_description) [[unlikely]] { | 162 | if (!handle_description) [[unlikely]] { |
| 139 | return 0; | 163 | return 0; |
| @@ -157,11 +181,10 @@ u32 NvMap::PinHandle(NvMap::Handle::Id handle) { | |||
| 157 | } | 181 | } |
| 158 | 182 | ||
| 159 | // If not then allocate some space and map it | 183 | // If not then allocate some space and map it |
| 160 | u32 address{}; | 184 | DAddr address{}; |
| 161 | auto& smmu_allocator = host1x.Allocator(); | 185 | auto& smmu = host1x.MemoryManager(); |
| 162 | auto& smmu_memory_manager = host1x.MemoryManager(); | 186 | while ((address = smmu.AllocatePinned( |
| 163 | while ((address = smmu_allocator.Allocate( | 187 | static_cast<size_t>(handle_description->aligned_size))) == 0) { |
| 164 | static_cast<u32>(handle_description->aligned_size))) == 0) { | ||
| 165 | // Free handles until the allocation succeeds | 188 | // Free handles until the allocation succeeds |
| 166 | std::scoped_lock queueLock(unmap_queue_lock); | 189 | std::scoped_lock queueLock(unmap_queue_lock); |
| 167 | if (auto freeHandleDesc{unmap_queue.front()}) { | 190 | if (auto freeHandleDesc{unmap_queue.front()}) { |
| @@ -175,9 +198,9 @@ u32 NvMap::PinHandle(NvMap::Handle::Id handle) { | |||
| 175 | } | 198 | } |
| 176 | } | 199 | } |
| 177 | 200 | ||
| 178 | smmu_memory_manager.Map(static_cast<GPUVAddr>(address), handle_description->address, | 201 | smmu.Map(address, handle_description->address, handle_description->aligned_size, |
| 179 | handle_description->aligned_size); | 202 | session_id); |
| 180 | handle_description->pin_virt_address = address; | 203 | handle_description->pin_virt_address = static_cast<u32>(address); |
| 181 | } | 204 | } |
| 182 | 205 | ||
| 183 | handle_description->pins++; | 206 | handle_description->pins++; |
| @@ -236,6 +259,11 @@ std::optional<NvMap::FreeInfo> NvMap::FreeHandle(Handle::Id handle, bool interna | |||
| 236 | std::scoped_lock queueLock(unmap_queue_lock); | 259 | std::scoped_lock queueLock(unmap_queue_lock); |
| 237 | UnmapHandle(*handle_description); | 260 | UnmapHandle(*handle_description); |
| 238 | } | 261 | } |
| 262 | if (handle_description->allocated) { | ||
| 263 | auto& smmu = host1x.MemoryManager(); | ||
| 264 | smmu.Free(handle_description->d_address, handle_description->aligned_size); | ||
| 265 | smmu.Unmap(handle_description->d_address, handle_description->aligned_size); | ||
| 266 | } | ||
| 239 | 267 | ||
| 240 | handle_description->pins = 0; | 268 | handle_description->pins = 0; |
| 241 | } | 269 | } |
diff --git a/src/core/hle/service/nvdrv/core/nvmap.h b/src/core/hle/service/nvdrv/core/nvmap.h index a8e573890..7c3110d91 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.h +++ b/src/core/hle/service/nvdrv/core/nvmap.h | |||
| @@ -61,8 +61,10 @@ public: | |||
| 61 | } flags{}; | 61 | } flags{}; |
| 62 | static_assert(sizeof(Flags) == sizeof(u32)); | 62 | static_assert(sizeof(Flags) == sizeof(u32)); |
| 63 | 63 | ||
| 64 | u64 address{}; //!< The memory location in the guest's AS that this handle corresponds to, | 64 | VAddr address{}; //!< The memory location in the guest's AS that this handle corresponds to, |
| 65 | //!< this can also be in the nvdrv tmem | 65 | //!< this can also be in the nvdrv tmem |
| 66 | DAddr d_address{}; //!< The memory location in the device's AS that this handle corresponds to, | ||
| 67 | //!< this can also be in the nvdrv tmem | ||
| 66 | bool is_shared_mem_mapped{}; //!< If this nvmap has been mapped with the MapSharedMem IPC | 68 | bool is_shared_mem_mapped{}; //!< If this nvmap has been mapped with the MapSharedMem IPC |
| 67 | //!< call | 69 | //!< call |
| 68 | 70 | ||
| @@ -125,7 +127,15 @@ public: | |||
| 125 | * number of calls to `UnpinHandle` | 127 | * number of calls to `UnpinHandle` |
| 126 | * @return The SMMU virtual address that the handle has been mapped to | 128 | * @return The SMMU virtual address that the handle has been mapped to |
| 127 | */ | 129 | */ |
| 128 | u32 PinHandle(Handle::Id handle); | 130 | u32 PinHandle(Handle::Id handle, size_t session_id); |
| 131 | |||
| 132 | /** | ||
| 133 | * @brief Maps a handle into the SMMU address space | ||
| 134 | * @note This operation is refcounted, the number of calls to this must eventually match the | ||
| 135 | * number of calls to `UnpinHandle` | ||
| 136 | * @return The SMMU virtual address that the handle has been mapped to | ||
| 137 | */ | ||
| 138 | NvResult AllocateHandle(Handle::Id handle, Handle::Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size_t session_id); | ||
| 129 | 139 | ||
| 130 | /** | 140 | /** |
| 131 | * @brief When this has been called an equal number of times to `PinHandle` for the supplied | 141 | * @brief When this has been called an equal number of times to `PinHandle` for the supplied |
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index a04538d5d..ff91aabcb 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h | |||
| @@ -62,7 +62,7 @@ public: | |||
| 62 | * Called once a device is opened | 62 | * Called once a device is opened |
| 63 | * @param fd The device fd | 63 | * @param fd The device fd |
| 64 | */ | 64 | */ |
| 65 | virtual void OnOpen(DeviceFD fd) = 0; | 65 | virtual void OnOpen(size_t session_id, DeviceFD fd) = 0; |
| 66 | 66 | ||
| 67 | /** | 67 | /** |
| 68 | * Called once a device is closed | 68 | * Called once a device is closed |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 05a43d8dc..0ff41c6b2 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -35,7 +35,7 @@ NvResult nvdisp_disp0::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 35 | return NvResult::NotImplemented; | 35 | return NvResult::NotImplemented; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | void nvdisp_disp0::OnOpen(DeviceFD fd) {} | 38 | void nvdisp_disp0::OnOpen(size_t session_id, DeviceFD fd) {} |
| 39 | void nvdisp_disp0::OnClose(DeviceFD fd) {} | 39 | void nvdisp_disp0::OnClose(DeviceFD fd) {} |
| 40 | 40 | ||
| 41 | void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, android::PixelFormat format, u32 width, | 41 | void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, android::PixelFormat format, u32 width, |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h index daee05fe8..4e32ec191 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | |||
| @@ -32,7 +32,7 @@ public: | |||
| 32 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, | 32 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 33 | std::span<u8> inline_output) override; | 33 | std::span<u8> inline_output) override; |
| 34 | 34 | ||
| 35 | void OnOpen(DeviceFD fd) override; | 35 | void OnOpen(size_t session_id, DeviceFD fd) override; |
| 36 | void OnClose(DeviceFD fd) override; | 36 | void OnClose(DeviceFD fd) override; |
| 37 | 37 | ||
| 38 | /// Performs a screen flip, drawing the buffer pointed to by the handle. | 38 | /// Performs a screen flip, drawing the buffer pointed to by the handle. |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 6b3639008..c92a7b2f6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -86,7 +86,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 86 | return NvResult::NotImplemented; | 86 | return NvResult::NotImplemented; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | void nvhost_as_gpu::OnOpen(DeviceFD fd) {} | 89 | void nvhost_as_gpu::OnOpen(size_t session_id, DeviceFD fd) {} |
| 90 | void nvhost_as_gpu::OnClose(DeviceFD fd) {} | 90 | void nvhost_as_gpu::OnClose(DeviceFD fd) {} |
| 91 | 91 | ||
| 92 | NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { | 92 | NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index 79a21683d..0dd279f88 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -55,7 +55,7 @@ public: | |||
| 55 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, | 55 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 56 | std::span<u8> inline_output) override; | 56 | std::span<u8> inline_output) override; |
| 57 | 57 | ||
| 58 | void OnOpen(DeviceFD fd) override; | 58 | void OnOpen(size_t session_id, DeviceFD fd) override; |
| 59 | void OnClose(DeviceFD fd) override; | 59 | void OnClose(DeviceFD fd) override; |
| 60 | 60 | ||
| 61 | Kernel::KEvent* QueryEvent(u32 event_id) override; | 61 | Kernel::KEvent* QueryEvent(u32 event_id) override; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index b8dd34e24..c4033cf1b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -76,7 +76,7 @@ NvResult nvhost_ctrl::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inp | |||
| 76 | return NvResult::NotImplemented; | 76 | return NvResult::NotImplemented; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | void nvhost_ctrl::OnOpen(DeviceFD fd) {} | 79 | void nvhost_ctrl::OnOpen(size_t session_id, DeviceFD fd) {} |
| 80 | 80 | ||
| 81 | void nvhost_ctrl::OnClose(DeviceFD fd) {} | 81 | void nvhost_ctrl::OnClose(DeviceFD fd) {} |
| 82 | 82 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 992124b60..84f419f16 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | |||
| @@ -32,7 +32,7 @@ public: | |||
| 32 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, | 32 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 33 | std::span<u8> inline_output) override; | 33 | std::span<u8> inline_output) override; |
| 34 | 34 | ||
| 35 | void OnOpen(DeviceFD fd) override; | 35 | void OnOpen(size_t session_id, DeviceFD fd) override; |
| 36 | void OnClose(DeviceFD fd) override; | 36 | void OnClose(DeviceFD fd) override; |
| 37 | 37 | ||
| 38 | Kernel::KEvent* QueryEvent(u32 event_id) override; | 38 | Kernel::KEvent* QueryEvent(u32 event_id) override; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 3e0c96456..75276c37c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | |||
| @@ -82,7 +82,7 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> | |||
| 82 | return NvResult::NotImplemented; | 82 | return NvResult::NotImplemented; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {} | 85 | void nvhost_ctrl_gpu::OnOpen(size_t session_id, DeviceFD fd) {} |
| 86 | void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {} | 86 | void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {} |
| 87 | 87 | ||
| 88 | NvResult nvhost_ctrl_gpu::GetCharacteristics1(IoctlCharacteristics& params) { | 88 | NvResult nvhost_ctrl_gpu::GetCharacteristics1(IoctlCharacteristics& params) { |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index d170299bd..6147e37cc 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h | |||
| @@ -28,7 +28,7 @@ public: | |||
| 28 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, | 28 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 29 | std::span<u8> inline_output) override; | 29 | std::span<u8> inline_output) override; |
| 30 | 30 | ||
| 31 | void OnOpen(DeviceFD fd) override; | 31 | void OnOpen(size_t session_id, DeviceFD fd) override; |
| 32 | void OnClose(DeviceFD fd) override; | 32 | void OnClose(DeviceFD fd) override; |
| 33 | 33 | ||
| 34 | Kernel::KEvent* QueryEvent(u32 event_id) override; | 34 | Kernel::KEvent* QueryEvent(u32 event_id) override; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index b0395c2f0..0929c7128 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -120,7 +120,7 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 120 | return NvResult::NotImplemented; | 120 | return NvResult::NotImplemented; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | void nvhost_gpu::OnOpen(DeviceFD fd) {} | 123 | void nvhost_gpu::OnOpen(size_t session_id, DeviceFD fd) {} |
| 124 | void nvhost_gpu::OnClose(DeviceFD fd) {} | 124 | void nvhost_gpu::OnClose(DeviceFD fd) {} |
| 125 | 125 | ||
| 126 | NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) { | 126 | NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) { |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index 88fd228ff..f5a396c40 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h | |||
| @@ -47,7 +47,7 @@ public: | |||
| 47 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, | 47 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 48 | std::span<u8> inline_output) override; | 48 | std::span<u8> inline_output) override; |
| 49 | 49 | ||
| 50 | void OnOpen(DeviceFD fd) override; | 50 | void OnOpen(size_t session_id, DeviceFD fd) override; |
| 51 | void OnClose(DeviceFD fd) override; | 51 | void OnClose(DeviceFD fd) override; |
| 52 | 52 | ||
| 53 | Kernel::KEvent* QueryEvent(u32 event_id) override; | 53 | Kernel::KEvent* QueryEvent(u32 event_id) override; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index f43914e1b..63228518e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | |||
| @@ -35,7 +35,7 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 35 | case 0x7: | 35 | case 0x7: |
| 36 | return WrapFixed(this, &nvhost_nvdec::SetSubmitTimeout, input, output); | 36 | return WrapFixed(this, &nvhost_nvdec::SetSubmitTimeout, input, output); |
| 37 | case 0x9: | 37 | case 0x9: |
| 38 | return WrapFixedVariable(this, &nvhost_nvdec::MapBuffer, input, output); | 38 | return WrapFixedVariable(this, &nvhost_nvdec::MapBuffer, input, output, fd); |
| 39 | case 0xa: | 39 | case 0xa: |
| 40 | return WrapFixedVariable(this, &nvhost_nvdec::UnmapBuffer, input, output); | 40 | return WrapFixedVariable(this, &nvhost_nvdec::UnmapBuffer, input, output); |
| 41 | default: | 41 | default: |
| @@ -68,9 +68,10 @@ NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 68 | return NvResult::NotImplemented; | 68 | return NvResult::NotImplemented; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | void nvhost_nvdec::OnOpen(DeviceFD fd) { | 71 | void nvhost_nvdec::OnOpen(size_t session_id, DeviceFD fd) { |
| 72 | LOG_INFO(Service_NVDRV, "NVDEC video stream started"); | 72 | LOG_INFO(Service_NVDRV, "NVDEC video stream started"); |
| 73 | system.SetNVDECActive(true); | 73 | system.SetNVDECActive(true); |
| 74 | sessions[fd] = session_id; | ||
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | void nvhost_nvdec::OnClose(DeviceFD fd) { | 77 | void nvhost_nvdec::OnClose(DeviceFD fd) { |
| @@ -81,6 +82,10 @@ void nvhost_nvdec::OnClose(DeviceFD fd) { | |||
| 81 | system.GPU().ClearCdmaInstance(iter->second); | 82 | system.GPU().ClearCdmaInstance(iter->second); |
| 82 | } | 83 | } |
| 83 | system.SetNVDECActive(false); | 84 | system.SetNVDECActive(false); |
| 85 | auto it = sessions.find(fd); | ||
| 86 | if (it != sessions.end()) { | ||
| 87 | sessions.erase(it); | ||
| 88 | } | ||
| 84 | } | 89 | } |
| 85 | 90 | ||
| 86 | } // namespace Service::Nvidia::Devices | 91 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index ad2233c49..1fb27b814 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | |||
| @@ -20,7 +20,7 @@ public: | |||
| 20 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, | 20 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 21 | std::span<u8> inline_output) override; | 21 | std::span<u8> inline_output) override; |
| 22 | 22 | ||
| 23 | void OnOpen(DeviceFD fd) override; | 23 | void OnOpen(size_t session_id, DeviceFD fd) override; |
| 24 | void OnClose(DeviceFD fd) override; | 24 | void OnClose(DeviceFD fd) override; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
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 74c701b95..9ab0ae4d8 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -133,10 +133,10 @@ NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) { | |||
| 133 | return NvResult::Success; | 133 | return NvResult::Success; |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries) { | 136 | NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries, DeviceFD fd) { |
| 137 | const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size())); | 137 | const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size())); |
| 138 | for (size_t i = 0; i < num_entries; i++) { | 138 | for (size_t i = 0; i < num_entries; i++) { |
| 139 | entries[i].map_address = nvmap.PinHandle(entries[i].map_handle); | 139 | entries[i].map_address = nvmap.PinHandle(entries[i].map_handle, sessions[fd]); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | return NvResult::Success; | 142 | return NvResult::Success; |
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 7ce748e18..b44b17a82 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | 5 | ||
| 6 | #include <deque> | 6 | #include <deque> |
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | #include <unordered_map> | ||
| 9 | |||
| 8 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 9 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| 10 | #include "core/hle/service/nvdrv/core/syncpoint_manager.h" | 12 | #include "core/hle/service/nvdrv/core/syncpoint_manager.h" |
| @@ -111,7 +113,7 @@ protected: | |||
| 111 | NvResult Submit(IoctlSubmit& params, std::span<u8> input, DeviceFD fd); | 113 | NvResult Submit(IoctlSubmit& params, std::span<u8> input, DeviceFD fd); |
| 112 | NvResult GetSyncpoint(IoctlGetSyncpoint& params); | 114 | NvResult GetSyncpoint(IoctlGetSyncpoint& params); |
| 113 | NvResult GetWaitbase(IoctlGetWaitbase& params); | 115 | NvResult GetWaitbase(IoctlGetWaitbase& params); |
| 114 | NvResult MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries); | 116 | NvResult MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries, DeviceFD fd); |
| 115 | NvResult UnmapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries); | 117 | NvResult UnmapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries); |
| 116 | NvResult SetSubmitTimeout(u32 timeout); | 118 | NvResult SetSubmitTimeout(u32 timeout); |
| 117 | 119 | ||
| @@ -125,6 +127,7 @@ protected: | |||
| 125 | NvCore::NvMap& nvmap; | 127 | NvCore::NvMap& nvmap; |
| 126 | NvCore::ChannelType channel_type; | 128 | NvCore::ChannelType channel_type; |
| 127 | std::array<u32, MaxSyncPoints> device_syncpoints{}; | 129 | std::array<u32, MaxSyncPoints> device_syncpoints{}; |
| 130 | std::unordered_map<DeviceFD, size_t> sessions; | ||
| 128 | }; | 131 | }; |
| 129 | }; // namespace Devices | 132 | }; // namespace Devices |
| 130 | } // namespace Service::Nvidia | 133 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp index 9e6b86458..1c88b39ab 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp | |||
| @@ -44,7 +44,7 @@ NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in | |||
| 44 | return NvResult::NotImplemented; | 44 | return NvResult::NotImplemented; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | void nvhost_nvjpg::OnOpen(DeviceFD fd) {} | 47 | void nvhost_nvjpg::OnOpen(size_t session_id, DeviceFD fd) {} |
| 48 | void nvhost_nvjpg::OnClose(DeviceFD fd) {} | 48 | void nvhost_nvjpg::OnClose(DeviceFD fd) {} |
| 49 | 49 | ||
| 50 | NvResult nvhost_nvjpg::SetNVMAPfd(IoctlSetNvmapFD& params) { | 50 | NvResult nvhost_nvjpg::SetNVMAPfd(IoctlSetNvmapFD& params) { |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h index 790c97f6a..3e33dffef 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h | |||
| @@ -22,7 +22,7 @@ public: | |||
| 22 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, | 22 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 23 | std::span<u8> inline_output) override; | 23 | std::span<u8> inline_output) override; |
| 24 | 24 | ||
| 25 | void OnOpen(DeviceFD fd) override; | 25 | void OnOpen(size_t session_id, DeviceFD fd) override; |
| 26 | void OnClose(DeviceFD fd) override; | 26 | void OnClose(DeviceFD fd) override; |
| 27 | 27 | ||
| 28 | private: | 28 | private: |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index 87f8d7c22..d4c93ea5d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | |||
| @@ -33,7 +33,7 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 33 | case 0x3: | 33 | case 0x3: |
| 34 | return WrapFixed(this, &nvhost_vic::GetWaitbase, input, output); | 34 | return WrapFixed(this, &nvhost_vic::GetWaitbase, input, output); |
| 35 | case 0x9: | 35 | case 0x9: |
| 36 | return WrapFixedVariable(this, &nvhost_vic::MapBuffer, input, output); | 36 | return WrapFixedVariable(this, &nvhost_vic::MapBuffer, input, output, fd); |
| 37 | case 0xa: | 37 | case 0xa: |
| 38 | return WrapFixedVariable(this, &nvhost_vic::UnmapBuffer, input, output); | 38 | return WrapFixedVariable(this, &nvhost_vic::UnmapBuffer, input, output); |
| 39 | default: | 39 | default: |
| @@ -68,7 +68,9 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu | |||
| 68 | return NvResult::NotImplemented; | 68 | return NvResult::NotImplemented; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | void nvhost_vic::OnOpen(DeviceFD fd) {} | 71 | void nvhost_vic::OnOpen(size_t session_id, DeviceFD fd) { |
| 72 | sessions[fd] = session_id; | ||
| 73 | } | ||
| 72 | 74 | ||
| 73 | void nvhost_vic::OnClose(DeviceFD fd) { | 75 | void nvhost_vic::OnClose(DeviceFD fd) { |
| 74 | auto& host1x_file = core.Host1xDeviceFile(); | 76 | auto& host1x_file = core.Host1xDeviceFile(); |
| @@ -76,6 +78,10 @@ void nvhost_vic::OnClose(DeviceFD fd) { | |||
| 76 | if (iter != host1x_file.fd_to_id.end()) { | 78 | if (iter != host1x_file.fd_to_id.end()) { |
| 77 | system.GPU().ClearCdmaInstance(iter->second); | 79 | system.GPU().ClearCdmaInstance(iter->second); |
| 78 | } | 80 | } |
| 81 | auto it = sessions.find(fd); | ||
| 82 | if (it != sessions.end()) { | ||
| 83 | sessions.erase(it); | ||
| 84 | } | ||
| 79 | } | 85 | } |
| 80 | 86 | ||
| 81 | } // namespace Service::Nvidia::Devices | 87 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index cadbcb0a5..d70df0f20 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h | |||
| @@ -19,7 +19,7 @@ public: | |||
| 19 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, | 19 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 20 | std::span<u8> inline_output) override; | 20 | std::span<u8> inline_output) override; |
| 21 | 21 | ||
| 22 | void OnOpen(DeviceFD fd) override; | 22 | void OnOpen(size_t session_id, DeviceFD fd) override; |
| 23 | void OnClose(DeviceFD fd) override; | 23 | void OnClose(DeviceFD fd) override; |
| 24 | }; | 24 | }; |
| 25 | } // namespace Service::Nvidia::Devices | 25 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 71b2e62ec..2b107f009 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -36,9 +36,9 @@ NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, | |||
| 36 | case 0x3: | 36 | case 0x3: |
| 37 | return WrapFixed(this, &nvmap::IocFromId, input, output); | 37 | return WrapFixed(this, &nvmap::IocFromId, input, output); |
| 38 | case 0x4: | 38 | case 0x4: |
| 39 | return WrapFixed(this, &nvmap::IocAlloc, input, output); | 39 | return WrapFixed(this, &nvmap::IocAlloc, input, output, fd); |
| 40 | case 0x5: | 40 | case 0x5: |
| 41 | return WrapFixed(this, &nvmap::IocFree, input, output); | 41 | return WrapFixed(this, &nvmap::IocFree, input, output, fd); |
| 42 | case 0x9: | 42 | case 0x9: |
| 43 | return WrapFixed(this, &nvmap::IocParam, input, output); | 43 | return WrapFixed(this, &nvmap::IocParam, input, output); |
| 44 | case 0xe: | 44 | case 0xe: |
| @@ -67,8 +67,15 @@ NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, st | |||
| 67 | return NvResult::NotImplemented; | 67 | return NvResult::NotImplemented; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | void nvmap::OnOpen(DeviceFD fd) {} | 70 | void nvmap::OnOpen(size_t session_id, DeviceFD fd) { |
| 71 | void nvmap::OnClose(DeviceFD fd) {} | 71 | sessions[fd] = session_id; |
| 72 | } | ||
| 73 | void nvmap::OnClose(DeviceFD fd) { | ||
| 74 | auto it = sessions.find(fd); | ||
| 75 | if (it != sessions.end()) { | ||
| 76 | sessions.erase(it); | ||
| 77 | } | ||
| 78 | } | ||
| 72 | 79 | ||
| 73 | NvResult nvmap::IocCreate(IocCreateParams& params) { | 80 | NvResult nvmap::IocCreate(IocCreateParams& params) { |
| 74 | LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); | 81 | LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); |
| @@ -87,7 +94,7 @@ NvResult nvmap::IocCreate(IocCreateParams& params) { | |||
| 87 | return NvResult::Success; | 94 | return NvResult::Success; |
| 88 | } | 95 | } |
| 89 | 96 | ||
| 90 | NvResult nvmap::IocAlloc(IocAllocParams& params) { | 97 | NvResult nvmap::IocAlloc(IocAllocParams& params, DeviceFD fd) { |
| 91 | LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); | 98 | LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); |
| 92 | 99 | ||
| 93 | if (!params.handle) { | 100 | if (!params.handle) { |
| @@ -116,15 +123,15 @@ NvResult nvmap::IocAlloc(IocAllocParams& params) { | |||
| 116 | return NvResult::InsufficientMemory; | 123 | return NvResult::InsufficientMemory; |
| 117 | } | 124 | } |
| 118 | 125 | ||
| 119 | const auto result = | 126 | const auto result = file.AllocateHandle(params.handle, params.flags, params.align, params.kind, |
| 120 | handle_description->Alloc(params.flags, params.align, params.kind, params.address); | 127 | params.address, sessions[fd]); |
| 121 | if (result != NvResult::Success) { | 128 | if (result != NvResult::Success) { |
| 122 | LOG_CRITICAL(Service_NVDRV, "Object failed to allocate, handle={:08X}", params.handle); | 129 | LOG_CRITICAL(Service_NVDRV, "Object failed to allocate, handle={:08X}", params.handle); |
| 123 | return result; | 130 | return result; |
| 124 | } | 131 | } |
| 125 | bool is_out_io{}; | 132 | bool is_out_io{}; |
| 126 | ASSERT(system.ApplicationProcess() | 133 | auto process = container.GetSession(sessions[fd])->process; |
| 127 | ->GetPageTable() | 134 | ASSERT(process->GetPageTable() |
| 128 | .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address, | 135 | .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address, |
| 129 | handle_description->size, | 136 | handle_description->size, |
| 130 | Kernel::KMemoryPermission::None, true, false) | 137 | Kernel::KMemoryPermission::None, true, false) |
| @@ -224,7 +231,7 @@ NvResult nvmap::IocParam(IocParamParams& params) { | |||
| 224 | return NvResult::Success; | 231 | return NvResult::Success; |
| 225 | } | 232 | } |
| 226 | 233 | ||
| 227 | NvResult nvmap::IocFree(IocFreeParams& params) { | 234 | NvResult nvmap::IocFree(IocFreeParams& params, DeviceFD fd) { |
| 228 | LOG_DEBUG(Service_NVDRV, "called"); | 235 | LOG_DEBUG(Service_NVDRV, "called"); |
| 229 | 236 | ||
| 230 | if (!params.handle) { | 237 | if (!params.handle) { |
| @@ -233,9 +240,9 @@ NvResult nvmap::IocFree(IocFreeParams& params) { | |||
| 233 | } | 240 | } |
| 234 | 241 | ||
| 235 | if (auto freeInfo{file.FreeHandle(params.handle, false)}) { | 242 | if (auto freeInfo{file.FreeHandle(params.handle, false)}) { |
| 243 | auto process = container.GetSession(sessions[fd])->process; | ||
| 236 | if (freeInfo->can_unlock) { | 244 | if (freeInfo->can_unlock) { |
| 237 | ASSERT(system.ApplicationProcess() | 245 | ASSERT(process->GetPageTable() |
| 238 | ->GetPageTable() | ||
| 239 | .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) | 246 | .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) |
| 240 | .IsSuccess()); | 247 | .IsSuccess()); |
| 241 | } | 248 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index 049c11028..ea5df2a9c 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h | |||
| @@ -33,7 +33,7 @@ public: | |||
| 33 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, | 33 | NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, |
| 34 | std::span<u8> inline_output) override; | 34 | std::span<u8> inline_output) override; |
| 35 | 35 | ||
| 36 | void OnOpen(DeviceFD fd) override; | 36 | void OnOpen(size_t session_id, DeviceFD fd) override; |
| 37 | void OnClose(DeviceFD fd) override; | 37 | void OnClose(DeviceFD fd) override; |
| 38 | 38 | ||
| 39 | enum class HandleParameterType : u32_le { | 39 | enum class HandleParameterType : u32_le { |
| @@ -100,11 +100,11 @@ public: | |||
| 100 | static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); | 100 | static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); |
| 101 | 101 | ||
| 102 | NvResult IocCreate(IocCreateParams& params); | 102 | NvResult IocCreate(IocCreateParams& params); |
| 103 | NvResult IocAlloc(IocAllocParams& params); | 103 | NvResult IocAlloc(IocAllocParams& params, DeviceFD fd); |
| 104 | NvResult IocGetId(IocGetIdParams& params); | 104 | NvResult IocGetId(IocGetIdParams& params); |
| 105 | NvResult IocFromId(IocFromIdParams& params); | 105 | NvResult IocFromId(IocFromIdParams& params); |
| 106 | NvResult IocParam(IocParamParams& params); | 106 | NvResult IocParam(IocParamParams& params); |
| 107 | NvResult IocFree(IocFreeParams& params); | 107 | NvResult IocFree(IocFreeParams& params, DeviceFD fd); |
| 108 | 108 | ||
| 109 | private: | 109 | private: |
| 110 | /// Id to use for the next handle that is created. | 110 | /// Id to use for the next handle that is created. |
| @@ -115,6 +115,7 @@ private: | |||
| 115 | 115 | ||
| 116 | NvCore::Container& container; | 116 | NvCore::Container& container; |
| 117 | NvCore::NvMap& file; | 117 | NvCore::NvMap& file; |
| 118 | std::unordered_map<DeviceFD, size_t> sessions; | ||
| 118 | }; | 119 | }; |
| 119 | 120 | ||
| 120 | } // namespace Service::Nvidia::Devices | 121 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 9e46ee8dd..5191341db 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -45,13 +45,22 @@ void EventInterface::FreeEvent(Kernel::KEvent* event) { | |||
| 45 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { | 45 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { |
| 46 | auto server_manager = std::make_unique<ServerManager>(system); | 46 | auto server_manager = std::make_unique<ServerManager>(system); |
| 47 | auto module = std::make_shared<Module>(system); | 47 | auto module = std::make_shared<Module>(system); |
| 48 | server_manager->RegisterNamedService("nvdrv", std::make_shared<NVDRV>(system, module, "nvdrv")); | 48 | const auto NvdrvInterfaceFactoryForApplication = [&, module] { |
| 49 | server_manager->RegisterNamedService("nvdrv:a", | 49 | return std::make_shared<NVDRV>(system, module, "nvdrv"); |
| 50 | std::make_shared<NVDRV>(system, module, "nvdrv:a")); | 50 | }; |
| 51 | server_manager->RegisterNamedService("nvdrv:s", | 51 | const auto NvdrvInterfaceFactoryForApplets = [&, module] { |
| 52 | std::make_shared<NVDRV>(system, module, "nvdrv:s")); | 52 | return std::make_shared<NVDRV>(system, module, "nvdrv:a"); |
| 53 | server_manager->RegisterNamedService("nvdrv:t", | 53 | }; |
| 54 | std::make_shared<NVDRV>(system, module, "nvdrv:t")); | 54 | const auto NvdrvInterfaceFactoryForSysmodules = [&, module] { |
| 55 | return std::make_shared<NVDRV>(system, module, "nvdrv:a"); | ||
| 56 | }; | ||
| 57 | const auto NvdrvInterfaceFactory = [&, module] { | ||
| 58 | return std::make_shared<NVDRV>(system, module, "nvdrv:t"); | ||
| 59 | }; | ||
| 60 | server_manager->RegisterNamedService("nvdrv", NvdrvInterfaceFactoryForApplication); | ||
| 61 | server_manager->RegisterNamedService("nvdrv:a", NvdrvInterfaceFactoryForApplets); | ||
| 62 | server_manager->RegisterNamedService("nvdrv:s", NvdrvInterfaceFactoryForSysmodules); | ||
| 63 | server_manager->RegisterNamedService("nvdrv:t", NvdrvInterfaceFactory); | ||
| 55 | server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system)); | 64 | server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system)); |
| 56 | nvnflinger.SetNVDrvInstance(module); | 65 | nvnflinger.SetNVDrvInstance(module); |
| 57 | ServerManager::RunServer(std::move(server_manager)); | 66 | ServerManager::RunServer(std::move(server_manager)); |
| @@ -113,7 +122,7 @@ NvResult Module::VerifyFD(DeviceFD fd) const { | |||
| 113 | return NvResult::Success; | 122 | return NvResult::Success; |
| 114 | } | 123 | } |
| 115 | 124 | ||
| 116 | DeviceFD Module::Open(const std::string& device_name) { | 125 | DeviceFD Module::Open(const std::string& device_name, size_t session_id) { |
| 117 | auto it = builders.find(device_name); | 126 | auto it = builders.find(device_name); |
| 118 | if (it == builders.end()) { | 127 | if (it == builders.end()) { |
| 119 | LOG_ERROR(Service_NVDRV, "Trying to open unknown device {}", device_name); | 128 | LOG_ERROR(Service_NVDRV, "Trying to open unknown device {}", device_name); |
| @@ -124,7 +133,7 @@ DeviceFD Module::Open(const std::string& device_name) { | |||
| 124 | auto& builder = it->second; | 133 | auto& builder = it->second; |
| 125 | auto device = builder(fd)->second; | 134 | auto device = builder(fd)->second; |
| 126 | 135 | ||
| 127 | device->OnOpen(fd); | 136 | device->OnOpen(session_id, fd); |
| 128 | 137 | ||
| 129 | return fd; | 138 | return fd; |
| 130 | } | 139 | } |
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index d8622b3ca..d7648fb15 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h | |||
| @@ -77,7 +77,7 @@ public: | |||
| 77 | NvResult VerifyFD(DeviceFD fd) const; | 77 | NvResult VerifyFD(DeviceFD fd) const; |
| 78 | 78 | ||
| 79 | /// Opens a device node and returns a file descriptor to it. | 79 | /// Opens a device node and returns a file descriptor to it. |
| 80 | DeviceFD Open(const std::string& device_name); | 80 | DeviceFD Open(const std::string& device_name, size_t session_id); |
| 81 | 81 | ||
| 82 | /// Sends an ioctl command to the specified file descriptor. | 82 | /// Sends an ioctl command to the specified file descriptor. |
| 83 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output); | 83 | NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output); |
| @@ -93,6 +93,10 @@ public: | |||
| 93 | 93 | ||
| 94 | NvResult QueryEvent(DeviceFD fd, u32 event_id, Kernel::KEvent*& event); | 94 | NvResult QueryEvent(DeviceFD fd, u32 event_id, Kernel::KEvent*& event); |
| 95 | 95 | ||
| 96 | NvCore::Container& GetContainer() { | ||
| 97 | return container; | ||
| 98 | } | ||
| 99 | |||
| 96 | private: | 100 | private: |
| 97 | friend class EventInterface; | 101 | friend class EventInterface; |
| 98 | friend class Service::Nvnflinger::Nvnflinger; | 102 | friend class Service::Nvnflinger::Nvnflinger; |
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp index c8a880e84..492ad849a 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp | |||
| @@ -3,14 +3,18 @@ | |||
| 3 | // SPDX-License-Identifier: GPL-3.0-or-later | 3 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 6 | #include "common/scope_exit.h" | ||
| 6 | #include "core/core.h" | 7 | #include "core/core.h" |
| 7 | #include "core/hle/kernel/k_event.h" | 8 | #include "core/hle/kernel/k_event.h" |
| 9 | #include "core/hle/kernel/k_process.h" | ||
| 8 | #include "core/hle/kernel/k_readable_event.h" | 10 | #include "core/hle/kernel/k_readable_event.h" |
| 9 | #include "core/hle/service/ipc_helpers.h" | 11 | #include "core/hle/service/ipc_helpers.h" |
| 10 | #include "core/hle/service/nvdrv/nvdata.h" | 12 | #include "core/hle/service/nvdrv/nvdata.h" |
| 11 | #include "core/hle/service/nvdrv/nvdrv.h" | 13 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 12 | #include "core/hle/service/nvdrv/nvdrv_interface.h" | 14 | #include "core/hle/service/nvdrv/nvdrv_interface.h" |
| 13 | 15 | ||
| 16 | #pragma optimize("", off) | ||
| 17 | |||
| 14 | namespace Service::Nvidia { | 18 | namespace Service::Nvidia { |
| 15 | 19 | ||
| 16 | void NVDRV::Open(HLERequestContext& ctx) { | 20 | void NVDRV::Open(HLERequestContext& ctx) { |
| @@ -37,7 +41,7 @@ void NVDRV::Open(HLERequestContext& ctx) { | |||
| 37 | return; | 41 | return; |
| 38 | } | 42 | } |
| 39 | 43 | ||
| 40 | DeviceFD fd = nvdrv->Open(device_name); | 44 | DeviceFD fd = nvdrv->Open(device_name, session_id); |
| 41 | 45 | ||
| 42 | rb.Push<DeviceFD>(fd); | 46 | rb.Push<DeviceFD>(fd); |
| 43 | rb.PushEnum(fd != INVALID_NVDRV_FD ? NvResult::Success : NvResult::FileOperationFailed); | 47 | rb.PushEnum(fd != INVALID_NVDRV_FD ? NvResult::Success : NvResult::FileOperationFailed); |
| @@ -150,12 +154,29 @@ void NVDRV::Close(HLERequestContext& ctx) { | |||
| 150 | 154 | ||
| 151 | void NVDRV::Initialize(HLERequestContext& ctx) { | 155 | void NVDRV::Initialize(HLERequestContext& ctx) { |
| 152 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 156 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 157 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 158 | SCOPE_EXIT({ | ||
| 159 | rb.Push(ResultSuccess); | ||
| 160 | rb.PushEnum(NvResult::Success); | ||
| 161 | }); | ||
| 153 | 162 | ||
| 154 | is_initialized = true; | 163 | if (is_initialized) { |
| 164 | // No need to initialize again | ||
| 165 | return; | ||
| 166 | } | ||
| 155 | 167 | ||
| 156 | IPC::ResponseBuilder rb{ctx, 3}; | 168 | IPC::RequestParser rp{ctx}; |
| 157 | rb.Push(ResultSuccess); | 169 | const auto process_handle{ctx.GetCopyHandle(0)}; |
| 158 | rb.PushEnum(NvResult::Success); | 170 | // The transfer memory is lent to nvdrv as a work buffer since nvdrv is |
| 171 | // unable to allocate as much memory on its own. For HLE it's unnecessary to handle it | ||
| 172 | [[maybe_unused]] const auto transfer_memory_handle{ctx.GetCopyHandle(1)}; | ||
| 173 | [[maybe_unused]] const auto transfer_memory_size = rp.Pop<u32>(); | ||
| 174 | |||
| 175 | auto& container = nvdrv->GetContainer(); | ||
| 176 | auto process = ctx.GetObjectFromHandle(process_handle); | ||
| 177 | session_id = container.OpenSession(process->DynamicCast<Kernel::KProcess*>()); | ||
| 178 | |||
| 179 | is_initialized = true; | ||
| 159 | } | 180 | } |
| 160 | 181 | ||
| 161 | void NVDRV::QueryEvent(HLERequestContext& ctx) { | 182 | void NVDRV::QueryEvent(HLERequestContext& ctx) { |
| @@ -242,6 +263,9 @@ NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* | |||
| 242 | RegisterHandlers(functions); | 263 | RegisterHandlers(functions); |
| 243 | } | 264 | } |
| 244 | 265 | ||
| 245 | NVDRV::~NVDRV() = default; | 266 | NVDRV::~NVDRV() { |
| 267 | auto& container = nvdrv->GetContainer(); | ||
| 268 | container.CloseSession(session_id); | ||
| 269 | } | ||
| 246 | 270 | ||
| 247 | } // namespace Service::Nvidia | 271 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h index 6e98115dc..e7237c881 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.h +++ b/src/core/hle/service/nvdrv/nvdrv_interface.h | |||
| @@ -35,6 +35,7 @@ private: | |||
| 35 | 35 | ||
| 36 | u64 pid{}; | 36 | u64 pid{}; |
| 37 | bool is_initialized{}; | 37 | bool is_initialized{}; |
| 38 | size_t session_id{}; | ||
| 38 | Common::ScratchBuffer<u8> output_buffer; | 39 | Common::ScratchBuffer<u8> output_buffer; |
| 39 | Common::ScratchBuffer<u8> inline_output_buffer; | 40 | Common::ScratchBuffer<u8> inline_output_buffer; |
| 40 | }; | 41 | }; |
diff --git a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp index 2fef6cc1a..d36eff4ec 100644 --- a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp +++ b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp | |||
| @@ -87,19 +87,19 @@ Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap, | |||
| 87 | R_SUCCEED(); | 87 | R_SUCCEED(); |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) { | 90 | Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Nvidia::DeviceFD nvmap_fd) { |
| 91 | // Free the handle. | 91 | // Free the handle. |
| 92 | Nvidia::Devices::nvmap::IocFreeParams free_params{ | 92 | Nvidia::Devices::nvmap::IocFreeParams free_params{ |
| 93 | .handle = handle, | 93 | .handle = handle, |
| 94 | }; | 94 | }; |
| 95 | R_UNLESS(nvmap.IocFree(free_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed); | 95 | R_UNLESS(nvmap.IocFree(free_params, nvmap_fd) == Nvidia::NvResult::Success, VI::ResultOperationFailed); |
| 96 | 96 | ||
| 97 | // We succeeded. | 97 | // We succeeded. |
| 98 | R_SUCCEED(); | 98 | R_SUCCEED(); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::ProcessAddress buffer, | 101 | Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::ProcessAddress buffer, |
| 102 | u32 size) { | 102 | u32 size, Nvidia::DeviceFD nvmap_fd) { |
| 103 | // Assign the allocated memory to the handle. | 103 | // Assign the allocated memory to the handle. |
| 104 | Nvidia::Devices::nvmap::IocAllocParams alloc_params{ | 104 | Nvidia::Devices::nvmap::IocAllocParams alloc_params{ |
| 105 | .handle = handle, | 105 | .handle = handle, |
| @@ -109,16 +109,15 @@ Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::Proce | |||
| 109 | .kind = 0, | 109 | .kind = 0, |
| 110 | .address = GetInteger(buffer), | 110 | .address = GetInteger(buffer), |
| 111 | }; | 111 | }; |
| 112 | R_UNLESS(nvmap.IocAlloc(alloc_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed); | 112 | R_UNLESS(nvmap.IocAlloc(alloc_params, nvmap_fd) == Nvidia::NvResult::Success, VI::ResultOperationFailed); |
| 113 | 113 | ||
| 114 | // We succeeded. | 114 | // We succeeded. |
| 115 | R_SUCCEED(); | 115 | R_SUCCEED(); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | Result AllocateHandleForBuffer(u32* out_handle, Nvidia::Module& nvdrv, | 118 | Result AllocateHandleForBuffer(u32* out_handle, Nvidia::Module& nvdrv, Nvidia::DeviceFD nvmap_fd, |
| 119 | Common::ProcessAddress buffer, u32 size) { | 119 | Common::ProcessAddress buffer, u32 size) { |
| 120 | // Get the nvmap device. | 120 | // Get the nvmap device. |
| 121 | auto nvmap_fd = nvdrv.Open("/dev/nvmap"); | ||
| 122 | auto nvmap = nvdrv.GetDevice<Nvidia::Devices::nvmap>(nvmap_fd); | 121 | auto nvmap = nvdrv.GetDevice<Nvidia::Devices::nvmap>(nvmap_fd); |
| 123 | ASSERT(nvmap != nullptr); | 122 | ASSERT(nvmap != nullptr); |
| 124 | 123 | ||
| @@ -127,11 +126,11 @@ Result AllocateHandleForBuffer(u32* out_handle, Nvidia::Module& nvdrv, | |||
| 127 | 126 | ||
| 128 | // Ensure we maintain a clean state on failure. | 127 | // Ensure we maintain a clean state on failure. |
| 129 | ON_RESULT_FAILURE { | 128 | ON_RESULT_FAILURE { |
| 130 | ASSERT(R_SUCCEEDED(FreeNvMapHandle(*nvmap, *out_handle))); | 129 | ASSERT(R_SUCCEEDED(FreeNvMapHandle(*nvmap, *out_handle, nvmap_fd))); |
| 131 | }; | 130 | }; |
| 132 | 131 | ||
| 133 | // Assign the allocated memory to the handle. | 132 | // Assign the allocated memory to the handle. |
| 134 | R_RETURN(AllocNvMapHandle(*nvmap, *out_handle, buffer, size)); | 133 | R_RETURN(AllocNvMapHandle(*nvmap, *out_handle, buffer, size, nvmap_fd)); |
| 135 | } | 134 | } |
| 136 | 135 | ||
| 137 | constexpr auto SharedBufferBlockLinearFormat = android::PixelFormat::Rgba8888; | 136 | constexpr auto SharedBufferBlockLinearFormat = android::PixelFormat::Rgba8888; |
| @@ -197,8 +196,12 @@ Result FbShareBufferManager::Initialize(u64* out_buffer_id, u64* out_layer_id, u | |||
| 197 | std::addressof(m_buffer_page_group), m_system, | 196 | std::addressof(m_buffer_page_group), m_system, |
| 198 | SharedBufferSize)); | 197 | SharedBufferSize)); |
| 199 | 198 | ||
| 199 | auto& container = m_nvdrv->GetContainer(); | ||
| 200 | m_session_id = container.OpenSession(m_system.ApplicationProcess()); | ||
| 201 | m_nvmap_fd = m_nvdrv->Open("/dev/nvmap", m_session_id); | ||
| 202 | |||
| 200 | // Create an nvmap handle for the buffer and assign the memory to it. | 203 | // Create an nvmap handle for the buffer and assign the memory to it. |
| 201 | R_TRY(AllocateHandleForBuffer(std::addressof(m_buffer_nvmap_handle), *m_nvdrv, map_address, | 204 | R_TRY(AllocateHandleForBuffer(std::addressof(m_buffer_nvmap_handle), *m_nvdrv, m_nvmap_fd, map_address, |
| 202 | SharedBufferSize)); | 205 | SharedBufferSize)); |
| 203 | 206 | ||
| 204 | // Record the display id. | 207 | // Record the display id. |
diff --git a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.h b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.h index c809c01b4..4b1a3d430 100644 --- a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.h +++ b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include "common/math_util.h" | 6 | #include "common/math_util.h" |
| 7 | #include "core/hle/service/nvnflinger/nvnflinger.h" | 7 | #include "core/hle/service/nvnflinger/nvnflinger.h" |
| 8 | #include "core/hle/service/nvnflinger/ui/fence.h" | 8 | #include "core/hle/service/nvnflinger/ui/fence.h" |
| 9 | #include "core/hle/service/nvdrv/nvdata.h" | ||
| 9 | 10 | ||
| 10 | namespace Kernel { | 11 | namespace Kernel { |
| 11 | class KPageGroup; | 12 | class KPageGroup; |
| @@ -53,13 +54,15 @@ private: | |||
| 53 | u64 m_layer_id = 0; | 54 | u64 m_layer_id = 0; |
| 54 | u32 m_buffer_nvmap_handle = 0; | 55 | u32 m_buffer_nvmap_handle = 0; |
| 55 | SharedMemoryPoolLayout m_pool_layout = {}; | 56 | SharedMemoryPoolLayout m_pool_layout = {}; |
| 56 | 57 | Nvidia::DeviceFD m_nvmap_fd = {}; | |
| 58 | size_t m_session_id = {}; | ||
| 57 | std::unique_ptr<Kernel::KPageGroup> m_buffer_page_group; | 59 | std::unique_ptr<Kernel::KPageGroup> m_buffer_page_group; |
| 58 | 60 | ||
| 59 | std::mutex m_guard; | 61 | std::mutex m_guard; |
| 60 | Core::System& m_system; | 62 | Core::System& m_system; |
| 61 | Nvnflinger& m_flinger; | 63 | Nvnflinger& m_flinger; |
| 62 | std::shared_ptr<Nvidia::Module> m_nvdrv; | 64 | std::shared_ptr<Nvidia::Module> m_nvdrv; |
| 65 | |||
| 63 | }; | 66 | }; |
| 64 | 67 | ||
| 65 | } // namespace Service::Nvnflinger | 68 | } // namespace Service::Nvnflinger |
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp index 0469110e8..e4b38ae0b 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.cpp +++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp | |||
| @@ -126,7 +126,7 @@ void Nvnflinger::ShutdownLayers() { | |||
| 126 | 126 | ||
| 127 | void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { | 127 | void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { |
| 128 | nvdrv = std::move(instance); | 128 | nvdrv = std::move(instance); |
| 129 | disp_fd = nvdrv->Open("/dev/nvdisp_disp0"); | 129 | disp_fd = nvdrv->Open("/dev/nvdisp_disp0", 0); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | std::optional<u64> Nvnflinger::OpenDisplay(std::string_view name) { | 132 | std::optional<u64> Nvnflinger::OpenDisplay(std::string_view name) { |
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index c22c7631c..2dda8ebc2 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -71,6 +71,8 @@ add_library(video_core STATIC | |||
| 71 | host1x/ffmpeg/ffmpeg.h | 71 | host1x/ffmpeg/ffmpeg.h |
| 72 | host1x/control.cpp | 72 | host1x/control.cpp |
| 73 | host1x/control.h | 73 | host1x/control.h |
| 74 | host1x/gpu_device_memory_manager.cpp | ||
| 75 | host1x/gpu_device_memory_manager.h | ||
| 74 | host1x/host1x.cpp | 76 | host1x/host1x.cpp |
| 75 | host1x/host1x.h | 77 | host1x/host1x.h |
| 76 | host1x/nvdec.cpp | 78 | host1x/nvdec.cpp |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 11549d448..1e915682f 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -85,7 +85,7 @@ struct GPU::Impl { | |||
| 85 | void BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer_) { | 85 | void BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer_) { |
| 86 | renderer = std::move(renderer_); | 86 | renderer = std::move(renderer_); |
| 87 | rasterizer = renderer->ReadRasterizer(); | 87 | rasterizer = renderer->ReadRasterizer(); |
| 88 | host1x.MemoryManager().BindRasterizer(rasterizer); | 88 | host1x.MemoryManager().BindInterface(rasterizer); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | /// Flush all current written commands into the host GPU for execution. | 91 | /// Flush all current written commands into the host GPU for execution. |
diff --git a/src/video_core/host1x/host1x.cpp b/src/video_core/host1x/host1x.cpp index 7c317a85d..d05bcaf26 100644 --- a/src/video_core/host1x/host1x.cpp +++ b/src/video_core/host1x/host1x.cpp | |||
| @@ -9,8 +9,7 @@ namespace Tegra { | |||
| 9 | namespace Host1x { | 9 | namespace Host1x { |
| 10 | 10 | ||
| 11 | Host1x::Host1x(Core::System& system_) | 11 | Host1x::Host1x(Core::System& system_) |
| 12 | : system{system_}, syncpoint_manager{}, memory_manager{system, 32, 12}, | 12 | : system{system_}, syncpoint_manager{}, memory_manager(system.DeviceMemory()) {} |
| 13 | allocator{std::make_unique<Common::FlatAllocator<u32, 0, 32>>(1 << 12)} {} | ||
| 14 | 13 | ||
| 15 | } // namespace Host1x | 14 | } // namespace Host1x |
| 16 | 15 | ||
diff --git a/src/video_core/host1x/host1x.h b/src/video_core/host1x/host1x.h index 57082ae54..18f7389f6 100644 --- a/src/video_core/host1x/host1x.h +++ b/src/video_core/host1x/host1x.h | |||
| @@ -5,9 +5,8 @@ | |||
| 5 | 5 | ||
| 6 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 7 | 7 | ||
| 8 | #include "common/address_space.h" | 8 | #include "video_core/host1x/gpu_device_memory_manager.h" |
| 9 | #include "video_core/host1x/syncpoint_manager.h" | 9 | #include "video_core/host1x/syncpoint_manager.h" |
| 10 | #include "video_core/memory_manager.h" | ||
| 11 | 10 | ||
| 12 | namespace Core { | 11 | namespace Core { |
| 13 | class System; | 12 | class System; |
| @@ -29,27 +28,18 @@ public: | |||
| 29 | return syncpoint_manager; | 28 | return syncpoint_manager; |
| 30 | } | 29 | } |
| 31 | 30 | ||
| 32 | Tegra::MemoryManager& MemoryManager() { | 31 | Tegra::MaxwellDeviceMemoryManager& MemoryManager() { |
| 33 | return memory_manager; | 32 | return memory_manager; |
| 34 | } | 33 | } |
| 35 | 34 | ||
| 36 | const Tegra::MemoryManager& MemoryManager() const { | 35 | const Tegra::MaxwellDeviceMemoryManager& MemoryManager() const { |
| 37 | return memory_manager; | 36 | return memory_manager; |
| 38 | } | 37 | } |
| 39 | 38 | ||
| 40 | Common::FlatAllocator<u32, 0, 32>& Allocator() { | ||
| 41 | return *allocator; | ||
| 42 | } | ||
| 43 | |||
| 44 | const Common::FlatAllocator<u32, 0, 32>& Allocator() const { | ||
| 45 | return *allocator; | ||
| 46 | } | ||
| 47 | |||
| 48 | private: | 39 | private: |
| 49 | Core::System& system; | 40 | Core::System& system; |
| 50 | SyncpointManager syncpoint_manager; | 41 | SyncpointManager syncpoint_manager; |
| 51 | Tegra::MemoryManager memory_manager; | 42 | Tegra::MaxwellDeviceMemoryManager memory_manager; |
| 52 | std::unique_ptr<Common::FlatAllocator<u32, 0, 32>> allocator; | ||
| 53 | }; | 43 | }; |
| 54 | 44 | ||
| 55 | } // namespace Host1x | 45 | } // namespace Host1x |