[core/nvdrv] Fix Random Unmap Memory Clearing (#176)

Now memory should only be unmapped after it was mapped.
Could eventually fix some graphical errors, and improve performance.

Reviewed-on: #176
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: SDK-Chan <sdkchan@eden-emu.dev>
Co-committed-by: SDK-Chan <sdkchan@eden-emu.dev>
This commit is contained in:
SDK-Chan 2025-08-14 14:30:09 +02:00 committed by crueter
parent 444b9f361e
commit c36cc0d3ee
Signed by: crueter
GPG key ID: 425ACD2D4830EBC6
2 changed files with 19 additions and 10 deletions

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project // SPDX-FileCopyrightText: 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors // SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
@ -312,7 +315,7 @@ NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries) {
NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) {
LOG_DEBUG(Service_NVDRV, LOG_DEBUG(Service_NVDRV,
"called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}"
", offset={}", ", offset=0x{:X}",
params.flags, params.handle, params.buffer_offset, params.mapping_size, params.flags, params.handle, params.buffer_offset, params.mapping_size,
params.offset); params.offset);
@ -406,19 +409,21 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) {
mapping_map[params.offset] = mapping; mapping_map[params.offset] = mapping;
} }
map_buffer_offsets.insert(params.offset);
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) { NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) {
LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); if (map_buffer_offsets.find(params.offset) != map_buffer_offsets.end()) {
LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
std::scoped_lock lock(mutex); std::scoped_lock lock(mutex);
if (!vm.initialised) { if (!vm.initialised) {
return NvResult::BadValue; return NvResult::BadValue;
} }
try {
auto mapping{mapping_map.at(params.offset)}; auto mapping{mapping_map.at(params.offset)};
if (!mapping->fixed) { if (!mapping->fixed) {
@ -440,10 +445,8 @@ NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) {
nvmap.UnpinHandle(mapping->handle); nvmap.UnpinHandle(mapping->handle);
mapping_map.erase(params.offset); mapping_map.erase(params.offset);
} catch (const std::out_of_range&) { map_buffer_offsets.erase(params.offset);
LOG_WARNING(Service_NVDRV, "Couldn't find region to unmap at 0x{:X}", params.offset);
} }
return NvResult::Success; return NvResult::Success;
} }

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project // SPDX-FileCopyrightText: 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors // SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
@ -10,6 +13,7 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <optional> #include <optional>
#include <unordered_set>
#include <vector> #include <vector>
#include "common/address_space.h" #include "common/address_space.h"
@ -109,6 +113,8 @@ private:
}; };
static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size"); static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size");
std::unordered_set<s64_le> map_buffer_offsets{};
struct IoctlMapBufferEx { struct IoctlMapBufferEx {
MappingFlags flags{}; // bit0: fixed_offset, bit2: cacheable MappingFlags flags{}; // bit0: fixed_offset, bit2: cacheable
u32_le kind{}; // -1 is default u32_le kind{}; // -1 is default