Sfoglia il codice sorgente

SMMU: Fix software rendering and cleanup

Fernando Sahmkow 2 anni fa
parent
commit
b0bca0f8b0

+ 4 - 4
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;

+ 2 - 2
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

+ 11 - 18
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
         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<const u8> 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<IoctlRemapEntry> entries, DeviceFD fd) {
+NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> 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<IoctlRemapEntry> 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<DAddr>(
                 base + (static_cast<u64>(entry.handle_offset_big_pages) << vm.big_page_size_bits))};
 
@@ -314,7 +307,7 @@ NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> 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<DAddr>(nvmap.PinHandle(params.handle, sessions[fd], false) +
-                                            params.buffer_offset)};
+    DAddr device_address{
+        static_cast<DAddr>(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);

+ 3 - 4
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<IoctlRemapEntry> params, DeviceFD fd);
-    NvResult MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd);
-    NvResult UnmapBuffer(IoctlUnmapBuffer& params, DeviceFD fd);
+    NvResult Remap(std::span<IoctlRemapEntry> 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<Tegra::MemoryManager> gmmu;
-    std::unordered_map<DeviceFD, size_t> sessions;
 };
 
 } // namespace Service::Nvidia::Devices

+ 1 - 1
src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp

@@ -140,7 +140,7 @@ NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span<MapBuf
                                         DeviceFD fd) {
     const size_t num_entries = std::min(params.num_entries, static_cast<u32>(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<u32>(pin_address);
     }
 

+ 1 - 1
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;

+ 2 - 0
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);
     }
 }