summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2023-12-30 23:08:55 +0100
committerGravatar Liam2024-01-18 21:12:30 -0500
commitb0bca0f8b04de630f9dec47cff14a640d40f65db (patch)
treec1723cc631a573340e1393aa81939fa1ce5dfad0 /src
parentSMMU: Add continuity tracking optimization. (diff)
downloadyuzu-b0bca0f8b04de630f9dec47cff14a640d40f65db.tar.gz
yuzu-b0bca0f8b04de630f9dec47cff14a640d40f65db.tar.xz
yuzu-b0bca0f8b04de630f9dec47cff14a640d40f65db.zip
SMMU: Fix software rendering and cleanup
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvdrv/core/nvmap.cpp8
-rw-r--r--src/core/hle/service/nvdrv/core/nvmap.h4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp29
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h7
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp2
-rw-r--r--src/core/hle/service/nvnflinger/ui/graphic_buffer.cpp2
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
25NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) { 25NvResult 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
157DAddr NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id, bool low_area_pin) { 158DAddr 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
89void nvhost_as_gpu::OnOpen(size_t session_id, DeviceFD fd) { 89void nvhost_as_gpu::OnOpen(size_t session_id, DeviceFD fd) {}
90 sessions[fd] = session_id; 90void nvhost_as_gpu::OnClose(DeviceFD fd) {}
91}
92void 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
99NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { 92NvResult 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
271NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries, DeviceFD fd) { 264NvResult 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
317NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params, DeviceFD fd) { 310NvResult 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
417NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params, DeviceFD fd) { 410NvResult 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
28GraphicBuffer::~GraphicBuffer() { 29GraphicBuffer::~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}