From b0bca0f8b04de630f9dec47cff14a640d40f65db Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 30 Dec 2023 23:08:55 +0100 Subject: SMMU: Fix software rendering and cleanup --- src/core/hle/service/nvdrv/core/nvmap.cpp | 8 +++--- src/core/hle/service/nvdrv/core/nvmap.h | 4 +-- .../hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 29 ++++++++-------------- src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | 7 +++--- .../service/nvdrv/devices/nvhost_nvdec_common.cpp | 2 +- src/core/hle/service/nvdrv/devices/nvmap.cpp | 2 +- .../hle/service/nvnflinger/ui/graphic_buffer.cpp | 2 ++ 7 files changed, 24 insertions(+), 30 deletions(-) (limited to 'src/core/hle') 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_) flags.raw = 0; } -NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) { +NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size_t pSessionId) { std::scoped_lock lock(mutex); // Handles cannot be allocated twice if (allocated) { @@ -32,6 +32,7 @@ NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) flags = pFlags; kind = pKind; align = pAlign < YUZU_PAGESIZE ? YUZU_PAGESIZE : pAlign; + session_id = pSessionId; // This flag is only applicable for handles with an address passed if (pAddress) { @@ -154,7 +155,7 @@ DAddr NvMap::GetHandleAddress(Handle::Id handle) { } } -DAddr NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id, bool low_area_pin) { +DAddr NvMap::PinHandle(NvMap::Handle::Id handle, bool low_area_pin) { auto handle_description{GetHandle(handle)}; if (!handle_description) [[unlikely]] { return 0; @@ -198,10 +199,9 @@ DAddr NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id, bool low_are // If not then allocate some space and map it DAddr address{}; auto& smmu = host1x.MemoryManager(); - auto* session = core.GetSession(session_id); + auto* session = core.GetSession(handle_description->session_id); const VAddr vaddress = handle_description->address; const size_t map_size = handle_description->aligned_size; - handle_description->session_id = session_id; if (session->has_preallocated_area && session->mapper->IsInBounds(vaddress, map_size)) { handle_description->d_address = session->mapper->Map(vaddress, map_size); 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: * @brief Sets up the handle with the given memory config, can allocate memory from the tmem * if a 0 address is passed */ - [[nodiscard]] NvResult Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress); + [[nodiscard]] NvResult Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size_t pSessionId); /** * @brief Increases the dupe counter of the handle for the given session @@ -130,7 +130,7 @@ public: * number of calls to `UnpinHandle` * @return The SMMU virtual address that the handle has been mapped to */ - DAddr PinHandle(Handle::Id handle, size_t session_id, bool low_area_pin); + DAddr PinHandle(Handle::Id handle, bool low_area_pin); /** * @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 i case 0x3: return WrapFixed(this, &nvhost_as_gpu::FreeSpace, input, output); case 0x5: - return WrapFixed(this, &nvhost_as_gpu::UnmapBuffer, input, output, fd); + return WrapFixed(this, &nvhost_as_gpu::UnmapBuffer, input, output); case 0x6: - return WrapFixed(this, &nvhost_as_gpu::MapBufferEx, input, output, fd); + return WrapFixed(this, &nvhost_as_gpu::MapBufferEx, input, output); case 0x8: return WrapFixed(this, &nvhost_as_gpu::GetVARegions1, input, output); case 0x9: return WrapFixed(this, &nvhost_as_gpu::AllocAsEx, input, output); case 0x14: - return WrapVariable(this, &nvhost_as_gpu::Remap, input, output, fd); + return WrapVariable(this, &nvhost_as_gpu::Remap, input, output); default: break; } @@ -86,15 +86,8 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span i return NvResult::NotImplemented; } -void nvhost_as_gpu::OnOpen(size_t session_id, DeviceFD fd) { - sessions[fd] = session_id; -} -void nvhost_as_gpu::OnClose(DeviceFD fd) { - auto it = sessions.find(fd); - if (it != sessions.end()) { - sessions.erase(it); - } -} +void nvhost_as_gpu::OnOpen(size_t session_id, DeviceFD fd) {} +void nvhost_as_gpu::OnClose(DeviceFD fd) {} NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { 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) { return NvResult::Success; } -NvResult nvhost_as_gpu::Remap(std::span entries, DeviceFD fd) { +NvResult nvhost_as_gpu::Remap(std::span entries) { LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", entries.size()); if (!vm.initialised) { @@ -302,7 +295,7 @@ NvResult nvhost_as_gpu::Remap(std::span entries, DeviceFD fd) { return NvResult::BadValue; } - DAddr base = nvmap.PinHandle(entry.handle, sessions[fd], false); + DAddr base = nvmap.PinHandle(entry.handle, false); DAddr device_address{static_cast( base + (static_cast(entry.handle_offset_big_pages) << vm.big_page_size_bits))}; @@ -314,7 +307,7 @@ NvResult nvhost_as_gpu::Remap(std::span entries, DeviceFD fd) { return NvResult::Success; } -NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd) { +NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { LOG_DEBUG(Service_NVDRV, "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" ", offset={}", @@ -358,8 +351,8 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd) { return NvResult::BadValue; } - DAddr device_address{static_cast(nvmap.PinHandle(params.handle, sessions[fd], false) + - params.buffer_offset)}; + DAddr device_address{ + static_cast(nvmap.PinHandle(params.handle, false) + params.buffer_offset)}; u64 size{params.mapping_size ? params.mapping_size : handle->orig_size}; bool big_page{[&]() { @@ -414,7 +407,7 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd) { return NvResult::Success; } -NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params, DeviceFD fd) { +NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) { LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); 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: NvResult AllocAsEx(IoctlAllocAsEx& params); NvResult AllocateSpace(IoctlAllocSpace& params); - NvResult Remap(std::span params, DeviceFD fd); - NvResult MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd); - NvResult UnmapBuffer(IoctlUnmapBuffer& params, DeviceFD fd); + NvResult Remap(std::span params); + NvResult MapBufferEx(IoctlMapBufferEx& params); + NvResult UnmapBuffer(IoctlUnmapBuffer& params); NvResult FreeSpace(IoctlFreeSpace& params); NvResult BindChannel(IoctlBindChannel& params); @@ -214,7 +214,6 @@ private: bool initialised{}; } vm; std::shared_ptr gmmu; - std::unordered_map sessions; }; } // 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(entries.size())); for (size_t i = 0; i < num_entries; i++) { - DAddr pin_address = nvmap.PinHandle(entries[i].map_handle, sessions[fd], true); + DAddr pin_address = nvmap.PinHandle(entries[i].map_handle, true); entries[i].map_address = static_cast(pin_address); } 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) { } const auto result = - handle_description->Alloc(params.flags, params.align, params.kind, params.address); + handle_description->Alloc(params.flags, params.align, params.kind, params.address, sessions[fd]); if (result != NvResult::Success) { LOG_CRITICAL(Service_NVDRV, "Object failed to allocate, handle={:08X}", params.handle); 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, : NvGraphicBuffer(GetBuffer(buffer)), m_nvmap(std::addressof(nvmap)) { if (this->BufferId() > 0) { m_nvmap->DuplicateHandle(this->BufferId(), true); + m_nvmap->PinHandle(this->BufferId(), false); } } GraphicBuffer::~GraphicBuffer() { if (m_nvmap != nullptr && this->BufferId() > 0) { + m_nvmap->UnpinHandle(this->BufferId()); m_nvmap->FreeHandle(this->BufferId(), true); } } -- cgit v1.2.3