From 2aa2ac7d9ac8e47f59a2475384c3afee9d5c60bc Mon Sep 17 00:00:00 2001 From: lizzie Date: Sun, 24 May 2026 01:04:32 +0200 Subject: [PATCH] [hle/service{nvdrv,apm}] fixes for TetrisSwitch (#3983) - testriswitch submits buffers with a fence id of -1, just skip them instead of trying to process them? - apm:u, which is removed, but hey, backwards compat never hurted - another instance of shared_memory crashing NPad Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3983 Reviewed-by: MaranBr Reviewed-by: CamilleLaVey --- src/core/hle/service/apm/apm.cpp | 14 ++++---- .../service/nvdrv/devices/nvdisp_disp0.cpp | 4 ++- src/core/hle/service/nvnflinger/ui/fence.h | 8 ++--- src/hid_core/resources/npad/npad.cpp | 5 +++ src/video_core/gpu.cpp | 35 +++++++++---------- 5 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index c23ff293d3..d73d08cb72 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -15,12 +18,11 @@ void LoopProcess(Core::System& system) { auto module = std::make_shared(); auto server_manager = std::make_unique(system); - server_manager->RegisterNamedService( - "apm", std::make_shared(system, module, system.GetAPMController(), "apm")); - server_manager->RegisterNamedService( - "apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); - server_manager->RegisterNamedService( - "apm:sys", std::make_shared(system, system.GetAPMController())); + server_manager->RegisterNamedService("apm", std::make_shared(system, module, system.GetAPMController(), "apm")); + server_manager->RegisterNamedService("apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); + // Removed on [+8.0.0] but kept for compatibility + server_manager->RegisterNamedService("apm:p", std::make_shared(system, module, system.GetAPMController(), "apm:p")); + server_manager->RegisterNamedService("apm:sys", std::make_shared(system, system.GetAPMController())); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index f26f5347eb..bdbb16ed04 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -79,7 +79,9 @@ void nvdisp_disp0::Composite(std::span sorted_layers }); for (size_t i = 0; i < layer.acquire_fence.num_fences; i++) { - output_fences.push_back(layer.acquire_fence.fences[i]); + if (layer.acquire_fence.fences[i].id >= 0) { + output_fences.push_back(layer.acquire_fence.fences[i]); + } } } diff --git a/src/core/hle/service/nvnflinger/ui/fence.h b/src/core/hle/service/nvnflinger/ui/fence.h index 177aed7580..261eb51669 100644 --- a/src/core/hle/service/nvnflinger/ui/fence.h +++ b/src/core/hle/service/nvnflinger/ui/fence.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2012 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -15,10 +18,8 @@ namespace Service::android { class Fence { public: - constexpr Fence() = default; - static constexpr Fence NoFence() { - Fence fence; + Fence fence{}; fence.fences[0].id = -1; fence.fences[1].id = -1; fence.fences[2].id = -1; @@ -26,7 +27,6 @@ public: return fence; } -public: u32 num_fences{}; std::array fences{}; }; diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp index 3a191f4539..4710342848 100644 --- a/src/hid_core/resources/npad/npad.cpp +++ b/src/hid_core/resources/npad/npad.cpp @@ -712,6 +712,11 @@ bool NPad::SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID: } auto& controller = GetControllerFromNpadIdType(aruid, npad_id); + if (!controller.shared_memory) { + LOG_WARNING(Service_HID, "shared_memory is null for npad_id={}", npad_id); + return false; + } + if (controller.shared_memory->assignment_mode != assignment_mode) { controller.shared_memory->assignment_mode = assignment_mode; } diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 5f4054212f..391ca4ef5f 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -303,26 +303,25 @@ struct GPU::Impl { free_swap_counters.pop_front(); } } - const auto wait_fence = - RequestSyncOperation([this, current_request_counter, &layers, &fences, num_fences] { - auto& syncpoint_manager = host1x.GetSyncpointManager(); - if (num_fences == 0) { - renderer->Composite(layers); - } - const auto executer = [this, current_request_counter, layers_copy = layers]() { - { - std::unique_lock lk(request_swap_mutex); - if (--request_swap_counters[current_request_counter] != 0) { - return; - } - free_swap_counters.push_back(current_request_counter); + const auto wait_fence = RequestSyncOperation([this, current_request_counter, &layers, &fences, num_fences] { + auto& syncpoint_manager = host1x.GetSyncpointManager(); + if (num_fences == 0) { + renderer->Composite(layers); + } + const auto executer = [this, current_request_counter, layers_copy = layers]() { + { + std::unique_lock lk(request_swap_mutex); + if (--request_swap_counters[current_request_counter] != 0) { + return; } - renderer->Composite(layers_copy); - }; - for (size_t i = 0; i < num_fences; i++) { - syncpoint_manager.RegisterGuestAction(fences[i].id, fences[i].value, executer); + free_swap_counters.push_back(current_request_counter); } - }); + renderer->Composite(layers_copy); + }; + for (size_t i = 0; i < num_fences; i++) { + syncpoint_manager.RegisterGuestAction(fences[i].id, fences[i].value, executer); + } + }); gpu_thread.TickGPU(); WaitForSyncOperation(wait_fence); }