diff options
| author | 2022-10-29 16:11:26 -0700 | |
|---|---|---|
| committer | 2022-10-29 16:11:26 -0700 | |
| commit | c4d91488d9e7d1aadfadb6ef8e27fa4f1896a5cb (patch) | |
| tree | 0653781de68f88b7910b78e5c3d893b06e9dc37d | |
| parent | Merge pull request #9140 from vonchenplus/darw_index_bufferx_first_error (diff) | |
| parent | nvnflinger: release queued handles immediately on disconnection (diff) | |
| download | yuzu-c4d91488d9e7d1aadfadb6ef8e27fa4f1896a5cb.tar.gz yuzu-c4d91488d9e7d1aadfadb6ef8e27fa4f1896a5cb.tar.xz yuzu-c4d91488d9e7d1aadfadb6ef8e27fa4f1896a5cb.zip | |
Merge pull request #9137 from liamwhite/hbmenu
Improved support for nx-hbmenu
Diffstat (limited to '')
| -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 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.h | 5 | ||||
| -rw-r--r-- | src/core/hle/service/vi/display/vi_display.h | 6 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 8 |
8 files changed, 45 insertions, 10 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: |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index dad93b38e..c3af12c90 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -138,6 +138,19 @@ std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) { | |||
| 138 | return itr->GetID(); | 138 | return itr->GetID(); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | bool NVFlinger::CloseDisplay(u64 display_id) { | ||
| 142 | const auto lock_guard = Lock(); | ||
| 143 | auto* const display = FindDisplay(display_id); | ||
| 144 | |||
| 145 | if (display == nullptr) { | ||
| 146 | return false; | ||
| 147 | } | ||
| 148 | |||
| 149 | display->Reset(); | ||
| 150 | |||
| 151 | return true; | ||
| 152 | } | ||
| 153 | |||
| 141 | std::optional<u64> NVFlinger::CreateLayer(u64 display_id) { | 154 | std::optional<u64> NVFlinger::CreateLayer(u64 display_id) { |
| 142 | const auto lock_guard = Lock(); | 155 | const auto lock_guard = Lock(); |
| 143 | auto* const display = FindDisplay(display_id); | 156 | auto* const display = FindDisplay(display_id); |
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index b8191c595..460bef976 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h | |||
| @@ -58,6 +58,11 @@ public: | |||
| 58 | /// If an invalid display name is provided, then an empty optional is returned. | 58 | /// If an invalid display name is provided, then an empty optional is returned. |
| 59 | [[nodiscard]] std::optional<u64> OpenDisplay(std::string_view name); | 59 | [[nodiscard]] std::optional<u64> OpenDisplay(std::string_view name); |
| 60 | 60 | ||
| 61 | /// Closes the specified display by its ID. | ||
| 62 | /// | ||
| 63 | /// Returns false if an invalid display ID is provided. | ||
| 64 | [[nodiscard]] bool CloseDisplay(u64 display_id); | ||
| 65 | |||
| 61 | /// Creates a layer on the specified display and returns the layer ID. | 66 | /// Creates a layer on the specified display and returns the layer ID. |
| 62 | /// | 67 | /// |
| 63 | /// If an invalid display ID is specified, then an empty optional is returned. | 68 | /// If an invalid display ID is specified, then an empty optional is returned. |
diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h index 33d5f398c..0b65a65da 100644 --- a/src/core/hle/service/vi/display/vi_display.h +++ b/src/core/hle/service/vi/display/vi_display.h | |||
| @@ -106,6 +106,12 @@ public: | |||
| 106 | /// | 106 | /// |
| 107 | void CloseLayer(u64 layer_id); | 107 | void CloseLayer(u64 layer_id); |
| 108 | 108 | ||
| 109 | /// Resets the display for a new connection. | ||
| 110 | void Reset() { | ||
| 111 | layers.clear(); | ||
| 112 | got_vsync_event = false; | ||
| 113 | } | ||
| 114 | |||
| 109 | /// Attempts to find a layer with the given ID. | 115 | /// Attempts to find a layer with the given ID. |
| 110 | /// | 116 | /// |
| 111 | /// @param layer_id The layer ID. | 117 | /// @param layer_id The layer ID. |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 9c917cacf..bb283e74e 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -324,10 +324,10 @@ private: | |||
| 324 | IPC::RequestParser rp{ctx}; | 324 | IPC::RequestParser rp{ctx}; |
| 325 | const u64 display = rp.Pop<u64>(); | 325 | const u64 display = rp.Pop<u64>(); |
| 326 | 326 | ||
| 327 | LOG_WARNING(Service_VI, "(STUBBED) called. display=0x{:016X}", display); | 327 | const Result rc = nv_flinger.CloseDisplay(display) ? ResultSuccess : ResultUnknown; |
| 328 | 328 | ||
| 329 | IPC::ResponseBuilder rb{ctx, 2}; | 329 | IPC::ResponseBuilder rb{ctx, 2}; |
| 330 | rb.Push(ResultSuccess); | 330 | rb.Push(rc); |
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | void CreateManagedLayer(Kernel::HLERequestContext& ctx) { | 333 | void CreateManagedLayer(Kernel::HLERequestContext& ctx) { |
| @@ -508,10 +508,10 @@ private: | |||
| 508 | IPC::RequestParser rp{ctx}; | 508 | IPC::RequestParser rp{ctx}; |
| 509 | const u64 display_id = rp.Pop<u64>(); | 509 | const u64 display_id = rp.Pop<u64>(); |
| 510 | 510 | ||
| 511 | LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id); | 511 | const Result rc = nv_flinger.CloseDisplay(display_id) ? ResultSuccess : ResultUnknown; |
| 512 | 512 | ||
| 513 | IPC::ResponseBuilder rb{ctx, 2}; | 513 | IPC::ResponseBuilder rb{ctx, 2}; |
| 514 | rb.Push(ResultSuccess); | 514 | rb.Push(rc); |
| 515 | } | 515 | } |
| 516 | 516 | ||
| 517 | // This literally does nothing internally in the actual service itself, | 517 | // This literally does nothing internally in the actual service itself, |