Compare commits

..

29 commits

Author SHA1 Message Date
46ec35d20d [meta] Add option to FORCE X11 as Graphics Backend
All checks were successful
eden-license / license-header (pull_request) Successful in 25s
* save the option on a external file because settings
  are loaded AFTER Qt window is created and then
  the graphics backend is already applied

Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-10-06 06:38:06 +02:00
bc1d093fe9
[frontend] add 1.25x resolution option (#2566)
It sits at 900p or 1350p.

Signed-off-by: Aleksandr Popovich <popovich@eden-emu.dev>

Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #2566
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Aleksandr Popovich <popovich@eden-emu.dev>
Co-committed-by: Aleksandr Popovich <popovich@eden-emu.dev>
2025-10-06 03:08:00 +02:00
f6d99e5032
[docs] initial user handbook draft (#2629)
This is the initial draft of a "User Handbook", or FAQ. Currently contains useful info on the basics, graphics, and architecture/platform info.

Archive.org OR archive.is should be used for linking external websites, especially since their content should not change. And most often than not, in a few years these could change.

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #2629
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-05 20:44:48 +02:00
a52ddf78a6
[docs] add packaging status to README (#2658)
Very surprising we are on repology already. Anyways this may help power users track which packages are outdated and whatnot wrt to others.

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2658
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-05 05:42:59 +02:00
Bix
191dd892e5
[android] Legacy build flavor (#51)
This adds a "legacy" build flavor, similar to the genshinSpoof flavor. The legacy flavor uses a white icon bg, alongside building with `YUZU_LEGACY=ON`, which applies the previously-made SD865 patches iff that value is truthy.

Co-authored-by: Bixthefin <114880614+Bixthefin@users.noreply.github.com>
Co-authored-by: Calchan <denis.dupeyron@gmail.com>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #51
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Bix <bix@bixed.xyz>
Co-committed-by: Bix <bix@bixed.xyz>
2025-10-05 05:41:20 +02:00
9f385bf627
[tools, cmake] refactor: update/hash check scripts, use tags for some more deps, proper CPMUtil separation (#2666)
Uses tags for a bunch of deps that can use them

Also adds a bunmch of scripts to tools/cpm, notably for checking hashes
and checking for updates.

TODO for the future:
- CI target to check hashes
- Weekly CI to check for updates

Need to get that other CI runner up

additional stuff

- Ports gentoo fixes
- makes solaris work (TODO: sdl2)
- way better docs
- properly separates CPMUtil as a standalone project

Reviewed-on: #2666
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2025-10-05 03:04:53 +02:00
1a13e79c3d
[cmake] fix video_core and tests comp errors on Windows (#2631)
did not link to video_core thus did not properly propagate the GPUOpen
target thus failed to find vk_mem_alloc

also msvc sucks

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #2631
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2025-10-05 00:00:52 +02:00
268918aece
[vk] Implement Shader Read Barrier (#2671)
Adding the shader read barrier keeps every render/compute/transfer write visible before the image is sampled, so it prevents the “read-before-writes-finish” hazards. Without it you can get random stale frames, flickering post process passes, partially updated HUD textures, and corrupted depth-to-color conversions especially in scenes that render into an offscreen image and immediately feed that image to a shader (reflections, bloom, dynamic resolution, depth visualizers, etc.). This fix makes those R2T chains deterministic again across all Vulkan drivers.

Co-authored-by: Ribbit <ribbit@placeholder.com>
Reviewed-on: #2671
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Ribbit <ribbit@eden-emu.dev>
Co-committed-by: Ribbit <ribbit@eden-emu.dev>
2025-10-04 23:58:08 +02:00
83730cd4c1
[cmake] update CI deps, feat: sirit CI + new CI spec (#2655)
Updates sirit to our fork's latest version w/ SPIRV Headers included
(end goal is to remove spirv-headers entirely, as spirv-tools-ci should
include them inline as well)

Adds a sirit CI on our fork for all platforms (saves a bit of compile
time)

My CI spec has changed a little bit, and now there is no need for an
additional CMake file after the initial CMakeLists.txt (since targets
are now global imported). Plus, UNIX amd64 now has the amd64 suffix like
aarch64 and windows

Updates SDL2 to 2.32.10 and OpenSSL to 3.6.0

Finally, on Solaris all CI packages (sans FFmpeg) are now built with OmniOS, which
should in theory be fully compatible with OpenIndiana (our recommended
Sun-based target) but obviously will need testing

Need testing:
- [ ] Make sure I didn't nuke shader emission
- [ ] Make sure FreeBSD, OpenBSD, and OpenIndiana work fine with bundled
  sirit (check linking especially)
- [ ] Make sure SDL2, OpenSSL work with OpenIndiana now
- [ ] SDL2 on all platforms (input, etc)

Signed-off-by: crueter <crueter@eden-emu.dev>

Reviewed-on: #2655
2025-10-04 09:27:13 +02:00
272df1fa83
[settings] default to opengl on solaris (#2659)
Vulkan support still wonky on most distros.

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2659
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-04 02:48:39 +02:00
71a87b2c55
[video_core] Fix stutters and freezes when playing FMV content in some games (#2650)
This fixes stutters and freezes when playing FMV content in some games.

Reviewed-on: #2650
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-03 23:08:20 +02:00
f4f3425d86
[sockets] block more domains (#2632)
* Bring in the domain-blocking code from the legacy branch
* Make blockedDomains a `static constexpr const std::array<std::string,6>`

Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: #2632
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Calchan <denis.dupeyron@gmail.com>
Co-committed-by: Calchan <denis.dupeyron@gmail.com>
2025-10-03 04:46:27 +02:00
9173eec402
[compat] fix logind DBus on non-linux unixes (#2648)
Backported from FreeBSD ports patches

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2648
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-02 23:39:59 +02:00
de594c8792
[dynarmic] add safe-opt to skip IR verification (#2613)
Most programs are well behaved and don't cause internal IR issues. Hence, verification can be safely skipped.

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2613
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-02 23:20:45 +02:00
2d8cb2d457
[file_sys] Properly fix the installation of new updates (#2651)
This removes the workaround and properly fix the installation of new updates.

Reviewed-on: #2651
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-02 22:48:52 +02:00
990a43a48c
[vk] Add missing flush per spec (#2624)
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 <ribbit@placeholder.com>
Reviewed-on: #2624
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: Ribbit <ribbit@eden-emu.dev>
Co-committed-by: Ribbit <ribbit@eden-emu.dev>
2025-10-02 20:00:34 +02:00
1a5b3fb239
[audio_core] Fix audio reverb effect (#2646)
This fixes the audio reverb effect that was causing loud noise in some games and on some platforms.

Reviewed-on: #2646
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-02 01:30:05 +02:00
24e6c62109
[vk, ogl] invalidate pipeline caches from <=0.0.3 (#2637)
Invalidates caches before next upcoming release, this will make transitions smoother especially for users whom do not know how to clear caches. The reasoning behind this is the recent changes to async shaders and other pipeline stuffs that may break compat

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2637
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-02 00:25:41 +02:00
326865cba2
[host1x] Improve FFmpeg error handling (#2643)
This improves the FFmpeg error handling.

Reviewed-on: #2643
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-02 00:15:14 +02:00
76b5d6778e
[common/logging] faster logging by avoiding constructing unused strings/results (and filtering first) (#2603)
basically std::string would be invoked even when the logging was filtered, then destroyed instantly, invoking malloc/free and polluting mem arenas for no good reason

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2603
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-01 23:18:37 +02:00
61adc85c4b
[ci] Minor change to fix building (#2644)
MSVC did not like that one of our variables was a constexpr since it was defined in the externals as a constexpr. Changed to const auto like the rest to ensure it built properly.

Reviewed-on: #2644
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-committed-by: Shinmegumi <shinmegumi@eden-emu.dev>
2025-10-01 21:09:27 +02:00
4be6d30cd9
[fixup] fix bad variable names (#2642)
* Mo[l]tenVK is only for apple, so desc is unnecessary
* fix mistipo on BUILD_AUTO_UPDATE_WEB[SI]TE

Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>

Reviewed-on: #2642
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-committed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-10-01 16:36:07 +02:00
020f1cdb1f
[qt] fix ci missing build_id (#2638)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #2638
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-01 12:16:42 +02:00
dfe10bc851
[common] use libc++ provided jthread instead of in-house one (which deadlocks on FBSD 14) (#351)
Needs test on our CI targets to see I didn't miss anything. Worried about android.

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #351
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-01 06:59:35 +02:00
9a098441de
[audio_core] Fix audio issue in The Legend of Zelda - Echoes of Wisdom (#2594)
This fixes the audio issue in The Legend of Zelda - Echoes of Wisdom on Windows.

Reviewed-on: #2594
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-01 05:33:37 +02:00
91fb1df624
[meta] allow customisation of auto-updater, remove hardcoded title names and fix dup title names (#2588)
Right now on all platforms, sdl2 will display something like "Eden Eden | master-8gd8fg8", this fixes so it only displays `Eden` (the REPO_NAME) once.

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: #2588
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-10-01 05:07:59 +02:00
43a7470a7d
[Maxwell]: Fix shaders compilation memory leak (#2606)
Co-authored-by: collecting <collecting@citron-emu.org>

"The ObjectPool<Statement> was never being cleared after use. When compiling complex shaders, this would allocate gigabytes of memory, causing the emulator to run out of RAM and be killed by the operating system. This is a critical fix that prevents out-of-memory crashes on all operating systems when playing games with complex shaders."

Co-authored-by: Gamer64 <76565986+Gamer64ytb@users.noreply.github.com>
Reviewed-on: #2606
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: Gamer64 <gamer64@eden-emu.dev>
Co-committed-by: Gamer64 <gamer64@eden-emu.dev>
2025-10-01 01:21:12 +02:00
dfca07f4e3
Initial a9 (minsdk=28) support (#2600)
Minimal changes to make android 10 installable and emulationFragment not immediately crashable.
Testers (mainly android 10) NEEDED!!!

Co-authored-by: Allison Cunha <allisonbzk@gmail.com>
Reviewed-on: #2600
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: xbzk <xbzk@eden-emu.dev>
Co-committed-by: xbzk <xbzk@eden-emu.dev>
2025-10-01 00:10:59 +02:00
2e0a4163cf
common: include missing headers after PCH disable (#2626)
Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-on: #2626
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-committed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-09-30 04:25:29 +02:00
134 changed files with 2223 additions and 1432 deletions

1
.shellcheckrc Normal file
View file

@ -0,0 +1 @@
shell=sh

View file

@ -32,10 +32,20 @@ endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
# NB: this does not account for SPARC
# If you get Eden working on SPARC, please shoot crueter@crueter.xyz multiple emails
# and you will be hailed for eternity
if (PLATFORM_SUN) if (PLATFORM_SUN)
# Terrific Solaris pkg shenanigans # Terrific Solaris pkg shenanigans
list(APPEND CMAKE_PREFIX_PATH "/usr/lib/qt/6.6/lib/amd64/cmake") list(APPEND CMAKE_PREFIX_PATH "/usr/lib/qt/6.6/lib/amd64/cmake")
list(APPEND CMAKE_MODULE_PATH "/usr/lib/qt/6.6/lib/amd64/cmake") list(APPEND CMAKE_MODULE_PATH "/usr/lib/qt/6.6/lib/amd64/cmake")
# amazing
# absolutely incredible
list(APPEND CMAKE_PREFIX_PATH "/usr/lib/amd64/cmake")
list(APPEND CMAKE_MODULE_PATH "/usr/lib/amd64/cmake")
# For some mighty reason, doing a normal release build sometimes may not trigger # For some mighty reason, doing a normal release build sometimes may not trigger
# the proper -O3 switch to materialize # the proper -O3 switch to materialize
if (CMAKE_BUILD_TYPE MATCHES "Release") if (CMAKE_BUILD_TYPE MATCHES "Release")
@ -147,6 +157,7 @@ if (ENABLE_SDL2)
option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}") option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}")
endif() endif()
# qt stuff
option(ENABLE_QT "Enable the Qt frontend" ON) option(ENABLE_QT "Enable the Qt frontend" ON)
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF) option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
option(ENABLE_QT_UPDATE_CHECKER "Enable update checker for the Qt frontend" OFF) option(ENABLE_QT_UPDATE_CHECKER "Enable update checker for the Qt frontend" OFF)
@ -163,8 +174,12 @@ if (MSVC OR ANDROID)
endif() endif()
option(YUZU_USE_CPM "Use CPM to fetch system dependencies (fmt, boost, etc) if needed. Externals will still be fetched." ${EXT_DEFAULT}) option(YUZU_USE_CPM "Use CPM to fetch system dependencies (fmt, boost, etc) if needed. Externals will still be fetched." ${EXT_DEFAULT})
# ffmpeg
option(YUZU_USE_BUNDLED_FFMPEG "Download bundled FFmpeg" ${EXT_DEFAULT}) option(YUZU_USE_BUNDLED_FFMPEG "Download bundled FFmpeg" ${EXT_DEFAULT})
cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from source" OFF "NOT WIN32 AND NOT ANDROID" OFF) cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from source" "${PLATFORM_SUN}" "NOT WIN32 AND NOT ANDROID" OFF)
# sirit
option(YUZU_USE_BUNDLED_SIRIT "Download bundled sirit" ${EXT_DEFAULT})
cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "NOT ANDROID" OFF) cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "NOT ANDROID" OFF)
@ -212,6 +227,8 @@ endif()
# TODO(crueter): CI this? # TODO(crueter): CI this?
option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON) option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON)
option(YUZU_LEGACY "Apply patches that improve compatibility with older GPUs (e.g. Snapdragon 865) at the cost of performance" OFF)
cmake_dependent_option(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF) cmake_dependent_option(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF)
cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF) cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF)
@ -224,7 +241,7 @@ set(YUZU_TZDB_PATH "" CACHE STRING "Path to a pre-downloaded timezone database")
cmake_dependent_option(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "LINUX" OFF) cmake_dependent_option(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "LINUX" OFF)
cmake_dependent_option(YUZU_APPLE_USE_BUNDLED_MONTENVK "Download bundled MoltenVK lib" ON "APPLE" OFF) cmake_dependent_option(YUZU_USE_BUNDLED_MOLTENVK "Download bundled MoltenVK lib" ON "APPLE" OFF)
option(YUZU_DISABLE_LLVM "Disable LLVM (useful for CI)" OFF) option(YUZU_DISABLE_LLVM "Disable LLVM (useful for CI)" OFF)
@ -309,16 +326,32 @@ if (UNIX)
add_compile_definitions(YUZU_UNIX=1) add_compile_definitions(YUZU_UNIX=1)
endif() endif()
if (YUZU_LEGACY)
message(WARNING "Making legacy build. Performance may suffer.")
add_compile_definitions(YUZU_LEGACY)
endif()
if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX)) if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX))
set(HAS_NCE 1) set(HAS_NCE 1)
add_compile_definitions(HAS_NCE=1) add_compile_definitions(HAS_NCE=1)
find_package(oaknut 2.0.1)
endif() endif()
if (YUZU_ROOM) if (YUZU_ROOM)
add_compile_definitions(YUZU_ROOM) add_compile_definitions(YUZU_ROOM)
endif() endif()
if (ANDROID OR PLATFORM_FREEBSD OR PLATFORM_OPENBSD OR PLATFORM_SUN OR APPLE)
if(CXX_APPLE OR CXX_CLANG)
# libc++ has stop_token and jthread as experimental
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexperimental-library")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexperimental-library")
else()
# Uses glibc, mostly?
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LIBCPP_ENABLE_EXPERIMENTAL=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_LIBCPP_ENABLE_EXPERIMENTAL=1")
endif()
endif()
# Build/optimization presets # Build/optimization presets
if (PLATFORM_LINUX OR CXX_CLANG) if (PLATFORM_LINUX OR CXX_CLANG)
if (ARCHITECTURE_x86_64) if (ARCHITECTURE_x86_64)
@ -438,22 +471,7 @@ if (YUZU_USE_CPM)
if (zstd_ADDED) if (zstd_ADDED)
add_library(zstd::zstd ALIAS libzstd_static) add_library(zstd::zstd ALIAS libzstd_static)
endif() add_library(zstd::libzstd ALIAS libzstd_static)
# Catch2
if (YUZU_TESTS OR DYNARMIC_TESTS)
AddJsonPackage(catch2)
endif()
# ENet
AddJsonPackage(enet)
if (enet_ADDED)
target_include_directories(enet INTERFACE ${enet_SOURCE_DIR}/include)
endif()
if (NOT TARGET enet::enet)
add_library(enet::enet ALIAS enet)
endif() endif()
# Opus # Opus
@ -470,31 +488,10 @@ if (YUZU_USE_CPM)
if (NOT TARGET Opus::opus) if (NOT TARGET Opus::opus)
add_library(Opus::opus ALIAS opus) add_library(Opus::opus ALIAS opus)
endif() endif()
# VulkanUtilityHeaders - pulls in headers and utility libs
AddJsonPackage(vulkan-utility-headers)
# small hack
if (NOT VulkanUtilityLibraries_ADDED)
find_package(VulkanHeaders 1.3.274 REQUIRED)
endif()
# SPIRV Headers
AddJsonPackage(spirv-headers)
# SPIRV Tools
AddJsonPackage(spirv-tools)
if (SPIRV-Tools_ADDED)
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools-static)
target_link_libraries(SPIRV-Tools-static PRIVATE SPIRV-Tools-opt SPIRV-Tools-link)
endif()
# mbedtls
AddJsonPackage(mbedtls)
else() else()
# Enforce the search mode of non-required packages for better and shorter failure messages # Enforce the search mode of non-required packages for better and shorter failure messages
find_package(fmt 8 REQUIRED) find_package(fmt 8 REQUIRED)
if (NOT YUZU_DISABLE_LLVM) if (NOT YUZU_DISABLE_LLVM)
find_package(LLVM MODULE COMPONENTS Demangle) find_package(LLVM MODULE COMPONENTS Demangle)
endif() endif()
@ -503,39 +500,16 @@ else()
find_package(lz4 REQUIRED) find_package(lz4 REQUIRED)
find_package(RenderDoc MODULE) find_package(RenderDoc MODULE)
find_package(stb MODULE) find_package(stb MODULE)
find_package(enet 1.3 MODULE REQUIRED)
find_package(Opus 1.3 MODULE REQUIRED) find_package(Opus 1.3 MODULE REQUIRED)
find_package(ZLIB 1.2 REQUIRED) find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED MODULE) find_package(zstd 1.5 REQUIRED MODULE)
# wow # wow
if (PLATFORM_LINUX) if (PLATFORM_LINUX)
find_package(Boost 1.57.0 REQUIRED headers context system fiber) find_package(Boost 1.57.0 CONFIG REQUIRED headers context system fiber)
else() else()
find_package(Boost 1.57.0 REQUIRED) find_package(Boost 1.57.0 CONFIG REQUIRED)
endif()
# OpenBSD does not package mbedtls3 (only 2)
if (PLATFORM_OPENBSD)
AddJsonPackage(mbedtls)
else()
find_package(MbedTLS 3 REQUIRED)
endif()
find_package(VulkanUtilityLibraries REQUIRED)
find_package(VulkanHeaders 1.3.274 REQUIRED)
# FreeBSD does not package spirv-headers
if (PLATFORM_FREEBSD)
AddJsonPackage(spirv-headers)
else()
find_package(SPIRV-Headers 1.3.274 REQUIRED)
endif()
find_package(SPIRV-Tools MODULE REQUIRED)
if (YUZU_TESTS)
find_package(Catch2 3.0.1 REQUIRED)
endif() endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID) if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID)
@ -551,90 +525,6 @@ if(NOT TARGET Boost::headers)
AddJsonPackage(boost_headers) AddJsonPackage(boost_headers)
endif() endif()
# DiscordRPC
if (USE_DISCORD_PRESENCE)
if (ARCHITECTURE_arm64)
add_compile_definitions(RAPIDJSON_ENDIAN=RAPIDJSON_LITTLEENDIAN)
endif()
AddJsonPackage(discord-rpc)
target_include_directories(discord-rpc INTERFACE ${discord-rpc_SOURCE_DIR}/include)
add_library(DiscordRPC::discord-rpc ALIAS discord-rpc)
endif()
# SimpleIni
AddJsonPackage(simpleini)
# Most linux distros don't package cubeb, so enable regardless of cpm settings
if(ENABLE_CUBEB)
AddJsonPackage(cubeb)
if (cubeb_ADDED)
if (NOT MSVC)
if (TARGET speex)
target_compile_options(speex PRIVATE -Wno-sign-compare)
endif()
set_target_properties(cubeb PROPERTIES COMPILE_OPTIONS "")
target_compile_options(cubeb INTERFACE
-Wno-implicit-const-int-float-conversion
-Wno-shadow
-Wno-missing-declarations
-Wno-return-type
-Wno-uninitialized
)
else()
target_compile_options(cubeb PRIVATE
/wd4456
/wd4458
)
endif()
endif()
if (NOT TARGET cubeb::cubeb)
add_library(cubeb::cubeb ALIAS cubeb)
endif()
endif()
# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the YUZU_find_package
if (ENABLE_SDL2)
if (YUZU_USE_EXTERNAL_SDL2)
message(STATUS "Using SDL2 from externals.")
if (NOT WIN32)
# Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers
# Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095)
# Yuzu-cmd also needs: Video (depends on Loadso/Dlopen)
# CPUinfo also required for SDL Audio, at least until 2.28.0 (see https://github.com/libsdl-org/SDL/issues/7809)
set(SDL_UNUSED_SUBSYSTEMS
File Filesystem
Locale Power Render)
foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT)
set(SDL_${_OPT} OFF)
endforeach()
set(HIDAPI ON)
endif()
if (APPLE)
set(SDL_FILE ON)
endif()
if ("${YUZU_SYSTEM_PROFILE}" STREQUAL "steamdeck")
set(SDL_PIPEWIRE OFF) # build errors out with this on
AddJsonPackage("sdl2_steamdeck")
else()
AddJsonPackage("sdl2_generic")
endif()
elseif (YUZU_USE_BUNDLED_SDL2)
message(STATUS "Using bundled SDL2")
AddJsonPackage(sdl2)
endif()
find_package(SDL2 2.26.4 REQUIRED)
endif()
# List of all FFmpeg components required # List of all FFmpeg components required
set(FFmpeg_COMPONENTS set(FFmpeg_COMPONENTS
avcodec avcodec
@ -665,6 +555,12 @@ add_subdirectory(externals)
# pass targets from externals # pass targets from externals
find_package(libusb) find_package(libusb)
find_package(VulkanMemoryAllocator) find_package(VulkanMemoryAllocator)
find_package(enet)
find_package(MbedTLS)
find_package(VulkanUtilityLibraries)
find_package(SimpleIni)
find_package(SPIRV-Tools)
find_package(sirit)
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
find_package(xbyak) find_package(xbyak)
@ -678,6 +574,26 @@ if (ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER)
find_package(cpp-jwt) find_package(cpp-jwt)
endif() endif()
if (ARCHITECTURE_arm64 OR DYNARMIC_TESTS)
find_package(oaknut)
endif()
if (ENABLE_SDL2)
find_package(SDL2)
endif()
if (USE_DISCORD_PRESENCE)
find_package(DiscordRPC)
endif()
if (ENABLE_CUBEB)
find_package(cubeb)
endif()
if (YUZU_TESTS OR DYNARMIC_TESTS)
find_package(Catch2)
endif()
if (ENABLE_QT) if (ENABLE_QT)
if (YUZU_USE_BUNDLED_QT) if (YUZU_USE_BUNDLED_QT)
download_qt(6.8.3) download_qt(6.8.3)
@ -696,6 +612,8 @@ if (ENABLE_QT)
endif() endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux") if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
# yes Qt, we get it
set(QT_NO_PRIVATE_MODULE_WARNING ON)
find_package(Qt6 REQUIRED COMPONENTS DBus OPTIONAL_COMPONENTS GuiPrivate) find_package(Qt6 REQUIRED COMPONENTS DBus OPTIONAL_COMPONENTS GuiPrivate)
elseif (UNIX AND NOT APPLE) elseif (UNIX AND NOT APPLE)
find_package(Qt6 REQUIRED COMPONENTS DBus Gui) find_package(Qt6 REQUIRED COMPONENTS DBus Gui)

View file

@ -743,9 +743,11 @@ function(CPMAddPackage)
if(NOT DEFINED CPM_ARGS_NAME) if(NOT DEFINED CPM_ARGS_NAME)
set(CPM_ARGS_NAME ${nameFromUrl}) set(CPM_ARGS_NAME ${nameFromUrl})
endif() endif()
if(NOT DEFINED CPM_ARGS_VERSION)
set(CPM_ARGS_VERSION ${verFromUrl}) # this is dumb and should not be done
endif() # if(NOT DEFINED CPM_ARGS_VERSION)
# set(CPM_ARGS_VERSION ${verFromUrl})
# endif()
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS URL "${CPM_ARGS_URL}") list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS URL "${CPM_ARGS_URL}")
endif() endif()

View file

@ -107,7 +107,6 @@ function(AddJsonPackage)
get_json_element("${object}" name name "${JSON_NAME}") get_json_element("${object}" name name "${JSON_NAME}")
get_json_element("${object}" extension extension "tar.zst") get_json_element("${object}" extension extension "tar.zst")
get_json_element("${object}" min_version min_version "") get_json_element("${object}" min_version min_version "")
get_json_element("${object}" cmake_filename cmake_filename "")
get_json_element("${object}" raw_disabled disabled_platforms "") get_json_element("${object}" raw_disabled disabled_platforms "")
if (raw_disabled) if (raw_disabled)
@ -124,7 +123,6 @@ function(AddJsonPackage)
EXTENSION ${extension} EXTENSION ${extension}
MIN_VERSION ${min_version} MIN_VERSION ${min_version}
DISABLED_PLATFORMS ${disabled_platforms} DISABLED_PLATFORMS ${disabled_platforms}
CMAKE_FILENAME ${cmake_filename}
) )
# pass stuff to parent scope # pass stuff to parent scope
@ -139,6 +137,7 @@ function(AddJsonPackage)
endif() endif()
get_json_element("${object}" hash hash "") get_json_element("${object}" hash hash "")
get_json_element("${object}" hash_suffix hash_suffix "")
get_json_element("${object}" sha sha "") get_json_element("${object}" sha sha "")
get_json_element("${object}" url url "") get_json_element("${object}" url url "")
get_json_element("${object}" key key "") get_json_element("${object}" key key "")
@ -208,6 +207,7 @@ function(AddJsonPackage)
VERSION "${version}" VERSION "${version}"
URL "${url}" URL "${url}"
HASH "${hash}" HASH "${hash}"
HASH_SUFFIX "${hash_suffix}"
SHA "${sha}" SHA "${sha}"
REPO "${repo}" REPO "${repo}"
KEY "${key}" KEY "${key}"
@ -277,6 +277,7 @@ function(AddPackage)
KEY KEY
BUNDLED_PACKAGE BUNDLED_PACKAGE
FORCE_BUNDLED_PACKAGE
FIND_PACKAGE_ARGUMENTS FIND_PACKAGE_ARGUMENTS
) )
@ -426,7 +427,9 @@ function(AddPackage)
- BUNDLED_PACKAGE - BUNDLED_PACKAGE
- default to allow local - default to allow local
]]# ]]#
if (${PKG_ARGS_NAME}_FORCE_SYSTEM) if (PKG_ARGS_FORCE_BUNDLED_PACKAGE)
set_precedence(OFF OFF)
elseif (${PKG_ARGS_NAME}_FORCE_SYSTEM)
set_precedence(ON ON) set_precedence(ON ON)
elseif (${PKG_ARGS_NAME}_FORCE_BUNDLED) elseif (${PKG_ARGS_NAME}_FORCE_BUNDLED)
set_precedence(OFF OFF) set_precedence(OFF OFF)
@ -446,9 +449,14 @@ function(AddPackage)
set_precedence(ON OFF) set_precedence(ON OFF)
endif() endif()
if (DEFINED PKG_ARGS_VERSION)
list(APPEND EXTRA_ARGS
VERSION ${PKG_ARGS_VERSION}
)
endif()
CPMAddPackage( CPMAddPackage(
NAME ${PKG_ARGS_NAME} NAME ${PKG_ARGS_NAME}
VERSION ${PKG_ARGS_VERSION}
URL ${pkg_url} URL ${pkg_url}
URL_HASH ${pkg_hash} URL_HASH ${pkg_hash}
CUSTOM_CACHE_KEY ${pkg_key} CUSTOM_CACHE_KEY ${pkg_key}
@ -459,6 +467,8 @@ function(AddPackage)
PATCHES ${PKG_ARGS_PATCHES} PATCHES ${PKG_ARGS_PATCHES}
EXCLUDE_FROM_ALL ON EXCLUDE_FROM_ALL ON
${EXTRA_ARGS}
${PKG_ARGS_UNPARSED_ARGUMENTS} ${PKG_ARGS_UNPARSED_ARGUMENTS}
) )
@ -511,12 +521,12 @@ function(add_ci_package key)
NAME ${ARTIFACT_PACKAGE} NAME ${ARTIFACT_PACKAGE}
REPO ${ARTIFACT_REPO} REPO ${ARTIFACT_REPO}
TAG v${ARTIFACT_VERSION} TAG v${ARTIFACT_VERSION}
VERSION ${ARTIFACT_VERSION} GIT_VERSION ${ARTIFACT_VERSION}
ARTIFACT ${ARTIFACT} ARTIFACT ${ARTIFACT}
KEY ${key} KEY ${key}-${ARTIFACT_VERSION}
HASH_SUFFIX sha512sum HASH_SUFFIX sha512sum
BUNDLED_PACKAGE ON FORCE_BUNDLED_PACKAGE ON
) )
set(ARTIFACT_DIR ${${ARTIFACT_PACKAGE}_SOURCE_DIR} PARENT_SCOPE) set(ARTIFACT_DIR ${${ARTIFACT_PACKAGE}_SOURCE_DIR} PARENT_SCOPE)
@ -533,7 +543,6 @@ function(AddCIPackage)
EXTENSION EXTENSION
MIN_VERSION MIN_VERSION
DISABLED_PLATFORMS DISABLED_PLATFORMS
CMAKE_FILENAME
) )
cmake_parse_arguments(PKG_ARGS "" "${oneValueArgs}" "" ${ARGN}) cmake_parse_arguments(PKG_ARGS "" "${oneValueArgs}" "" ${ARGN})
@ -589,25 +598,28 @@ function(AddCIPackage)
add_ci_package(android) add_ci_package(android)
endif() endif()
if(PLATFORM_SUN AND NOT "solaris" IN_LIST DISABLED_PLATFORMS) if(PLATFORM_SUN AND NOT "solaris-amd64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(solaris) add_ci_package(solaris-amd64)
endif() endif()
if(PLATFORM_FREEBSD AND NOT "freebsd" IN_LIST DISABLED_PLATFORMS) if(PLATFORM_FREEBSD AND NOT "freebsd-amd64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(freebsd) add_ci_package(freebsd-amd64)
endif() endif()
if((PLATFORM_LINUX AND ARCHITECTURE_x86_64) AND NOT "linux" IN_LIST DISABLED_PLATFORMS) if((PLATFORM_LINUX AND ARCHITECTURE_x86_64) AND NOT "linux-amd64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(linux) add_ci_package(linux-amd64)
endif() endif()
if((PLATFORM_LINUX AND ARCHITECTURE_arm64) AND NOT "linux-aarch64" IN_LIST DISABLED_PLATFORMS) if((PLATFORM_LINUX AND ARCHITECTURE_arm64) AND NOT "linux-aarch64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(linux-aarch64) add_ci_package(linux-aarch64)
endif() endif()
if (DEFINED ARTIFACT_DIR) # TODO(crueter): macOS amd64/aarch64 split mayhaps
include(${ARTIFACT_DIR}/${ARTIFACT_CMAKE}.cmake) if (APPLE AND NOT "macos-universal" IN_LIST DISABLED_PLATFORMS)
add_ci_package(macos-universal)
endif()
if (DEFINED ARTIFACT_DIR)
set(${ARTIFACT_PACKAGE}_ADDED TRUE PARENT_SCOPE) set(${ARTIFACT_PACKAGE}_ADDED TRUE PARENT_SCOPE)
set(${ARTIFACT_PACKAGE}_SOURCE_DIR "${ARTIFACT_DIR}" PARENT_SCOPE) set(${ARTIFACT_PACKAGE}_SOURCE_DIR "${ARTIFACT_DIR}" PARENT_SCOPE)
else() else()

View file

@ -13,9 +13,12 @@ find_package_handle_standard_args(zstd
if (zstd_FOUND AND NOT TARGET zstd::zstd) if (zstd_FOUND AND NOT TARGET zstd::zstd)
if (TARGET zstd::libzstd_shared) if (TARGET zstd::libzstd_shared)
add_library(zstd::zstd ALIAS zstd::libzstd_shared) add_library(zstd::zstd ALIAS zstd::libzstd_shared)
add_library(zstd::libzstd ALIAS zstd::libzstd_shared)
elseif (TARGET zstd::libzstd_static) elseif (TARGET zstd::libzstd_static)
add_library(zstd::zstd ALIAS zstd::libzstd_static) add_library(zstd::zstd ALIAS zstd::libzstd_static)
add_library(zstd::libzstd ALIAS zstd::libzstd_static)
else() else()
add_library(zstd::zstd ALIAS PkgConfig::ZSTD) add_library(zstd::zstd ALIAS PkgConfig::ZSTD)
add_library(zstd::libzstd ALIAS PkgConfig::ZSTD)
endif() endif()
endif() endif()

View file

@ -31,7 +31,11 @@ set(GIT_DESC ${BUILD_VERSION})
set(REPO_NAME "Eden") set(REPO_NAME "Eden")
set(BUILD_ID ${GIT_REFSPEC}) set(BUILD_ID ${GIT_REFSPEC})
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ") set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ")
set(CXX_COMPILER "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") set(CXX_COMPILER "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
# Auto-updater metadata! Must somewhat mirror GitHub API endpoint
set(BUILD_AUTO_UPDATE_WEBSITE "https://github.com")
set(BUILD_AUTO_UPDATE_API "http://api.github.com")
set(BUILD_AUTO_UPDATE_REPO "eden-emulator/Releases")
configure_file(scm_rev.cpp.in scm_rev.cpp @ONLY) configure_file(scm_rev.cpp.in scm_rev.cpp @ONLY)

View file

@ -48,6 +48,8 @@ A list of supported games will be available in future. Please be patient.
Check out our [website](https://eden-emu.dev) for the latest news on exciting features, monthly progress reports, and more! Check out our [website](https://eden-emu.dev) for the latest news on exciting features, monthly progress reports, and more!
[![Packaging status](https://repology.org/badge/vertical-allrepos/eden-emulator.svg)](https://repology.org/project/eden-emulator/versions)
## Development ## Development
Most of the development happens on our Git server. It is also where [our central repository](https://git.eden-emu.dev/eden-emu/eden) is hosted. For development discussions, please join us on [Discord](https://discord.gg/kXAmGCXBGD) or [Revolt](https://rvlt.gg/qKgFEAbH). Most of the development happens on our Git server. It is also where [our central repository](https://git.eden-emu.dev/eden-emu/eden) is hosted. For development discussions, please join us on [Discord](https://discord.gg/kXAmGCXBGD) or [Revolt](https://rvlt.gg/qKgFEAbH).
@ -63,6 +65,8 @@ Alternatively, if you wish to add translations, go to the [Eden project on Trans
See the [General Build Guide](docs/Build.md) See the [General Build Guide](docs/Build.md)
For information on provided development tooling, see the [Tools directory](./tools)
## Download ## Download
You can download the latest releases from [here](https://github.com/eden-emulator/Releases/releases). You can download the latest releases from [here](https://github.com/eden-emulator/Releases/releases).

View file

@ -4,8 +4,11 @@
"package": "OpenSSL", "package": "OpenSSL",
"name": "openssl", "name": "openssl",
"repo": "crueter-ci/OpenSSL", "repo": "crueter-ci/OpenSSL",
"version": "3.5.3", "version": "3.6.0",
"min_version": "1.1.1" "min_version": "1.1.1",
"disabled_platforms": [
"macos-universal"
]
}, },
"boost": { "boost": {
"package": "Boost", "package": "Boost",
@ -15,6 +18,7 @@
"hash": "4fb7f6fde92762305aad8754d7643cd918dd1f3f67e104e9ab385b18c73178d72a17321354eb203b790b6702f2cf6d725a5d6e2dfbc63b1e35f9eb59fb42ece9", "hash": "4fb7f6fde92762305aad8754d7643cd918dd1f3f67e104e9ab385b18c73178d72a17321354eb203b790b6702f2cf6d725a5d6e2dfbc63b1e35f9eb59fb42ece9",
"git_version": "1.89.0", "git_version": "1.89.0",
"version": "1.57", "version": "1.57",
"find_args": "CONFIG",
"patches": [ "patches": [
"0001-clang-cl.patch", "0001-clang-cl.patch",
"0002-use-marmasm.patch", "0002-use-marmasm.patch",
@ -23,12 +27,10 @@
}, },
"fmt": { "fmt": {
"repo": "fmtlib/fmt", "repo": "fmtlib/fmt",
"sha": "40626af88b", "tag": "%VERSION%",
"hash": "d59f06c24339f223de4ec2afeba1c67b5835a0f350a1ffa86242a72fc3e616a6b8b21798355428d4200c75287308b66634619ffa0b52ba5bd74cc01772ea1a8a", "hash": "c4ab814c20fbad7e3f0ae169125a4988a2795631194703251481dc36b18da65c886c4faa9acd046b0a295005217b3689eb0126108a9ba5aac2ca909aae263c2f",
"version": "8", "version": "8",
"options": [ "git_version": "12.0.0"
"FMT_INSTALL OFF"
]
}, },
"lz4": { "lz4": {
"name": "lz4", "name": "lz4",
@ -40,16 +42,18 @@
"nlohmann": { "nlohmann": {
"package": "nlohmann_json", "package": "nlohmann_json",
"repo": "nlohmann/json", "repo": "nlohmann/json",
"sha": "55f93686c0", "tag": "v%VERSION%",
"hash": "b739749b066800e21154506ea150d2c5cbce8a45344177f46f884547a1399d26753166fd0df8135269ce28cf223552b1b65cd625b88c844d54753f2434900486", "hash": "6cc1e86261f8fac21cc17a33da3b6b3c3cd5c116755651642af3c9e99bb3538fd42c1bd50397a77c8fb6821bc62d90e6b91bcdde77a78f58f2416c62fc53b97d",
"version": "3.8" "version": "3.8",
"git_version": "3.12.0"
}, },
"zlib": { "zlib": {
"package": "ZLIB", "package": "ZLIB",
"repo": "madler/zlib", "repo": "madler/zlib",
"sha": "51b7f2abda", "tag": "v%VERSION%",
"hash": "16eaf1f3752489d12fd9ce30f7b5f7cbd5cb8ff53d617005a9847ae72d937f65e01e68be747f62d7ac19fd0c9aeba9956e60f16d6b465c5fdc2f3d08b4db2e6c", "hash": "8c9642495bafd6fad4ab9fb67f09b268c69ff9af0f4f20cf15dfc18852ff1f312bd8ca41de761b3f8d8e90e77d79f2ccacd3d4c5b19e475ecf09d021fdfe9088",
"version": "1.2", "version": "1.2",
"git_version": "1.3.1",
"options": [ "options": [
"ZLIB_BUILD_SHARED OFF", "ZLIB_BUILD_SHARED OFF",
"ZLIB_INSTALL OFF" "ZLIB_INSTALL OFF"
@ -57,8 +61,8 @@
}, },
"zstd": { "zstd": {
"repo": "facebook/zstd", "repo": "facebook/zstd",
"sha": "f8745da6ff", "sha": "b8d6101fba",
"hash": "3037007f990040fe32573b46f9bef8762fd5dbeeb07ffffcbfeba51ec98167edae39bb9c87f9299efcd61c4e467c5e84f7c19f0df7799bc1fc04864a278792ee", "hash": "a6c8e5272214fd3e65e03ae4fc375f452bd2f646623886664ee23e239e35751cfc842db4d34a84a8039d89fc8f76556121f2a4ae350d017bdff5e22150f9c3de",
"version": "1.5", "version": "1.5",
"source_subdir": "build/cmake", "source_subdir": "build/cmake",
"find_args": "MODULE", "find_args": "MODULE",
@ -66,20 +70,6 @@
"ZSTD_BUILD_SHARED OFF" "ZSTD_BUILD_SHARED OFF"
] ]
}, },
"catch2": {
"package": "Catch2",
"repo": "catchorg/Catch2",
"sha": "644821ce28",
"hash": "f8795f98acf2c02c0db8e734cc866d5caebab4b4a306e93598b97cb3c0c728dafe8283dce27ffe8d42460e5ae7302f3f32e7e274a7f991b73511ac88eef21b1f",
"version": "3.0.1"
},
"enet": {
"repo": "lsalzman/enet",
"sha": "2662c0de09",
"hash": "3de1beb4fa3d6b1e03eda8dd1e7580694f854af3ed3975dcdabfdcdf76b97f322b9734d35ea7f185855bb490d957842b938b26da4dd2dfded509390f8d2794dd",
"version": "1.3",
"find_args": "MODULE"
},
"opus": { "opus": {
"package": "Opus", "package": "Opus",
"repo": "crueter/opus", "repo": "crueter/opus",
@ -91,101 +81,16 @@
"OPUS_PRESUME_NEON ON" "OPUS_PRESUME_NEON ON"
] ]
}, },
"vulkan-utility-headers": {
"package": "VulkanUtilityLibraries",
"repo": "scripts/VulkanUtilityHeaders",
"tag": "1.4.326",
"artifact": "VulkanUtilityHeaders.tar.zst",
"git_host": "git.crueter.xyz",
"hash": "5924629755cb1605c4aa4eee20ef7957a9dd8d61e4df548be656d98054f2730c4109693c1bd35811f401f4705d2ccff9fc849be32b0d8480bc3f73541a5e0964"
},
"spirv-tools": {
"package": "SPIRV-Tools",
"repo": "KhronosGroup/SPIRV-Tools",
"sha": "40eb301f32",
"hash": "58d0fb1047d69373cf24c73e6f78c73a72a6cca3b4df1d9f083b9dcc0962745ef154abf3dbe9b3623b835be20c6ec769431cf11733349f45e7568b3525f707aa",
"find_args": "MODULE",
"options": [
"SPIRV_SKIP_EXECUTABLES ON"
]
},
"spirv-headers": {
"package": "SPIRV-Headers",
"repo": "KhronosGroup/SPIRV-Headers",
"sha": "4e209d3d7e",
"hash": "f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4",
"options": [
"SPIRV_WERROR OFF"
]
},
"mbedtls": {
"package": "MbedTLS",
"repo": "Mbed-TLS/mbedtls",
"tag": "mbedtls-%VERSION%",
"hash": "6671fb8fcaa832e5b115dfdce8f78baa6a4aea71f5c89a640583634cdee27aefe3bf4be075744da91f7c3ae5ea4e0c765c8fc3937b5cfd9ea73d87ef496524da",
"version": "3",
"git_version": "3.6.4",
"artifact": "%TAG%.tar.bz2"
},
"cubeb": {
"repo": "mozilla/cubeb",
"sha": "fa02160712",
"hash": "82d808356752e4064de48c8fecbe7856715ade1e76b53937116bf07129fc1cc5b3de5e4b408de3cd000187ba8dc32ca4109661cb7e0355a52e54bd81b9be1c61",
"find_args": "CONFIG",
"options": [
"USE_SANITIZERS OFF",
"BUILD_TESTS OFF",
"BUILD_TOOLS OFF",
"BUNDLE_SPEEX ON"
]
},
"boost_headers": { "boost_headers": {
"repo": "boostorg/headers", "repo": "boostorg/headers",
"sha": "95930ca8f5", "sha": "95930ca8f5",
"hash": "d1dece16f3b209109de02123c537bfe1adf07a62b16c166367e7e5d62e0f7c323bf804c89b3192dd6871bc58a9d879d25a1cc3f7b9da0e497cf266f165816e2a", "hash": "d1dece16f3b209109de02123c537bfe1adf07a62b16c166367e7e5d62e0f7c323bf804c89b3192dd6871bc58a9d879d25a1cc3f7b9da0e497cf266f165816e2a",
"bundled": true "bundled": true
}, },
"discord-rpc": {
"repo": "eden-emulator/discord-rpc",
"sha": "1cf7772bb6",
"hash": "e9b35e6f2c075823257bcd59f06fe7bb2ccce1976f44818d2e28810435ef79c712a3c4f20f40da41f691342a4058cf86b078eb7f9d9e4dae83c0547c21ec4f97"
},
"simpleini": {
"package": "SimpleIni",
"repo": "brofield/simpleini",
"sha": "09c21bda1d",
"hash": "99779ca9b6e040d36558cadf484f9ffdab5b47bcc8fc72e4d33639d1d60c0ceb4410d335ba445d72a4324e455167fd6769d99b459943aa135bec085dff2d4b7c",
"find_args": "MODULE"
},
"sdl2_generic": {
"package": "SDL2",
"repo": "libsdl-org/SDL",
"sha": "54772f345a",
"hash": "2a68a0e01c390043aa9d9df63d8a20a52076c88bb460ac4e0f33194ca7d9bc8fadbbcc04e7506872ac4b6354a73fbc267c036f82200da59465789b87c7d9e3a4",
"key": "generic",
"bundled": true
},
"sdl2_steamdeck": {
"package": "SDL2",
"repo": "libsdl-org/SDL",
"sha": "cc016b0046",
"hash": "34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b",
"key": "steamdeck",
"bundled": true
},
"sdl2": {
"ci": true,
"package": "SDL2",
"name": "SDL2",
"repo": "crueter-ci/SDL2",
"version": "2.32.8",
"min_version": "2.26.4",
"cmake_filename": "sdl2"
},
"llvm-mingw": { "llvm-mingw": {
"repo": "misc/llvm-mingw", "repo": "misc/llvm-mingw",
"git_host": "git.crueter.xyz", "git_host": "git.crueter.xyz",
"tag": "20250828", "tag": "%VERSION%",
"version": "20250828", "version": "20250828",
"artifact": "clang-rt-builtins.tar.zst", "artifact": "clang-rt-builtins.tar.zst",
"hash": "d902392caf94e84f223766e2cc51ca5fab6cae36ab8dc6ef9ef6a683ab1c483bfcfe291ef0bd38ab16a4ecc4078344fa8af72da2f225ab4c378dee23f6186181" "hash": "d902392caf94e84f223766e2cc51ca5fab6cae36ab8dc6ef9ef6a683ab1c483bfcfe291ef0bd38ab16a4ecc4078344fa8af72da2f225ab4c378dee23f6186181"

View file

@ -1,250 +0,0 @@
# CPM
CPM (CMake Package Manager) is the preferred method of managing dependencies within Eden.
Global Options:
- `YUZU_USE_CPM` is set by default on MSVC and Android. Other platforms should use this if certain "required" system dependencies (e.g. OpenSSL) are broken or missing
* If this is `OFF`, required system dependencies will be searched via `find_package`, although certain externals use CPM regardless.
- `CPMUTIL_FORCE_SYSTEM` (default `OFF`): Require all CPM dependencies to use system packages. NOT RECOMMENDED!
* Many packages, e.g. mcl, sirit, xbyak, discord-rpc, are not generally available as a system package.
* You may optionally override these (see CPMUtil section)
- `CPMUTIL_FORCE_BUNDLED` (default `ON` on MSVC and Android, `OFF` elsewhere): Require all CPM dependencies to use bundled packages.
## CPMUtil
CPMUtil is a wrapper around CPM that aims to reduce boilerplate and add useful utility functions to make dependency management a piece of cake.
### AddPackage
`AddPackage` is the core of the CPMUtil wrapper, and is generally the lowest level you will need to go when dealing with dependencies.
**Identification/Fetching**
- `NAME` (required): The package name (must be the same as the `find_package` name if applicable)
- `VERSION`: The minimum version of this package that can be used on the system
- `GIT_VERSION`: The "version" found within git
- `URL`: The URL to fetch.
- `REPO`: The GitHub repo to use (`owner/repo`).
* Only GitHub is supported for now, though other platforms will see support at some point
- `TAG`: The tag to fetch, if applicable.
- `ARTIFACT`: The name of the artifact, if applicable.
- `SHA`: Commit sha to fetch, if applicable.
- `BRANCH`: Branch to fetch, if applicable.
The following configurations are supported, in descending order of precedence:
- `URL`: Bare URL download, useful for custom artifacts
* If this is set, `GIT_URL` or `REPO` should be set to allow the dependency viewer to link to the project's Git repository.
* If this is NOT set, `REPO` must be defined.
- `REPO + TAG + ARTIFACT`: GitHub release artifact
* The final download URL will be `https://github.com/${REPO}/releases/download/${TAG}/${ARTIFACT}`
* Useful for prebuilt libraries and prefetched archives
- `REPO + TAG`: GitHub tag archive
* The final download URL will be `https://github.com/${REPO}/archive/refs/tags/${TAG}.tar.gz`
* Useful for pinning to a specific tag, better for build identification
- `REPO + SHA`: GitHub commit archive
* The final download URL will be `https://github.com/${REPO}/archive/${SHA}.zip`
* Useful for pinning to a specific commit
- `REPO + BRANCH`: GitHub branch archive
* The final download URL will be `https://github.com/${REPO}/archive/refs/heads/${BRANCH}.zip`
* Generally not recommended unless the branch is frozen
- `REPO`: GitHub master archive
* The final download URL will be `https://github.com/${REPO}/archive/refs/heads/master.zip`
* Generally not recommended unless the project is dead
**Hashing**
Hashing is used for verifying downloads. It's highly recommended to use these.
- `HASH_ALGO` (default `SHA512`): Hash algorithm to use
Hashing strategies, descending order of precedence:
- `HASH`: Bare hash verification, useful for static downloads e.g. commit archives
- `HASH_SUFFIX`: Download the hash as `${DOWNLOAD_URL}.${HASH_SUFFIX}`
* The downloaded hash *must* match the hash algorithm and contain nothing but the hash; no filenames or extra content.
- `HASH_URL`: Download the hash from a separate URL
**Additional Options**
- `KEY`: Custom cache key to use (stored as `.cache/cpm/${packagename_lower}/${key}`)
* Default is based on, in descending order of precedence:
- First 4 characters of the sha
- `GIT_VERSION`
- Tag
- `VERSION`
- Otherwise, CPM defaults will be used. This is not recommended as it doesn't produce reproducible caches
- `DOWNLOAD_ONLY`: Whether or not to configure the downloaded package via CMake
* Useful to turn `OFF` if the project doesn't use CMake
- `SOURCE_SUBDIR`: Subdirectory of the project containing a CMakeLists.txt file
- `FIND_PACKAGE_ARGUMENTS`: Arguments to pass to the `find_package` call
- `BUNDLED_PACKAGE`: Set to `ON` to force the usage of a bundled package
- `OPTIONS`: Options to pass to the configuration of the package
- `PATCHES`: Patches to apply to the package, stored in `.patch/${packagename_lower}/0001-patch-name.patch` and so on
- Other arguments can be passed to CPM as well
**Extra Variables**
For each added package, users may additionally force usage of the system/bundled package.
- `${package}_FORCE_SYSTEM`: Require the package to be installed on the system
- `${package}_FORCE_BUNDLED`: Force the package to be fetched and use the bundled version
**Bundled/System Switching**
Descending order of precedence:
- If `${package}_FORCE_SYSTEM` is true, requires the package to be on the system
- If `${package}_FORCE_BUNDLED` is true, forcefully uses the bundled package
- If `CPMUTIL_FORCE_SYSTEM` is true, requires the package to be on the system
- If `CPMUTIL_FORCE_BUNDLED` is true, forcefully uses the bundled package
- If the `BUNDLED_PACKAGE` argument is true, forcefully uses the bundled package
- Otherwise, CPM will search for the package first, and if not found, will use the bundled package
**Identification**
All dependencies must be identifiable in some way for usage in the dependency viewer. Lists are provided in descending order of precedence.
URLs:
- `GIT_URL`
- `REPO` as a GitHub repository
- `URL`
Versions (bundled):
- `SHA`
- `GIT_VERSION`
- `VERSION`
- `TAG`
- "unknown"
If the package is a system package, AddPackage will attempt to determine the package version and append ` (system)` to the identifier. Otherwise, it will be marked as `unknown (system)`
### AddCIPackage
Adds a package that follows crueter's CI repository spec.
- `VERSION` (required): The version to get (the tag will be `v${VERSION}`)
- `NAME` (required): Name used within the artifacts
- `REPO` (required): CI repository, e.g. `crueter-ci/OpenSSL`
- `PACKAGE` (required): `find_package` package name
- `EXTENSION`: Artifact extension (default `tar.zst`)
- `MIN_VERSION`: Minimum version for `find_package`. Only used if platform does not support this package as a bundled artifact
- `DISABLED_PLATFORMS`: List of platforms that lack artifacts for this package. One of:
* `windows-amd64`
* `windows-arm64`
* `android`
* `solaris`
* `freebsd`
* `linux`
* `linux-aarch64`
- `CMAKE_FILENAME`: Custom CMake filename, relative to the package root (default `${PACKAGE_ROOT}/${NAME}.cmake`)
### AddJsonPackage
This is the recommended method of usage for CPMUtil. In each directory that utilizes `CPMUtil`, there must be a `cpmfile.json` that defines dependencies in a similar manner to the individual calls.
The cpmfile is an object of objects, with each sub-object being named according to the package's identifier, e.g. `openssl`, which can then be fetched with `AddJsonPackage(<identifier>)`. Options are designed to map closely to the argument names, and are always strings unless otherwise specified.
- `package` -> `NAME` (`PACKAGE` for CI), defaults to the object key
- `repo` -> `REPO`
- `version` -> `VERSION`
- `ci` (bool)
If `ci` is `false`:
- `hash` -> `HASH`
- `sha` -> `SHA`
- `tag` -> `TAG`
- `artifact` -> `ARTIFACT`
- `git_version` -> `GIT_VERSION`
- `source_subdir` -> `SOURCE_SUBDIR`
- `bundled` -> `BUNDLED_PACKAGE`
- `find_args` -> `FIND_PACKAGE_ARGUMENTS`
- `patches` -> `PATCHES` (array)
- `options` -> `OPTIONS` (array)
Other arguments aren't currently supported. If you wish to add them, see the `AddJsonPackage` function in `CMakeModules/CPMUtil.cmake`.
If `ci` is `true`:
- `name` -> `NAME`, defaults to the object key
- `extension` -> `EXTENSION`, defaults to `tar.zst`
- `min_version` -> `MIN_VERSION`
- `cmake_filename` -> `CMAKE_FILENAME`
- `extension` -> `EXTENSION`
### Examples
In order: OpenSSL CI, Boost (tag + artifact), Opus (options + find_args), discord-rpc (sha + options + patches)
```json
{
"openssl": {
"ci": true,
"package": "OpenSSL",
"name": "openssl",
"repo": "crueter-ci/OpenSSL",
"version": "3.5.2",
"min_version": "1.1.1"
},
"boost": {
"package": "Boost",
"repo": "boostorg/boost",
"tag": "boost-1.88.0",
"artifact": "boost-1.88.0-cmake.7z",
"hash": "e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01",
"git_version": "1.88.0",
"version": "1.57"
},
"opus": {
"package": "Opus",
"repo": "xiph/opus",
"sha": "5ded705cf4",
"hash": "0dc89e58ddda1f3bc6a7037963994770c5806c10e66f5cc55c59286fc76d0544fe4eca7626772b888fd719f434bc8a92f792bdb350c807968b2ac14cfc04b203",
"version": "1.3",
"find_args": "MODULE",
"options": [
"OPUS_BUILD_TESTING OFF",
"OPUS_BUILD_PROGRAMS OFF",
"OPUS_INSTALL_PKG_CONFIG_MODULE OFF",
"OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF"
]
},
"discord-rpc": {
"repo": "discord/discord-rpc",
"sha": "963aa9f3e5",
"hash": "386e1344e9a666d730f2d335ee3aef1fd05b1039febefd51aa751b705009cc764411397f3ca08dffd46205c72f75b235c870c737b2091a4ed0c3b061f5919bde",
"options": [
"BUILD_EXAMPLES OFF"
],
"patches": [
"0001-cmake-version.patch",
"0002-no-clang-format.patch",
"0003-fix-cpp17.patch"
]
},
}
```
### Inclusion
To include CPMUtil:
```cmake
include(CPMUtil)
```
## Prefetching
- To prefetch a CPM dependency (requires cpmfile):
* `tools/cpm-fetch.sh <packages>`
- To prefetch all CPM dependencies:
* `tools/cpm-fetch-all.sh`
Currently, `cpm-fetch.sh` defines the following directories for cpmfiles (max depth of 2, so subdirs are caught as well):
`externals src/qt_common src/dynarmic .`
Whenever you add a new cpmfile, update the script accordingly

14
docs/CPMUtil.md Normal file
View file

@ -0,0 +1,14 @@
# CPMUtil
CPMUtil is a wrapper around CPM that aims to reduce boilerplate and add useful utility functions to make dependency management a piece of cake.
See more in [its repository](https://git.crueter.xyz/CMake/CPMUtil)
Eden-specific options:
- `YUZU_USE_CPM` is set by default on MSVC and Android. Other platforms should use this if certain "required" system dependencies (e.g. OpenSSL) are broken or missing
* If this is `OFF`, required system dependencies will be searched via `find_package`, although most externals use CPM regardless.
## Tooling
See the [tooling docs](../tools/cpm)

View file

@ -63,6 +63,7 @@ Certain other dependencies will be fetched by CPM regardless. System packages *c
* [VulkanMemoryAllocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) * [VulkanMemoryAllocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator)
* [sirit](https://github.com/eden-emulator/sirit) * [sirit](https://github.com/eden-emulator/sirit)
* [httplib](https://github.com/yhirose/cpp-httplib) - if `ENABLE_QT_UPDATE_CHECKER` or `ENABLE_WEB_SERVICE` are on * [httplib](https://github.com/yhirose/cpp-httplib) - if `ENABLE_QT_UPDATE_CHECKER` or `ENABLE_WEB_SERVICE` are on
- This package is known to be broken on the AUR.
* [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on * [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on
* [unordered-dense](https://github.com/martinus/unordered_dense) * [unordered-dense](https://github.com/martinus/unordered_dense)
* [mcl](https://github.com/azahar-emu/mcl) - subject to removal * [mcl](https://github.com/azahar-emu/mcl) - subject to removal
@ -194,7 +195,7 @@ Run the usual update + install of essential toolings: `sudo pkg update && sudo p
- **gcc**: `sudo pkg install developer/gcc-14`. - **gcc**: `sudo pkg install developer/gcc-14`.
- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. - **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`.
Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`. Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/lz4 libusb-1 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`.
</details> </details>
<details> <details>

View file

@ -31,7 +31,7 @@ Notes:
* Currently, build fails without this * Currently, build fails without this
- `YUZU_USE_FASTER_LD` (ON) Check if a faster linker is available - `YUZU_USE_FASTER_LD` (ON) Check if a faster linker is available
* Only available on UNIX * Only available on UNIX
- `YUZU_APPLE_USE_BUNDLED_MONTENVK` (ON, macOS only) Download bundled MoltenVK lib) - `YUZU_USE_BUNDLED_MOLTENVK` (ON, macOS only) Download bundled MoltenVK lib)
- `YUZU_TZDB_PATH` (string) Path to a pre-downloaded timezone database (useful for nixOS) - `YUZU_TZDB_PATH` (string) Path to a pre-downloaded timezone database (useful for nixOS)
- `ENABLE_OPENSSL` (ON for Linux and *BSD) Enable OpenSSL backend for the ssl service - `ENABLE_OPENSSL` (ON for Linux and *BSD) Enable OpenSSL backend for the ssl service
* Always enabled if the web service is enabled * Always enabled if the web service is enabled

View file

@ -5,6 +5,6 @@ This contains documentation created by developers. This contains build instructi
- **[General Build Instructions](Build.md)** - **[General Build Instructions](Build.md)**
- **[Development Guidelines](Development.md)** - **[Development Guidelines](Development.md)**
- **[Dependencies](Deps.md)** - **[Dependencies](Deps.md)**
- **[CPM - CMake Package Manager](CPM.md)** - **[CPM - CMake Package Manager](CPMUtil.md)**
- **[Platform-Specific Caveats](Caveats.md)** - **[Platform-Specific Caveats](Caveats.md)**
- **[User Directory Handling](User.md)** - **[User Handbook](User.md)**

View file

@ -27,6 +27,7 @@ The following are not valid reasons to sign up:
* To download and use Eden, see our [Releases page](https://github.com/eden-emulator/Releases/releases)! * To download and use Eden, see our [Releases page](https://github.com/eden-emulator/Releases/releases)!
- I want to see the source code. - I want to see the source code.
* To see Eden's source code, go [here](https://git.eden-emu.dev/eden-emu/eden). * To see Eden's source code, go [here](https://git.eden-emu.dev/eden-emu/eden).
## Other Information ## Other Information
Requests that appear suspicious, automated, OR blank will generally be automatically filtered. In cases of suspicion, or any of the invalid reasons listed above, you may receive an email back asking for clarification. Requests that appear suspicious, automated, OR blank will generally be automatically filtered. In cases of suspicion, or any of the invalid reasons listed above, you may receive an email back asking for clarification.

View file

@ -1,11 +1,10 @@
# User configuration # User Handbook
## Configuration directories The "FAQ".
Eden will store configuration in the following directories: This handbook is primarily aimed at the end-user - baking useful knowledge for enhancing their emulation experience.
- **Windows**: `%AppData%\Roaming`. - **[The Basics](user/Basics.md)**
- **Android**: Data is stored internally. - **[Audio](user/Audio.md)**
- **Linux, macOS, FreeBSD, Solaris, OpenBSD**: `$XDG_DATA_HOME`, `$XDG_CACHE_HOME`, `$XDG_CONFIG_HOME`. - **[Graphics](user/Graphics.md)**
- **[Platforms and Architectures](user/Architectures.md)**
If a `user` directory is present in the current working directory, that will override all global configuration directories and the emulator will use that instead.

130
docs/user/Architectures.md Normal file
View file

@ -0,0 +1,130 @@
# User Handbook - Architectures and Platforms
Notes and caveats for different architectures and platforms.
# Architectures
Eden is primarily designed to run on amd64 (x86_64--Intel/AMD 64-bit) and aarch64 (arm64--ARM 64-bit) CPUs. Each architecture tends to have their own quirks and fun stuff; this page serves as a reference for these quirks.
## amd64
AMD64, aka x86_64, is the most tested and supported architecture for desktop targets. Android is entirely unsupported.
### Caveats
AMD64 systems are almost always limited by the CPU. For example, a Zen 5/RX 6600 system will often hit max CPU usage before the GPU ever reaches 70% usage, with minimal exceptions (that tend to pop up only at >200fps). JIT is slow!
Computers on Linux will almost always run Eden strictly better than an equivalent machine on Windows. This is largely due to the way the Linux kernel handles memory management (and the lack of Microsoft spyware).
Intel Macs are believed to be supported, but no CI is provided for them. Performance will likely be awful on all but the highest-end iMacs and Pro-level Macs, and the MoltenVK requirement generally means Vulkan compatibility will suffer.
## aarch64
ARM64, aka aarch64, is the only supported architecture for Android, with limited experimental support available on Linux, Windows, and macOS.
### Caveats
NCE (Native Code Execution) is currently only available on Android and (experimentally) Linux. Support for macOS is in the works, but Windows is extremely unlikely to ever happen (if you want it--submit patches!). Generally, if NCE is available, you should pretty much always use it due to the massive performance hit JIT has.
When NCE is enabled, do note that the GPU will almost always be the limiting factor. This is especially the case for Android, as well as desktops that lack dedicated GPUs; Adreno, Mali, PowerVR, etc. GPUs are generally significantly weaker relative to their respective CPUs.
Windows/arm64 is *very* experimental and is unlikely to work at all. Support and testing is in the works.
## riscv64
RISC-V, aka riscv64, is sparsely tested, but preliminary tests from developers have reported at least partial support on Milk-V's Fedora/riscv64 Linux distribution. Performance, Vulkan support, compatibility, and build system caveats are largely unknown for the time being.
### Caveats
Windows/riscv64 doesn't exist, and may never (until corporate greed no longer consumes Microsoft).
Android/riscv64 is interesting. While support for it may be added if and when RISC-V phones/handhelds ever go mainstream, arm64 devices will always be preferred due to NCE.
Only Fedora/riscv64 has been tested, but in theory, every riscv64 distribution that has *at least* the standard build tools, Qt, FFmpeg, and SDL2 should work.
## Other
Other architectures, such as SPARC, MIPS, PowerPC, Loong, and all 32-bit architectures are completely unsupported, as there is no JIT backend or emitter thereof. If you want support for it--submit patches!
IA-64 (Itanium) support is completely unknown. Existing amd64 packages will not run on IA-64 (assuming you can even find a supported Windows/Linux distribution)
# Platforms
The vast majority of Eden's testing is done on Windows, Linux, and Android. However, first-class support is also provided for:
- FreeBSD
- OpenBSD
- OpenIndiana (Solaris)
- macOS
## Linux
While all modern Linux distributions are supported (Fedora >40, Ubuntu >24.04, Debian >12, Arch, Gentoo, etc.), the vast majority of testing and development for Linux is on Arch and Gentoo. Most major build system changes are tested on Gentoo first and foremost, so if builds fail on any modern distribution no matter what you do, it's likely a bug and should be reported.
Intel and Nvidia GPU support is limited. AMD (RADV) drivers receive first-class testing and are known to provide the most stable Eden experience possible.
## Windows
Windows 10 and 11 are supported. Support for Windows 8.x is unknown, and Windows 7 support is unlikely to ever be added.
In order to run Eden, you will probably need to install the [Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170).
Neither AMD nor Nvidia drivers work nearly as well as Linux's RADV drivers. Compatibility is still largely the same, but performance and some hard-to-run games may suffer compared to Linux.
## Android
A cooler is always recommended. Phone SoCs tend to get very hot, especially those manufactured with the Samsung process or those lacking in power.
Adreno 6xx and 7xx GPUs with Turnip drivers will always have the best compatibility. "Stock" (system) drivers will have better performance on Adreno, but compatibility will suffer. Better support for stock drivers (including Adreno 8xx) is in the works.
Android 16 is always recommended, as it brought major improvements to Vulkan requirements and compatibility, *plus* significant performance gains. Some users reported an over 50% performance gain on some Pixel phones after updating.
Mali, PowerVR, Xclipse, and other GPU vendors generally lack in performance and compatibility. Notably:
- No PowerVR GPUs *except* the DXT-48-1536 are known to work with Eden at all.
- No Xclipse GPUs *except* the very latest (e.g. Xclipse 950) are known to work with Eden at all.
- Mali has especially bad performance, though the Mali-G715 (Tensor G4) and Immortalis-G925 are known to generally run surprisingly well, especially on Android 16.
- The status of all other GPU vendors is unknown. As long as they support Vulkan, they theoretically can run Eden.
- Note that these GPUs generally don't play well with driver injection. If you choose to inject custom drivers via a rooted system (Panfrost, RADV, etc), you may see good results.
Qualcomm Snapdragon SoCs are generally the most well supported.
- Google Tensor chips have pretty terrible performance, but even the G1 has been proven to be able to run some games well on the Pixel 6 Pro.
* The Tensor G4 is the best-supported at the time. How the G5 currently fares is unknown, but on paper, it should do about as well as a Snapdragon 8 Gen 2 with stock drivers.
- Samsung Exynos chips made before 2022 are not supported.
- MediaTek Dimensity chips are extremely weak and most before mid-2023 don't work at all.
* This means that most budget phones won't work, as they tend to use old MediaTek SoCs.
* Generally, if your phone doesn't cost *at least* as much as a Switch itself, it will not *emulate* the Switch very well.
- Snapdragon 865 and other old-ish SoCs may benefit from the Legacy build. These will reduce performance but *should* drastically improve compatibility.
- If you're not sure how powerful your SoC is, check [NanoReview](https://nanoreview.net/en/soc-compare) - e.g. [Tensor G5](https://archive.is/ylC4Z).
* A good base to compare to is the Snapdragon 865--e.g. [Tensor vs SD865](https://archive.is/M1P58)
* Some benchmarks may be misleading due to thermal throttling OR RAM requirements.
- For example, a Pixel 6a (Tensor G1) performs about 1/3 as well as an 865 due to its lack of RAM and poor thermals.
* Remember--always use a cooler if you can, and you MUST have *at least* 8GB of RAM!
- If you're not sure what SoC you have, check [GSMArena](https://www.gsmarena.com) - e.g. [Pixel 9 Pro](https://archive.ph/91VhA)
Custom ROMs are recommended, *as long as* you know what you're doing.
- For most devices, [LineageOS](https://lineageos.org/) is preferred.
- [CalyxOS](https://calyxos.org/) is available as well.
- For Google Pixel devices ONLY... and [soon another OEM](https://archive.ph/cPpMd)... [GrapheneOS](https://grapheneos.org/) is highly recommended.
* As of October 5, 2025, the Pixel 10 line is unsupported, however, [it will be](https://archive.is/viAUl) in the very near future!
* Keep checking the [FAQ page](https://grapheneos.org/faq#supported-devices) for news.
- Custom ROMs will likely be exclusively recommended in the future due to Google's upcoming [draconian](https://archive.is/hGIjZ), [anti-privacy, anti-user](https://archive.is/mc1CJ) verification requirements.
Eden is currently unavailable on F-Droid or the Play Store. Check back occasionally.
## macOS
macOS is relatively stable, with only the occasional crash and bug. Compatibility may suffer due to the MoltenVK layer, however.
Do note that building the GUI version with Qt versions higher than 6.7.3 will cause mysterious bugs, Vulkan errors, and crashes, alongside the cool feature of freezing the entire system UI randomly; we recommend you build with 6.7.3 (via aqtinstall) or earlier as the CI does.
## *BSD, Solaris
BSD and Solaris distributions tend to lag behind Linux in terms of Vulkan and other library compatibility. For example, OpenIndiana (Solaris) does not properly package Qt, meaning the recommended method of usage is to use `eden-cli` only for now. Solaris also generally works better with OpenGL.
AMD GPU support on these platforms is limited or nonexistent.
## VMs
Eden "can" run in a VM, but only with the software renderer, *unless* you create a hardware-accelerated KVM with GPU passthrough. If you *really* want to do this and don't have a spare GPU lying around, RX 570 and 580 GPUs are extremely cheap on the black market and are powerful enough to run most commercial games at 60fps.
Some users and developers have had success using a pure OpenGL-accelerated KVM on Linux with a Windows VM, but this is ridiculously tedious to set up. You're probably better off dual-booting.

3
docs/user/Audio.md Normal file
View file

@ -0,0 +1,3 @@
# User Handbook - Audio
`PULSE_SERVER=none` forces cubeb to use ALSA.

57
docs/user/Basics.md Normal file
View file

@ -0,0 +1,57 @@
# User Handbook - The Basics
## Introduction
Eden is a very complicated piece of software, and as such there are many knobs and toggles that can be configured. Most of these are invisible to normal users, however power users may be able to leverage them to their advantage.
This handbook primarily describes such knobs and toggles. Normal configuration options are described within the emulator itself and will not be covered in detail.
## Requirements
The emulator is very demanding on hardware, and as such requires a decent mid-range computer/cellphone.
See [the requirements page](https://archive.is/sv83h) for recommended and minimum specs.
The CPU must support FMA for an optimal gameplay experience. The GPU needs to support OpenGL 4.6 ([compatibility list](https://opengl.gpuinfo.org/)), or Vulkan 1.1 ([compatibility list](https://vulkan.gpuinfo.org/)).
If your GPU doesn't support or is just behind by a minor version, see Mesa environment variables below (*nix only).
## User configuration
### Configuration directories
Eden will store configuration files in the following directories:
- **Windows**: `%AppData%\Roaming`.
- **Android**: Data is stored internally.
- **Linux, macOS, FreeBSD, Solaris, OpenBSD**: `$XDG_DATA_HOME`, `$XDG_CACHE_HOME`, `$XDG_CONFIG_HOME`.
If a `user` directory is present in the current working directory, that will override all global configuration directories and the emulator will use that instead.
### Environment variables
Throughout the handbook, environment variables are mentioned. These are often either global (system wide) or local (set in a script, bound only to the current session). It's heavily recommended to use them in a local context only, as this allows you to rollback changes easily (if for example, there are regressions setting them).
The recommended way is to create a `.bat` file alongside the emulator `.exe`; contents of which could resemble something like:
```bat
set "__GL_THREADED_OPTIMIZATIONS=1"
set "SOME_OTHER_VAR=1"
eden.exe
```
Android doesn't have a convenient way to set environment variables.
For other platforms, the recommended method is using a shell script:
```sh
export __GL_THREADED_OPTIMIZATIONS=1
export SOME_OTHER_VAR=1
./eden
```
Then just running `chmod +x script.sh && source script.sh`.
## Compatibility list
Eden doesn't mantain a compatibility list. However, [EmuReady](https://www.emuready.com/) has a more fine-grained compatibility information for multiple emulators/forks as well.

62
docs/user/Graphics.md Normal file
View file

@ -0,0 +1,62 @@
# User Handbook - Graphics
## Visual Enhancements
### Anti-aliasing
Enhancements aimed at removing jagged lines/sharp edges and/or masking artifacts.
- **No AA**: Default, provides no anti-aliasing.
- **FXAA**: Fast Anti-Aliasing, an implementation as described on [this blog post](https://web.archive.org/web/20110831051323/http://timothylottes.blogspot.com/2011/03/nvidia-fxaa.html). Generally fast but with some innocuos artifacts.
- **SMAA**: Subpixel Morphological Anti-Aliasing, an implementation as described on [this article](https://web.archive.org/web/20250000000000*/https://www.iryoku.com/smaa/).
### Filters
Various graphical filters exist - each of them aimed at a specific target/image quality preset.
- **Nearest**: Provides no filtering - useful for debugging.
- **Pros**: Fast, works in any hardware.
- **Cons**: Less image quality.
- **Bilinear**: Provides the hardware default filtering of the Tegra X1.
- **Pros**: Fast with acceptable image quality.
- **Bicubic**: Provides a bicubic interpolation using a Catmull-Rom (or hardware-accelerated) implementation.
- **Pros**: Better image quality with more rounded edges.
- **Zero-Tangent, B-Spline, Mitchell**: Provides bicubic interpolation using the respective matrix weights. They're normally not hardware accelerated unless the device supports the `VK_QCOM_filter_cubic_weights` extension. The matrix weights are those matching [the specification itself](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#VkSamplerCubicWeightsCreateInfoQCOM).
- **Pros/Cons**: Each of them is a variation of the Bicubic interpolation model with different weights, they offer different methods to fix some artifacts present in Catmull-Rom.
- **Spline-1**: Bicubic interpolation (similar to Mitchell) but with a faster texel fetch method. Generally less blurry than bicubic.
- **Pros**: Faster than bicubic even without hardware accelerated bicubic.
- **Gaussian**: Whole-area blur, an applied gaussian blur is done to the entire frame.
- **Pros**: Less edge artifacts.
- **Cons**: Slow and sometimes blurry.
- **Lanczos**: An implementation using `a = 3` (49 texel fetches). Provides sharper edges but blurrier artifacts.
- **Pros**: Less edge artifacts and less blurry than gaussian.
- **Cons**: Slow.
- **ScaleForce**: Experimental texture upscale method, see [ScaleFish](https://github.com/BreadFish64/ScaleFish).
- **Pros**: Relatively fast.
- **FSR**: Uses AMD FidelityFX Super Resolution to enhance image quality.
- **Pros**: Great for upscaling, and offers sharper visual quality.
- **Cons**: Somewhat slow, and may be offputtingly sharp.
- **Area**: Area interpolation (high kernel count).
- **Pros**: Best for downscaling (internal resolution > display resolution).
- **Cons**: Costly and slow.
- **MMPX**: Nearest-neighbour filter aimed at providing higher pixel-art quality.
- **Pros**: Offers decent pixel-art upscaling.
- **Cons**: Only works for pixel-art.
### External
While stock shaders offer a basic subset of options for most users, programs such as [ReShade](https://github.com/crosire/reshade) offer a more flexible experience. In addition to that users can also seek out modifications (mods) for enhancing visual experience (60 FPS mods, HDR, etc).
## Driver specifics
### Mesa environment variable hacks
The software requires a certain version of Vulkan and a certain version of OpenGL to work - otherwise it will refuse to load, this can be easily bypassed by setting an environment variable: `MESA_GL_VERSION_OVERRIDE=4.6 MESA_GLSL_VERSION_OVERRIDE=460` (OpenGL) and `MESA_VK_VERSION_OVERRIDE=1.3` (Vulkan), for more information see [Environment variables for Mesa](https://web.archive.org/web/20250000000000*/https://docs.mesa3d.org/envvars.html).
### NVIDIA OpenGL environment variables
Unstable multithreaded optimisations are offered by the stock proprietary NVIDIA driver on X11 platforms. Setting `__GL_THREADED_OPTIMIZATIONS` to `1` would enable such optimisations. This mainly benefits the OpenGL backend. For more information see [Environment Variables for X11 NVIDIA](https://web.archive.org/web/20250115162518/https://download.nvidia.com/XFree86/Linux-x86_64/435.17/README/openglenvvariables.html).
### swrast/LLVMpipe crashes under high load
The OpenGL backend would invoke behaviour that would result in swarst/LLVMpipe writing an invalid SSA IR (on old versions of Mesa), and then proceeding to crash. The solution is using a script found in [tools/llvmpipe-run.sh](../../tools/llvmpipe-run.sh).

View file

@ -39,6 +39,145 @@ if (ARCHITECTURE_arm64 OR DYNARMIC_TESTS)
AddJsonPackage(oaknut) AddJsonPackage(oaknut)
endif() endif()
# enet
AddJsonPackage(enet)
if (enet_ADDED)
target_include_directories(enet INTERFACE ${enet_SOURCE_DIR}/include)
endif()
if (NOT TARGET enet::enet)
add_library(enet::enet ALIAS enet)
endif()
# mbedtls
AddJsonPackage(mbedtls)
# VulkanUtilityHeaders - pulls in headers and utility libs
AddJsonPackage(vulkan-utility-headers)
# small hack
if (NOT VulkanUtilityLibraries_ADDED)
find_package(VulkanHeaders 1.3.274 REQUIRED)
endif()
# DiscordRPC
if (USE_DISCORD_PRESENCE)
if (ARCHITECTURE_arm64)
add_compile_definitions(RAPIDJSON_ENDIAN=RAPIDJSON_LITTLEENDIAN)
endif()
AddJsonPackage(discord-rpc)
if (DiscordRPC_ADDED)
target_include_directories(discord-rpc INTERFACE ${DiscordRPC_SOURCE_DIR}/include)
add_library(DiscordRPC::discord-rpc ALIAS discord-rpc)
endif()
endif()
# SimpleIni
AddJsonPackage(simpleini)
# Most linux distros don't package cubeb, so enable regardless of cpm settings
if(ENABLE_CUBEB)
AddJsonPackage(cubeb)
if (cubeb_ADDED)
if (NOT MSVC)
if (TARGET speex)
target_compile_options(speex PRIVATE -Wno-sign-compare)
endif()
set_target_properties(cubeb PROPERTIES COMPILE_OPTIONS "")
target_compile_options(cubeb INTERFACE
-Wno-implicit-const-int-float-conversion
-Wno-shadow
-Wno-missing-declarations
-Wno-return-type
-Wno-uninitialized
)
else()
target_compile_options(cubeb PRIVATE
/wd4456
/wd4458
)
endif()
endif()
if (NOT TARGET cubeb::cubeb)
add_library(cubeb::cubeb ALIAS cubeb)
endif()
endif()
# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the YUZU_find_package
if (ENABLE_SDL2)
if (YUZU_USE_EXTERNAL_SDL2)
message(STATUS "Using SDL2 from externals.")
if (NOT WIN32)
# Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers
# Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095)
# Yuzu-cmd also needs: Video (depends on Loadso/Dlopen)
# CPUinfo also required for SDL Audio, at least until 2.28.0 (see https://github.com/libsdl-org/SDL/issues/7809)
set(SDL_UNUSED_SUBSYSTEMS
File Filesystem
Locale Power Render)
foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT)
set(SDL_${_OPT} OFF)
endforeach()
set(HIDAPI ON)
endif()
if (APPLE)
set(SDL_FILE ON)
endif()
if ("${YUZU_SYSTEM_PROFILE}" STREQUAL "steamdeck")
set(SDL_PIPEWIRE OFF) # build errors out with this on
AddJsonPackage("sdl2_steamdeck")
else()
AddJsonPackage("sdl2_generic")
endif()
elseif (YUZU_USE_BUNDLED_SDL2)
message(STATUS "Using bundled SDL2")
AddJsonPackage(sdl2)
endif()
find_package(SDL2 2.26.4 REQUIRED)
endif()
# SPIRV Headers
AddJsonPackage(spirv-headers)
# Sirit
if (YUZU_USE_BUNDLED_SIRIT)
AddJsonPackage(sirit-ci)
else()
AddJsonPackage(sirit)
if(MSVC AND USE_CCACHE AND sirit_ADDED)
get_target_property(_opts sirit COMPILE_OPTIONS)
list(FILTER _opts EXCLUDE REGEX "/Zi")
list(APPEND _opts "/Z7")
set_target_properties(siritobj PROPERTIES COMPILE_OPTIONS "${_opts}")
elseif(MSVC AND CXX_CLANG)
target_compile_options(siritobj PRIVATE -Wno-error=unused-command-line-argument)
endif()
endif()
# SPIRV Tools
AddJsonPackage(spirv-tools)
if (SPIRV-Tools_ADDED)
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools-static)
target_link_libraries(SPIRV-Tools-static PRIVATE SPIRV-Tools-opt SPIRV-Tools-link)
endif()
# Catch2
if (YUZU_TESTS OR DYNARMIC_TESTS)
AddJsonPackage(catch2)
endif()
# getopt # getopt
if (MSVC) if (MSVC)
add_subdirectory(getopt) add_subdirectory(getopt)
@ -67,18 +206,6 @@ if (VulkanMemoryAllocator_ADDED)
endif() endif()
endif() endif()
# Sirit
AddJsonPackage(sirit)
if(MSVC AND USE_CCACHE AND sirit_ADDED)
get_target_property(_opts sirit COMPILE_OPTIONS)
list(FILTER _opts EXCLUDE REGEX "/Zi")
list(APPEND _opts "/Z7")
set_target_properties(sirit PROPERTIES COMPILE_OPTIONS "${_opts}")
elseif(MSVC AND CXX_CLANG)
target_compile_options(sirit PRIVATE -Wno-error=unused-command-line-argument)
endif()
# httplib # httplib
if (ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER) if (ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER)
AddJsonPackage(httplib) AddJsonPackage(httplib)

170
externals/cpmfile.json vendored
View file

@ -2,23 +2,34 @@
"vulkan-memory-allocator": { "vulkan-memory-allocator": {
"package": "VulkanMemoryAllocator", "package": "VulkanMemoryAllocator",
"repo": "GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator", "repo": "GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator",
"sha": "1076b348ab", "tag": "v%VERSION%",
"hash": "a46b44e4286d08cffda058e856c47f44c7fed3da55fe9555976eb3907fdcc20ead0b1860b0c38319cda01dbf9b1aa5d4b4038c7f1f8fbd97283d837fa9af9772", "hash": "deb5902ef8db0e329fbd5f3f4385eb0e26bdd9f14f3a2334823fb3fe18f36bc5d235d620d6e5f6fe3551ec3ea7038638899db8778c09f6d5c278f5ff95c3344b",
"find_args": "CONFIG" "find_args": "CONFIG",
"git_version": "3.3.0"
}, },
"sirit": { "sirit": {
"repo": "eden-emulator/sirit", "repo": "eden-emulator/sirit",
"sha": "db1f1e8ab5", "git_version": "1.0.2",
"hash": "73eb3a042848c63a10656545797e85f40d142009dfb7827384548a385e1e28e1ac72f42b25924ce530d58275f8638554281e884d72f9c7aaf4ed08690a414b05", "tag": "v%VERSION%",
"artifact": "sirit-source-%VERSION%.tar.zst",
"hash_suffix": "sha512sum",
"find_args": "CONFIG", "find_args": "CONFIG",
"options": [ "options": [
"SIRIT_USE_SYSTEM_SPIRV_HEADERS ON" "SIRIT_USE_SYSTEM_SPIRV_HEADERS ON"
] ]
}, },
"sirit-ci": {
"ci": true,
"package": "sirit",
"name": "sirit",
"repo": "eden-emulator/sirit",
"version": "1.0.2"
},
"httplib": { "httplib": {
"repo": "yhirose/cpp-httplib", "repo": "yhirose/cpp-httplib",
"sha": "a609330e4c", "tag": "v%VERSION%",
"hash": "dd3fd0572f8367d8549e1319fd98368b3e75801a293b0c3ac9b4adb806473a4506a484b3d389dc5bee5acc460cb90af7a20e5df705a1696b56496b30b9ce7ed2" "hash": "b364500f76e2ecb0fe21b032d831272e3f1dfeea71af74e325f8fc4ce9dcdb3c941b97a5b422bdeafb9facd058597b90f8bfc284fb9afe3c33fefa15dd5a010b",
"git_version": "0.26.0"
}, },
"cpp-jwt": { "cpp-jwt": {
"version": "1.4", "version": "1.4",
@ -33,22 +44,26 @@
"xbyak_sun": { "xbyak_sun": {
"package": "xbyak", "package": "xbyak",
"repo": "herumi/xbyak", "repo": "herumi/xbyak",
"sha": "9bb219333a", "tag": "v%VERSION%",
"hash": "303165d45c8c19387ec49d9fda7d7a4e0d86d4c0153898c23f25ce2d58ece567f44c0bbbfe348239b933edb6e1a1e34f4bc1c0ab3a285bee5da0e548879387b0", "hash": "e84992c65ad62c577e2746ec5180132fd2875166d1e6b1521a0ff619787e1645792fe5f6a858fe94ed66f297912b6a6b89a509b5d5f5e81a2db1dd7e6790b1f5",
"bundled": true "bundled": true,
"git_version": "7.30"
}, },
"xbyak": { "xbyak": {
"package": "xbyak", "package": "xbyak",
"repo": "herumi/xbyak", "repo": "herumi/xbyak",
"sha": "4e44f4614d", "tag": "v%VERSION%",
"hash": "5824e92159e07fa36a774aedd3b3ef3541d0241371d522cffa4ab3e1f215fa5097b1b77865b47b2481376c704fa079875557ea463ca63d0a7fd6a8a20a589e70", "hash": "1042090405c426e339506c179d53e91d4d545ce9c9f53d8f797caa092d589f913a9bcb9c8f31c4c60870acb954c556e305fb6732c66bc3c8f1cd924f9172def9",
"bundled": true "git_version": "7.22",
"bundled": true,
"skip_updates": true
}, },
"oaknut": { "oaknut": {
"repo": "eden-emulator/oaknut",
"version": "2.0.1", "version": "2.0.1",
"repo": "merryhime/oaknut", "git_version": "2.0.3",
"sha": "94c726ce03", "tag": "v%VERSION%",
"hash": "d8d082242fa1881abce3c82f8dafa002c4e561e66a69e7fc038af67faa5eff2630f082d3d19579c88c4c9f9488e54552accc8cb90e7ce743efe043b6230c08ac" "hash": "9697e80a7d5d9bcb3ce51051a9a24962fb90ca79d215f1f03ae6b58da8ba13a63b5dda1b4dde3d26ac6445029696b8ef2883f4e5a777b342bba01283ed293856"
}, },
"libadrenotools": { "libadrenotools": {
"repo": "bylaws/libadrenotools", "repo": "bylaws/libadrenotools",
@ -60,15 +75,128 @@
}, },
"oboe": { "oboe": {
"repo": "google/oboe", "repo": "google/oboe",
"sha": "2bc873e53c", "tag": "%VERSION%",
"hash": "02329058a7f9cf7d5039afaae5ab170d9f42f60f4c01e21eaf4f46073886922b057a9ae30eeac040b3ac182f51b9c1bfe9fe1050a2c9f6ce567a1a9a0ec2c768", "hash": "ce4011afe7345370d4ead3b891cd69a5ef224b129535783586c0ca75051d303ed446e6c7f10bde8da31fff58d6e307f1732a3ffd03b249f9ef1fd48fd4132715",
"git_version": "1.10.0",
"bundled": true "bundled": true
}, },
"unordered-dense": { "unordered-dense": {
"package": "unordered_dense", "package": "unordered_dense",
"repo": "martinus/unordered_dense", "repo": "martinus/unordered_dense",
"sha": "73f3cbb237", "tag": "v%VERSION%",
"hash": "c08c03063938339d61392b687562909c1a92615b6ef39ec8df19ea472aa6b6478e70d7d5e33d4a27b5d23f7806daf57fe1bacb8124c8a945c918c7663a9e8532", "hash": "f9c819e28e1c1a387acfee09277d6af5e366597a0d39acf1c687acf0608a941ba966af8aaebdb8fba0126c7360269c4a51754ef4cab17c35c01a30215f953368",
"find_args": "CONFIG" "find_args": "CONFIG",
"git_version": "4.5.0"
},
"mbedtls": {
"package": "MbedTLS",
"repo": "Mbed-TLS/mbedtls",
"tag": "mbedtls-%VERSION%",
"hash": "6671fb8fcaa832e5b115dfdce8f78baa6a4aea71f5c89a640583634cdee27aefe3bf4be075744da91f7c3ae5ea4e0c765c8fc3937b5cfd9ea73d87ef496524da",
"version": "3",
"git_version": "3.6.4",
"artifact": "%TAG%.tar.bz2",
"skip_updates": true
},
"enet": {
"repo": "lsalzman/enet",
"tag": "v%VERSION%",
"hash": "a0d2fa8c957704dd49e00a726284ac5ca034b50b00d2b20a94fa1bbfbb80841467834bfdc84aa0ed0d6aab894608fd6c86c3b94eee46343f0e6d9c22e391dbf9",
"version": "1.3",
"git_version": "1.3.18",
"find_args": "MODULE"
},
"vulkan-utility-headers": {
"package": "VulkanUtilityLibraries",
"repo": "scripts/VulkanUtilityHeaders",
"tag": "%VERSION%",
"git_version": "1.4.328",
"artifact": "VulkanUtilityHeaders.tar.zst",
"git_host": "git.crueter.xyz",
"hash": "9922217b39faf73cd4fc1510f2fdba14a49aa5c0d77f9ee24ee0512cef16b234d0cabc83c1fec861fa5df1d43e7f086ca9b6501753899119f39c5ca530cb0dae"
},
"spirv-tools": {
"package": "SPIRV-Tools",
"repo": "KhronosGroup/SPIRV-Tools",
"tag": "v%VERSION%",
"hash": "b17940433ced72e004c5eeffd7dd411b6afcc6a52ee31de6427d88edceb8172369be8ec8bf5b65708a78bf41fdae264d554aa7750b2209831679ab36bc867567",
"git_version": "2025.4",
"options": [
"SPIRV_SKIP_EXECUTABLES ON"
]
},
"spirv-headers": {
"package": "SPIRV-Headers",
"repo": "KhronosGroup/SPIRV-Headers",
"sha": "01e0577914",
"hash": "d0f905311faf7d743de686fdf241dc4cb0a4f08e2184f5a3b3b2946e680db3cd89eeb72954eafe6fa457f93550e27d516575c8709cb134d8aecc0b43064636ce",
"options": [
"SPIRV_WERROR OFF"
]
},
"cubeb": {
"repo": "mozilla/cubeb",
"sha": "fa02160712",
"hash": "82d808356752e4064de48c8fecbe7856715ade1e76b53937116bf07129fc1cc5b3de5e4b408de3cd000187ba8dc32ca4109661cb7e0355a52e54bd81b9be1c61",
"find_args": "CONFIG",
"options": [
"USE_SANITIZERS OFF",
"BUILD_TESTS OFF",
"BUILD_TOOLS OFF",
"BUNDLE_SPEEX ON"
]
},
"sdl2": {
"ci": true,
"package": "SDL2",
"name": "SDL2",
"repo": "crueter-ci/SDL2",
"version": "2.32.10",
"min_version": "2.26.4",
"disabled_platforms": [
"macos-universal"
]
},
"catch2": {
"package": "Catch2",
"repo": "catchorg/Catch2",
"tag": "v%VERSION%",
"hash": "a95495142f915d6e9c2a23e80fe360343e9097680066a2f9d3037a070ba5f81ee5559a0407cc9e972dc2afae325873f1fc7ea07a64012c0f01aac6e549f03e3f",
"version": "3.0.1",
"git_version": "3.11.0"
},
"discord-rpc": {
"package": "DiscordRPC",
"repo": "eden-emulator/discord-rpc",
"sha": "1cf7772bb6",
"hash": "e9b35e6f2c075823257bcd59f06fe7bb2ccce1976f44818d2e28810435ef79c712a3c4f20f40da41f691342a4058cf86b078eb7f9d9e4dae83c0547c21ec4f97",
"find_args": "MODULE"
},
"simpleini": {
"package": "SimpleIni",
"repo": "brofield/simpleini",
"tag": "v%VERSION%",
"hash": "6c198636816a0018adbf7f735d402c64245c6fcd540b7360d4388d46f007f3a520686cdaec4705cb8cb31401b2cb4797a80b42ea5d08a6a5807c0848386f7ca1",
"find_args": "MODULE",
"git_version": "4.22"
},
"sdl2_generic": {
"package": "SDL2",
"repo": "libsdl-org/SDL",
"tag": "release-%VERSION%",
"hash": "d5622d6bb7266f7942a7b8ad43e8a22524893bf0c2ea1af91204838d9b78d32768843f6faa248757427b8404b8c6443776d4afa6b672cd8571a4e0c03a829383",
"key": "generic",
"bundled": true,
"git_version": "2.32.10",
"skip_updates": true
},
"sdl2_steamdeck": {
"package": "SDL2",
"repo": "libsdl-org/SDL",
"sha": "cc016b0046",
"hash": "34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b",
"key": "steamdeck",
"bundled": true,
"skip_updates": "true"
} }
} }

View file

@ -5,16 +5,17 @@
"hash": "2a89d664119debbb3c006ab1c48d5d7f26e889f4a65ad2e25c8b0503308295123d5a9c5c78bf683aef5ff09acef8c3fc2837f22d3e8c611528b933bf03bcdd97", "hash": "2a89d664119debbb3c006ab1c48d5d7f26e889f4a65ad2e25c8b0503308295123d5a9c5c78bf683aef5ff09acef8c3fc2837f22d3e8c611528b933bf03bcdd97",
"bundled": true "bundled": true
}, },
"ffmpeg-ci": { "ffmpeg-ci": {
"ci": true, "ci": true,
"package": "FFmpeg", "package": "FFmpeg",
"name": "ffmpeg", "name": "ffmpeg",
"repo": "crueter-ci/FFmpeg", "repo": "crueter-ci/FFmpeg",
"version": "8.0", "version": "8.0",
"min_version": "4.1", "min_version": "4.1",
"disabled_platforms": [ "disabled_platforms": [
"freebsd", "freebsd-amd64",
"solaris" "solaris-amd64",
] "macos-universal"
]
} }
} }

View file

@ -6,18 +6,7 @@
include(CPMUtil) include(CPMUtil)
# we love our libraries don't we folks AddJsonPackage(libusb)
if (PLATFORM_SUN)
set(libusb_bundled ON)
else()
set(libusb_bundled OFF)
endif()
# TODO(crueter): Fix on Solaris
AddJsonPackage(
NAME libusb
BUNDLED_PACKAGE ${libusb_bundled}
)
if (NOT libusb_ADDED) if (NOT libusb_ADDED)
return() return()

View file

@ -1,8 +1,9 @@
{ {
"libusb": { "libusb": {
"repo": "libusb/libusb", "repo": "libusb/libusb",
"sha": "c060e9ce30", "tag": "v%VERSION%",
"hash": "44647357ba1179020cfa6674d809fc35cf6f89bff1c57252fe3a610110f5013ad678fc6eb5918e751d4384c30e2fe678868dbffc5f85736157e546cb9d10accc", "hash": "98c5f7940ff06b25c9aa65aa98e23de4c79a4c1067595f4c73cc145af23a1c286639e1ba11185cd91bab702081f307b973f08a4c9746576dc8d01b3620a3aeb5",
"find_args": "MODULE" "find_args": "MODULE",
} "git_version": "1.0.29"
} }
}

View file

@ -57,9 +57,9 @@ android {
} }
defaultConfig { defaultConfig {
// TODO If this is ever modified, change application_id in strings.xml
applicationId = "dev.eden.eden_emulator" applicationId = "dev.eden.eden_emulator"
minSdk = 30
minSdk = 28
targetSdk = 36 targetSdk = 36
versionName = getGitVersion() versionName = getGitVersion()
@ -72,8 +72,30 @@ android {
buildConfigField("String", "GIT_HASH", "\"${getGitHash()}\"") buildConfigField("String", "GIT_HASH", "\"${getGitHash()}\"")
buildConfigField("String", "BRANCH", "\"${getBranch()}\"") buildConfigField("String", "BRANCH", "\"${getBranch()}\"")
externalNativeBuild {
cmake {
arguments.addAll(listOf(
"-DENABLE_QT=0", // Don't use QT
"-DENABLE_SDL2=0", // Don't use SDL
"-DENABLE_WEB_SERVICE=1", // Enable web service
"-DENABLE_OPENSSL=ON",
"-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work
"-DYUZU_USE_CPM=ON",
"-DCPMUTIL_FORCE_BUNDLED=ON",
"-DYUZU_USE_BUNDLED_FFMPEG=ON",
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
"-DBUILD_TESTING=OFF",
"-DYUZU_TESTS=OFF",
"-DDYNARMIC_TESTS=OFF"
))
abiFilters("arm64-v8a")
}
}
} }
val keystoreFile = System.getenv("ANDROID_KEYSTORE_FILE") val keystoreFile = System.getenv("ANDROID_KEYSTORE_FILE")
signingConfigs { signingConfigs {
if (keystoreFile != null) { if (keystoreFile != null) {
@ -94,7 +116,6 @@ android {
// Define build types, which are orthogonal to product flavors. // Define build types, which are orthogonal to product flavors.
buildTypes { buildTypes {
// Signed by release key, allowing for upload to Play Store. // Signed by release key, allowing for upload to Play Store.
release { release {
signingConfig = if (keystoreFile != null) { signingConfig = if (keystoreFile != null) {
@ -103,7 +124,6 @@ android {
signingConfigs.getByName("default") signingConfigs.getByName("default")
} }
resValue("string", "app_name_suffixed", "Eden")
isMinifyEnabled = true isMinifyEnabled = true
isDebuggable = false isDebuggable = false
proguardFiles( proguardFiles(
@ -116,7 +136,6 @@ android {
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build. // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
register("relWithDebInfo") { register("relWithDebInfo") {
isDefault = true isDefault = true
resValue("string", "app_name_suffixed", "Eden Debug Release")
signingConfig = signingConfigs.getByName("default") signingConfig = signingConfigs.getByName("default")
isDebuggable = true isDebuggable = true
proguardFiles( proguardFiles(
@ -132,7 +151,6 @@ android {
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build. // Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
debug { debug {
signingConfig = signingConfigs.getByName("default") signingConfig = signingConfigs.getByName("default")
resValue("string", "app_name_suffixed", "Eden Debug")
isDebuggable = true isDebuggable = true
isJniDebuggable = true isJniDebuggable = true
versionNameSuffix = "-debug" versionNameSuffix = "-debug"
@ -140,19 +158,62 @@ android {
} }
} }
// this is really annoying but idk any other ways to fix this behavior
applicationVariants.all {
val variant = this
when {
variant.flavorName == "legacy" && variant.buildType.name == "debug" -> {
variant.resValue("string", "app_name_suffixed", "Eden Legacy Debug")
}
variant.flavorName == "mainline" && variant.buildType.name == "debug" -> {
variant.resValue("string", "app_name_suffixed", "Eden Debug")
}
variant.flavorName == "genshinSpoof" && variant.buildType.name == "debug" -> {
variant.resValue("string", "app_name_suffixed", "Eden Optimized Debug")
}
variant.flavorName == "legacy" && variant.buildType.name == "relWithDebInfo" -> {
variant.resValue("string", "app_name_suffixed", "Eden Legacy Debug Release")
}
variant.flavorName == "mainline" && variant.buildType.name == "relWithDebInfo" -> {
variant.resValue("string", "app_name_suffixed", "Eden Debug Release")
}
variant.flavorName == "genshinSpoof" && variant.buildType.name == "relWithDebInfo" -> {
variant.resValue("string", "app_name_suffixed", "Eden Optimized Debug Release")
}
}
}
android { android {
flavorDimensions.add("version") flavorDimensions.add("version")
productFlavors { productFlavors {
create("mainline") { create("mainline") {
dimension = "version" dimension = "version"
// No need to set applicationId here resValue("string", "app_name_suffixed", "Eden")
} }
create("genshinSpoof") { create("genshinSpoof") {
dimension = "version" dimension = "version"
resValue("string", "app_name_suffixed", "Eden Optimised") resValue("string", "app_name_suffixed", "Eden Optimized")
applicationId = "com.miHoYo.Yuanshen" applicationId = "com.miHoYo.Yuanshen"
} }
create("legacy") {
dimension = "version"
resValue("string", "app_name_suffixed", "Eden Legacy")
applicationId = "dev.legacy.eden_emulator"
externalNativeBuild {
cmake {
arguments.add("-DYUZU_LEGACY=ON")
}
}
sourceSets {
getByName("legacy") {
res.srcDirs("src/main/legacy")
}
}
}
} }
} }
@ -162,29 +223,6 @@ android {
path = file("../../../CMakeLists.txt") path = file("../../../CMakeLists.txt")
} }
} }
defaultConfig {
externalNativeBuild {
cmake {
arguments(
"-DENABLE_QT=0", // Don't use QT
"-DENABLE_SDL2=0", // Don't use SDL
"-DENABLE_WEB_SERVICE=1", // Enable web service
"-DENABLE_OPENSSL=ON",
"-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work
"-DYUZU_USE_CPM=ON",
"-DCPMUTIL_FORCE_BUNDLED=ON",
"-DYUZU_USE_BUNDLED_FFMPEG=ON",
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
"-DBUILD_TESTING=OFF",
"-DYUZU_TESTS=OFF",
"-DDYNARMIC_TESTS=OFF"
)
abiFilters("arm64-v8a")
}
}
}
} }
tasks.register<Delete>("ktlintReset", fun Delete.() { tasks.register<Delete>("ktlintReset", fun Delete.() {

View file

@ -19,6 +19,7 @@ import org.yuzu.yuzu_emu.adapters.GameAdapter
import androidx.core.view.doOnNextLayout import androidx.core.view.doOnNextLayout
import org.yuzu.yuzu_emu.YuzuApplication import org.yuzu.yuzu_emu.YuzuApplication
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.core.view.WindowInsetsCompat
/** /**
* CarouselRecyclerView encapsulates all carousel logic for the games UI. * CarouselRecyclerView encapsulates all carousel logic for the games UI.
@ -205,8 +206,8 @@ class CarouselRecyclerView @JvmOverloads constructor(
if (enabled) { if (enabled) {
useCustomDrawingOrder = true useCustomDrawingOrder = true
val insets = rootWindowInsets val insets = rootWindowInsets?.let { WindowInsetsCompat.toWindowInsetsCompat(it, this) }
val bottomInset = insets?.getInsets(android.view.WindowInsets.Type.systemBars())?.bottom ?: 0 val bottomInset = insets?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom ?: 0
val internalFactor = resources.getFraction(R.fraction.carousel_card_size_factor, 1, 1) val internalFactor = resources.getFraction(R.fraction.carousel_card_size_factor, 1, 1)
val userFactor = preferences.getFloat(CAROUSEL_CARD_SIZE_FACTOR, internalFactor).coerceIn( val userFactor = preferences.getFloat(CAROUSEL_CARD_SIZE_FACTOR, internalFactor).coerceIn(
0f, 0f,

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

View file

@ -180,6 +180,7 @@
<item>@string/resolution_half</item> <item>@string/resolution_half</item>
<item>@string/resolution_three_quarter</item> <item>@string/resolution_three_quarter</item>
<item>@string/resolution_one</item> <item>@string/resolution_one</item>
<item>@string/resolution_five_quarter</item>
<item>@string/resolution_three_half</item> <item>@string/resolution_three_half</item>
<item>@string/resolution_two</item> <item>@string/resolution_two</item>
<item>@string/resolution_three</item> <item>@string/resolution_three</item>
@ -202,6 +203,7 @@
<item>5</item> <item>5</item>
<item>6</item> <item>6</item>
<item>7</item> <item>7</item>
<item>8</item>
</integer-array> </integer-array>
<integer-array name="rendererVSyncValues"> <integer-array name="rendererVSyncValues">

View file

@ -996,6 +996,7 @@
<string name="resolution_half">0.5X (360p/540p)</string> <string name="resolution_half">0.5X (360p/540p)</string>
<string name="resolution_three_quarter">0.75X (540p/810p)</string> <string name="resolution_three_quarter">0.75X (540p/810p)</string>
<string name="resolution_one">1X (720p/1080p)</string> <string name="resolution_one">1X (720p/1080p)</string>
<string name="resolution_five_quarter">1.25X (900p/1350p)</string>
<string name="resolution_three_half">1.5X (1080p/1620p)</string> <string name="resolution_three_half">1.5X (1080p/1620p)</string>
<string name="resolution_two">2X (1440p/2160p) (Slow)</string> <string name="resolution_two">2X (1440p/2160p) (Slow)</string>
<string name="resolution_three">3X (2160p/3240p) (Slow)</string> <string name="resolution_three">3X (2160p/3240p) (Slow)</string>

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

View file

@ -191,8 +191,6 @@ static void InitializeReverbEffect(const ReverbInfo::ParameterVersion2& params,
const auto center_delay_time{(5 * delay).to_uint_floor()}; const auto center_delay_time{(5 * delay).to_uint_floor()};
state.center_delay_line.Initialize(center_delay_time, 1.0f); state.center_delay_line.Initialize(center_delay_time, 1.0f);
UpdateReverbEffectParameter(params, state);
for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) { for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
std::ranges::fill(state.fdn_delay_lines[i].buffer, 0); std::ranges::fill(state.fdn_delay_lines[i].buffer, 0);
std::ranges::fill(state.decay_delay_lines[i].buffer, 0); std::ranges::fill(state.decay_delay_lines[i].buffer, 0);

View file

@ -293,8 +293,7 @@ void SinkStream::WaitFreeSpace(std::stop_token stop_token) {
release_cv.wait_for(lk, std::chrono::milliseconds(5), release_cv.wait_for(lk, std::chrono::milliseconds(5),
[this]() { return paused || queued_buffers < max_queue_size; }); [this]() { return paused || queued_buffers < max_queue_size; });
if (queued_buffers > max_queue_size + 3) { if (queued_buffers > max_queue_size + 3) {
Common::CondvarWait(release_cv, lk, stop_token, release_cv.wait(lk, stop_token, [this] { return paused || queued_buffers < max_queue_size; });
[this] { return paused || queued_buffers < max_queue_size; });
} }
} }

View file

@ -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-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -123,7 +126,7 @@ private:
} else if constexpr (Mode == PopMode::WaitWithStopToken) { } else if constexpr (Mode == PopMode::WaitWithStopToken) {
// Wait until the queue is not empty. // Wait until the queue is not empty.
std::unique_lock lock{consumer_cv_mutex}; std::unique_lock lock{consumer_cv_mutex};
Common::CondvarWait(consumer_cv, lock, stop_token, [this, read_index] { consumer_cv.wait(lock, stop_token, [this, read_index] {
return read_index != m_write_index.load(std::memory_order::acquire); return read_index != m_write_index.load(std::memory_order::acquire);
}); });
if (stop_token.stop_requested()) { if (stop_token.stop_requested()) {

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2012 Gekko Emulator // SPDX-FileCopyrightText: 2012 Gekko Emulator
// SPDX-FileContributor: ShizZy <shizzy247@gmail.com> // SPDX-FileContributor: ShizZy <shizzy247@gmail.com>
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -30,7 +33,6 @@
#include <array> #include <array>
#include <cstdint> #include <cstdint>
#include <memory>
using u8 = std::uint8_t; ///< 8-bit unsigned byte using u8 = std::uint8_t; ///< 8-bit unsigned byte
using u16 = std::uint16_t; ///< 16-bit unsigned short using u16 = std::uint16_t; ///< 16-bit unsigned short

View file

@ -3,6 +3,7 @@
#include <vector> #include <vector>
#include "common/assert.h"
#include "common/fs/file.h" #include "common/fs/file.h"
#include "common/fs/fs.h" #include "common/fs/fs.h"
#ifdef ANDROID #ifdef ANDROID

View file

@ -9,6 +9,7 @@
#include <sstream> #include <sstream>
#include <unordered_map> #include <unordered_map>
#include "common/assert.h"
#include "common/fs/fs.h" #include "common/fs/fs.h"
#ifdef ANDROID #ifdef ANDROID
#include "common/fs/fs_android.h" #include "common/fs/fs_android.h"

View file

@ -56,6 +56,16 @@
#include "common/host_memory.h" #include "common/host_memory.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#if defined(__ANDROID__) && __ANDROID_API__ < 30
#include <sys/syscall.h>
#ifndef MFD_CLOEXEC
#define MFD_CLOEXEC 0x0001U
#endif
static int memfd_create(const char* name, unsigned int flags) {
return syscall(__NR_memfd_create, name, flags);
}
#endif
namespace Common { namespace Common {
constexpr size_t PageAlignment = 0x1000; constexpr size_t PageAlignment = 0x1000;

View file

@ -39,9 +39,17 @@ namespace Common::Log {
namespace { namespace {
/** /// @brief Trims up to and including the last of ../, ..\, src/, src\ in a string
* Interface for logging backends. /// do not be fooled this isn't generating new strings on .rodata :)
*/ constexpr const char* TrimSourcePath(std::string_view source) {
const auto rfind = [source](const std::string_view match) {
return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size());
};
auto idx = (std::max)({rfind("src/"), rfind("src\\"), rfind("../"), rfind("..\\")});
return source.data() + idx;
}
/// @brief Interface for logging backends.
class Backend { class Backend {
public: public:
virtual ~Backend() = default; virtual ~Backend() = default;
@ -53,9 +61,7 @@ public:
virtual void Flush() = 0; virtual void Flush() = 0;
}; };
/** /// @brief Backend that writes to stderr and with color
* Backend that writes to stderr and with color
*/
class ColorConsoleBackend final : public Backend { class ColorConsoleBackend final : public Backend {
public: public:
explicit ColorConsoleBackend() = default; explicit ColorConsoleBackend() = default;
@ -84,9 +90,7 @@ private:
std::atomic_bool enabled{false}; std::atomic_bool enabled{false};
}; };
/** /// @brief Backend that writes to a file passed into the constructor
* Backend that writes to a file passed into the constructor
*/
class FileBackend final : public Backend { class FileBackend final : public Backend {
public: public:
explicit FileBackend(const std::filesystem::path& filename) { explicit FileBackend(const std::filesystem::path& filename) {
@ -248,13 +252,14 @@ public:
color_console_backend.SetEnabled(enabled); color_console_backend.SetEnabled(enabled);
} }
bool CanPushEntry(Class log_class, Level log_level) const noexcept {
return filter.CheckMessage(log_class, log_level);
}
void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, std::string&& message) { const char* function, std::string&& message) noexcept {
if (!filter.CheckMessage(log_class, log_level)) {
return;
}
message_queue.EmplaceWait( message_queue.EmplaceWait(
CreateEntry(log_class, log_level, filename, line_num, function, std::move(message))); CreateEntry(log_class, log_level, TrimSourcePath(filename), line_num, function, std::move(message)));
} }
private: private:
@ -368,8 +373,9 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, fmt::string_view format, unsigned int line_num, const char* function, fmt::string_view format,
const fmt::format_args& args) { const fmt::format_args& args) {
if (!initialization_in_progress_suppress_logging) { if (!initialization_in_progress_suppress_logging) {
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function, auto& instance = Impl::Instance();
fmt::vformat(format, args)); if (instance.CanPushEntry(log_class, log_level))
instance.PushEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args));
} }
} }
} // namespace Common::Log } // namespace Common::Log

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-FileCopyrightText: 2014 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -9,22 +12,20 @@ namespace Common::Log {
namespace { namespace {
template <typename It> template <typename It>
Level GetLevelByName(const It begin, const It end) { Level GetLevelByName(const It begin, const It end) {
for (u8 i = 0; i < static_cast<u8>(Level::Count); ++i) { for (u32 i = 0; i < u32(Level::Count); ++i) {
const char* level_name = GetLevelName(static_cast<Level>(i)); const char* level_name = GetLevelName(Level(i));
if (Common::ComparePartialString(begin, end, level_name)) { if (Common::ComparePartialString(begin, end, level_name))
return static_cast<Level>(i); return Level(i);
}
} }
return Level::Count; return Level::Count;
} }
template <typename It> template <typename It>
Class GetClassByName(const It begin, const It end) { Class GetClassByName(const It begin, const It end) {
for (u8 i = 0; i < static_cast<u8>(Class::Count); ++i) { for (u32 i = 0; i < u32(Class::Count); ++i) {
const char* level_name = GetLogClassName(static_cast<Class>(i)); const char* level_name = GetLogClassName(Class(i));
if (Common::ComparePartialString(begin, end, level_name)) { if (Common::ComparePartialString(begin, end, level_name))
return static_cast<Class>(i); return Class(i);
}
} }
return Class::Count; return Class::Count;
} }
@ -229,13 +230,12 @@ void Filter::ParseFilterString(std::string_view filter_view) {
} }
bool Filter::CheckMessage(Class log_class, Level level) const { bool Filter::CheckMessage(Class log_class, Level level) const {
return static_cast<u8>(level) >= return u8(level) >= u8(class_levels[std::size_t(log_class)]);
static_cast<u8>(class_levels[static_cast<std::size_t>(log_class)]);
} }
bool Filter::IsDebug() const { bool Filter::IsDebug() const {
return std::any_of(class_levels.begin(), class_levels.end(), [](const Level& l) { return std::any_of(class_levels.begin(), class_levels.end(), [](const Level& l) {
return static_cast<u8>(l) <= static_cast<u8>(Level::Debug); return u8(l) <= u8(Level::Debug);
}); });
} }

View file

@ -16,15 +16,6 @@
namespace Common::Log { namespace Common::Log {
// trims up to and including the last of ../, ..\, src/, src\ in a string
constexpr const char* TrimSourcePath(std::string_view source) {
const auto rfind = [source](const std::string_view match) {
return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size());
};
auto idx = (std::max)({rfind("src/"), rfind("src\\"), rfind("../"), rfind("..\\")});
return source.data() + idx;
}
/// Logs a message to the global logger, using fmt /// Logs a message to the global logger, using fmt
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, fmt::string_view format, unsigned int line_num, const char* function, fmt::string_view format,
@ -42,7 +33,7 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
#ifdef _DEBUG #ifdef _DEBUG
#define LOG_TRACE(log_class, ...) \ #define LOG_TRACE(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#else #else
#define LOG_TRACE(log_class, fmt, ...) (void(0)) #define LOG_TRACE(log_class, fmt, ...) (void(0))
@ -50,21 +41,21 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
#define LOG_DEBUG(log_class, ...) \ #define LOG_DEBUG(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_INFO(log_class, ...) \ #define LOG_INFO(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_WARNING(log_class, ...) \ #define LOG_WARNING(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_ERROR(log_class, ...) \ #define LOG_ERROR(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)
#define LOG_CRITICAL(log_class, ...) \ #define LOG_CRITICAL(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \ Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
__VA_ARGS__) __VA_ARGS__)

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2022 yuzu Emulator Project // SPDX-FileCopyrightText: 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -7,23 +10,13 @@
#pragma once #pragma once
#include <version>
#ifdef __cpp_lib_jthread
#include <chrono> #include <chrono>
#include <condition_variable> #include <condition_variable>
#include <stop_token>
#include <thread> #include <thread>
#include <utility> #include <utility>
namespace Common { namespace Common {
template <typename Condvar, typename Lock, typename Pred>
void CondvarWait(Condvar& cv, std::unique_lock<Lock>& lk, std::stop_token token, Pred&& pred) {
cv.wait(lk, token, std::forward<Pred>(pred));
}
template <typename Rep, typename Period> template <typename Rep, typename Period>
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) { bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
std::condition_variable_any cv; std::condition_variable_any cv;
@ -35,341 +28,3 @@ bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep,
} }
} // namespace Common } // namespace Common
#else
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <thread>
#include <type_traits>
#include <utility>
namespace std {
namespace polyfill {
using stop_state_callback = size_t;
class stop_state {
public:
stop_state() = default;
~stop_state() = default;
bool request_stop() {
unique_lock lk{m_lock};
if (m_stop_requested) {
// Already set, nothing to do.
return false;
}
// Mark stop requested.
m_stop_requested = true;
while (!m_callbacks.empty()) {
// Get an iterator to the first element.
const auto it = m_callbacks.begin();
// Move the callback function out of the map.
function<void()> f;
swap(it->second, f);
// Erase the now-empty map element.
m_callbacks.erase(it);
// Run the callback.
if (f) {
f();
}
}
return true;
}
bool stop_requested() const {
unique_lock lk{m_lock};
return m_stop_requested;
}
stop_state_callback insert_callback(function<void()> f) {
unique_lock lk{m_lock};
if (m_stop_requested) {
// Stop already requested. Don't insert anything,
// just run the callback synchronously.
if (f) {
f();
}
return 0;
}
// Insert the callback.
stop_state_callback ret = ++m_next_callback;
m_callbacks.emplace(ret, std::move(f));
return ret;
}
void remove_callback(stop_state_callback cb) {
unique_lock lk{m_lock};
m_callbacks.erase(cb);
}
private:
mutable recursive_mutex m_lock;
map<stop_state_callback, function<void()>> m_callbacks;
stop_state_callback m_next_callback{0};
bool m_stop_requested{false};
};
} // namespace polyfill
class stop_token;
class stop_source;
struct nostopstate_t {
explicit nostopstate_t() = default;
};
inline constexpr nostopstate_t nostopstate{};
template <class Callback>
class stop_callback;
class stop_token {
public:
stop_token() noexcept = default;
stop_token(const stop_token&) noexcept = default;
stop_token(stop_token&&) noexcept = default;
stop_token& operator=(const stop_token&) noexcept = default;
stop_token& operator=(stop_token&&) noexcept = default;
~stop_token() = default;
void swap(stop_token& other) noexcept {
m_stop_state.swap(other.m_stop_state);
}
[[nodiscard]] bool stop_requested() const noexcept {
return m_stop_state && m_stop_state->stop_requested();
}
[[nodiscard]] bool stop_possible() const noexcept {
return m_stop_state != nullptr;
}
private:
friend class stop_source;
template <typename Callback>
friend class stop_callback;
stop_token(shared_ptr<polyfill::stop_state> stop_state) : m_stop_state(std::move(stop_state)) {}
private:
shared_ptr<polyfill::stop_state> m_stop_state;
};
class stop_source {
public:
stop_source() : m_stop_state(make_shared<polyfill::stop_state>()) {}
explicit stop_source(nostopstate_t) noexcept {}
stop_source(const stop_source&) noexcept = default;
stop_source(stop_source&&) noexcept = default;
stop_source& operator=(const stop_source&) noexcept = default;
stop_source& operator=(stop_source&&) noexcept = default;
~stop_source() = default;
void swap(stop_source& other) noexcept {
m_stop_state.swap(other.m_stop_state);
}
[[nodiscard]] stop_token get_token() const noexcept {
return stop_token(m_stop_state);
}
[[nodiscard]] bool stop_possible() const noexcept {
return m_stop_state != nullptr;
}
[[nodiscard]] bool stop_requested() const noexcept {
return m_stop_state && m_stop_state->stop_requested();
}
bool request_stop() noexcept {
return m_stop_state && m_stop_state->request_stop();
}
private:
friend class jthread;
explicit stop_source(shared_ptr<polyfill::stop_state> stop_state)
: m_stop_state(std::move(stop_state)) {}
private:
shared_ptr<polyfill::stop_state> m_stop_state;
};
template <typename Callback>
class stop_callback {
static_assert(is_nothrow_destructible_v<Callback>);
static_assert(is_invocable_v<Callback>);
public:
using callback_type = Callback;
template <typename C>
requires constructible_from<Callback, C>
explicit stop_callback(const stop_token& st,
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
: m_stop_state(st.m_stop_state) {
if (m_stop_state) {
m_callback = m_stop_state->insert_callback(std::move(cb));
}
}
template <typename C>
requires constructible_from<Callback, C>
explicit stop_callback(stop_token&& st,
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
: m_stop_state(std::move(st.m_stop_state)) {
if (m_stop_state) {
m_callback = m_stop_state->insert_callback(std::move(cb));
}
}
~stop_callback() {
if (m_stop_state && m_callback) {
m_stop_state->remove_callback(m_callback);
}
}
stop_callback(const stop_callback&) = delete;
stop_callback(stop_callback&&) = delete;
stop_callback& operator=(const stop_callback&) = delete;
stop_callback& operator=(stop_callback&&) = delete;
private:
shared_ptr<polyfill::stop_state> m_stop_state;
polyfill::stop_state_callback m_callback;
};
template <typename Callback>
stop_callback(stop_token, Callback) -> stop_callback<Callback>;
class jthread {
public:
using id = thread::id;
using native_handle_type = thread::native_handle_type;
jthread() noexcept = default;
template <typename F, typename... Args,
typename = enable_if_t<!is_same_v<remove_cvref_t<F>, jthread>>>
explicit jthread(F&& f, Args&&... args)
: m_stop_state(make_shared<polyfill::stop_state>()),
m_thread(make_thread(std::forward<F>(f), std::forward<Args>(args)...)) {}
~jthread() {
if (joinable()) {
request_stop();
join();
}
}
jthread(const jthread&) = delete;
jthread(jthread&&) noexcept = default;
jthread& operator=(const jthread&) = delete;
jthread& operator=(jthread&& other) noexcept {
m_thread.swap(other.m_thread);
m_stop_state.swap(other.m_stop_state);
return *this;
}
void swap(jthread& other) noexcept {
m_thread.swap(other.m_thread);
m_stop_state.swap(other.m_stop_state);
}
[[nodiscard]] bool joinable() const noexcept {
return m_thread.joinable();
}
void join() {
m_thread.join();
}
void detach() {
m_thread.detach();
m_stop_state.reset();
}
[[nodiscard]] id get_id() const noexcept {
return m_thread.get_id();
}
[[nodiscard]] native_handle_type native_handle() {
return m_thread.native_handle();
}
[[nodiscard]] stop_source get_stop_source() noexcept {
return stop_source(m_stop_state);
}
[[nodiscard]] stop_token get_stop_token() const noexcept {
return stop_source(m_stop_state).get_token();
}
bool request_stop() noexcept {
return get_stop_source().request_stop();
}
[[nodiscard]] static unsigned int hardware_concurrency() noexcept {
return thread::hardware_concurrency();
}
private:
template <typename F, typename... Args>
thread make_thread(F&& f, Args&&... args) {
if constexpr (is_invocable_v<decay_t<F>, stop_token, decay_t<Args>...>) {
return thread(std::forward<F>(f), get_stop_token(), std::forward<Args>(args)...);
} else {
return thread(std::forward<F>(f), std::forward<Args>(args)...);
}
}
shared_ptr<polyfill::stop_state> m_stop_state;
thread m_thread;
};
} // namespace std
namespace Common {
template <typename Condvar, typename Lock, typename Pred>
void CondvarWait(Condvar& cv, std::unique_lock<Lock>& lk, std::stop_token token, Pred pred) {
if (token.stop_requested()) {
return;
}
std::stop_callback callback(token, [&] {
{ std::scoped_lock lk2{*lk.mutex()}; }
cv.notify_all();
});
cv.wait(lk, [&] { return pred() || token.stop_requested(); });
}
template <typename Rep, typename Period>
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
if (token.stop_requested()) {
return false;
}
bool stop_requested = false;
std::condition_variable cv;
std::mutex m;
std::stop_callback cb(token, [&] {
// Wake up the waiting thread.
{
std::scoped_lock lk{m};
stop_requested = true;
}
cv.notify_one();
});
// Perform the timed wait.
std::unique_lock lk{m};
return !cv.wait_for(lk, rel_time, [&] { return stop_requested; });
}
} // namespace Common
#endif

View file

@ -18,6 +18,9 @@
#define TITLE_BAR_FORMAT_RUNNING "@TITLE_BAR_FORMAT_RUNNING@" #define TITLE_BAR_FORMAT_RUNNING "@TITLE_BAR_FORMAT_RUNNING@"
#define IS_DEV_BUILD @IS_DEV_BUILD@ #define IS_DEV_BUILD @IS_DEV_BUILD@
#define COMPILER_ID "@CXX_COMPILER@" #define COMPILER_ID "@CXX_COMPILER@"
#define BUILD_AUTO_UPDATE_WEBSITE "@BUILD_AUTO_UPDATE_WEBSITE@"
#define BUILD_AUTO_UPDATE_API "@BUILD_AUTO_UPDATE_API@"
#define BUILD_AUTO_UPDATE_REPO "@BUILD_AUTO_UPDATE_REPO@"
namespace Common { namespace Common {
@ -34,4 +37,8 @@ constexpr const char g_title_bar_format_running[] = TITLE_BAR_FORMAT_RUNNING;
constexpr const char g_compiler_id[] = COMPILER_ID; constexpr const char g_compiler_id[] = COMPILER_ID;
constexpr const bool g_is_dev_build = IS_DEV_BUILD; constexpr const bool g_is_dev_build = IS_DEV_BUILD;
constexpr const char g_build_auto_update_website[] = BUILD_AUTO_UPDATE_WEBSITE;
constexpr const char g_build_auto_update_api[] = BUILD_AUTO_UPDATE_API;
constexpr const char g_build_auto_update_repo[] = BUILD_AUTO_UPDATE_REPO;
} // namespace Common } // namespace Common

View file

@ -21,5 +21,8 @@ extern const char g_title_bar_format_running[];
extern const char g_shader_cache_version[]; extern const char g_shader_cache_version[];
extern const char g_compiler_id[]; extern const char g_compiler_id[];
extern const bool g_is_dev_build; extern const bool g_is_dev_build;
extern const char g_build_auto_update_website[];
extern const char g_build_auto_update_api[];
extern const char g_build_auto_update_repo[];
} // namespace Common } // namespace Common

View file

@ -301,6 +301,10 @@ void TranslateResolutionInfo(ResolutionSetup setup, ResolutionScalingInfo& info)
info.up_scale = 3; info.up_scale = 3;
info.down_shift = 1; info.down_shift = 1;
break; break;
case ResolutionSetup::Res5_4X:
info.up_scale = 5;
info.down_shift = 2;
break;
case ResolutionSetup::Res2X: case ResolutionSetup::Res2X:
info.up_scale = 2; info.up_scale = 2;
info.down_shift = 0; info.down_shift = 0;

View file

@ -320,11 +320,19 @@ struct Values {
linkage, true, "cpuopt_unsafe_ignore_global_monitor", Category::CpuUnsafe}; linkage, true, "cpuopt_unsafe_ignore_global_monitor", Category::CpuUnsafe};
// Renderer // Renderer
SwitchableSetting<RendererBackend, true> renderer_backend{ SwitchableSetting<RendererBackend, true> renderer_backend{linkage,
linkage, RendererBackend::Vulkan, #if defined(__sun__) || defined(__managarm__)
RendererBackend::OpenGL,
#else
RendererBackend::Vulkan,
#endif
"backend", Category::Renderer}; "backend", Category::Renderer};
SwitchableSetting<ShaderBackend, true> shader_backend{ SwitchableSetting<ShaderBackend, true> shader_backend{linkage,
linkage, ShaderBackend::SpirV, #if defined(__sun__) || defined(__managarm__)
ShaderBackend::Glsl,
#else
ShaderBackend::SpirV,
#endif
"shader_backend", Category::Renderer, Specialization::RuntimeList}; "shader_backend", Category::Renderer, Specialization::RuntimeList};
SwitchableSetting<int> vulkan_device{linkage, 0, "vulkan_device", Category::Renderer, SwitchableSetting<int> vulkan_device{linkage, 0, "vulkan_device", Category::Renderer,
Specialization::RuntimeList}; Specialization::RuntimeList};

View file

@ -142,7 +142,7 @@ ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb)
ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
ENUM(FullscreenMode, Borderless, Exclusive); ENUM(FullscreenMode, Borderless, Exclusive);
ENUM(NvdecEmulation, Off, Cpu, Gpu); ENUM(NvdecEmulation, Off, Cpu, Gpu);
ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X); ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res5_4X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X);
ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum); ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum);
ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum); ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project // SPDX-FileCopyrightText: 2013 Dolphin Emulator Project
// SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-FileCopyrightText: 2014 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -80,7 +83,7 @@ public:
condvar.notify_all(); condvar.notify_all();
return true; return true;
} else { } else {
CondvarWait(condvar, lk, token, condvar.wait(lk, token,
[this, current_generation] { return current_generation != generation; }); [this, current_generation] { return current_generation != generation; });
return !token.stop_requested(); return !token.stop_requested();
} }

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -47,8 +50,8 @@ public:
if (requests.empty()) { if (requests.empty()) {
wait_condition.notify_all(); wait_condition.notify_all();
} }
Common::CondvarWait(condition, lock, stop_token, condition.wait(lock, stop_token,
[this] { return !requests.empty(); }); [this] { return !requests.empty(); });
if (stop_token.stop_requested()) { if (stop_token.stop_requested()) {
break; break;
} }

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2010 Dolphin Emulator Project // SPDX-FileCopyrightText: 2010 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -99,7 +102,11 @@ public:
T PopWait(std::stop_token stop_token) { T PopWait(std::stop_token stop_token) {
if (Empty()) { if (Empty()) {
std::unique_lock lock{cv_mutex}; std::unique_lock lock{cv_mutex};
Common::CondvarWait(cv, lock, stop_token, [this] { return !Empty(); }); if constexpr (with_stop_token) {
cv.wait(lock, stop_token, [this] { return !Empty(); });
} else {
cv.wait(lock, [this] { return !Empty(); });
}
} }
if (stop_token.stop_requested()) { if (stop_token.stop_requested()) {
return T{}; return T{};

View file

@ -227,7 +227,7 @@ HaltReason ArmNce::RunThread(Kernel::KThread* thread) {
if (auto it = post_handlers.find(m_guest_ctx.pc); it != post_handlers.end()) { if (auto it = post_handlers.find(m_guest_ctx.pc); it != post_handlers.end()) {
hr = ReturnToRunCodeByTrampoline(thread_params, &m_guest_ctx, it->second); hr = ReturnToRunCodeByTrampoline(thread_params, &m_guest_ctx, it->second);
} else { } else {
hr = ReturnToRunCodeByExceptionLevelChange(m_thread_id, thread_params); hr = ReturnToRunCodeByExceptionLevelChange(m_thread_id, thread_params); // Android: Use "process handle SIGUSR2 -n true -p true -s false" (and SIGURG) in LLDB when debugging
} }
// Critical section for thread cleanup // Critical section for thread cleanup

View file

@ -38,9 +38,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca)
reader = std::make_shared<NcaReader>(); reader = std::make_shared<NcaReader>();
if (Result rc = reader->Initialize(file, GetCryptoConfiguration(), GetNcaCompressionConfiguration()); R_FAILED(rc)) { 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; status = Loader::ResultStatus::ErrorBadNCAHeader;
return; return;
} }
@ -85,7 +82,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca)
for (s32 i = 0; i < fs_count; i++) { for (s32 i = 0; i < fs_count; i++) {
NcaFsHeaderReader header_reader; NcaFsHeaderReader header_reader;
if (Result rc = fs.OpenStorage(&filesystems[i], &header_reader, i); R_FAILED(rc)) { 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; status = Loader::ResultStatus::ErrorBadNCAHeader;
return; return;
} }

View file

@ -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-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

View file

@ -1049,13 +1049,11 @@ Result NcaFileSystemDriver::CreatePatchMetaStorage(
ASSERT(out_aes_ctr_ex_meta != nullptr); ASSERT(out_aes_ctr_ex_meta != nullptr);
ASSERT(out_indirect_meta != nullptr); ASSERT(out_indirect_meta != nullptr);
ASSERT(base_storage != nullptr); ASSERT(base_storage != nullptr);
//ASSERT(patch_info.HasAesCtrExTable());
//ASSERT(patch_info.HasIndirectTable());
ASSERT(Common::IsAligned<s64>(patch_info.aes_ctr_ex_size, NcaHeader::XtsBlockSize)); ASSERT(Common::IsAligned<s64>(patch_info.aes_ctr_ex_size, NcaHeader::XtsBlockSize));
// Validate patch info extents. // Validate patch info extents.
R_UNLESS(patch_info.indirect_size > 0, ResultInvalidNcaPatchInfoIndirectSize); R_UNLESS(patch_info.aes_ctr_ex_size >= 0 && patch_info.HasAesCtrExTable(), ResultInvalidNcaPatchInfoAesCtrExSize);
R_UNLESS(patch_info.aes_ctr_ex_size >= 0, 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, R_UNLESS(patch_info.indirect_size + patch_info.indirect_offset <= patch_info.aes_ctr_ex_offset,
ResultInvalidNcaPatchInfoAesCtrExOffset); ResultInvalidNcaPatchInfoAesCtrExOffset);
R_UNLESS(patch_info.aes_ctr_ex_offset + patch_info.aes_ctr_ex_size <= 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, R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset,
ResultRomNcaInvalidIntegrityLayerInfoOffset); ResultRomNcaInvalidIntegrityLayerInfoOffset);
} }
storage_info[level_hash_info.max_layers - 1]
= std::make_shared<OffsetVfsFile>(std::move(base_storage), switch (level_hash_info.max_layers - 1) {
layer_info.size, case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::MasterStorage:
last_layer_info_offset); storage_info.SetMasterHashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer1Storage:
storage_info.SetLayer1HashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer2Storage:
storage_info.SetLayer2HashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer3Storage:
storage_info.SetLayer3HashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer4Storage:
storage_info.SetLayer4HashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::Layer5Storage:
storage_info.SetLayer5HashStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::DataStorage:
storage_info.SetDataStorage(std::make_shared<OffsetVfsFile>(std::move(base_storage), layer_info.size, last_layer_info_offset));
break;
}
// Make the integrity romfs storage. // Make the integrity romfs storage.
auto integrity_storage = std::make_shared<IntegrityRomFsStorage>(); auto integrity_storage = std::make_shared<IntegrityRomFsStorage>();

View file

@ -1,9 +1,14 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#pragma once #pragma once
#include <functional> #include <functional>
#include <memory>
#include "core/frontend/applets/applet.h" #include "core/frontend/applets/applet.h"
#include "core/hle/service/nfp/nfp_types.h" #include "core/hle/service/nfp/nfp_types.h"

View file

@ -135,8 +135,8 @@ NvResult nvhost_nvdec_common::GetSyncpoint(IoctlGetSyncpoint& params) {
} }
NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) { NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) {
LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); LOG_DEBUG(Service_NVDRV, "called WAITBASE");
params.value = 0; // Seems to be hard coded at 0 params.value = 0;
return NvResult::Success; return NvResult::Success;
} }

View file

@ -53,6 +53,19 @@ enum class NetDbError : s32 {
NoData = 4, NoData = 4,
}; };
static const constexpr std::array blockedDomains = {"srv.nintendo.net",
"battle.net",
"microsoft.com",
"mojang.com",
"xboxlive.com",
"minecraftservices.com"};
static bool IsBlockedHost(const std::string& host) {
return std::any_of(
blockedDomains.begin(), blockedDomains.end(),
[&host](const std::string& domain) { return host.find(domain) != std::string::npos; });
}
static NetDbError GetAddrInfoErrorToNetDbError(GetAddrInfoError result) { static NetDbError GetAddrInfoErrorToNetDbError(GetAddrInfoError result) {
// These combinations have been verified on console (but are not // These combinations have been verified on console (but are not
// exhaustive). // exhaustive).
@ -154,7 +167,7 @@ static std::pair<u32, GetAddrInfoError> GetHostByNameRequestImpl(HLERequestConte
// For now, ignore options, which are in input buffer 1 for GetHostByNameRequestWithOptions. // For now, ignore options, which are in input buffer 1 for GetHostByNameRequestWithOptions.
// Prevent resolution of Nintendo servers // Prevent resolution of Nintendo servers
if (host.find("srv.nintendo.net") != std::string::npos) { if (IsBlockedHost(host)) {
LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host);
return {0, GetAddrInfoError::AGAIN}; return {0, GetAddrInfoError::AGAIN};
} }
@ -271,7 +284,7 @@ static std::pair<u32, GetAddrInfoError> GetAddrInfoRequestImpl(HLERequestContext
const std::string host = Common::StringFromBuffer(host_buffer); const std::string host = Common::StringFromBuffer(host_buffer);
// Prevent resolution of Nintendo servers // Prevent resolution of Nintendo servers
if (host.find("srv.nintendo.net") != std::string::npos) { if (IsBlockedHost(host)) {
LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host); LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host);
return {0, GetAddrInfoError::AGAIN}; return {0, GetAddrInfoError::AGAIN};
} }
@ -359,5 +372,4 @@ void SFDNSRES::ResolverSetOptionRequest(HLERequestContext& ctx) {
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.Push<s32>(0); // bsd errno rb.Push<s32>(0); // bsd errno
} }
} // namespace Service::Sockets } // namespace Service::Sockets

View file

@ -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-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -286,7 +289,7 @@ Result CheckOpenSSLErrors() {
msg.append(data); msg.append(data);
} }
Common::Log::FmtLogMessage(Common::Log::Class::Service_SSL, Common::Log::Level::Error, Common::Log::FmtLogMessage(Common::Log::Class::Service_SSL, Common::Log::Level::Error,
Common::Log::TrimSourcePath(file), line, func, "OpenSSL: {}", file, line, func, "OpenSSL: {}",
msg); msg);
} }
return ResultInternalError; return ResultInternalError;

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -5,6 +8,8 @@
#include <variant> #include <variant>
#include <vector> #include <vector>
#include <memory>
#include <fmt/printf.h> #include <fmt/printf.h>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/memory/dmnt_cheat_types.h" #include "core/memory/dmnt_cheat_types.h"

View file

@ -1,9 +1,10 @@
{ {
"biscuit": { "biscuit": {
"version": "0.9.1",
"repo": "lioncash/biscuit", "repo": "lioncash/biscuit",
"sha": "76b0be8dae", "tag": "v%VERSION%",
"hash": "47d55ed02d032d6cf3dc107c6c0a9aea686d5f25aefb81d1af91db027b6815bd5add1755505e19d76625feeb17aa2db6cd1668fe0dad2e6a411519bde6ca4489" "hash": "1229f345b014f7ca544dedb4edb3311e41ba736f9aa9a67f88b5f26f3c983288c6bb6cdedcfb0b8a02c63088a37e6a0d7ba97d9c2a4d721b213916327cffe28a",
"version": "0.9.1",
"git_version": "0.19.0"
}, },
"mcl": { "mcl": {
"version": "0.1.12", "version": "0.1.12",

View file

@ -2,7 +2,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
include(TargetArchitectureSpecificSources) include(TargetArchitectureSpecificSources)
add_library(dynarmic add_library(dynarmic STATIC
backend/block_range_information.cpp backend/block_range_information.cpp
backend/block_range_information.h backend/block_range_information.h
backend/exception_handler.h backend/exception_handler.h

View file

@ -1,9 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
// TODO(crueter): This is identical to root common_types.h
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <cstdlib>
#include <array> #include <array>
using u8 = std::uint8_t; ///< 8-bit unsigned byte using u8 = std::uint8_t; ///< 8-bit unsigned byte

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
* Copyright (c) 2020 MerryMage * Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
@ -34,6 +37,8 @@ enum class OptimizationFlag : std::uint32_t {
MiscIROpt = 0x00000020, MiscIROpt = 0x00000020,
/// Optimize for code speed rather than for code size (this serves well for tight loops) /// Optimize for code speed rather than for code size (this serves well for tight loops)
CodeSpeed = 0x00000040, CodeSpeed = 0x00000040,
/// Disable verification passes
DisableVerification = 0x00000080,
/// This is an UNSAFE optimization that reduces accuracy of fused multiply-add operations. /// This is an UNSAFE optimization that reduces accuracy of fused multiply-add operations.
/// This unfuses fused instructions to improve performance on host CPUs without FMA support. /// This unfuses fused instructions to improve performance on host CPUs without FMA support.

View file

@ -1491,9 +1491,9 @@ void Optimize(IR::Block& block, const A32::UserConfig& conf, const Optimization:
Optimization::DeadCodeElimination(block); Optimization::DeadCodeElimination(block);
} }
Optimization::IdentityRemovalPass(block); Optimization::IdentityRemovalPass(block);
//if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
Optimization::VerificationPass(block); Optimization::VerificationPass(block);
//} }
} }
void Optimize(IR::Block& block, const A64::UserConfig& conf, const Optimization::PolyfillOptions& polyfill_options) { void Optimize(IR::Block& block, const A64::UserConfig& conf, const Optimization::PolyfillOptions& polyfill_options) {
@ -1511,9 +1511,9 @@ void Optimize(IR::Block& block, const A64::UserConfig& conf, const Optimization:
if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) [[likely]] { if (conf.HasOptimization(OptimizationFlag::MiscIROpt)) [[likely]] {
Optimization::A64MergeInterpretBlocksPass(block, conf.callbacks); Optimization::A64MergeInterpretBlocksPass(block, conf.callbacks);
} }
//if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) { if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
Optimization::VerificationPass(block); Optimization::VerificationPass(block);
//} }
} }
} // namespace Dynarmic::Optimization } // namespace Dynarmic::Optimization

View file

@ -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-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
@ -5,6 +8,7 @@
#include <array> #include <array>
#include <mutex> #include <mutex>
#include <memory>
#include "common/bit_field.h" #include "common/bit_field.h"
#include "common/common_types.h" #include "common/common_types.h"

View file

@ -1,9 +1,13 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#pragma once #pragma once
#include <mutex> #include <mutex>
#include <memory>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/result.h" #include "core/hle/result.h"

View file

@ -1,9 +1,13 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#pragma once #pragma once
#include <mutex> #include <mutex>
#include <memory>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/result.h" #include "core/hle/result.h"

View file

@ -1,9 +1,13 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#pragma once #pragma once
#include <mutex> #include <mutex>
#include <memory>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/result.h" #include "core/hle/result.h"

View file

@ -43,7 +43,7 @@ endif()
add_subdirectory(externals) add_subdirectory(externals)
target_link_libraries(qt_common PRIVATE core Qt6::Core SimpleIni::SimpleIni QuaZip::QuaZip frozen::frozen) target_link_libraries(qt_common PRIVATE core Qt6::Core SimpleIni::SimpleIni QuaZip::QuaZip)
if (NOT APPLE AND ENABLE_OPENGL) if (NOT APPLE AND ENABLE_OPENGL)
target_compile_definitions(qt_common PUBLIC HAS_OPENGL) target_compile_definitions(qt_common PUBLIC HAS_OPENGL)

View file

@ -17,4 +17,4 @@ AddJsonPackage(quazip)
# frozen # frozen
# TODO(crueter): Qt String Lookup # TODO(crueter): Qt String Lookup
AddJsonPackage(frozen) # AddJsonPackage(frozen)

View file

@ -544,6 +544,7 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
PAIR(ResolutionSetup, Res1_2X, tr("0.5X (360p/540p) [EXPERIMENTAL]")), PAIR(ResolutionSetup, Res1_2X, tr("0.5X (360p/540p) [EXPERIMENTAL]")),
PAIR(ResolutionSetup, Res3_4X, tr("0.75X (540p/810p) [EXPERIMENTAL]")), PAIR(ResolutionSetup, Res3_4X, tr("0.75X (540p/810p) [EXPERIMENTAL]")),
PAIR(ResolutionSetup, Res1X, tr("1X (720p/1080p)")), PAIR(ResolutionSetup, Res1X, tr("1X (720p/1080p)")),
PAIR(ResolutionSetup, Res5_4X, tr("1.25X (900p/1350p) [EXPERIMENTAL]")),
PAIR(ResolutionSetup, Res3_2X, tr("1.5X (1080p/1620p) [EXPERIMENTAL]")), PAIR(ResolutionSetup, Res3_2X, tr("1.5X (1080p/1620p) [EXPERIMENTAL]")),
PAIR(ResolutionSetup, Res2X, tr("2X (1440p/2160p)")), PAIR(ResolutionSetup, Res2X, tr("2X (1440p/2160p)")),
PAIR(ResolutionSetup, Res3X, tr("3X (2160p/3240p)")), PAIR(ResolutionSetup, Res3X, tr("3X (2160p/3240p)")),

View file

@ -246,7 +246,7 @@ add_library(shader_recompiler STATIC
) )
target_link_libraries(shader_recompiler PUBLIC common fmt::fmt sirit SPIRV-Tools::SPIRV-Tools) target_link_libraries(shader_recompiler PUBLIC common fmt::fmt sirit::sirit SPIRV-Tools::SPIRV-Tools)
if (MSVC) if (MSVC)
target_compile_options(shader_recompiler PRIVATE target_compile_options(shader_recompiler PRIVATE

View file

@ -991,6 +991,7 @@ IR::AbstractSyntaxList BuildASL(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::
Statement& root{goto_pass.RootStatement()}; Statement& root{goto_pass.RootStatement()};
IR::AbstractSyntaxList syntax_list; IR::AbstractSyntaxList syntax_list;
TranslatePass{inst_pool, block_pool, stmt_pool, env, root, syntax_list, host_info}; TranslatePass{inst_pool, block_pool, stmt_pool, env, root, syntax_list, host_info};
stmt_pool.ReleaseContents();
return syntax_list; return syntax_list;
} }

View file

@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project # SPDX-FileCopyrightText: 2018 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
@ -21,7 +24,7 @@ add_executable(tests
create_target_directory_groups(tests) create_target_directory_groups(tests)
target_link_libraries(tests PRIVATE common core input_common) target_link_libraries(tests PRIVATE common core input_common video_core)
target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} Catch2::Catch2WithMain Threads::Threads) target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} Catch2::Catch2WithMain Threads::Threads)
add_test(NAME tests COMMAND tests) add_test(NAME tests COMMAND tests)

View file

@ -333,7 +333,7 @@ target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS})
add_dependencies(video_core host_shaders) add_dependencies(video_core host_shaders)
target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE}) target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE})
target_link_libraries(video_core PRIVATE sirit) target_link_libraries(video_core PRIVATE sirit::sirit)
# Header-only stuff needed by all dependent targets # Header-only stuff needed by all dependent targets
target_link_libraries(video_core PUBLIC Vulkan::UtilityHeaders GPUOpen::VulkanMemoryAllocator) target_link_libraries(video_core PUBLIC Vulkan::UtilityHeaders GPUOpen::VulkanMemoryAllocator)

View file

@ -26,7 +26,9 @@ BufferCache<P>::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, R
void(slot_buffers.insert(runtime, NullBufferParams{})); void(slot_buffers.insert(runtime, NullBufferParams{}));
gpu_modified_ranges.Clear(); gpu_modified_ranges.Clear();
inline_buffer_id = NULL_BUFFER_ID; inline_buffer_id = NULL_BUFFER_ID;
#ifdef YUZU_LEGACY
immediately_free = (Settings::values.vram_usage_mode.GetValue() == Settings::VramUsageMode::Aggressive);
#endif
if (!runtime.CanReportMemoryUsage()) { if (!runtime.CanReportMemoryUsage()) {
minimum_memory = DEFAULT_EXPECTED_MEMORY; minimum_memory = DEFAULT_EXPECTED_MEMORY;
critical_memory = DEFAULT_CRITICAL_MEMORY; critical_memory = DEFAULT_CRITICAL_MEMORY;
@ -1378,6 +1380,10 @@ void BufferCache<P>::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id,
}); });
new_buffer.MarkUsage(copies[0].dst_offset, copies[0].size); new_buffer.MarkUsage(copies[0].dst_offset, copies[0].size);
runtime.CopyBuffer(new_buffer, overlap, copies, true); runtime.CopyBuffer(new_buffer, overlap, copies, true);
#ifdef YUZU_LEGACY
if (immediately_free)
runtime.Finish();
#endif
DeleteBuffer(overlap_id, true); DeleteBuffer(overlap_id, true);
} }
@ -1668,7 +1674,12 @@ void BufferCache<P>::DeleteBuffer(BufferId buffer_id, bool do_not_mark) {
} }
Unregister(buffer_id); Unregister(buffer_id);
delayed_destruction_ring.Push(std::move(slot_buffers[buffer_id]));
#ifdef YUZU_LEGACY
if (!do_not_mark || !immediately_free)
#endif
delayed_destruction_ring.Push(std::move(slot_buffers[buffer_id]));
slot_buffers.erase(buffer_id); slot_buffers.erase(buffer_id);
if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {

View file

@ -154,7 +154,11 @@ template <class P>
class BufferCache : public VideoCommon::ChannelSetupCaches<BufferCacheChannelInfo> { class BufferCache : public VideoCommon::ChannelSetupCaches<BufferCacheChannelInfo> {
// Page size for caching purposes. // Page size for caching purposes.
// This is unrelated to the CPU page size and it can be changed as it seems optimal. // This is unrelated to the CPU page size and it can be changed as it seems optimal.
#ifdef YUZU_LEGACY
static constexpr u32 CACHING_PAGEBITS = 12;
#else
static constexpr u32 CACHING_PAGEBITS = 16; static constexpr u32 CACHING_PAGEBITS = 16;
#endif
static constexpr u64 CACHING_PAGESIZE = u64{1} << CACHING_PAGEBITS; static constexpr u64 CACHING_PAGESIZE = u64{1} << CACHING_PAGEBITS;
static constexpr bool IS_OPENGL = P::IS_OPENGL; static constexpr bool IS_OPENGL = P::IS_OPENGL;
@ -168,9 +172,14 @@ class BufferCache : public VideoCommon::ChannelSetupCaches<BufferCacheChannelInf
static constexpr bool SEPARATE_IMAGE_BUFFERS_BINDINGS = P::SEPARATE_IMAGE_BUFFER_BINDINGS; static constexpr bool SEPARATE_IMAGE_BUFFERS_BINDINGS = P::SEPARATE_IMAGE_BUFFER_BINDINGS;
static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = P::USE_MEMORY_MAPS_FOR_UPLOADS; static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = P::USE_MEMORY_MAPS_FOR_UPLOADS;
#ifdef YUZU_LEGACY
static constexpr s64 TARGET_THRESHOLD = 3_GiB;
#else
static constexpr s64 TARGET_THRESHOLD = 4_GiB;
#endif
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 512_MiB; static constexpr s64 DEFAULT_EXPECTED_MEMORY = 512_MiB;
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB; static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB;
static constexpr s64 TARGET_THRESHOLD = 4_GiB;
// Debug Flags. // Debug Flags.
@ -446,7 +455,12 @@ private:
Tegra::MaxwellDeviceMemoryManager& device_memory; Tegra::MaxwellDeviceMemoryManager& device_memory;
Common::SlotVector<Buffer> slot_buffers; Common::SlotVector<Buffer> slot_buffers;
DelayedDestructionRing<Buffer, 8> delayed_destruction_ring; #ifdef YUZU_LEGACY
static constexpr size_t TICKS_TO_DESTROY = 6;
#else
static constexpr size_t TICKS_TO_DESTROY = 8;
#endif
DelayedDestructionRing<Buffer, TICKS_TO_DESTROY> delayed_destruction_ring;
const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{}; const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{};
@ -478,6 +492,9 @@ private:
u64 minimum_memory = 0; u64 minimum_memory = 0;
u64 critical_memory = 0; u64 critical_memory = 0;
BufferId inline_buffer_id; BufferId inline_buffer_id;
#ifdef YUZU_LEGACY
bool immediately_free = false;
#endif
std::array<BufferId, ((1ULL << 34) >> CACHING_PAGEBITS)> page_table; std::array<BufferId, ((1ULL << 34) >> CACHING_PAGEBITS)> page_table;
Common::ScratchBuffer<u8> tmp_buffer; Common::ScratchBuffer<u8> tmp_buffer;

View file

@ -39,8 +39,8 @@ void CDmaPusher::ProcessEntries(std::stop_token stop_token) {
while (!stop_token.stop_requested()) { while (!stop_token.stop_requested()) {
{ {
std::unique_lock l{command_mutex}; std::unique_lock l{command_mutex};
Common::CondvarWait(command_cv, l, stop_token, command_cv.wait(l, stop_token,
[this]() { return command_lists.size() > 0; }); [this]() { return command_lists.size() > 0; });
if (stop_token.stop_requested()) { if (stop_token.stop_requested()) {
return; return;
} }

View file

@ -64,7 +64,6 @@ void MaxwellDMA::Launch() {
// TODO(Subv): Perform more research and implement all features of this engine. // TODO(Subv): Perform more research and implement all features of this engine.
const LaunchDMA& launch = regs.launch_dma; const LaunchDMA& launch = regs.launch_dma;
ASSERT(launch.interrupt_type == LaunchDMA::InterruptType::NONE); ASSERT(launch.interrupt_type == LaunchDMA::InterruptType::NONE);
ASSERT(launch.data_transfer_type == LaunchDMA::DataTransferType::NON_PIPELINED);
if (launch.multi_line_enable) { if (launch.multi_line_enable) {
const bool is_src_pitch = launch.src_memory_layout == LaunchDMA::MemoryLayout::PITCH; const bool is_src_pitch = launch.src_memory_layout == LaunchDMA::MemoryLayout::PITCH;
@ -157,7 +156,7 @@ void MaxwellDMA::Launch() {
} }
void MaxwellDMA::CopyBlockLinearToPitch() { void MaxwellDMA::CopyBlockLinearToPitch() {
UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0);
u32 bytes_per_pixel = 1; u32 bytes_per_pixel = 1;
DMA::ImageOperand src_operand; DMA::ImageOperand src_operand;

View file

@ -116,7 +116,7 @@ u64 ThreadManager::PushCommand(CommandData&& command_data, bool block) {
state.queue.EmplaceWait(std::move(command_data), fence, block); state.queue.EmplaceWait(std::move(command_data), fence, block);
if (block) { if (block) {
Common::CondvarWait(state.cv, lk, thread.get_stop_token(), [this, fence] { state.cv.wait(lk, thread.get_stop_token(), [this, fence] {
return fence <= state.signaled_fence.load(std::memory_order_relaxed); return fence <= state.signaled_fence.load(std::memory_order_relaxed);
}); });
} }

View file

@ -38,6 +38,10 @@ void Decoder::Decode() {
// Receive output frames from decoder. // Receive output frames from decoder.
auto frame = decode_api.ReceiveFrame(); auto frame = decode_api.ReceiveFrame();
if (!frame) {
return;
}
if (IsInterlaced()) { if (IsInterlaced()) {
auto [luma_top, luma_bottom, chroma_top, chroma_bottom] = GetInterlacedOffsets(); auto [luma_top, luma_bottom, chroma_top, chroma_bottom] = GetInterlacedOffsets();
auto frame_copy = frame; auto frame_copy = frame;

View file

@ -233,7 +233,7 @@ bool DecoderContext::OpenContext(const Decoder& decoder) {
} }
bool DecoderContext::SendPacket(const Packet& packet) { bool DecoderContext::SendPacket(const Packet& packet) {
if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0 && ret != AVERROR_EOF) { if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) {
LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret)); LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret));
return false; return false;
} }
@ -242,31 +242,31 @@ bool DecoderContext::SendPacket(const Packet& packet) {
} }
std::shared_ptr<Frame> DecoderContext::ReceiveFrame() { std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
auto ReceiveImpl = [&](AVFrame* frame) -> bool { auto ReceiveImpl = [&](AVFrame* frame) -> int {
if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0 && ret != AVERROR_EOF) { const int ret = avcodec_receive_frame(m_codec_context, frame);
if (ret < 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) {
LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret)); LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret));
return false;
} }
return true; return ret;
}; };
std::shared_ptr<Frame> intermediate_frame = std::make_shared<Frame>(); std::shared_ptr<Frame> intermediate_frame = std::make_shared<Frame>();
if (!ReceiveImpl(intermediate_frame->GetFrame())) { if (ReceiveImpl(intermediate_frame->GetFrame()) < 0) {
return {}; return {};
} }
m_temp_frame = std::make_shared<Frame>(); m_final_frame = std::make_shared<Frame>();
if (m_codec_context->hw_device_ctx) { if (m_codec_context->hw_device_ctx) {
m_temp_frame->SetFormat(PreferredGpuFormat); m_final_frame->SetFormat(PreferredGpuFormat);
if (int ret = av_hwframe_transfer_data(m_temp_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) { if (const int ret = av_hwframe_transfer_data(m_final_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) {
LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret)); LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret));
return {}; return {};
} }
} else { } else {
m_temp_frame = std::move(intermediate_frame); m_final_frame = std::move(intermediate_frame);
} }
return std::move(m_temp_frame); return std::move(m_final_frame);
} }
void DecodeApi::Reset() { void DecodeApi::Reset() {

View file

@ -194,7 +194,7 @@ public:
private: private:
const Decoder& m_decoder; const Decoder& m_decoder;
AVCodecContext* m_codec_context{}; AVCodecContext* m_codec_context{};
std::shared_ptr<Frame> m_temp_frame{}; std::shared_ptr<Frame> m_final_frame{};
bool m_decode_order{}; bool m_decode_order{};
}; };

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-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
@ -18,9 +21,15 @@ Host1x::~Host1x() = default;
void Host1x::StartDevice(s32 fd, ChannelType type, u32 syncpt) { void Host1x::StartDevice(s32 fd, ChannelType type, u32 syncpt) {
switch (type) { switch (type) {
case ChannelType::NvDec: case ChannelType::NvDec:
#ifdef YUZU_LEGACY
std::call_once(nvdec_first_init, []() {std::this_thread::sleep_for(std::chrono::milliseconds{500});}); // HACK: For Astroneer
#endif
devices[fd] = std::make_unique<Tegra::Host1x::Nvdec>(*this, fd, syncpt, frame_queue); devices[fd] = std::make_unique<Tegra::Host1x::Nvdec>(*this, fd, syncpt, frame_queue);
break; break;
case ChannelType::VIC: case ChannelType::VIC:
#ifdef YUZU_LEGACY
std::call_once(vic_first_init, []() {std::this_thread::sleep_for(std::chrono::milliseconds{500});}); // HACK: For Astroneer
#endif
devices[fd] = std::make_unique<Tegra::Host1x::Vic>(*this, fd, syncpt, frame_queue); devices[fd] = std::make_unique<Tegra::Host1x::Vic>(*this, fd, syncpt, frame_queue);
break; break;
default: default:

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-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
@ -201,6 +204,10 @@ private:
std::unique_ptr<Common::FlatAllocator<u32, 0, 32>> allocator; std::unique_ptr<Common::FlatAllocator<u32, 0, 32>> allocator;
FrameQueue frame_queue; FrameQueue frame_queue;
std::unordered_map<s32, std::unique_ptr<CDmaPusher>> devices; std::unordered_map<s32, std::unique_ptr<CDmaPusher>> devices;
#ifdef YUZU_LEGACY
std::once_flag nvdec_first_init;
std::once_flag vic_first_init;
#endif
}; };
} // namespace Tegra::Host1x } // namespace Tegra::Host1x

View file

@ -146,6 +146,11 @@ void Vic::Execute() {
} }
auto frame = frame_queue.GetFrame(nvdec_id, luma_offset); auto frame = frame_queue.GetFrame(nvdec_id, luma_offset);
if (!frame) {
continue;
}
if (!frame.get()) { if (!frame.get()) {
LOG_ERROR(HW_GPU, "Vic {} failed to get frame with offset {:#X}", id, luma_offset); LOG_ERROR(HW_GPU, "Vic {} failed to get frame with offset {:#X}", id, luma_offset);
continue; continue;

View file

@ -54,7 +54,7 @@ using VideoCommon::LoadPipelines;
using VideoCommon::SerializePipeline; using VideoCommon::SerializePipeline;
using Context = ShaderContext::Context; using Context = ShaderContext::Context;
constexpr u32 CACHE_VERSION = 10; constexpr u32 CACHE_VERSION = 13;
template <typename Container> template <typename Container>
auto MakeSpan(Container& container) { auto MakeSpan(Container& container) {

View file

@ -46,6 +46,38 @@ namespace Vulkan {
using VideoCommon::ImageViewType; using VideoCommon::ImageViewType;
namespace { namespace {
[[nodiscard]] VkImageAspectFlags AspectMaskFromFormat(VideoCore::Surface::PixelFormat format) {
using VideoCore::Surface::SurfaceType;
switch (VideoCore::Surface::GetFormatType(format)) {
case SurfaceType::ColorTexture:
return VK_IMAGE_ASPECT_COLOR_BIT;
case SurfaceType::Depth:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case SurfaceType::Stencil:
return VK_IMAGE_ASPECT_STENCIL_BIT;
case SurfaceType::DepthStencil:
return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
default:
return VK_IMAGE_ASPECT_COLOR_BIT;
}
}
[[nodiscard]] VkImageSubresourceRange SubresourceRangeFromView(const ImageView& image_view) {
auto range = image_view.range;
if ((image_view.flags & VideoCommon::ImageViewFlagBits::Slice) != VideoCommon::ImageViewFlagBits{}) {
range.base.layer = 0;
range.extent.layers = 1;
}
return VkImageSubresourceRange{
.aspectMask = AspectMaskFromFormat(image_view.format),
.baseMipLevel = static_cast<u32>(range.base.level),
.levelCount = static_cast<u32>(range.extent.levels),
.baseArrayLayer = static_cast<u32>(range.base.layer),
.layerCount = static_cast<u32>(range.extent.layers),
};
}
struct PushConstants { struct PushConstants {
std::array<float, 2> tex_scale; std::array<float, 2> tex_scale;
std::array<float, 2> tex_offset; std::array<float, 2> tex_offset;
@ -417,6 +449,40 @@ void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayo
0, barrier); 0, barrier);
} }
void RecordShaderReadBarrier(Scheduler& scheduler, const ImageView& image_view) {
const VkImage image = image_view.ImageHandle();
const VkImageSubresourceRange subresource_range = SubresourceRangeFromView(image_view);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([image, subresource_range](vk::CommandBuffer cmdbuf) {
const VkImageMemoryBarrier barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
VK_ACCESS_SHADER_WRITE_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image,
.subresourceRange = subresource_range,
};
cmdbuf.PipelineBarrier(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_TRANSFER_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0,
barrier);
});
}
void BeginRenderPass(vk::CommandBuffer& cmdbuf, const Framebuffer* framebuffer) { void BeginRenderPass(vk::CommandBuffer& cmdbuf, const Framebuffer* framebuffer) {
const VkRenderPass render_pass = framebuffer->RenderPass(); const VkRenderPass render_pass = framebuffer->RenderPass();
const VkFramebuffer framebuffer_handle = framebuffer->Handle(); const VkFramebuffer framebuffer_handle = framebuffer->Handle();
@ -484,7 +550,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
BlitImageHelper::~BlitImageHelper() = default; BlitImageHelper::~BlitImageHelper() = default;
void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView src_view, void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
const Region2D& dst_region, const Region2D& src_region, const Region2D& dst_region, const Region2D& src_region,
Tegra::Engines::Fermi2D::Filter filter, Tegra::Engines::Fermi2D::Filter filter,
Tegra::Engines::Fermi2D::Operation operation) { Tegra::Engines::Fermi2D::Operation operation) {
@ -496,10 +562,12 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView
const VkPipelineLayout layout = *one_texture_pipeline_layout; const VkPipelineLayout layout = *one_texture_pipeline_layout;
const VkSampler sampler = is_linear ? *linear_sampler : *nearest_sampler; const VkSampler sampler = is_linear ? *linear_sampler : *nearest_sampler;
const VkPipeline pipeline = FindOrEmplaceColorPipeline(key); const VkPipeline pipeline = FindOrEmplaceColorPipeline(key);
const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D);
RecordShaderReadBarrier(scheduler, src_image_view);
scheduler.RequestRenderpass(dst_framebuffer); scheduler.RequestRenderpass(dst_framebuffer);
scheduler.Record([this, dst_region, src_region, pipeline, layout, sampler, scheduler.Record([this, dst_region, src_region, pipeline, layout, sampler,
src_view](vk::CommandBuffer cmdbuf) { src_view](vk::CommandBuffer cmdbuf) {
// TODO: Barriers
const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view); UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view);
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
@ -538,7 +606,7 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView
} }
void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer, void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
VkImageView src_depth_view, VkImageView src_stencil_view, ImageView& src_image_view,
const Region2D& dst_region, const Region2D& src_region, const Region2D& dst_region, const Region2D& src_region,
Tegra::Engines::Fermi2D::Filter filter, Tegra::Engines::Fermi2D::Filter filter,
Tegra::Engines::Fermi2D::Operation operation) { Tegra::Engines::Fermi2D::Operation operation) {
@ -554,10 +622,13 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
const VkPipelineLayout layout = *two_textures_pipeline_layout; const VkPipelineLayout layout = *two_textures_pipeline_layout;
const VkSampler sampler = *nearest_sampler; const VkSampler sampler = *nearest_sampler;
const VkPipeline pipeline = FindOrEmplaceDepthStencilPipeline(key); const VkPipeline pipeline = FindOrEmplaceDepthStencilPipeline(key);
const VkImageView src_depth_view = src_image_view.DepthView();
const VkImageView src_stencil_view = src_image_view.StencilView();
RecordShaderReadBarrier(scheduler, src_image_view);
scheduler.RequestRenderpass(dst_framebuffer); scheduler.RequestRenderpass(dst_framebuffer);
scheduler.Record([dst_region, src_region, pipeline, layout, sampler, src_depth_view, scheduler.Record([dst_region, src_region, pipeline, layout, sampler, src_depth_view,
src_stencil_view, this](vk::CommandBuffer cmdbuf) { src_stencil_view, this](vk::CommandBuffer cmdbuf) {
// TODO: Barriers
const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit(); const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit();
UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view, UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view,
src_stencil_view); src_stencil_view);
@ -692,6 +763,7 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb
const VkSampler sampler = *nearest_sampler; const VkSampler sampler = *nearest_sampler;
const VkExtent2D extent = GetConversionExtent(src_image_view); const VkExtent2D extent = GetConversionExtent(src_image_view);
RecordShaderReadBarrier(scheduler, src_image_view);
scheduler.RequestRenderpass(dst_framebuffer); scheduler.RequestRenderpass(dst_framebuffer);
scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) { scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) {
const VkOffset2D offset{ const VkOffset2D offset{
@ -717,7 +789,6 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb
const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view); UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view);
// TODO: Barriers
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
nullptr); nullptr);
@ -737,6 +808,7 @@ void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer
const VkSampler sampler = *nearest_sampler; const VkSampler sampler = *nearest_sampler;
const VkExtent2D extent = GetConversionExtent(src_image_view); const VkExtent2D extent = GetConversionExtent(src_image_view);
RecordShaderReadBarrier(scheduler, src_image_view);
scheduler.RequestRenderpass(dst_framebuffer); scheduler.RequestRenderpass(dst_framebuffer);
scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent, scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent,
this](vk::CommandBuffer cmdbuf) { this](vk::CommandBuffer cmdbuf) {
@ -763,7 +835,6 @@ void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer
const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit(); const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit();
UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view, UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view,
src_stencil_view); src_stencil_view);
// TODO: Barriers
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
nullptr); nullptr);

View file

@ -1,4 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#pragma once #pragma once
@ -43,7 +46,7 @@ public:
StateTracker& state_tracker, DescriptorPool& descriptor_pool); StateTracker& state_tracker, DescriptorPool& descriptor_pool);
~BlitImageHelper(); ~BlitImageHelper();
void BlitColor(const Framebuffer* dst_framebuffer, VkImageView src_image_view, void BlitColor(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
const Region2D& dst_region, const Region2D& src_region, const Region2D& dst_region, const Region2D& src_region,
Tegra::Engines::Fermi2D::Filter filter, Tegra::Engines::Fermi2D::Filter filter,
Tegra::Engines::Fermi2D::Operation operation); Tegra::Engines::Fermi2D::Operation operation);
@ -52,9 +55,9 @@ public:
VkImage src_image, VkSampler src_sampler, const Region2D& dst_region, VkImage src_image, VkSampler src_sampler, const Region2D& dst_region,
const Region2D& src_region, const Extent3D& src_size); const Region2D& src_region, const Extent3D& src_size);
void BlitDepthStencil(const Framebuffer* dst_framebuffer, VkImageView src_depth_view, void BlitDepthStencil(const Framebuffer* dst_framebuffer, ImageView& src_image_view,
VkImageView src_stencil_view, const Region2D& dst_region, const Region2D& dst_region, const Region2D& src_region,
const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, Tegra::Engines::Fermi2D::Filter filter,
Tegra::Engines::Fermi2D::Operation operation); Tegra::Engines::Fermi2D::Operation operation);
void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);

View file

@ -280,6 +280,7 @@ void Layer::UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t i
Tegra::Texture::UnswizzleTexture( Tegra::Texture::UnswizzleTexture(
mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size), 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); 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{ const VkBufferImageCopy copy{

View file

@ -208,7 +208,7 @@ void MasterSemaphore::WaitThread(std::stop_token token) {
vk::Fence fence; vk::Fence fence;
{ {
std::unique_lock lock{wait_mutex}; std::unique_lock lock{wait_mutex};
Common::CondvarWait(wait_cv, lock, token, [this] { return !wait_queue.empty(); }); wait_cv.wait(lock, token, [this] { return !wait_queue.empty(); });
if (token.stop_requested()) { if (token.stop_requested()) {
return; return;
} }

View file

@ -55,7 +55,7 @@ using VideoCommon::FileEnvironment;
using VideoCommon::GenericEnvironment; using VideoCommon::GenericEnvironment;
using VideoCommon::GraphicsEnvironment; using VideoCommon::GraphicsEnvironment;
constexpr u32 CACHE_VERSION = 12; constexpr u32 CACHE_VERSION = 13;
constexpr std::array<char, 8> VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'}; constexpr std::array<char, 8> VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'};
template <typename Container> template <typename Container>

View file

@ -279,7 +279,7 @@ void PresentManager::PresentThread(std::stop_token token) {
std::unique_lock lock{queue_mutex}; std::unique_lock lock{queue_mutex};
// Wait for presentation frames // Wait for presentation frames
Common::CondvarWait(frame_cv, lock, token, [this] { return !present_queue.empty(); }); frame_cv.wait(lock, token, [this] { return !present_queue.empty(); });
if (token.stop_requested()) { if (token.stop_requested()) {
return; return;
} }

View file

@ -166,7 +166,7 @@ void Scheduler::WorkerThread(std::stop_token stop_token) {
std::unique_lock lk{queue_mutex}; std::unique_lock lk{queue_mutex};
// Wait for work. // Wait for work.
Common::CondvarWait(event_cv, lk, stop_token, [&] { return TryPopQueue(work); }); event_cv.wait(lk, stop_token, [&] { return TryPopQueue(work); });
// If we've been asked to stop, we're done. // If we've been asked to stop, we're done.
if (stop_token.stop_requested()) { if (stop_token.stop_requested()) {

View file

@ -1086,8 +1086,8 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
return; return;
} }
if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT && !is_src_msaa && !is_dst_msaa) { if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT && !is_src_msaa && !is_dst_msaa) {
blit_image_helper.BlitColor(dst_framebuffer, src.Handle(Shader::TextureType::Color2D), blit_image_helper.BlitColor(dst_framebuffer, src, dst_region, src_region, filter,
dst_region, src_region, filter, operation); operation);
return; return;
} }
ASSERT(src.format == dst.format); ASSERT(src.format == dst.format);
@ -1106,8 +1106,8 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
}(); }();
if (!can_blit_depth_stencil) { if (!can_blit_depth_stencil) {
UNIMPLEMENTED_IF(is_src_msaa || is_dst_msaa); UNIMPLEMENTED_IF(is_src_msaa || is_dst_msaa);
blit_image_helper.BlitDepthStencil(dst_framebuffer, src.DepthView(), src.StencilView(), blit_image_helper.BlitDepthStencil(dst_framebuffer, src, dst_region, src_region,
dst_region, src_region, filter, operation); filter, operation);
return; return;
} }
} }
@ -1968,18 +1968,17 @@ bool Image::BlitScaleHelper(bool scale_up) {
blit_framebuffer = blit_framebuffer =
std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent, scale_up); std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent, scale_up);
} }
const auto color_view = blit_view->Handle(Shader::TextureType::Color2D);
runtime->blit_image_helper.BlitColor(blit_framebuffer.get(), color_view, dst_region, runtime->blit_image_helper.BlitColor(blit_framebuffer.get(), *blit_view, dst_region,
src_region, operation, BLIT_OPERATION); src_region, operation, BLIT_OPERATION);
} else if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { } else if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
if (!blit_framebuffer) { if (!blit_framebuffer) {
blit_framebuffer = blit_framebuffer =
std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent, scale_up); std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent, scale_up);
} }
runtime->blit_image_helper.BlitDepthStencil(blit_framebuffer.get(), blit_view->DepthView(), runtime->blit_image_helper.BlitDepthStencil(blit_framebuffer.get(), *blit_view,
blit_view->StencilView(), dst_region, dst_region, src_region, operation,
src_region, operation, BLIT_OPERATION); BLIT_OPERATION);
} else { } else {
// TODO: Use helper blits where applicable // TODO: Use helper blits where applicable
flags &= ~ImageFlagBits::Rescaled; flags &= ~ImageFlagBits::Rescaled;

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -224,7 +227,7 @@ void TurboMode::Run(std::stop_token stop_token) {
#endif #endif
// Wait for the next graphics queue submission if necessary. // Wait for the next graphics queue submission if necessary.
std::unique_lock lk{m_submission_lock}; std::unique_lock lk{m_submission_lock};
Common::CondvarWait(m_submission_cv, lk, stop_token, [this] { m_submission_cv.wait(lk, stop_token, [this] {
return (std::chrono::steady_clock::now() - m_submission_time) <= return (std::chrono::steady_clock::now() - m_submission_time) <=
std::chrono::milliseconds{100}; std::chrono::milliseconds{100};
}); });

View file

@ -110,7 +110,12 @@ class TextureCache : public VideoCommon::ChannelSetupCaches<TextureCacheChannelI
static constexpr size_t UNSET_CHANNEL{(std::numeric_limits<size_t>::max)()}; static constexpr size_t UNSET_CHANNEL{(std::numeric_limits<size_t>::max)()};
#ifdef YUZU_LEGACY
static constexpr s64 TARGET_THRESHOLD = 3_GiB;
#else
static constexpr s64 TARGET_THRESHOLD = 4_GiB; static constexpr s64 TARGET_THRESHOLD = 4_GiB;
#endif
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB; static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB;
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB; static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB;
static constexpr size_t GC_EMERGENCY_COUNTS = 2; static constexpr size_t GC_EMERGENCY_COUNTS = 2;
@ -479,7 +484,11 @@ private:
}; };
Common::LeastRecentlyUsedCache<LRUItemParams> lru_cache; Common::LeastRecentlyUsedCache<LRUItemParams> lru_cache;
#ifdef YUZU_LEGACY
static constexpr size_t TICKS_TO_DESTROY = 6;
#else
static constexpr size_t TICKS_TO_DESTROY = 8; static constexpr size_t TICKS_TO_DESTROY = 8;
#endif
DelayedDestructionRing<Image, TICKS_TO_DESTROY> sentenced_images; DelayedDestructionRing<Image, TICKS_TO_DESTROY> sentenced_images;
DelayedDestructionRing<ImageView, TICKS_TO_DESTROY> sentenced_image_view; DelayedDestructionRing<ImageView, TICKS_TO_DESTROY> sentenced_image_view;
DelayedDestructionRing<Framebuffer, TICKS_TO_DESTROY> sentenced_framebuffers; DelayedDestructionRing<Framebuffer, TICKS_TO_DESTROY> sentenced_framebuffers;

View file

@ -10,4 +10,12 @@
#define VMA_STATIC_VULKAN_FUNCTIONS 0 #define VMA_STATIC_VULKAN_FUNCTIONS 0
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4189 )
#endif
#include "vk_mem_alloc.h" #include "vk_mem_alloc.h"
#ifdef _MSC_VER
#pragma warning( pop )
#endif

View file

@ -325,4 +325,6 @@ namespace Vulkan {
return MemoryCommit(allocator, a, info); return MemoryCommit(allocator, a, info);
} }
} // namespace Vulkan } // namespace Vulkan

View file

@ -366,7 +366,7 @@ if (APPLE)
set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE TRUE) set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE TRUE)
set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
if (YUZU_APPLE_USE_BUNDLED_MONTENVK) if (YUZU_USE_BUNDLED_MOLTENVK)
set(MOLTENVK_PLATFORM "macOS") set(MOLTENVK_PLATFORM "macOS")
set(MOLTENVK_VERSION "v1.3.0") set(MOLTENVK_VERSION "v1.3.0")
download_moltenvk(${MOLTENVK_PLATFORM} ${MOLTENVK_VERSION}) download_moltenvk(${MOLTENVK_PLATFORM} ${MOLTENVK_VERSION})
@ -397,8 +397,6 @@ if (NOT WIN32)
target_include_directories(yuzu PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS}) target_include_directories(yuzu PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
endif() endif()
target_link_libraries(yuzu PRIVATE Vulkan::Headers)
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
target_link_libraries(yuzu PRIVATE Qt6::DBus) target_link_libraries(yuzu PRIVATE Qt6::DBus)

Some files were not shown because too many files have changed in this diff Show more