From 990a43a48c77816f0f9f5edad40ec905f05df62b Mon Sep 17 00:00:00 2001 From: Ribbit Date: Thu, 2 Oct 2025 20:00:34 +0200 Subject: [PATCH 1/4] [vk] Add missing flush per spec (#2624) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We copy pixels into a CPU-side staging buffer and then ask the GPU to read from it. On some systems those CPU writes aren’t automatically visible to the GPU unless explicitly flushed, so the GPU can sometimes read stale data. By calling buffer.Flush() immediately after writing, we force those CPU changes to become visible to the device, ensuring the GPU sees the latest frame. However, this is an emulator, so sometimes what spec says may not work cause reasons. Co-authored-by: Ribbit Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2624 Reviewed-by: Shinmegumi Reviewed-by: MaranBr Co-authored-by: Ribbit Co-committed-by: Ribbit --- src/video_core/renderer_vulkan/present/layer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video_core/renderer_vulkan/present/layer.cpp b/src/video_core/renderer_vulkan/present/layer.cpp index fa7c457573..5676dfe62a 100644 --- a/src/video_core/renderer_vulkan/present/layer.cpp +++ b/src/video_core/renderer_vulkan/present/layer.cpp @@ -280,6 +280,7 @@ void Layer::UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t i Tegra::Texture::UnswizzleTexture( mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size), bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0); + buffer.Flush(); // Ensure host writes are visible before the GPU copy. } const VkBufferImageCopy copy{ From 0577da534f662f9d328ca8b9f370608c218e74ac Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 2 Oct 2025 18:27:58 +0000 Subject: [PATCH 2/4] [android] allow use of mouse and keyboard on motion events Signed-off-by: lizzie --- .../org/yuzu/yuzu_emu/activities/EmulationActivity.kt | 8 ++++++-- .../yuzu_emu/features/settings/ui/InputDialogFragment.kt | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt index da40453497..ba60aeace2 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt @@ -230,7 +230,9 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { override fun dispatchKeyEvent(event: KeyEvent): Boolean { if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK && - event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD + event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD && + event.source and InputDevice.SOURCE_KEYBOARD != InputDevice.SOURCE_KEYBOARD && + event.source and InputDevice.SOURCE_MOUSE != InputDevice.SOURCE_MOUSE ) { return super.dispatchKeyEvent(event) } @@ -244,7 +246,9 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { override fun dispatchGenericMotionEvent(event: MotionEvent): Boolean { if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK && - event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD + event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD && + event.source and InputDevice.SOURCE_KEYBOARD != InputDevice.SOURCE_KEYBOARD && + event.source and InputDevice.SOURCE_MOUSE != InputDevice.SOURCE_MOUSE ) { return super.dispatchGenericMotionEvent(event) } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputDialogFragment.kt index 16a1d05044..bc54fddc09 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputDialogFragment.kt @@ -149,7 +149,9 @@ class InputDialogFragment : DialogFragment() { private fun onKeyEvent(event: KeyEvent): Boolean { if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK && - event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD + event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD && + event.source and InputDevice.SOURCE_KEYBOARD != InputDevice.SOURCE_KEYBOARD && + event.source and InputDevice.SOURCE_MOUSE != InputDevice.SOURCE_MOUSE ) { return false } @@ -173,7 +175,9 @@ class InputDialogFragment : DialogFragment() { private fun onMotionEvent(event: MotionEvent): Boolean { if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK && - event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD + event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD && + event.source and InputDevice.SOURCE_KEYBOARD != InputDevice.SOURCE_KEYBOARD && + event.source and InputDevice.SOURCE_MOUSE != InputDevice.SOURCE_MOUSE ) { return false } From 2d8cb2d4570b35985648079d2cfd69e96481ff2a Mon Sep 17 00:00:00 2001 From: MaranBr Date: Thu, 2 Oct 2025 22:48:52 +0200 Subject: [PATCH 3/4] [file_sys] Properly fix the installation of new updates (#2651) This removes the workaround and properly fix the installation of new updates. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2651 Co-authored-by: MaranBr Co-committed-by: MaranBr --- src/core/file_sys/content_archive.cpp | 4 --- src/core/file_sys/fssystem/fs_types.h | 3 ++ .../fssystem_nca_file_system_driver.cpp | 34 ++++++++++++++----- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index edd25644ac..4e3313f83c 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -38,9 +38,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca) reader = std::make_shared(); if (Result rc = reader->Initialize(file, GetCryptoConfiguration(), GetNcaCompressionConfiguration()); R_FAILED(rc)) { - if (rc != ResultInvalidNcaSignature) { - LOG_ERROR(Loader, "File reader errored out during header read: {:#x}", rc.GetInnerValue()); - } status = Loader::ResultStatus::ErrorBadNCAHeader; return; } @@ -85,7 +82,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca) for (s32 i = 0; i < fs_count; i++) { NcaFsHeaderReader header_reader; if (Result rc = fs.OpenStorage(&filesystems[i], &header_reader, i); R_FAILED(rc)) { - LOG_DEBUG(Loader, "File reader errored out during read of section {}: {:#x}", i, rc.GetInnerValue()); status = Loader::ResultStatus::ErrorBadNCAHeader; return; } diff --git a/src/core/file_sys/fssystem/fs_types.h b/src/core/file_sys/fssystem/fs_types.h index 43aeaf447b..f11b7f1dae 100644 --- a/src/core/file_sys/fssystem/fs_types.h +++ b/src/core/file_sys/fssystem/fs_types.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp index 25036b02c1..d496d58cec 100644 --- a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp +++ b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp @@ -1049,13 +1049,11 @@ Result NcaFileSystemDriver::CreatePatchMetaStorage( ASSERT(out_aes_ctr_ex_meta != nullptr); ASSERT(out_indirect_meta != nullptr); ASSERT(base_storage != nullptr); - //ASSERT(patch_info.HasAesCtrExTable()); - //ASSERT(patch_info.HasIndirectTable()); ASSERT(Common::IsAligned(patch_info.aes_ctr_ex_size, NcaHeader::XtsBlockSize)); // Validate patch info extents. - R_UNLESS(patch_info.indirect_size > 0, ResultInvalidNcaPatchInfoIndirectSize); - R_UNLESS(patch_info.aes_ctr_ex_size >= 0, ResultInvalidNcaPatchInfoAesCtrExSize); + R_UNLESS(patch_info.aes_ctr_ex_size >= 0 && patch_info.HasAesCtrExTable(), ResultInvalidNcaPatchInfoAesCtrExSize); + R_UNLESS(patch_info.indirect_size > 0 && patch_info.HasIndirectTable(), ResultInvalidNcaPatchInfoIndirectSize); R_UNLESS(patch_info.indirect_size + patch_info.indirect_offset <= patch_info.aes_ctr_ex_offset, ResultInvalidNcaPatchInfoAesCtrExOffset); R_UNLESS(patch_info.aes_ctr_ex_offset + patch_info.aes_ctr_ex_size <= @@ -1333,10 +1331,30 @@ Result NcaFileSystemDriver::CreateIntegrityVerificationStorageImpl( R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset, ResultRomNcaInvalidIntegrityLayerInfoOffset); } - storage_info[level_hash_info.max_layers - 1] - = std::make_shared(std::move(base_storage), - layer_info.size, - last_layer_info_offset); + + switch (level_hash_info.max_layers - 1) { + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::MasterStorage: + storage_info.SetMasterHashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer1Storage: + storage_info.SetLayer1HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer2Storage: + storage_info.SetLayer2HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer3Storage: + storage_info.SetLayer3HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer4Storage: + storage_info.SetLayer4HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer5Storage: + storage_info.SetLayer5HashStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::DataStorage: + storage_info.SetDataStorage(std::make_shared(std::move(base_storage), layer_info.size, last_layer_info_offset)); + break; + } // Make the integrity romfs storage. auto integrity_storage = std::make_shared(); From 921fb4561c3f825702f960bd61278898b6209578 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 2 Oct 2025 18:27:58 +0000 Subject: [PATCH 4/4] [android] allow use of mouse and keyboard on motion events Signed-off-by: lizzie --- .../org/yuzu/yuzu_emu/activities/EmulationActivity.kt | 8 ++++++-- .../yuzu_emu/features/settings/ui/InputDialogFragment.kt | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt index da40453497..ba60aeace2 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt @@ -230,7 +230,9 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { override fun dispatchKeyEvent(event: KeyEvent): Boolean { if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK && - event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD + event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD && + event.source and InputDevice.SOURCE_KEYBOARD != InputDevice.SOURCE_KEYBOARD && + event.source and InputDevice.SOURCE_MOUSE != InputDevice.SOURCE_MOUSE ) { return super.dispatchKeyEvent(event) } @@ -244,7 +246,9 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { override fun dispatchGenericMotionEvent(event: MotionEvent): Boolean { if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK && - event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD + event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD && + event.source and InputDevice.SOURCE_KEYBOARD != InputDevice.SOURCE_KEYBOARD && + event.source and InputDevice.SOURCE_MOUSE != InputDevice.SOURCE_MOUSE ) { return super.dispatchGenericMotionEvent(event) } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputDialogFragment.kt index 16a1d05044..bc54fddc09 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputDialogFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/InputDialogFragment.kt @@ -149,7 +149,9 @@ class InputDialogFragment : DialogFragment() { private fun onKeyEvent(event: KeyEvent): Boolean { if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK && - event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD + event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD && + event.source and InputDevice.SOURCE_KEYBOARD != InputDevice.SOURCE_KEYBOARD && + event.source and InputDevice.SOURCE_MOUSE != InputDevice.SOURCE_MOUSE ) { return false } @@ -173,7 +175,9 @@ class InputDialogFragment : DialogFragment() { private fun onMotionEvent(event: MotionEvent): Boolean { if (event.source and InputDevice.SOURCE_JOYSTICK != InputDevice.SOURCE_JOYSTICK && - event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD + event.source and InputDevice.SOURCE_GAMEPAD != InputDevice.SOURCE_GAMEPAD && + event.source and InputDevice.SOURCE_KEYBOARD != InputDevice.SOURCE_KEYBOARD && + event.source and InputDevice.SOURCE_MOUSE != InputDevice.SOURCE_MOUSE ) { return false }