diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/nvdrv/core/nvmap.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/core/nvmap.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvmap.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue_producer.cpp | 7 |
4 files changed, 17 insertions, 6 deletions
diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp index fbd8a74a5..a51ca5444 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.cpp +++ b/src/core/hle/service/nvdrv/core/nvmap.cpp | |||
| @@ -255,15 +255,16 @@ std::optional<NvMap::FreeInfo> NvMap::FreeHandle(Handle::Id handle, bool interna | |||
| 255 | .address = handle_description->address, | 255 | .address = handle_description->address, |
| 256 | .size = handle_description->size, | 256 | .size = handle_description->size, |
| 257 | .was_uncached = handle_description->flags.map_uncached.Value() != 0, | 257 | .was_uncached = handle_description->flags.map_uncached.Value() != 0, |
| 258 | .can_unlock = true, | ||
| 258 | }; | 259 | }; |
| 259 | } else { | 260 | } else { |
| 260 | return std::nullopt; | 261 | return std::nullopt; |
| 261 | } | 262 | } |
| 262 | 263 | ||
| 263 | // Handle hasn't been freed from memory, set address to 0 to mark that the handle wasn't freed | 264 | // If the handle hasn't been freed from memory, mark that |
| 264 | if (!hWeak.expired()) { | 265 | if (!hWeak.expired()) { |
| 265 | LOG_DEBUG(Service_NVDRV, "nvmap handle: {} wasn't freed as it is still in use", handle); | 266 | LOG_DEBUG(Service_NVDRV, "nvmap handle: {} wasn't freed as it is still in use", handle); |
| 266 | freeInfo.address = 0; | 267 | freeInfo.can_unlock = false; |
| 267 | } | 268 | } |
| 268 | 269 | ||
| 269 | return freeInfo; | 270 | return freeInfo; |
diff --git a/src/core/hle/service/nvdrv/core/nvmap.h b/src/core/hle/service/nvdrv/core/nvmap.h index b9dd3801f..a8e573890 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.h +++ b/src/core/hle/service/nvdrv/core/nvmap.h | |||
| @@ -105,6 +105,7 @@ public: | |||
| 105 | u64 address; //!< Address the handle referred to before deletion | 105 | u64 address; //!< Address the handle referred to before deletion |
| 106 | u64 size; //!< Page-aligned handle size | 106 | u64 size; //!< Page-aligned handle size |
| 107 | bool was_uncached; //!< If the handle was allocated as uncached | 107 | bool was_uncached; //!< If the handle was allocated as uncached |
| 108 | bool can_unlock; //!< If the address region is ready to be unlocked | ||
| 108 | }; | 109 | }; |
| 109 | 110 | ||
| 110 | explicit NvMap(Tegra::Host1x::Host1x& host1x); | 111 | explicit NvMap(Tegra::Host1x::Host1x& host1x); |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index b60679021..44388655d 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -251,10 +251,12 @@ NvResult nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | if (auto freeInfo{file.FreeHandle(params.handle, false)}) { | 253 | if (auto freeInfo{file.FreeHandle(params.handle, false)}) { |
| 254 | ASSERT(system.CurrentProcess() | 254 | if (freeInfo->can_unlock) { |
| 255 | ->PageTable() | 255 | ASSERT(system.CurrentProcess() |
| 256 | .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) | 256 | ->PageTable() |
| 257 | .IsSuccess()); | 257 | .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) |
| 258 | .IsSuccess()); | ||
| 259 | } | ||
| 258 | params.address = freeInfo->address; | 260 | params.address = freeInfo->address; |
| 259 | params.size = static_cast<u32>(freeInfo->size); | 261 | params.size = static_cast<u32>(freeInfo->size); |
| 260 | params.flags.raw = 0; | 262 | params.flags.raw = 0; |
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp index 77ddbb6ef..41ba44b21 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp | |||
| @@ -742,6 +742,13 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) { | |||
| 742 | return Status::NoError; | 742 | return Status::NoError; |
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | // HACK: We are not Android. Remove handle for items in queue, and clear queue. | ||
| 746 | // Allows synchronous destruction of nvmap handles. | ||
| 747 | for (auto& item : core->queue) { | ||
| 748 | nvmap.FreeHandle(item.graphic_buffer->BufferId(), true); | ||
| 749 | } | ||
| 750 | core->queue.clear(); | ||
| 751 | |||
| 745 | switch (api) { | 752 | switch (api) { |
| 746 | case NativeWindowApi::Egl: | 753 | case NativeWindowApi::Egl: |
| 747 | case NativeWindowApi::Cpu: | 754 | case NativeWindowApi::Cpu: |