diff options
7 files changed, 24 insertions, 30 deletions
diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp index 97634b59d..296b4d8d2 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.cpp +++ b/src/core/hle/service/nvdrv/core/nvmap.cpp | |||
| @@ -22,7 +22,7 @@ NvMap::Handle::Handle(u64 size_, Id id_) | |||
| 22 | flags.raw = 0; | 22 | flags.raw = 0; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) { | 25 | NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size_t pSessionId) { |
| 26 | std::scoped_lock lock(mutex); | 26 | std::scoped_lock lock(mutex); |
| 27 | // Handles cannot be allocated twice | 27 | // Handles cannot be allocated twice |
| 28 | if (allocated) { | 28 | if (allocated) { |
| @@ -32,6 +32,7 @@ NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) | |||
| 32 | flags = pFlags; | 32 | flags = pFlags; |
| 33 | kind = pKind; | 33 | kind = pKind; |
| 34 | align = pAlign < YUZU_PAGESIZE ? YUZU_PAGESIZE : pAlign; | 34 | align = pAlign < YUZU_PAGESIZE ? YUZU_PAGESIZE : pAlign; |
| 35 | session_id = pSessionId; | ||
| 35 | 36 | ||
| 36 | // This flag is only applicable for handles with an address passed | 37 | // This flag is only applicable for handles with an address passed |
| 37 | if (pAddress) { | 38 | if (pAddress) { |
| @@ -154,7 +155,7 @@ DAddr NvMap::GetHandleAddress(Handle::Id handle) { | |||
| 154 | } | 155 | } |
| 155 | } | 156 | } |
| 156 | 157 | ||
| 157 | DAddr NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id, bool low_area_pin) { | 158 | DAddr NvMap::PinHandle(NvMap::Handle::Id handle, bool low_area_pin) { |
| 158 | auto handle_description{GetHandle(handle)}; | 159 | auto handle_description{GetHandle(handle)}; |
| 159 | if (!handle_description) [[unlikely]] { | 160 | if (!handle_description) [[unlikely]] { |
| 160 | return 0; | 161 | return 0; |
| @@ -198,10 +199,9 @@ DAddr NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id, bool low_are | |||
| 198 | // If not then allocate some space and map it | 199 | // If not then allocate some space and map it |
| 199 | DAddr address{}; | 200 | DAddr address{}; |
| 200 | auto& smmu = host1x.MemoryManager(); | 201 | auto& smmu = host1x.MemoryManager(); |
| 201 | auto* session = core.GetSession(session_id); | 202 | auto* session = core.GetSession(handle_description->session_id); |
| 202 | const VAddr vaddress = handle_description->address; | 203 | const VAddr vaddress = handle_description->address; |
| 203 | const size_t map_size = handle_description->aligned_size; | 204 | const size_t map_size = handle_description->aligned_size; |
| 204 | handle_description->session_id = session_id; | ||
| 205 | if (session->has_preallocated_area && session->mapper->IsInBounds(vaddress, map_size)) { | 205 | if (session->has_preallocated_area && session->mapper->IsInBounds(vaddress, map_size)) { |
| 206 | handle_description->d_address = session->mapper->Map(vaddress, map_size); | 206 | handle_description->d_address = session->mapper->Map(vaddress, map_size); |
| 207 | handle_description->in_heap = true; | 207 | handle_description->in_heap = true; |
diff --git a/src/core/hle/service/nvdrv/core/nvmap.h b/src/core/hle/service/nvdrv/core/nvmap.h index 4af61289e..119efc38d 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.h +++ b/src/core/hle/service/nvdrv/core/nvmap.h | |||
| @@ -82,7 +82,7 @@ public: | |||
| 82 | * @brief Sets up the handle with the given memory config, can allocate memory from the tmem | 82 | * @brief Sets up the handle with the given memory config, can allocate memory from the tmem |
| 83 | * if a 0 address is passed | 83 | * if a 0 address is passed |
| 84 | */ | 84 | */ |
| 85 | [[nodiscard]] NvResult Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress); | 85 | [[nodiscard]] NvResult Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size_t pSessionId); |
| 86 | 86 | ||
| 87 | /** | 87 | /** |
| 88 | * @brief Increases the dupe counter of the handle for the given session | 88 | * @brief Increases the dupe counter of the handle for the given session |
| @@ -130,7 +130,7 @@ public: | |||
| 130 | * number of calls to `UnpinHandle` | 130 | * number of calls to `UnpinHandle` |
| 131 | * @return The SMMU virtual address that the handle has been mapped to | 131 | * @return The SMMU virtual address that the handle has been mapped to |
| 132 | */ | 132 | */ |
| 133 | DAddr PinHandle(Handle::Id handle, size_t session_id, bool low_area_pin); | 133 | DAddr PinHandle(Handle::Id handle, bool low_area_pin); |
| 134 | 134 | ||
| 135 | /** | 135 | /** |
| 136 | * @brief When this has been called an equal number of times to `PinHandle` for the supplied | 136 | * @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/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 8bc10eac2..936b93bd9 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -40,15 +40,15 @@ NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 40 | case 0x3: | 40 | case 0x3: |
| 41 | return WrapFixed(this, &nvhost_as_gpu::FreeSpace, input, output); | 41 | return WrapFixed(this, &nvhost_as_gpu::FreeSpace, input, output); |
| 42 | case 0x5: | 42 | case 0x5: |
| 43 | return WrapFixed(this, &nvhost_as_gpu::UnmapBuffer, input, output, fd); | 43 | return WrapFixed(this, &nvhost_as_gpu::UnmapBuffer, input, output); |
| 44 | case 0x6: | 44 | case 0x6: |
| 45 | return WrapFixed(this, &nvhost_as_gpu::MapBufferEx, input, output, fd); | 45 | return WrapFixed(this, &nvhost_as_gpu::MapBufferEx, input, output); |
| 46 | case 0x8: | 46 | case 0x8: |
| 47 | return WrapFixed(this, &nvhost_as_gpu::GetVARegions1, input, output); | 47 | return WrapFixed(this, &nvhost_as_gpu::GetVARegions1, input, output); |
| 48 | case 0x9: | 48 | case 0x9: |
| 49 | return WrapFixed(this, &nvhost_as_gpu::AllocAsEx, input, output); | 49 | return WrapFixed(this, &nvhost_as_gpu::AllocAsEx, input, output); |
| 50 | case 0x14: | 50 | case 0x14: |
| 51 | return WrapVariable(this, &nvhost_as_gpu::Remap, input, output, fd); | 51 | return WrapVariable(this, &nvhost_as_gpu::Remap, input, output); |
| 52 | default: | 52 | default: |
| 53 | break; | 53 | break; |
| 54 | } | 54 | } |
| @@ -86,15 +86,8 @@ 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(size_t session_id, DeviceFD fd) { | 89 | void nvhost_as_gpu::OnOpen(size_t session_id, DeviceFD fd) {} |
| 90 | sessions[fd] = session_id; | 90 | void nvhost_as_gpu::OnClose(DeviceFD fd) {} |
| 91 | } | ||
| 92 | void nvhost_as_gpu::OnClose(DeviceFD fd) { | ||
| 93 | auto it = sessions.find(fd); | ||
| 94 | if (it != sessions.end()) { | ||
| 95 | sessions.erase(it); | ||
| 96 | } | ||
| 97 | } | ||
| 98 | 91 | ||
| 99 | NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { | 92 | NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { |
| 100 | LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size); | 93 | LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size); |
| @@ -268,7 +261,7 @@ NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) { | |||
| 268 | return NvResult::Success; | 261 | return NvResult::Success; |
| 269 | } | 262 | } |
| 270 | 263 | ||
| 271 | NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries, DeviceFD fd) { | 264 | NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries) { |
| 272 | LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", entries.size()); | 265 | LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", entries.size()); |
| 273 | 266 | ||
| 274 | if (!vm.initialised) { | 267 | if (!vm.initialised) { |
| @@ -302,7 +295,7 @@ NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries, DeviceFD fd) { | |||
| 302 | return NvResult::BadValue; | 295 | return NvResult::BadValue; |
| 303 | } | 296 | } |
| 304 | 297 | ||
| 305 | DAddr base = nvmap.PinHandle(entry.handle, sessions[fd], false); | 298 | DAddr base = nvmap.PinHandle(entry.handle, false); |
| 306 | DAddr device_address{static_cast<DAddr>( | 299 | DAddr device_address{static_cast<DAddr>( |
| 307 | base + (static_cast<u64>(entry.handle_offset_big_pages) << vm.big_page_size_bits))}; | 300 | base + (static_cast<u64>(entry.handle_offset_big_pages) << vm.big_page_size_bits))}; |
| 308 | 301 | ||
| @@ -314,7 +307,7 @@ NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries, DeviceFD fd) { | |||
| 314 | return NvResult::Success; | 307 | return NvResult::Success; |
| 315 | } | 308 | } |
| 316 | 309 | ||
| 317 | NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd) { | 310 | NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { |
| 318 | LOG_DEBUG(Service_NVDRV, | 311 | LOG_DEBUG(Service_NVDRV, |
| 319 | "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" | 312 | "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" |
| 320 | ", offset={}", | 313 | ", offset={}", |
| @@ -358,8 +351,8 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd) { | |||
| 358 | return NvResult::BadValue; | 351 | return NvResult::BadValue; |
| 359 | } | 352 | } |
| 360 | 353 | ||
| 361 | DAddr device_address{static_cast<DAddr>(nvmap.PinHandle(params.handle, sessions[fd], false) + | 354 | DAddr device_address{ |
| 362 | params.buffer_offset)}; | 355 | static_cast<DAddr>(nvmap.PinHandle(params.handle, false) + params.buffer_offset)}; |
| 363 | u64 size{params.mapping_size ? params.mapping_size : handle->orig_size}; | 356 | u64 size{params.mapping_size ? params.mapping_size : handle->orig_size}; |
| 364 | 357 | ||
| 365 | bool big_page{[&]() { | 358 | bool big_page{[&]() { |
| @@ -414,7 +407,7 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd) { | |||
| 414 | return NvResult::Success; | 407 | return NvResult::Success; |
| 415 | } | 408 | } |
| 416 | 409 | ||
| 417 | NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params, DeviceFD fd) { | 410 | NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) { |
| 418 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); | 411 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); |
| 419 | 412 | ||
| 420 | std::scoped_lock lock(mutex); | 413 | std::scoped_lock lock(mutex); |
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 4b28f5078..7fd704bce 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -141,9 +141,9 @@ private: | |||
| 141 | 141 | ||
| 142 | NvResult AllocAsEx(IoctlAllocAsEx& params); | 142 | NvResult AllocAsEx(IoctlAllocAsEx& params); |
| 143 | NvResult AllocateSpace(IoctlAllocSpace& params); | 143 | NvResult AllocateSpace(IoctlAllocSpace& params); |
| 144 | NvResult Remap(std::span<IoctlRemapEntry> params, DeviceFD fd); | 144 | NvResult Remap(std::span<IoctlRemapEntry> params); |
| 145 | NvResult MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd); | 145 | NvResult MapBufferEx(IoctlMapBufferEx& params); |
| 146 | NvResult UnmapBuffer(IoctlUnmapBuffer& params, DeviceFD fd); | 146 | NvResult UnmapBuffer(IoctlUnmapBuffer& params); |
| 147 | NvResult FreeSpace(IoctlFreeSpace& params); | 147 | NvResult FreeSpace(IoctlFreeSpace& params); |
| 148 | NvResult BindChannel(IoctlBindChannel& params); | 148 | NvResult BindChannel(IoctlBindChannel& params); |
| 149 | 149 | ||
| @@ -214,7 +214,6 @@ private: | |||
| 214 | bool initialised{}; | 214 | bool initialised{}; |
| 215 | } vm; | 215 | } vm; |
| 216 | std::shared_ptr<Tegra::MemoryManager> gmmu; | 216 | std::shared_ptr<Tegra::MemoryManager> gmmu; |
| 217 | std::unordered_map<DeviceFD, size_t> sessions; | ||
| 218 | }; | 217 | }; |
| 219 | 218 | ||
| 220 | } // namespace Service::Nvidia::Devices | 219 | } // namespace Service::Nvidia::Devices |
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 a50577c75..a0a7bfa40 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -140,7 +140,7 @@ NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span<MapBuf | |||
| 140 | DeviceFD fd) { | 140 | DeviceFD fd) { |
| 141 | const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size())); | 141 | const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size())); |
| 142 | for (size_t i = 0; i < num_entries; i++) { | 142 | for (size_t i = 0; i < num_entries; i++) { |
| 143 | DAddr pin_address = nvmap.PinHandle(entries[i].map_handle, sessions[fd], true); | 143 | DAddr pin_address = nvmap.PinHandle(entries[i].map_handle, true); |
| 144 | entries[i].map_address = static_cast<u32>(pin_address); | 144 | entries[i].map_address = static_cast<u32>(pin_address); |
| 145 | } | 145 | } |
| 146 | 146 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 7765ca1be..24f49ddcd 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -124,7 +124,7 @@ NvResult nvmap::IocAlloc(IocAllocParams& params, DeviceFD fd) { | |||
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | const auto result = | 126 | const auto result = |
| 127 | handle_description->Alloc(params.flags, params.align, params.kind, params.address); | 127 | handle_description->Alloc(params.flags, params.align, params.kind, params.address, sessions[fd]); |
| 128 | if (result != NvResult::Success) { | 128 | if (result != NvResult::Success) { |
| 129 | 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); |
| 130 | return result; | 130 | return result; |
diff --git a/src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp b/src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp index ce70946ec..ede2a1193 100644 --- a/src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp +++ b/src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp | |||
| @@ -22,11 +22,13 @@ GraphicBuffer::GraphicBuffer(Service::Nvidia::NvCore::NvMap& nvmap, | |||
| 22 | : NvGraphicBuffer(GetBuffer(buffer)), m_nvmap(std::addressof(nvmap)) { | 22 | : NvGraphicBuffer(GetBuffer(buffer)), m_nvmap(std::addressof(nvmap)) { |
| 23 | if (this->BufferId() > 0) { | 23 | if (this->BufferId() > 0) { |
| 24 | m_nvmap->DuplicateHandle(this->BufferId(), true); | 24 | m_nvmap->DuplicateHandle(this->BufferId(), true); |
| 25 | m_nvmap->PinHandle(this->BufferId(), false); | ||
| 25 | } | 26 | } |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | GraphicBuffer::~GraphicBuffer() { | 29 | GraphicBuffer::~GraphicBuffer() { |
| 29 | if (m_nvmap != nullptr && this->BufferId() > 0) { | 30 | if (m_nvmap != nullptr && this->BufferId() > 0) { |
| 31 | m_nvmap->UnpinHandle(this->BufferId()); | ||
| 30 | m_nvmap->FreeHandle(this->BufferId(), true); | 32 | m_nvmap->FreeHandle(this->BufferId(), true); |
| 31 | } | 33 | } |
| 32 | } | 34 | } |