Compare commits

...

20 Commits

Author SHA1 Message Date
lizzie
21b4c2fe86 fix
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-10-04 09:34:53 +02:00
lizzie
694ae45a58 [core/memory] Remove defered heap allocation on Linux.
Authored-by: weakboson <weakboson@eden-emu.dev>
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2025-10-04 09:34:53 +02:00
crueter
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: https://git.eden-emu.dev/eden-emu/eden/pulls/2655
2025-10-04 09:27:13 +02:00
lizzie
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
MaranBr
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: https://git.eden-emu.dev/eden-emu/eden/pulls/2650
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-03 23:08:20 +02:00
Calchan
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
lizzie
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
lizzie
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
MaranBr
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: https://git.eden-emu.dev/eden-emu/eden/pulls/2651
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-02 22:48:52 +02:00
Ribbit
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
MaranBr
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: https://git.eden-emu.dev/eden-emu/eden/pulls/2646
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-02 01:30:05 +02:00
lizzie
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
MaranBr
326865cba2 [host1x] Improve FFmpeg error handling (#2643)
This improves the FFmpeg error handling.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2643
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-10-02 00:15:14 +02:00
lizzie
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
Shinmegumi
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
Caio Oliveira
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
lizzie
020f1cdb1f [qt] fix ci missing build_id (#2638)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/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
lizzie
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
MaranBr
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
lizzie
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: https://git.eden-emu.dev/eden-emu/eden/pulls/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
65 changed files with 626 additions and 926 deletions

View File

@@ -147,6 +147,7 @@ if (ENABLE_SDL2)
option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}")
endif()
# qt stuff
option(ENABLE_QT "Enable the Qt frontend" ON)
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
option(ENABLE_QT_UPDATE_CHECKER "Enable update checker for the Qt frontend" OFF)
@@ -163,8 +164,12 @@ if (MSVC OR ANDROID)
endif()
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})
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)
@@ -224,7 +229,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_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)
@@ -312,13 +317,24 @@ endif()
if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX))
set(HAS_NCE 1)
add_compile_definitions(HAS_NCE=1)
find_package(oaknut 2.0.1)
endif()
if (YUZU_ROOM)
add_compile_definitions(YUZU_ROOM)
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
if (PLATFORM_LINUX OR CXX_CLANG)
if (ARCHITECTURE_x86_64)
@@ -440,22 +456,6 @@ if (YUZU_USE_CPM)
add_library(zstd::zstd ALIAS libzstd_static)
endif()
# 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()
# Opus
AddJsonPackage(opus)
@@ -470,31 +470,10 @@ if (YUZU_USE_CPM)
if (NOT TARGET Opus::opus)
add_library(Opus::opus ALIAS opus)
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()
# Enforce the search mode of non-required packages for better and shorter failure messages
find_package(fmt 8 REQUIRED)
if (NOT YUZU_DISABLE_LLVM)
find_package(LLVM MODULE COMPONENTS Demangle)
endif()
@@ -503,7 +482,7 @@ else()
find_package(lz4 REQUIRED)
find_package(RenderDoc MODULE)
find_package(stb MODULE)
find_package(enet 1.3 MODULE REQUIRED)
find_package(Opus 1.3 MODULE REQUIRED)
find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED MODULE)
@@ -515,29 +494,6 @@ else()
find_package(Boost 1.57.0 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()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID)
find_package(gamemode 1.7 MODULE)
endif()
@@ -551,90 +507,6 @@ if(NOT TARGET Boost::headers)
AddJsonPackage(boost_headers)
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
set(FFmpeg_COMPONENTS
avcodec
@@ -665,6 +537,11 @@ add_subdirectory(externals)
# pass targets from externals
find_package(libusb)
find_package(VulkanMemoryAllocator)
find_package(enet)
find_package(MbedTLS)
find_package(VulkanUtilityLibraries)
find_package(SimpleIni)
find_package(SPIRV-Tools)
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
find_package(xbyak)
@@ -678,6 +555,26 @@ if (ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER)
find_package(cpp-jwt)
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 (YUZU_USE_BUNDLED_QT)
download_qt(6.8.3)

View File

@@ -107,7 +107,6 @@ function(AddJsonPackage)
get_json_element("${object}" name name "${JSON_NAME}")
get_json_element("${object}" extension extension "tar.zst")
get_json_element("${object}" min_version min_version "")
get_json_element("${object}" cmake_filename cmake_filename "")
get_json_element("${object}" raw_disabled disabled_platforms "")
if (raw_disabled)
@@ -124,7 +123,6 @@ function(AddJsonPackage)
EXTENSION ${extension}
MIN_VERSION ${min_version}
DISABLED_PLATFORMS ${disabled_platforms}
CMAKE_FILENAME ${cmake_filename}
)
# pass stuff to parent scope
@@ -139,6 +137,7 @@ function(AddJsonPackage)
endif()
get_json_element("${object}" hash hash "")
get_json_element("${object}" hash_suffix hash_suffix "")
get_json_element("${object}" sha sha "")
get_json_element("${object}" url url "")
get_json_element("${object}" key key "")
@@ -208,6 +207,7 @@ function(AddJsonPackage)
VERSION "${version}"
URL "${url}"
HASH "${hash}"
HASH_SUFFIX "${hash_suffix}"
SHA "${sha}"
REPO "${repo}"
KEY "${key}"
@@ -533,7 +533,6 @@ function(AddCIPackage)
EXTENSION
MIN_VERSION
DISABLED_PLATFORMS
CMAKE_FILENAME
)
cmake_parse_arguments(PKG_ARGS "" "${oneValueArgs}" "" ${ARGN})
@@ -589,25 +588,28 @@ function(AddCIPackage)
add_ci_package(android)
endif()
if(PLATFORM_SUN AND NOT "solaris" IN_LIST DISABLED_PLATFORMS)
add_ci_package(solaris)
if(PLATFORM_SUN AND NOT "solaris-amd64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(solaris-amd64)
endif()
if(PLATFORM_FREEBSD AND NOT "freebsd" IN_LIST DISABLED_PLATFORMS)
add_ci_package(freebsd)
if(PLATFORM_FREEBSD AND NOT "freebsd-amd64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(freebsd-amd64)
endif()
if((PLATFORM_LINUX AND ARCHITECTURE_x86_64) AND NOT "linux" IN_LIST DISABLED_PLATFORMS)
add_ci_package(linux)
if((PLATFORM_LINUX AND ARCHITECTURE_x86_64) AND NOT "linux-amd64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(linux-amd64)
endif()
if((PLATFORM_LINUX AND ARCHITECTURE_arm64) AND NOT "linux-aarch64" IN_LIST DISABLED_PLATFORMS)
add_ci_package(linux-aarch64)
endif()
if (DEFINED ARTIFACT_DIR)
include(${ARTIFACT_DIR}/${ARTIFACT_CMAKE}.cmake)
# TODO(crueter): macOS amd64/aarch64 split mayhaps
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}_SOURCE_DIR "${ARTIFACT_DIR}" PARENT_SCOPE)
else()

View File

@@ -31,7 +31,11 @@ set(GIT_DESC ${BUILD_VERSION})
set(REPO_NAME "Eden")
set(BUILD_ID ${GIT_REFSPEC})
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_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)

View File

@@ -4,8 +4,11 @@
"package": "OpenSSL",
"name": "openssl",
"repo": "crueter-ci/OpenSSL",
"version": "3.5.3",
"min_version": "1.1.1"
"version": "3.6.0",
"min_version": "1.1.1",
"disabled_platforms": [
"macos-universal"
]
},
"boost": {
"package": "Boost",
@@ -66,20 +69,6 @@
"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": {
"package": "Opus",
"repo": "crueter/opus",
@@ -91,97 +80,12 @@
"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": {
"repo": "boostorg/headers",
"sha": "95930ca8f5",
"hash": "d1dece16f3b209109de02123c537bfe1adf07a62b16c166367e7e5d62e0f7c323bf804c89b3192dd6871bc58a9d879d25a1cc3f7b9da0e497cf266f165816e2a",
"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": {
"repo": "misc/llvm-mingw",
"git_host": "git.crueter.xyz",

View File

@@ -108,7 +108,9 @@ All dependencies must be identifiable in some way for usage in the dependency vi
URLs:
- `GIT_URL`
- `REPO` as a GitHub repository
- `REPO` as a Git repository
* You may optionally specify `GIT_HOST` to use a custom host, e.g. `GIT_HOST git.crueter.xyz`. Note that the git host MUST be GitHub-like in its artifact/archive downloads, e.g. Forgejo
* If `GIT_HOST` is unspecified, defaults to `github.com`
- `URL`
Versions (bundled):
@@ -135,11 +137,11 @@ Adds a package that follows crueter's CI repository spec.
* `windows-amd64`
* `windows-arm64`
* `android`
* `solaris`
* `freebsd`
* `linux`
* `solaris-amd64`
* `freebsd-amd64`
* `linux-amd64`
* `linux-aarch64`
- `CMAKE_FILENAME`: Custom CMake filename, relative to the package root (default `${PACKAGE_ROOT}/${NAME}.cmake`)
* `macos-universal`
### AddJsonPackage
@@ -155,10 +157,17 @@ The cpmfile is an object of objects, with each sub-object being named according
If `ci` is `false`:
- `hash` -> `HASH`
- `hash_suffix` -> `HASH_SUFFIX`
- `sha` -> `SHA`
- `key` -> `KEY`
- `tag` -> `TAG`
* If the tag contains `%VERSION%`, that part will be replaced by the `git_version`, OR `version` if `git_version` is not specified
- `url` -> `URL`
- `artifact` -> `ARTIFACT`
* If the artifact contains `%VERSION%`, that part will be replaced by the `git_version`, OR `version` if `git_version` is not specified
* If the artifact contains `%TAG%`, that part will be replaced by the `tag` (with its replacement already done)
- `git_version` -> `GIT_VERSION`
- `git_host` -> `GIT_HOST`
- `source_subdir` -> `SOURCE_SUBDIR`
- `bundled` -> `BUNDLED_PACKAGE`
- `find_args` -> `FIND_PACKAGE_ARGUMENTS`
@@ -172,7 +181,6 @@ 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
@@ -192,8 +200,8 @@ In order: OpenSSL CI, Boost (tag + artifact), Opus (options + find_args), discor
"boost": {
"package": "Boost",
"repo": "boostorg/boost",
"tag": "boost-1.88.0",
"artifact": "boost-1.88.0-cmake.7z",
"tag": "boost-%VERSION%",
"artifact": "%TAG%-cmake.7z",
"hash": "e5b049e5b61964480ca816395f63f95621e66cb9bcf616a8b10e441e0e69f129e22443acb11e77bc1e8170f8e4171b9b7719891efc43699782bfcd4b3a365f01",
"git_version": "1.88.0",
"version": "1.57"

View File

@@ -31,7 +31,7 @@ Notes:
* Currently, build fails without this
- `YUZU_USE_FASTER_LD` (ON) Check if a faster linker is available
* 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)
- `ENABLE_OPENSSL` (ON for Linux and *BSD) Enable OpenSSL backend for the ssl service
* Always enabled if the web service is enabled

View File

@@ -39,6 +39,144 @@ if (ARCHITECTURE_arm64 OR DYNARMIC_TESTS)
AddJsonPackage(oaknut)
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
# We only need SPIRV-Headers iff spirv-tools is bundled
if (SPIRV-Tools_FORCE_BUNDLED OR CPMUTIL_FORCE_BUNDLED)
set(NEED_SPIRV_HEADERS ON)
else()
find_package(SPIRV-Tools MODULE QUIET)
if (NOT SPIRV-Tools_FOUND)
set(NEED_SPIRV_HEADERS ON)
else()
set(NEED_SPIRV_HEADERS OFF)
endif()
endif()
if (NEED_SPIRV_HEADERS)
AddJsonPackage(spirv-headers)
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
if (MSVC)
add_subdirectory(getopt)
@@ -68,15 +206,18 @@ if (VulkanMemoryAllocator_ADDED)
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)
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()
# httplib

120
externals/cpmfile.json vendored
View File

@@ -8,12 +8,18 @@
},
"sirit": {
"repo": "eden-emulator/sirit",
"sha": "db1f1e8ab5",
"hash": "73eb3a042848c63a10656545797e85f40d142009dfb7827384548a385e1e28e1ac72f42b25924ce530d58275f8638554281e884d72f9c7aaf4ed08690a414b05",
"find_args": "CONFIG",
"options": [
"SIRIT_USE_SYSTEM_SPIRV_HEADERS ON"
]
"version": "1.0.1",
"tag": "v%VERSION%",
"artifact": "sirit-source-%VERSION%.tar.zst",
"hash_suffix": "sha512sum",
"find_args": "CONFIG"
},
"sirit-ci": {
"ci": true,
"package": "sirit",
"name": "sirit",
"repo": "eden-emulator/sirit",
"version": "1.0.0"
},
"httplib": {
"repo": "yhirose/cpp-httplib",
@@ -70,5 +76,107 @@
"sha": "73f3cbb237",
"hash": "c08c03063938339d61392b687562909c1a92615b6ef39ec8df19ea472aa6b6478e70d7d5e33d4a27b5d23f7806daf57fe1bacb8124c8a945c918c7663a9e8532",
"find_args": "CONFIG"
},
"mbedtls": {
"package": "MbedTLS",
"repo": "Mbed-TLS/mbedtls",
"tag": "mbedtls-%VERSION%",
"hash": "6671fb8fcaa832e5b115dfdce8f78baa6a4aea71f5c89a640583634cdee27aefe3bf4be075744da91f7c3ae5ea4e0c765c8fc3937b5cfd9ea73d87ef496524da",
"version": "3",
"git_version": "3.6.4",
"artifact": "%TAG%.tar.bz2"
},
"enet": {
"repo": "lsalzman/enet",
"sha": "2662c0de09",
"hash": "3de1beb4fa3d6b1e03eda8dd1e7580694f854af3ed3975dcdabfdcdf76b97f322b9734d35ea7f185855bb490d957842b938b26da4dd2dfded509390f8d2794dd",
"version": "1.3",
"find_args": "MODULE"
},
"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"
]
},
"cubeb": {
"repo": "mozilla/cubeb",
"sha": "fa02160712",
"hash": "82d808356752e4064de48c8fecbe7856715ade1e76b53937116bf07129fc1cc5b3de5e4b408de3cd000187ba8dc32ca4109661cb7e0355a52e54bd81b9be1c61",
"find_args": "CONFIG",
"options": [
"USE_SANITIZERS OFF",
"BUILD_TESTS OFF",
"BUILD_TOOLS OFF",
"BUNDLE_SPEEX ON"
]
},
"discord-rpc": {
"package": "DiscordRPC",
"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.10",
"min_version": "2.26.4",
"disabled_platforms": [
"macos-universal"
]
},
"catch2": {
"package": "Catch2",
"repo": "catchorg/Catch2",
"sha": "644821ce28",
"hash": "f8795f98acf2c02c0db8e734cc866d5caebab4b4a306e93598b97cb3c0c728dafe8283dce27ffe8d42460e5ae7302f3f32e7e274a7f991b73511ac88eef21b1f",
"version": "3.0.1"
}
}

View File

@@ -13,8 +13,9 @@
"version": "8.0",
"min_version": "4.1",
"disabled_platforms": [
"freebsd",
"solaris"
"freebsd-amd64",
"solaris-amd64",
"macos-universal"
]
}
}

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-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()};
state.center_delay_line.Initialize(center_delay_time, 1.0f);
UpdateReverbEffectParameter(params, state);
for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
std::ranges::fill(state.fdn_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),
[this]() { return paused || queued_buffers < max_queue_size; });
if (queued_buffers > max_queue_size + 3) {
Common::CondvarWait(release_cv, lk, stop_token,
[this] { return paused || queued_buffers < max_queue_size; });
release_cv.wait(lk, stop_token, [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-License-Identifier: GPL-2.0-or-later
@@ -123,7 +126,7 @@ private:
} else if constexpr (Mode == PopMode::WaitWithStopToken) {
// Wait until the queue is not empty.
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);
});
if (stop_token.stop_requested()) {

View File

@@ -1,13 +1,13 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <fstream>
#include <vector>
#include "common/heap_tracker.h"
#include "common/logging/log.h"
#include "common/assert.h"
namespace Common {
@@ -36,6 +36,8 @@ HeapTracker::~HeapTracker() = default;
void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length,
MemoryPermission perm, bool is_separate_heap) {
bool rebuild_required = false;
// When mapping other memory, map pages immediately.
if (!is_separate_heap) {
m_buffer.Map(virtual_offset, host_offset, length, perm, false);
@@ -57,11 +59,29 @@ void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length,
// Insert into mappings.
m_map_count++;
m_mappings.insert(*map);
const auto it = m_mappings.insert(*map);
// Update tick before possible rebuild.
it->tick = m_tick++;
// Check if we need to rebuild.
if (m_resident_map_count >= m_max_resident_map_count) {
rebuild_required = true;
}
// Map the area.
m_buffer.Map(it->vaddr, it->paddr, it->size, it->perm, false);
// This map is now resident.
it->is_resident = true;
m_resident_map_count++;
m_resident_mappings.insert(*it);
}
// Finally, map.
this->DeferredMapSeparateHeap(virtual_offset);
if (rebuild_required) {
// A rebuild was required, so perform it now.
this->RebuildSeparateHeapAddressSpace();
}
}
void HeapTracker::Unmap(size_t virtual_offset, size_t size, bool is_separate_heap) {
@@ -147,7 +167,8 @@ void HeapTracker::Protect(size_t virtual_offset, size_t size, MemoryPermission p
}
// Clamp to end.
next = (std::min)(next, end);
next = std::min(next, end);
// Reprotect, if we need to.
if (should_protect) {
m_buffer.Protect(cur, next - cur, perm);
@@ -158,51 +179,6 @@ void HeapTracker::Protect(size_t virtual_offset, size_t size, MemoryPermission p
}
}
bool HeapTracker::DeferredMapSeparateHeap(u8* fault_address) {
if (m_buffer.IsInVirtualRange(fault_address)) {
return this->DeferredMapSeparateHeap(fault_address - m_buffer.VirtualBasePointer());
}
return false;
}
bool HeapTracker::DeferredMapSeparateHeap(size_t virtual_offset) {
bool rebuild_required = false;
{
std::scoped_lock lk{m_lock};
// Check to ensure this was a non-resident separate heap mapping.
const auto it = this->GetNearestHeapMapLocked(virtual_offset);
if (it == m_mappings.end() || it->is_resident) {
return false;
}
// Update tick before possible rebuild.
it->tick = m_tick++;
// Check if we need to rebuild.
if (m_resident_map_count > m_max_resident_map_count) {
rebuild_required = true;
}
// Map the area.
m_buffer.Map(it->vaddr, it->paddr, it->size, it->perm, false);
// This map is now resident.
it->is_resident = true;
m_resident_map_count++;
m_resident_mappings.insert(*it);
}
if (rebuild_required) {
// A rebuild was required, so perform it now.
this->RebuildSeparateHeapAddressSpace();
}
return true;
}
void HeapTracker::RebuildSeparateHeapAddressSpace() {
std::scoped_lock lk{m_rebuild_lock, m_lock};
@@ -213,8 +189,8 @@ void HeapTracker::RebuildSeparateHeapAddressSpace() {
// Despite being worse in theory, this has proven to be better in practice than more
// regularly dumping a smaller amount, because it significantly reduces average case
// lock contention.
std::size_t const desired_count = (std::min)(m_resident_map_count, m_max_resident_map_count) / 2;
std::size_t const evict_count = m_resident_map_count - desired_count;
const size_t desired_count = std::min(m_resident_map_count, m_max_resident_map_count) / 2;
const size_t evict_count = m_resident_map_count - desired_count;
auto it = m_resident_mappings.begin();
for (size_t i = 0; i < evict_count && it != m_resident_mappings.end(); i++) {

View File

@@ -39,9 +39,17 @@ namespace Common::Log {
namespace {
/**
* Interface for logging backends.
*/
/// @brief Trims up to and including the last of ../, ..\, src/, src\ in a string
/// 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 {
public:
virtual ~Backend() = default;
@@ -53,9 +61,7 @@ public:
virtual void Flush() = 0;
};
/**
* Backend that writes to stderr and with color
*/
/// @brief Backend that writes to stderr and with color
class ColorConsoleBackend final : public Backend {
public:
explicit ColorConsoleBackend() = default;
@@ -84,9 +90,7 @@ private:
std::atomic_bool enabled{false};
};
/**
* Backend that writes to a file passed into the constructor
*/
/// @brief Backend that writes to a file passed into the constructor
class FileBackend final : public Backend {
public:
explicit FileBackend(const std::filesystem::path& filename) {
@@ -248,13 +252,14 @@ public:
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,
const char* function, std::string&& message) {
if (!filter.CheckMessage(log_class, log_level)) {
return;
}
const char* function, std::string&& message) noexcept {
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:
@@ -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,
const fmt::format_args& args) {
if (!initialization_in_progress_suppress_logging) {
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function,
fmt::vformat(format, args));
auto& instance = Impl::Instance();
if (instance.CanPushEntry(log_class, log_level))
instance.PushEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args));
}
}
} // 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-License-Identifier: GPL-2.0-or-later
@@ -9,22 +12,20 @@ namespace Common::Log {
namespace {
template <typename It>
Level GetLevelByName(const It begin, const It end) {
for (u8 i = 0; i < static_cast<u8>(Level::Count); ++i) {
const char* level_name = GetLevelName(static_cast<Level>(i));
if (Common::ComparePartialString(begin, end, level_name)) {
return static_cast<Level>(i);
}
for (u32 i = 0; i < u32(Level::Count); ++i) {
const char* level_name = GetLevelName(Level(i));
if (Common::ComparePartialString(begin, end, level_name))
return Level(i);
}
return Level::Count;
}
template <typename It>
Class GetClassByName(const It begin, const It end) {
for (u8 i = 0; i < static_cast<u8>(Class::Count); ++i) {
const char* level_name = GetLogClassName(static_cast<Class>(i));
if (Common::ComparePartialString(begin, end, level_name)) {
return static_cast<Class>(i);
}
for (u32 i = 0; i < u32(Class::Count); ++i) {
const char* level_name = GetLogClassName(Class(i));
if (Common::ComparePartialString(begin, end, level_name))
return Class(i);
}
return Class::Count;
}
@@ -229,13 +230,12 @@ void Filter::ParseFilterString(std::string_view filter_view) {
}
bool Filter::CheckMessage(Class log_class, Level level) const {
return static_cast<u8>(level) >=
static_cast<u8>(class_levels[static_cast<std::size_t>(log_class)]);
return u8(level) >= u8(class_levels[std::size_t(log_class)]);
}
bool Filter::IsDebug() const {
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 {
// 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
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
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
#define LOG_TRACE(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__FILE__, __LINE__, __func__, \
__VA_ARGS__)
#else
#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, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__FILE__, __LINE__, __func__, \
__VA_ARGS__)
#define LOG_INFO(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__FILE__, __LINE__, __func__, \
__VA_ARGS__)
#define LOG_WARNING(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__FILE__, __LINE__, __func__, \
__VA_ARGS__)
#define LOG_ERROR(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__FILE__, __LINE__, __func__, \
__VA_ARGS__)
#define LOG_CRITICAL(log_class, ...) \
Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \
Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
__FILE__, __LINE__, __func__, \
__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-License-Identifier: GPL-2.0-or-later
@@ -7,23 +10,13 @@
#pragma once
#include <version>
#ifdef __cpp_lib_jthread
#include <chrono>
#include <condition_variable>
#include <stop_token>
#include <thread>
#include <utility>
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>
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
std::condition_variable_any cv;
@@ -35,341 +28,3 @@ bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep,
}
} // 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 IS_DEV_BUILD @IS_DEV_BUILD@
#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 {
@@ -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 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

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_compiler_id[];
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

View File

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

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: 2014 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -80,7 +83,7 @@ public:
condvar.notify_all();
return true;
} else {
CondvarWait(condvar, lk, token,
condvar.wait(lk, token,
[this, current_generation] { return current_generation != generation; });
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-License-Identifier: GPL-2.0-or-later
@@ -47,8 +50,8 @@ public:
if (requests.empty()) {
wait_condition.notify_all();
}
Common::CondvarWait(condition, lock, stop_token,
[this] { return !requests.empty(); });
condition.wait(lock, stop_token,
[this] { return !requests.empty(); });
if (stop_token.stop_requested()) {
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-License-Identifier: GPL-2.0-or-later
@@ -99,7 +102,11 @@ public:
T PopWait(std::stop_token stop_token) {
if (Empty()) {
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()) {
return T{};

View File

@@ -1229,7 +1229,6 @@ endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_sources(core PRIVATE
arm/dynarmic/arm_dynarmic.cpp
arm/dynarmic/arm_dynarmic.h
arm/dynarmic/arm_dynarmic_64.cpp
arm/dynarmic/arm_dynarmic_64.h

View File

@@ -1,49 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#ifdef __linux__
#include "common/signal_chain.h"
#include "core/arm/dynarmic/arm_dynarmic.h"
#include "core/hle/kernel/k_process.h"
#include "core/memory.h"
namespace Core {
namespace {
thread_local Core::Memory::Memory* g_current_memory{};
std::once_flag g_registered{};
struct sigaction g_old_segv {};
void HandleSigSegv(int sig, siginfo_t* info, void* ctx) {
if (g_current_memory && g_current_memory->InvalidateSeparateHeap(info->si_addr)) {
return;
}
return g_old_segv.sa_sigaction(sig, info, ctx);
}
} // namespace
ScopedJitExecution::ScopedJitExecution(Kernel::KProcess* process) {
g_current_memory = std::addressof(process->GetMemory());
}
ScopedJitExecution::~ScopedJitExecution() {
g_current_memory = nullptr;
}
void ScopedJitExecution::RegisterHandler() {
std::call_once(g_registered, [] {
struct sigaction sa {};
sa.sa_sigaction = &HandleSigSegv;
sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
Common::SigAction(SIGSEGV, std::addressof(sa), std::addressof(g_old_segv));
});
}
} // namespace Core
#endif

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-License-Identifier: GPL-2.0-or-later
@@ -26,24 +29,4 @@ constexpr HaltReason TranslateHaltReason(Dynarmic::HaltReason hr) {
return static_cast<HaltReason>(hr);
}
#ifdef __linux__
class ScopedJitExecution {
public:
explicit ScopedJitExecution(Kernel::KProcess* process);
~ScopedJitExecution();
static void RegisterHandler();
};
#else
class ScopedJitExecution {
public:
explicit ScopedJitExecution(Kernel::KProcess* process) {}
~ScopedJitExecution() {}
static void RegisterHandler() {}
};
#endif
} // namespace Core

View File

@@ -343,15 +343,11 @@ bool ArmDynarmic32::IsInThumbMode() const {
}
HaltReason ArmDynarmic32::RunThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Run());
}
HaltReason ArmDynarmic32::StepThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Step());
}
@@ -393,7 +389,6 @@ ArmDynarmic32::ArmDynarmic32(System& system, bool uses_wall_clock, Kernel::KProc
m_cp15(std::make_shared<DynarmicCP15>(*this)), m_core_index{core_index} {
auto& page_table_impl = process->GetPageTable().GetBasePageTable().GetImpl();
m_jit = MakeJit(&page_table_impl);
ScopedJitExecution::RegisterHandler();
}
ArmDynarmic32::~ArmDynarmic32() = default;

View File

@@ -374,15 +374,11 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa
}
HaltReason ArmDynarmic64::RunThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Run());
}
HaltReason ArmDynarmic64::StepThread(Kernel::KThread* thread) {
ScopedJitExecution sj(thread->GetOwnerProcess());
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Step());
}
@@ -422,7 +418,6 @@ ArmDynarmic64::ArmDynarmic64(System& system, bool uses_wall_clock, Kernel::KProc
auto& page_table = process->GetPageTable().GetBasePageTable();
auto& page_table_impl = page_table.GetImpl();
m_jit = MakeJit(&page_table_impl, page_table.GetAddressSpaceWidth());
ScopedJitExecution::RegisterHandler();
}
ArmDynarmic64::~ArmDynarmic64() = default;

View File

@@ -38,9 +38,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca)
reader = std::make_shared<NcaReader>();
if (Result rc = reader->Initialize(file, GetCryptoConfiguration(), GetNcaCompressionConfiguration()); R_FAILED(rc)) {
if (rc != ResultInvalidNcaSignature) {
LOG_ERROR(Loader, "File reader errored out during header read: {:#x}", rc.GetInnerValue());
}
status = Loader::ResultStatus::ErrorBadNCAHeader;
return;
}
@@ -85,7 +82,6 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca)
for (s32 i = 0; i < fs_count; i++) {
NcaFsHeaderReader header_reader;
if (Result rc = fs.OpenStorage(&filesystems[i], &header_reader, i); R_FAILED(rc)) {
LOG_DEBUG(Loader, "File reader errored out during read of section {}: {:#x}", i, rc.GetInnerValue());
status = Loader::ResultStatus::ErrorBadNCAHeader;
return;
}

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-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_indirect_meta != 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));
// Validate patch info extents.
R_UNLESS(patch_info.indirect_size > 0, ResultInvalidNcaPatchInfoIndirectSize);
R_UNLESS(patch_info.aes_ctr_ex_size >= 0, ResultInvalidNcaPatchInfoAesCtrExSize);
R_UNLESS(patch_info.aes_ctr_ex_size >= 0 && patch_info.HasAesCtrExTable(), ResultInvalidNcaPatchInfoAesCtrExSize);
R_UNLESS(patch_info.indirect_size > 0 && patch_info.HasIndirectTable(), ResultInvalidNcaPatchInfoIndirectSize);
R_UNLESS(patch_info.indirect_size + patch_info.indirect_offset <= patch_info.aes_ctr_ex_offset,
ResultInvalidNcaPatchInfoAesCtrExOffset);
R_UNLESS(patch_info.aes_ctr_ex_offset + patch_info.aes_ctr_ex_size <=
@@ -1333,10 +1331,30 @@ Result NcaFileSystemDriver::CreateIntegrityVerificationStorageImpl(
R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset,
ResultRomNcaInvalidIntegrityLayerInfoOffset);
}
storage_info[level_hash_info.max_layers - 1]
= std::make_shared<OffsetVfsFile>(std::move(base_storage),
layer_info.size,
last_layer_info_offset);
switch (level_hash_info.max_layers - 1) {
case FileSys::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation::MasterStorage:
storage_info.SetMasterHashStorage(std::make_shared<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.
auto integrity_storage = std::make_shared<IntegrityRomFsStorage>();

View File

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

View File

@@ -53,6 +53,19 @@ enum class NetDbError : s32 {
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) {
// These combinations have been verified on console (but are not
// exhaustive).
@@ -154,7 +167,7 @@ static std::pair<u32, GetAddrInfoError> GetHostByNameRequestImpl(HLERequestConte
// For now, ignore options, which are in input buffer 1 for GetHostByNameRequestWithOptions.
// 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);
return {0, GetAddrInfoError::AGAIN};
}
@@ -271,7 +284,7 @@ static std::pair<u32, GetAddrInfoError> GetAddrInfoRequestImpl(HLERequestContext
const std::string host = Common::StringFromBuffer(host_buffer);
// 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);
return {0, GetAddrInfoError::AGAIN};
}
@@ -359,5 +372,4 @@ void SFDNSRES::ResolverSetOptionRequest(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
rb.Push<s32>(0); // bsd errno
}
} // 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-License-Identifier: GPL-2.0-or-later
@@ -286,7 +289,7 @@ Result CheckOpenSSLErrors() {
msg.append(data);
}
Common::Log::FmtLogMessage(Common::Log::Class::Service_SSL, Common::Log::Level::Error,
Common::Log::TrimSourcePath(file), line, func, "OpenSSL: {}",
file, line, func, "OpenSSL: {}",
msg);
}
return ResultInternalError;

View File

@@ -1230,22 +1230,7 @@ bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) {
if (rasterizer) {
impl->InvalidateGPUMemory(ptr, size);
}
#ifdef __linux__
if (!rasterizer && mapped) {
impl->buffer->DeferredMapSeparateHeap(GetInteger(vaddr));
}
#endif
return mapped && ptr != nullptr;
}
bool Memory::InvalidateSeparateHeap(void* fault_address) {
#ifdef __linux__
return impl->buffer->DeferredMapSeparateHeap(static_cast<u8*>(fault_address));
#else
return false;
#endif
}
} // namespace Core::Memory

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-License-Identifier: GPL-2.0-or-later
@@ -492,8 +495,6 @@ public:
bool InvalidateNCE(Common::ProcessAddress vaddr, size_t size);
bool InvalidateSeparateHeap(void* fault_address);
private:
Core::System& system;

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.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
@@ -34,6 +37,8 @@ enum class OptimizationFlag : std::uint32_t {
MiscIROpt = 0x00000020,
/// Optimize for code speed rather than for code size (this serves well for tight loops)
CodeSpeed = 0x00000040,
/// Disable verification passes
DisableVerification = 0x00000080,
/// 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.

View File

@@ -1491,9 +1491,9 @@ void Optimize(IR::Block& block, const A32::UserConfig& conf, const Optimization:
Optimization::DeadCodeElimination(block);
}
Optimization::IdentityRemovalPass(block);
//if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
Optimization::VerificationPass(block);
//}
}
}
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]] {
Optimization::A64MergeInterpretBlocksPass(block, conf.callbacks);
}
//if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
if (!conf.HasOptimization(OptimizationFlag::DisableVerification)) {
Optimization::VerificationPass(block);
//}
}
}
} // namespace Dynarmic::Optimization

View File

@@ -39,7 +39,7 @@ endif()
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)
target_compile_definitions(qt_common PUBLIC HAS_OPENGL)

View File

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

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)
target_compile_options(shader_recompiler PRIVATE

View File

@@ -333,7 +333,7 @@ target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS})
add_dependencies(video_core host_shaders)
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
target_link_libraries(video_core PUBLIC Vulkan::UtilityHeaders GPUOpen::VulkanMemoryAllocator)

View File

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

View File

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

View File

@@ -116,7 +116,7 @@ u64 ThreadManager::PushCommand(CommandData&& command_data, bool block) {
state.queue.EmplaceWait(std::move(command_data), fence, 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);
});
}

View File

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

View File

@@ -233,7 +233,7 @@ bool DecoderContext::OpenContext(const Decoder& decoder) {
}
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));
return false;
}
@@ -242,31 +242,31 @@ bool DecoderContext::SendPacket(const Packet& packet) {
}
std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
auto ReceiveImpl = [&](AVFrame* frame) -> bool {
if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0 && ret != AVERROR_EOF) {
auto ReceiveImpl = [&](AVFrame* frame) -> int {
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));
return false;
}
return true;
return ret;
};
std::shared_ptr<Frame> intermediate_frame = std::make_shared<Frame>();
if (!ReceiveImpl(intermediate_frame->GetFrame())) {
if (ReceiveImpl(intermediate_frame->GetFrame()) < 0) {
return {};
}
m_temp_frame = std::make_shared<Frame>();
m_final_frame = std::make_shared<Frame>();
if (m_codec_context->hw_device_ctx) {
m_temp_frame->SetFormat(PreferredGpuFormat);
if (int ret = av_hwframe_transfer_data(m_temp_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) {
m_final_frame->SetFormat(PreferredGpuFormat);
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));
return {};
}
} 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() {

View File

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

View File

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

View File

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

View File

@@ -280,6 +280,7 @@ void Layer::UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t i
Tegra::Texture::UnswizzleTexture(
mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size),
bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0);
buffer.Flush(); // Ensure host writes are visible before the GPU copy.
}
const VkBufferImageCopy copy{

View File

@@ -208,7 +208,7 @@ void MasterSemaphore::WaitThread(std::stop_token token) {
vk::Fence fence;
{
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()) {
return;
}

View File

@@ -55,7 +55,7 @@ using VideoCommon::FileEnvironment;
using VideoCommon::GenericEnvironment;
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'};
template <typename Container>

View File

@@ -279,7 +279,7 @@ void PresentManager::PresentThread(std::stop_token token) {
std::unique_lock lock{queue_mutex};
// 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()) {
return;
}

View File

@@ -166,7 +166,7 @@ void Scheduler::WorkerThread(std::stop_token stop_token) {
std::unique_lock lk{queue_mutex};
// 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 (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: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -224,7 +227,7 @@ void TurboMode::Run(std::stop_token stop_token) {
#endif
// Wait for the next graphics queue submission if necessary.
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) <=
std::chrono::milliseconds{100};
});

View File

@@ -366,7 +366,7 @@ if (APPLE)
set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE TRUE)
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_VERSION "v1.3.0")
download_moltenvk(${MOLTENVK_PLATFORM} ${MOLTENVK_VERSION})
@@ -397,8 +397,6 @@ if (NOT WIN32)
target_include_directories(yuzu PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
endif()
target_link_libraries(yuzu PRIVATE Vulkan::Headers)
if (UNIX AND NOT APPLE)
target_link_libraries(yuzu PRIVATE Qt6::DBus)

View File

@@ -14,11 +14,12 @@ AboutDialog::AboutDialog(QWidget* parent)
: QDialog(parent)
, ui{std::make_unique<Ui::AboutDialog>()}
{
static const std::string description = std::string{Common::g_build_version};
static const std::string build_id = std::string{Common::g_build_id};
static const std::string compiler = std::string{Common::g_compiler_id};
static const std::string yuzu_build = fmt::format("Eden | {} | {}", description, compiler);
static const std::string yuzu_build = fmt::format("{} | {} | {}",
std::string{Common::g_build_name},
std::string{Common::g_build_version},
std::string{Common::g_compiler_id}
);
const auto override_build = fmt::format(fmt::runtime(
std::string(Common::g_title_bar_format_idle)),

View File

@@ -108,13 +108,13 @@ void EmuThread::run() {
m_system.Run();
m_stopped.Reset();
Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return !m_should_run; });
m_should_run_cv.wait(lk, stop_token, [&] { return !m_should_run; });
} else {
m_system.Pause();
m_stopped.Set();
EmulationPaused(lk);
Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return m_should_run; });
m_should_run_cv.wait(lk, stop_token, [&] { return m_should_run; });
EmulationResumed(lk);
}
}

View File

@@ -1770,16 +1770,25 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
void GMainWindow::SetupPrepareForSleep() {
#ifdef __unix__
auto bus = QDBusConnection::systemBus();
if (bus.isConnected()) {
if (auto bus = QDBusConnection::systemBus(); bus.isConnected()) {
// See https://github.com/ConsoleKit2/ConsoleKit2/issues/150
#ifdef __linux__
const auto dbus_logind_service = QStringLiteral("org.freedesktop.login1");
const auto dbus_logind_path = QStringLiteral("/org/freedesktop/login1");
const auto dbus_logind_manager_if = QStringLiteral("org.freedesktop.login1.Manager");
//const auto dbus_logind_session_if = QStringLiteral("org.freedesktop.login1.Session");
#else
const auto dbus_logind_service = QStringLiteral("org.freedesktop.ConsoleKit");
const auto dbus_logind_path = QStringLiteral("/org/freedesktop/ConsoleKit/Manager");
const auto dbus_logind_manager_if = QStringLiteral("org.freedesktop.ConsoleKit.Manager");
//const auto dbus_logind_session_if = QStringLiteral("org.freedesktop.ConsoleKit.Session");
#endif
const bool success = bus.connect(
QStringLiteral("org.freedesktop.login1"), QStringLiteral("/org/freedesktop/login1"),
QStringLiteral("org.freedesktop.login1.Manager"), QStringLiteral("PrepareForSleep"),
dbus_logind_service, dbus_logind_path,
dbus_logind_manager_if, QStringLiteral("PrepareForSleep"),
QStringLiteral("b"), this, SLOT(OnPrepareForSleep(bool)));
if (!success) {
if (!success)
LOG_WARNING(Frontend, "Couldn't register PrepareForSleep signal");
}
} else {
LOG_WARNING(Frontend, "QDBusConnection system bus is not connected");
}
@@ -4192,23 +4201,25 @@ void GMainWindow::OnEmulatorUpdateAvailable() {
update_prompt.addButton(QMessageBox::Yes);
update_prompt.addButton(QMessageBox::Ignore);
update_prompt.setText(
tr("Update %1 for Eden is available.\nWould you like to download it?").arg(version_string));
tr("Download the %1 update?").arg(version_string));
update_prompt.exec();
if (update_prompt.button(QMessageBox::Yes) == update_prompt.clickedButton()) {
QDesktopServices::openUrl(
QUrl(QString::fromStdString("https://github.com/eden-emulator/Releases/releases/tag/") +
version_string));
auto const full_url = fmt::format("{}/{}/releases/tag/",
std::string{Common::g_build_auto_update_website},
std::string{Common::g_build_auto_update_repo}
);
QDesktopServices::openUrl(QUrl(QString::fromStdString(full_url) + version_string));
}
}
#endif
void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_view title_version,
std::string_view gpu_vendor) {
static const std::string description = std::string{Common::g_build_version};
void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_view title_version, std::string_view gpu_vendor) {
static const std::string build_id = std::string{Common::g_build_id};
static const std::string compiler = std::string{Common::g_compiler_id};
static const std::string yuzu_title = fmt::format("Eden | {} | {}", description, compiler);
static const std::string yuzu_title = fmt::format("{} | {} | {}",
std::string{Common::g_build_name},
std::string{Common::g_build_version},
std::string{Common::g_compiler_id}
);
const auto override_title =
fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id);

View File

@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright Citra Emulator Project / Azahar Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -12,6 +15,7 @@
#include <nlohmann/json.hpp>
#include <optional>
#include <string>
#include "common/scm_rev.h"
std::optional<std::string> UpdateChecker::GetResponse(std::string url, std::string path)
{
@@ -54,8 +58,8 @@ std::optional<std::string> UpdateChecker::GetResponse(std::string url, std::stri
std::optional<std::string> UpdateChecker::GetLatestRelease(bool include_prereleases)
{
constexpr auto update_check_url = "http://api.github.com";
std::string update_check_path = "/repos/eden-emulator/Releases";
const auto update_check_url = std::string{Common::g_build_auto_update_api};
std::string update_check_path = fmt::format("/repos/{}", std::string{Common::g_build_auto_update_repo});
try {
if (include_prereleases) { // This can return either a prerelease or a stable release,
// whichever is more recent.

View File

@@ -229,7 +229,7 @@ void EmuWindow_SDL2::WaitEvent() {
const u32 current_time = SDL_GetTicks();
if (current_time > last_time + 2000) {
const auto results = system.GetAndResetPerfStats();
const auto title = fmt::format("Eden {} | {}-{} | FPS: {:.0f} ({:.0f}%)",
const auto title = fmt::format("{} | {}-{} | FPS: {:.0f} ({:.0f}%)",
Common::g_build_fullname,
Common::g_scm_branch,
Common::g_scm_desc,

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-License-Identifier: GPL-2.0-or-later
@@ -90,7 +93,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste
}
SDL_GL_SetSwapInterval(0);
std::string window_title = fmt::format("Eden {} | {}-{}", Common::g_build_fullname,
std::string window_title = fmt::format("{} | {}-{}", Common::g_build_fullname,
Common::g_scm_branch, Common::g_scm_desc);
render_window =
SDL_CreateWindow(window_title.c_str(),
@@ -138,7 +141,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste
OnResize();
OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size);
SDL_PumpEvents();
LOG_INFO(Frontend, "Eden Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,
LOG_INFO(Frontend, "Build string: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,
Common::g_scm_desc);
Settings::LogSettings();
}

View File

@@ -84,7 +84,7 @@ ci_package() {
echo "-- CI package $PACKAGE"
for platform in windows-amd64 windows-arm64 android solaris freebsd linux linux-aarch64; do
for platform in windows-amd64 windows-arm64 android solaris-amd64 freebsd-amd64 linux-amd64 linux-aarch64 macos-universal; do
echo "-- * platform $platform"
case $DISABLED in
@@ -227,7 +227,7 @@ do
HASH_URL="${DOWNLOAD}.${HASH_SUFFIX}"
fi
HASH=$(curl "$HASH_URL" -L -o -)
HASH=$(curl "$HASH_URL" -sS -L -o -)
fi
download_package