Compare commits

..

1 Commits

Author SHA1 Message Date
Eden CI d4a5cb448a [dist, android] Update translations from Transifex
Signed-off-by: Eden CI <ci@eden-emu.dev>
2026-05-02 10:01:54 -04:00
63 changed files with 1211 additions and 809 deletions
+116
View File
@@ -0,0 +1,116 @@
#!/bin/bash -e
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
case "$1" in
amd64 | "")
echo "Making amd64-v3 optimized build of Eden"
ARCH="amd64_v3"
ARCH_FLAGS="-march=x86-64-v3"
export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=v3)
;;
steamdeck | zen2)
echo "Making Steam Deck (Zen 2) optimized build of Eden"
ARCH="steamdeck"
ARCH_FLAGS="-march=znver2 -mtune=znver2"
export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=zen2 -DYUZU_SYSTEM_PROFILE=steamdeck)
;;
rog-ally | allyx | zen4)
echo "Making ROG Ally X (Zen 4) optimized build of Eden"
ARCH="rog-ally-x"
ARCH_FLAGS="-march=znver4 -mtune=znver4"
export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=zen2 -DYUZU_SYSTEM_PROFILE=steamdeck)
;;
legacy)
echo "Making amd64 generic build of Eden"
ARCH=amd64
ARCH_FLAGS="-march=x86-64 -mtune=generic"
export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=generic)
;;
aarch64)
echo "Making armv8-a build of Eden"
ARCH=aarch64
ARCH_FLAGS="-march=armv8-a -mtune=generic -w"
export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=generic)
;;
armv9)
echo "Making armv9-a build of Eden"
ARCH=armv9
ARCH_FLAGS="-march=armv9-a -mtune=generic -w"
export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=armv9)
;;
native)
echo "Making native build of Eden"
ARCH="$(uname -m)"
ARCH_FLAGS="-march=native -mtune=native"
export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=native)
;;
*)
echo "Invalid target $1 specified, must be one of native, amd64, steamdeck, zen2, allyx, rog-ally, zen4, legacy, aarch64, armv9"
exit 1
;;
esac
export ARCH_FLAGS="$ARCH_FLAGS -O3"
if [ -z "$NPROC" ]; then
NPROC="$(nproc)"
fi
if [ "$1" != "" ]; then shift; fi
if [ "$TARGET" = "appimage" ]; then
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DCMAKE_INSTALL_PREFIX=/usr -DYUZU_ROOM=ON -DYUZU_ROOM_STANDALONE=OFF -DYUZU_CMD=OFF)
else
# For the linux-fresh verification target, verify compilation without PCH as well.
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DYUZU_USE_PRECOMPILED_HEADERS=OFF)
fi
if [ "$DEVEL" != "true" ]; then
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DENABLE_UPDATE_CHECKER=ON)
fi
if [ "$USE_WEBENGINE" = "true" ]; then
WEBENGINE=ON
else
WEBENGINE=OFF
fi
if [ "$USE_MULTIMEDIA" = "false" ]; then
MULTIMEDIA=OFF
else
MULTIMEDIA=ON
fi
if [ -z "$BUILD_TYPE" ]; then
export BUILD_TYPE="Release"
fi
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" $@)
mkdir -p build && cd build
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
-DENABLE_QT_TRANSLATION=ON \
-DUSE_DISCORD_PRESENCE=ON \
-DCMAKE_CXX_FLAGS="$ARCH_FLAGS" \
-DCMAKE_C_FLAGS="$ARCH_FLAGS" \
-DYUZU_USE_BUNDLED_QT=OFF \
-DYUZU_USE_BUNDLED_SDL2=OFF \
-DYUZU_USE_EXTERNAL_SDL2=ON \
-DYUZU_TESTS=OFF \
-DYUZU_USE_QT_MULTIMEDIA=$MULTIMEDIA \
-DYUZU_USE_QT_WEB_ENGINE=$WEBENGINE \
-DYUZU_USE_FASTER_LD=ON \
-DENABLE_LTO=ON \
"${EXTRA_CMAKE_FLAGS[@]}"
ninja -j${NPROC}
if [ -d "bin/Release" ]; then
strip -s bin/Release/*
else
strip -s bin/*
fi
+250
View File
@@ -0,0 +1,250 @@
AppRun
eden.desktop
dev.eden_emu.eden.desktop
shared/bin/eden
shared/lib/lib.path
shared/lib/ld-linux-x86-64.so.2
shared/lib/libQt6Widgets.so.6.4.2
shared/lib/libQt6DBus.so.6.4.2
shared/lib/libudev.so.1.7.5
shared/lib/libbrotlienc.so.1.0.9
shared/lib/libbrotlidec.so.1.0.9
shared/lib/libssl.so.3
shared/lib/libcrypto.so.3
shared/lib/libavcodec.so.59.37.100
shared/lib/libavutil.so.57.28.100
shared/lib/libQt6Gui.so.6.4.2
shared/lib/libQt6Core.so.6.4.2
shared/lib/libstdc++.so.6.0.30
shared/lib/libm.so.6
shared/lib/libgcc_s.so.1
shared/lib/libc.so.6
shared/lib/libdbus-1.so.3.32.4
shared/lib/libbrotlicommon.so.1.0.9
shared/lib/libswresample.so.4.7.100
shared/lib/libvpx.so.7.1.0
shared/lib/libwebpmux.so.3.0.10
shared/lib/libwebp.so.7.1.5
shared/lib/liblzma.so.5.4.1
shared/lib/libdav1d.so.6.6.0
shared/lib/librsvg-2.so.2.48.0
shared/lib/libgobject-2.0.so.0.7400.6
shared/lib/libglib-2.0.so.0.7400.6
shared/lib/libcairo.so.2.11600.0
shared/lib/libzvbi.so.0.13.2
shared/lib/libz.so.1.2.13
shared/lib/libsnappy.so.1.1.9
shared/lib/libaom.so.3.6.0
shared/lib/libcodec2.so.1.0
shared/lib/libgsm.so.1.0.19
shared/lib/libjxl.so.0.7.0
shared/lib/libjxl_threads.so.0.7.0
shared/lib/libmp3lame.so.0.0.0
shared/lib/libopenjp2.so.2.5.0
shared/lib/libopus.so.0.8.0
shared/lib/librav1e.so.0.5.1
shared/lib/libshine.so.3.0.1
shared/lib/libspeex.so.1.5.2
shared/lib/libSvtAv1Enc.so.1.4.1
shared/lib/libtheoraenc.so.1.1.2
shared/lib/libtheoradec.so.1.1.4
shared/lib/libtwolame.so.0.0.0
shared/lib/libvorbis.so.0.4.9
shared/lib/libvorbisenc.so.2.0.12
shared/lib/libx264.so.164
shared/lib/libx265.so.199
shared/lib/libxvidcore.so.4.3
shared/lib/libva.so.2.1700.0
shared/lib/libmfx.so.1.35
shared/lib/libva-drm.so.2.1700.0
shared/lib/libva-x11.so.2.1700.0
shared/lib/libvdpau.so.1.0.0
shared/lib/libX11.so.6.4.0
shared/lib/libdrm.so.2.4.0
shared/lib/libOpenCL.so.1.0.0
shared/lib/libEGL.so.1.1.0
shared/lib/libfontconfig.so.1.12.0
shared/lib/libxkbcommon.so.0.0.0
shared/lib/libGLX.so.0.0.0
shared/lib/libOpenGL.so.0.0.0
shared/lib/libpng16.so.16.39.0
shared/lib/libharfbuzz.so.0.60000.0
shared/lib/libmd4c.so.0.4.8
shared/lib/libfreetype.so.6.18.3
shared/lib/libicui18n.so.72.1
shared/lib/libicuuc.so.72.1
shared/lib/libdouble-conversion.so.3.1
shared/lib/libb2.so.1.0.4
shared/lib/libpcre2-16.so.0.11.2
shared/lib/libzstd.so.1.5.4
shared/lib/libsystemd.so.0.35.0
shared/lib/libsoxr.so.0.1.2
shared/lib/libcairo-gobject.so.2.11600.0
shared/lib/libgdk_pixbuf-2.0.so.0.4200.10
shared/lib/libgio-2.0.so.0.7400.6
shared/lib/libxml2.so.2.9.14
shared/lib/libpangocairo-1.0.so.0.5000.12
shared/lib/libpango-1.0.so.0.5000.12
shared/lib/libffi.so.8.1.2
shared/lib/libpcre2-8.so.0.11.2
shared/lib/libpixman-1.so.0.42.2
shared/lib/libxcb-shm.so.0.0.0
shared/lib/libxcb.so.1.1.0
shared/lib/libxcb-render.so.0.0.0
shared/lib/libXrender.so.1.3.0
shared/lib/libXext.so.6.4.0
shared/lib/libhwy.so.1.0.3
shared/lib/liblcms2.so.2.0.14
shared/lib/libogg.so.0.8.5
shared/lib/libnuma.so.1.0.0
shared/lib/libpthread.so.0
shared/lib/libXfixes.so.3.1.0
shared/lib/libX11-xcb.so.1.0.0
shared/lib/libxcb-dri3.so.0.1.0
shared/lib/libGLdispatch.so.0.0.0
shared/lib/libexpat.so.1.8.10
shared/lib/libgraphite2.so.3.2.1
shared/lib/libicudata.so.72.1
shared/lib/libgomp.so.1.0.0
shared/lib/libcap.so.2.66
shared/lib/libgcrypt.so.20.4.1
shared/lib/liblz4.so.1.9.4
shared/lib/libgmodule-2.0.so.0.7400.6
shared/lib/libjpeg.so.62.3.0
shared/lib/libmount.so.1.1.0
shared/lib/libselinux.so.1
shared/lib/libpangoft2-1.0.so.0.5000.12
shared/lib/libfribidi.so.0.4.0
shared/lib/libthai.so.0.3.1
shared/lib/libXau.so.6.0.0
shared/lib/libXdmcp.so.6.0.0
shared/lib/libgpg-error.so.0.33.1
shared/lib/libblkid.so.1.1.0
shared/lib/libdatrie.so.1.4.0
shared/lib/libbsd.so.0.11.7
shared/lib/libmd.so.0.0.5
shared/lib/libvulkan.so.1.3.239
share/vulkan/icd.d/intel_hasvk_icd.x86_64.json
shared/lib/libvulkan_intel_hasvk.so
shared/lib/libwayland-client.so.0.21.0
shared/lib/libxcb-present.so.0.0.0
shared/lib/libxcb-xfixes.so.0.0.0
shared/lib/libxcb-sync.so.1.0.0
shared/lib/libxcb-randr.so.0.1.0
shared/lib/libxshmfence.so.1.0.0
share/vulkan/icd.d/intel_icd.x86_64.json
shared/lib/libvulkan_intel.so
share/vulkan/icd.d/lvp_icd.x86_64.json
shared/lib/libvulkan_lvp.so
shared/lib/libLLVM-15.so.1
shared/lib/libedit.so.2.0.70
shared/lib/libz3.so.4
shared/lib/libtinfo.so.6.4
share/vulkan/icd.d/radeon_icd.x86_64.json
shared/lib/libvulkan_radeon.so
shared/lib/libdrm_amdgpu.so.1.0.0
shared/lib/libelf-0.188.so
shared/lib/libVkLayer_MESA_device_select.so
bin/qt.conf
shared/lib/qt6/plugins/platforms/libqeglfs.so
shared/lib/qt6/plugins/platforms/libqlinuxfb.so
shared/lib/qt6/plugins/platforms/libqminimal.so
shared/lib/qt6/plugins/platforms/libqminimalegl.so
shared/lib/qt6/plugins/platforms/libqoffscreen.so
shared/lib/qt6/plugins/platforms/libqvkkhrdisplay.so
shared/lib/qt6/plugins/platforms/libqvnc.so
shared/lib/qt6/plugins/platforms/libqwayland-egl.so
shared/lib/qt6/plugins/platforms/libqwayland-generic.so
shared/lib/qt6/plugins/platforms/libqxcb.so
shared/lib/libQt6WaylandClient.so.6.4.2
shared/lib/libwayland-cursor.so.0.21.0
shared/lib/qt6/plugins/platformthemes/libqgtk3.so
shared/lib/libgtk-3.so.0.2406.32
shared/lib/libgdk-3.so.0.2406.32
shared/lib/libatk-1.0.so.0.24609.1
shared/lib/libepoxy.so.0.0.0
shared/lib/libXi.so.6.1.0
shared/lib/libatk-bridge-2.0.so.0.0.0
shared/lib/libwayland-egl.so.1.21.0
shared/lib/libXcursor.so.1.0.2
shared/lib/libXdamage.so.1.1.0
shared/lib/libXcomposite.so.1.0.0
shared/lib/libXrandr.so.2.2.0
shared/lib/libXinerama.so.1.0.0
shared/lib/libdl.so.2
shared/lib/libatspi.so.0.0.1
share/glib-2.0/schemas/gschemas.compiled
shared/lib/gio/modules/giomodule.cache
shared/lib/gio/modules/libdconfsettings.so
shared/lib/gio/modules/libgvfsdbus.so
shared/lib/gvfs/libgvfscommon.so
share/X11/xkb/rules/evdev
share/X11/xkb/keycodes/evdev
share/X11/xkb/keycodes/aliases
share/X11/xkb/types/complete
share/X11/xkb/types/basic
share/X11/xkb/types/mousekeys
share/X11/xkb/types/pc
share/X11/xkb/types/iso9995
share/X11/xkb/types/level5
share/X11/xkb/types/extra
share/X11/xkb/types/numpad
share/X11/xkb/compat/complete
share/X11/xkb/compat/basic
share/X11/xkb/compat/ledcaps
share/X11/xkb/compat/lednum
share/X11/xkb/compat/iso9995
share/X11/xkb/compat/mousekeys
share/X11/xkb/compat/accessx
share/X11/xkb/compat/misc
share/X11/xkb/compat/ledscroll
share/X11/xkb/compat/xfree86
share/X11/xkb/compat/level5
share/X11/xkb/compat/caps
share/X11/xkb/symbols/pc
share/X11/xkb/symbols/srvr_ctrl
share/X11/xkb/symbols/keypad
share/X11/xkb/symbols/altwin
share/X11/xkb/symbols/us
share/X11/xkb/symbols/inet
shared/lib/qt6/plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.so
shared/lib/qt6/plugins/platforminputcontexts/libibusplatforminputcontextplugin.so
shared/lib/qt6/plugins/iconengines/libqsvgicon.so
shared/lib/qt6/plugins/imageformats/libqgif.so
shared/lib/qt6/plugins/imageformats/libqico.so
shared/lib/qt6/plugins/imageformats/libqjpeg.so
shared/lib/qt6/plugins/imageformats/libqsvg.so
shared/lib/libQt6Svg.so.6.4.2
etc/fonts/fonts.conf
shared/lib/qt6/plugins/wayland-shell-integration/libfullscreen-shell-v1.so
shared/lib/qt6/plugins/wayland-shell-integration/libivi-shell.so
shared/lib/qt6/plugins/wayland-shell-integration/libqt-shell.so
shared/lib/qt6/plugins/wayland-shell-integration/libwl-shell-plugin.so
shared/lib/qt6/plugins/wayland-shell-integration/libxdg-shell.so
shared/lib/qt6/plugins/wayland-graphics-integration-client/libdmabuf-server.so
shared/lib/qt6/plugins/wayland-graphics-integration-client/libdrm-egl-server.so
shared/lib/qt6/plugins/wayland-graphics-integration-client/libqt-plugin-wayland-egl.so
shared/lib/qt6/plugins/wayland-graphics-integration-client/libshm-emulation-server.so
shared/lib/qt6/plugins/wayland-graphics-integration-client/libvulkan-server.so
shared/lib/libQt6WaylandEglClientHwIntegration.so.6.4.2
shared/lib/libQt6OpenGL.so.6.4.2
share/glvnd/egl_vendor.d/50_mesa.json
shared/lib/libEGL_mesa.so.0.0.0
shared/lib/libgbm.so.1.0.0
shared/lib/libglapi.so.0.0.0
shared/lib/libxcb-dri2.so.0.0.0
shared/lib/libwayland-server.so.0.21.0
shared/lib/dri/swrast_dri.so
shared/lib/libsensors.so.5.0.0
shared/lib/libdrm_radeon.so.1.0.1
shared/lib/libdrm_nouveau.so.2.0.0
shared/lib/libdrm_intel.so.1.0.0
shared/lib/libpciaccess.so.0.11.1
shared/lib/qt6/plugins/wayland-decoration-client/libbradient.so
shared/lib/gtk-3.0/modules/libcanberra-gtk3-module.so
shared/lib/libcanberra-gtk3.so.0.1.9
shared/lib/libcanberra.so.0.2.5
shared/lib/libvorbisfile.so.3.3.8
shared/lib/libtdb.so.1.4.8
shared/lib/libltdl.so.7.3.2
shared/lib/libXss.so.1.0.0
+153
View File
@@ -0,0 +1,153 @@
#!/bin/sh -e
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# This script assumes you're in the source directory
export APPIMAGE_EXTRACT_AND_RUN=1
export BASE_ARCH="$(uname -m)"
SHARUN="https://github.com/VHSgunzo/sharun/releases/latest/download/sharun-${BASE_ARCH}-aio"
URUNTIME="https://github.com/VHSgunzo/uruntime/releases/latest/download/uruntime-appimage-dwarfs-${BASE_ARCH}"
case "$1" in
amd64|"")
echo "Packaging amd64-v3 optimized build of Eden"
ARCH="amd64_v3"
;;
steamdeck|zen2)
echo "Packaging Steam Deck (Zen 2) optimized build of Eden"
ARCH="steamdeck"
;;
rog-ally|allyx|zen4)
echo "Packaging ROG Ally X (Zen 4) optimized build of Eden"
ARCH="rog-ally-x"
;;
legacy)
echo "Packaging amd64 generic build of Eden"
ARCH=amd64
;;
aarch64)
echo "Packaging armv8-a build of Eden"
ARCH=aarch64
;;
armv9)
echo "Packaging armv9-a build of Eden"
ARCH=armv9
;;
native)
echo "Packaging native build of Eden"
ARCH="$BASE_ARCH"
;;
esac
export BUILDDIR="$2"
if [ "$BUILDDIR" = '' ]
then
BUILDDIR=build
fi
EDEN_TAG=$(git describe --tags --abbrev=0)
echo "Making \"$EDEN_TAG\" build"
# git checkout "$EDEN_TAG"
VERSION="$(echo "$EDEN_TAG")"
# NOW MAKE APPIMAGE
mkdir -p ./AppDir
cd ./AppDir
cp ../dist/dev.eden_emu.eden.desktop .
cp ../dist/dev.eden_emu.eden.svg .
ln -sf ./dev.eden_emu.eden.svg ./.DirIcon
UPINFO='gh-releases-zsync|eden-emulator|Releases|latest|*.AppImage.zsync'
if [ "$DEVEL" = 'true' ]; then
sed -i 's|Name=Eden|Name=Eden Nightly|' ./dev.eden_emu.eden.desktop
UPINFO="$(echo "$UPINFO" | sed 's|Releases|nightly|')"
fi
LIBDIR="/usr/lib"
# Workaround for Gentoo
if [ ! -d "$LIBDIR/qt6" ]
then
LIBDIR="/usr/lib64"
fi
# Workaround for Debian
if [ ! -d "$LIBDIR/qt6" ]
then
LIBDIR="/usr/lib/${BASE_ARCH}-linux-gnu"
fi
# Bundle all libs
wget --retry-connrefused --tries=30 "$SHARUN" -O ./sharun-aio
chmod +x ./sharun-aio
xvfb-run -a ./sharun-aio l -p -v -e -s -k \
../$BUILDDIR/bin/eden* \
$LIBDIR/lib*GL*.so* \
$LIBDIR/dri/* \
$LIBDIR/vdpau/* \
$LIBDIR/libvulkan* \
$LIBDIR/libXss.so* \
$LIBDIR/libdecor-0.so* \
$LIBDIR/libgamemode.so* \
$LIBDIR/qt6/plugins/audio/* \
$LIBDIR/qt6/plugins/bearer/* \
$LIBDIR/qt6/plugins/imageformats/* \
$LIBDIR/qt6/plugins/iconengines/* \
$LIBDIR/qt6/plugins/platforms/* \
$LIBDIR/qt6/plugins/platformthemes/* \
$LIBDIR/qt6/plugins/platforminputcontexts/* \
$LIBDIR/qt6/plugins/styles/* \
$LIBDIR/qt6/plugins/xcbglintegrations/* \
$LIBDIR/qt6/plugins/wayland-*/* \
$LIBDIR/pulseaudio/* \
$LIBDIR/pipewire-0.3/* \
$LIBDIR/spa-0.2/*/* \
$LIBDIR/alsa-lib/*
rm -f ./sharun-aio
# Prepare sharun
if [ "$ARCH" = 'aarch64' ]; then
# allow the host vulkan to be used for aarch64 given the sad situation
echo 'SHARUN_ALLOW_SYS_VKICD=1' > ./.env
fi
# Workaround for Gentoo
if [ -d "shared/libproxy" ]; then
cp shared/libproxy/* lib/
fi
ln -f ./sharun ./AppRun
./sharun -g
# turn appdir into appimage
cd ..
wget -q "$URUNTIME" -O ./uruntime
chmod +x ./uruntime
#Add udpate info to runtime
echo "Adding update information \"$UPINFO\" to runtime..."
./uruntime --appimage-addupdinfo "$UPINFO"
echo "Generating AppImage..."
./uruntime --appimage-mkdwarfs -f \
--set-owner 0 --set-group 0 \
--no-history --no-create-timestamp \
--categorize=hotness --hotness-list=.ci/linux/eden.dwfsprof \
--compression zstd:level=22 -S26 -B32 \
--header uruntime \
-N 4 \
-i ./AppDir -o Eden-"$VERSION"-"$ARCH".AppImage
echo "Generating zsync file..."
zsyncmake *.AppImage -u *.AppImage
echo "All Done!"
+51
View File
@@ -0,0 +1,51 @@
#!/bin/bash -ex
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
if [ "$COMPILER" == "clang" ]
then
EXTRA_CMAKE_FLAGS+=(
-DCMAKE_CXX_COMPILER=clang-cl
-DCMAKE_C_COMPILER=clang-cl
-DCMAKE_CXX_FLAGS="-O3"
-DCMAKE_C_FLAGS="-O3"
)
BUILD_TYPE="RelWithDebInfo"
fi
[ -z "$WINDEPLOYQT" ] && { echo "WINDEPLOYQT environment variable required."; exit 1; }
echo $EXTRA_CMAKE_FLAGS
mkdir -p build && cd build
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE:-Release}" \
-DENABLE_QT_TRANSLATION=ON \
-DUSE_DISCORD_PRESENCE=ON \
-DYUZU_USE_BUNDLED_SDL2=ON \
-DBUILD_TESTING=OFF \
-DYUZU_TESTS=OFF \
-DDYNARMIC_TESTS=OFF \
-DYUZU_CMD=OFF \
-DYUZU_ROOM_STANDALONE=OFF \
-DYUZU_USE_QT_MULTIMEDIA=${USE_MULTIMEDIA:-false} \
-DYUZU_USE_QT_WEB_ENGINE=${USE_WEBENGINE:-false} \
-DENABLE_LTO=ON \
-DCMAKE_EXE_LINKER_FLAGS=" /LTCG" \
-DYUZU_USE_BUNDLED_QT=${BUNDLE_QT:-false} \
-DUSE_CCACHE=${CCACHE:-false} \
-DENABLE_UPDATE_CHECKER=${DEVEL:-true} \
"${EXTRA_CMAKE_FLAGS[@]}" \
"$@"
ninja
set +e
rm -f bin/*.pdb
set -e
$WINDEPLOYQT --release --no-compiler-runtime --no-opengl-sw --no-system-dxc-compiler --no-system-d3d-compiler --dir pkg bin/eden.exe
cp bin/* pkg
+18
View File
@@ -0,0 +1,18 @@
GITDATE=$(git show -s --date=short --format='%ad' | tr -d "-")
GITREV=$(git show -s --format='%h')
ZIP_NAME="Eden-Windows-${ARCH}-${GITDATE}-${GITREV}.zip"
ARTIFACTS_DIR="artifacts"
PKG_DIR="build/pkg"
mkdir -p "$ARTIFACTS_DIR"
TMP_DIR=$(mktemp -d)
cp -r "$PKG_DIR"/* "$TMP_DIR"/
cp LICENSE* README* "$TMP_DIR"/
7z a -tzip "$ARTIFACTS_DIR/$ZIP_NAME" "$TMP_DIR"/*
rm -rf "$TMP_DIR"
+1 -1
View File
@@ -3403,7 +3403,7 @@ Would you like to delete the old save data?</source>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_extensions.ui" line="62"/>
<source>Vulkan Extensions</source>
<translation>Расширения Vulcan</translation>
<translation>Расшиерния Vulcan</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_extensions.cpp" line="49"/>
+24 -27
View File
@@ -9,7 +9,6 @@ When reporting issues or finding bugs, we often need backtraces, debug logs, or
If your bug is related to a graphical issue--e.g. mismatched colors, vertex explosions, flickering, etc.--then you are required to include graphical debugging logs in your issue reports.
Graphics Debugging is found in General -> Debug on desktop, and Advanced Settings -> Debug on Android. Android users are all set; however, desktop users may need to install the Vulkan Validation Layers:
- Windows: Install the [Vulkan SDK](https://vulkan.lunarg.com/sdk/home)
- Linux, BSD, etc: Install `vulkan-validation-layers`, `vulkan-layers`, or similar from your package manager. It should be located in e.g. `/usr/lib64/libVkLayer_khronos_validation.so`
@@ -31,16 +30,15 @@ Ignoring SIGSEGV when debugging in host:
### gdb
You must have GDB installed for aarch64 to debug the target. Install it through your package manager, e.g.:
* On Arch:
* `sudo pacman -Syu aarch64-linux-gnu-gdb`
* On Gentoo:
* `sudo emerge --ask crossdev`
* `sudo crossdev -t aarch64-unknown-linux-gnu --ex-gdb`
- On Arch:
- `sudo pacman -Syu aarch64-linux-gnu-gdb`
- On Gentoo:
- `sudo emerge --ask crossdev`
- `sudo crossdev -t aarch64-unknown-linux-gnu --ex-gdb`
Run `./build/bin/eden-cli -c <path to your config file (see logs where you run eden normally to see where it is)> -d -g <path to game>`, or `Enable GDB Stub` at General > Debug, then hook up an aarch64-gdb:
- `target remote localhost:6543`
Run `./build/bin/eden-cli -c <path to your config file (see logs where you run eden normally to see where it is)> -d -g <path to game>`
Or `Enable GDB Stub` at General > Debug, then hook up an aarch64-gdb:
* `target remote localhost:6543`
Type `c` (for continue) and then if it crashes just do a `bt` (backtrace) and `layout asm`
@@ -71,27 +69,26 @@ For more information type `info gdb` and read [the man page](https://man7.org/li
## Simple checklist for debugging black screens using Renderdoc
Renderdoc is a free, cross platform, multi-graphics API debugger. It is an invaluable tool for diagnosing issues with graphics applications, and includes support for Vulkan. Get it at [renderdoc.org](https://renderdoc.org).
Renderdoc is a free, cross platform, multi-graphics API debugger. It is an invaluable tool for diagnosing issues with graphics applications, and includes support for Vulkan. Get it [here](https://renderdoc.org).
Before using renderdoc to diagnose issues, it is always good to make sure there are no validation errors. Any errors means the behavior of the application is undefined. That said, renderdoc can help debug validation errors if you do have them.
When debugging a black screen, there are many ways the application could have setup Vulkan wrong.
Here is a short checklist of items to look at to make sure are appropriate:
- Draw call counts are correct (aka not zero, or if rendering many triangles, not 3)
- Vertex buffers are bound
- vertex attributes are correct - Make sure the size & offset of each attribute matches what should it should be
- Any bound push constants and descriptors have the right data - including:
- Matrices have correct values - double check the model, view, & projection matrices are uploaded correctly
- Pipeline state is correct
- viewport range is correct - x,y are 0,0; width & height are screen dimensions, minDepth is 0, maxDepth is 1, NDCDepthRange is 0,1
- Fill mode matches expected - usually solid
- Culling mode makes sense - commonly back or none
- The winding direction is correct - typically CCW (counter clockwise)
- Scissor region is correct - usually same as viewport's x,y,width, &height
- Blend state is correct
- Depth state is correct - typically enabled with Function set to Less than or Equal
- Swapchain images are bound when rendering to the swapchain
- Image being rendered to is the same as the one being presented when rendering to the swapchain
* Draw call counts are correct (aka not zero, or if rendering many triangles, not 3)
* Vertex buffers are bound
* vertex attributes are correct - Make sure the size & offset of each attribute matches what should it should be
* Any bound push constants and descriptors have the right data - including:
* Matrices have correct values - double check the model, view, & projection matrices are uploaded correctly
* Pipeline state is correct
* viewport range is correct - x,y are 0,0; width & height are screen dimensions, minDepth is 0, maxDepth is 1, NDCDepthRange is 0,1
* Fill mode matches expected - usually solid
* Culling mode makes sense - commonly back or none
* The winding direction is correct - typically CCW (counter clockwise)
* Scissor region is correct - usually same as viewport's x,y,width, &height
* Blend state is correct
* Depth state is correct - typically enabled with Function set to Less than or Equal
* Swapchain images are bound when rendering to the swapchain
* Image being rendered to is the same as the one being presented when rendering to the swapchain
Alternatively, a [RenderDoc Extension](https://github.com/baldurk/renderdoc-contrib/tree/main/baldurk/whereismydraw) ([Archive](https://web.archive.org/web/20250000000000*/https://github.com/baldurk/renderdoc-contrib/tree/main/baldurk/whereismydraw)) exists which automates doing a lot of these manual steps.
+121 -14
View File
@@ -1,11 +1,9 @@
# Development guidelines
## License Headers
All commits must have proper license header accreditation.
You can easily add all necessary license headers by running:
```sh
git fetch origin master:master
.ci/license-header.sh -u -c
@@ -13,7 +11,6 @@ git push
```
Alternatively, you may omit `-c` and do an amend commit:
```sh
git fetch origin master:master
.ci/license-header.sh
@@ -25,10 +22,8 @@ If the work is licensed/vendored from other people or projects, you may omit the
For more information on the license header script, run `.ci/license-header.sh -h`.
## Pull Requests
Pull requests are only to be merged by core developers when properly tested and discussions conclude on Discord or other communication channels. Labels are recommended but not required. However, all PRs MUST be namespaced and optionally typed:
```txt
```
[cmake] refactor: CPM over submodules
[desktop] feat: implement firmware install from ZIP
[hle] stub fw20 functions
@@ -39,7 +34,7 @@ Pull requests are only to be merged by core developers when properly tested and
- The level of namespacing is generally left to the committer's choice.
- However, we never recommend going more than two levels *except* in `hle`, in which case you may go as many as four levels depending on the specificity of your changes.
- Ocassionally, up to two additional namespaces may be provided for more clarity.
- Changes that affect the entire project (sans CMake changes) should be namespaced as `meta`.
* Changes that affect the entire project (sans CMake changes) should be namespaced as `meta`.
- Maintainers are permitted to change namespaces at will.
- Commits within PRs are not required to be namespaced, but it is highly recommended.
@@ -55,7 +50,6 @@ When adding new settings, use `tr("Setting:")` if the setting is meant to be a f
- Try to not write "slow/fast" options unless it clearly degrades/increases performance for a given case, as most options may modify behaviour that result in different metrics accross different systems. If for example the option is an "accuracy" option, writing "High" is sufficient to imply "Slow". No need to write "High (Slow)".
Some examples:
- "[...] negatively affecting image quality", "[...] degrading image quality": Same wording but with less filler.
- "[...] this may cause some glitches or crashes in some games", "[...] this may cause soft-crashes": Crashes implies there may be glitches (as crashes are technically a form of a fatal glitch). The entire sentence is structured as "may cause [...] on some games", which is redundant, because "may cause [...] in games" has the same semantic meaning ("may" is a chance that it will occur on "some" given set).
- "FIFO Relaxed is similar to FIFO [...]", "FIFO Relaxed [...]": The name already implies similarity.
@@ -63,16 +57,13 @@ Some examples:
- "[...] it can [...] in some cases", "[...] it can [...]": Implied probability.
Before adding a new setting, consider:
- Does the piece of code that the setting pertains to, make a significant difference if it's on/off?
- Can it be auto-detected?
# IDE setup
## VSCode
Copy this to `.vscode/settings.json`, get CMake tools and it should be ready to build:
```json
{
"editor.tabSize": 4,
@@ -92,7 +83,6 @@ You may additionally need the `Qt Extension Pack` extension if building Qt.
# Build speedup
If you have an HDD, use ramdisk (build in RAM), approximatedly you need 4GB for a full build with debug symbols:
```sh
mkdir /tmp/ramdisk
chmod 777 /tmp/ramdisk
@@ -106,11 +96,128 @@ umount /tmp/ramdisk
# Assets and large files
A general rule of thumb, before uploading files:
- PNG files: Use [optipng](https://web.archive.org/web/20240325055059/https://optipng.sourceforge.net/).
- SVG files: Use [svgo](https://github.com/svg/svgo).
May not be used but worth mentioning nonethless:
- OGG files: Use [OptiVorbis](https://github.com/OptiVorbis/OptiVorbis).
- Video files: Use ffmpeg, preferably re-encode as AV1.
# Bisecting older commits
Since going into the past can be tricky (especially due to the dependencies from the project being lost thru time). This should "restore" the URLs for the respective submodules.
```sh
#!/bin/sh -e
cat > .gitmodules <<EOF
[submodule "enet"]
path = externals/enet
url = https://github.com/lsalzman/enet.git
[submodule "cubeb"]
path = externals/cubeb
url = https://github.com/mozilla/cubeb.git
[submodule "dynarmic"]
path = externals/dynarmic
url = https://github.com/lioncash/dynarmic.git
[submodule "libusb"]
path = externals/libusb/libusb
url = https://github.com/libusb/libusb.git
[submodule "discord-rpc"]
path = externals/discord-rpc
url = https://github.com/yuzu-emu-mirror/discord-rpc.git
[submodule "Vulkan-Headers"]
path = externals/Vulkan-Headers
url = https://github.com/KhronosGroup/Vulkan-Headers.git
[submodule "sirit"]
path = externals/sirit
url = https://github.com/yuzu-emu-mirror/sirit.git
[submodule "mbedtls"]
path = externals/mbedtls
url = https://github.com/yuzu-emu-mirror/mbedtls.git
[submodule "xbyak"]
path = externals/xbyak
url = https://github.com/herumi/xbyak.git
[submodule "opus"]
path = externals/opus
url = https://github.com/xiph/opus.git
[submodule "SDL"]
path = externals/SDL
url = https://github.com/libsdl-org/SDL.git
[submodule "cpp-httplib"]
path = externals/cpp-httplib
url = https://github.com/yhirose/cpp-httplib.git
[submodule "ffmpeg"]
path = externals/ffmpeg/ffmpeg
url = https://github.com/FFmpeg/FFmpeg.git
[submodule "vcpkg"]
path = externals/vcpkg
url = https://github.com/microsoft/vcpkg.git
[submodule "cpp-jwt"]
path = externals/cpp-jwt
url = https://github.com/arun11299/cpp-jwt.git
[submodule "libadrenotools"]
path = externals/libadrenotools
url = https://github.com/bylaws/libadrenotools.git
[submodule "tzdb_to_nx"]
path = externals/nx_tzdb/tzdb_to_nx
url = https://github.com/lat9nq/tzdb_to_nx.git
[submodule "VulkanMemoryAllocator"]
path = externals/VulkanMemoryAllocator
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
[submodule "breakpad"]
path = externals/breakpad
url = https://github.com/yuzu-emu-mirror/breakpad.git
[submodule "simpleini"]
path = externals/simpleini
url = https://github.com/brofield/simpleini.git
[submodule "oaknut"]
path = externals/oaknut
url = https://github.com/merryhime/oaknut.git
[submodule "Vulkan-Utility-Libraries"]
path = externals/Vulkan-Utility-Libraries
url = https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git
[submodule "oboe"]
path = externals/oboe
url = https://github.com/google/oboe.git
[submodule "externals/boost-headers"]
path = externals/boost-headers
url = https://github.com/boostorg/headers.git
EOF
git submodule sync
update_or_checkout () {
if [ $0 = 'externals/sirit' ] \
|| [ $0 = 'externals/dynarmic' ] \
|| [ $0 = 'externals/breakpad' ] \
|| [ $0 = 'externals/discord-rpc' ] \
|| [ $0 = 'externals/mbedtls' ]; then
[ -f $0/CMakeLists.txt ] || git submodule update --force --remote --init -- $0
echo $0 ':remote' && git submodule update --remote $0
exit
elif [ $0 = 'externals/nx_tzdb/tzdb_to_nx' ]; then
[ -f $0/CMakeLists.txt ] || git submodule update --force --remote --init -- $0
echo $0 ':remote' && git submodule update --remote $0
else
echo $0 ':update' && git submodule update --init $0 && exit
echo $0 ':remote' && git submodule update --remote $0 && exit
echo $0 ':failure'
fi
}
export -f update_or_checkout
grep path .gitmodules | sed 's/.*= //' | xargs -n 1 -I {} bash -c 'update_or_checkout "$@"' {}
# Fix for LLVM builds
sed -i 's/src\/yuzu\/main.cpp/${CMAKE_SOURCE_DIR}\/src\/yuzu\/main.cpp/g' CMakeModules/FindLLVM.cmake
# Only after cloning and everything - fixes issues with Zydis
cat > externals/dynarmic/src/dynarmic/common/x64_disassemble.cpp <<EOF
#include <cstddef>
#include <vector>
#include <string>
namespace Dynarmic::Common {
void DumpDisassembledX64(const void* ptr, size_t size) {}
std::vector<std::string> DisassembleX64(const void* ptr, size_t size) { return {}; }
}
EOF
```
If having issues with older artifacts, then run `rm -r externals/dynarmic/build externals/dynarmic/externals externals/nx_tzdb/tzdb_to_nx/externals externals/sirit/externals`.
Configuring CMake with `-DSIRIT_USE_SYSTEM_SPIRV_HEADERS=1 -DCMAKE_CXX_FLAGS="-Wno-error" -DCMAKE_C_FLAGS="-Wno-error -Wno-array-parameter -Wno-stringop-overflow"` is also recommended.
-4
View File
@@ -17,10 +17,6 @@
if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
set(PLATFORM_SUN ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenOrbis")
set(PLATFORM_PS4 ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "managarm")
set(PLATFORM_MANAGARM ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
set(PLATFORM_FREEBSD ON)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+66 -116
View File
@@ -11,105 +11,63 @@ set(FFmpeg_HWACCEL_FLAGS)
set(FFmpeg_HWACCEL_INCLUDE_DIRS)
set(FFmpeg_HWACCEL_LDFLAGS)
if (NOT YUZU_USE_BUNDLED_FFMPEG)
set(FFmpeg_CROSS_COMPILE_FLAGS "")
if (ANDROID)
# TODO: Maybe use CMAKE_SYSROOT? and probably provide a toolchain file for android
# I mean isn't that the "proper" way anyways?
string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" FFmpeg_HOST_SYSTEM_NAME)
set(TOOLCHAIN "${ANDROID_NDK}/toolchains/llvm/prebuilt/${FFmpeg_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}")
set(SYSROOT "${TOOLCHAIN}/sysroot")
set(FFmpeg_CPU "armv8-a")
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
--enable-cross-compile
--arch=arm64
#--cpu=${FFmpeg_CPU}
--cross-prefix="${TOOLCHAIN}/bin/aarch64-linux-android-"
--sysroot="${SYSROOT}"
--target-os=android
--extra-ldflags="--ld-path=${TOOLCHAIN}/bin/ld.lld"
--extra-ldflags="-nostdlib"
)
set(FFmpeg_IS_CROSS_COMPILING TRUE)
# User attempts to do a FFmpeg cross compilation because...
# Here we just quickly test against host/system processors not matching
# TODO: Test for versions not matching as well?
elseif (NOT (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES CMAKE_SYSTEM_PROCESSOR
AND CMAKE_HOST_SYSTEM_NAME MATCHES CMAKE_SYSTEM_NAME))
string(TOLOWER "${CMAKE_SYSTEM_NAME}" FFmpeg_SYSTEM_NAME)
if (FFmpeg_SYSTEM_NAME STREQUAL "openorbis" OR FFmpeg_SYSTEM_NAME STREQUAL "managarm")
set(FFmpeg_SYSTEM_NAME "none")
endif()
# TODO: Can we really do better? Auto-detection? Something clever?
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
--enable-cross-compile
--arch="${CMAKE_SYSTEM_PROCESSOR}"
--target-os="${FFmpeg_SYSTEM_NAME}"
--sysroot="${CMAKE_SYSROOT}"
)
if (DEFINED FFmpeg_CROSS_PREFIX)
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --cross-prefix="${FFmpeg_CROSS_PREFIX}")
else()
message(WARNING "Please set FFmpeg_CROSS_PREFIX to your cross toolchain prefix, for example: \${CMAKE_STAGING_PREFIX}/bin/${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_SYSTEM_NAME}-")
endif()
set(FFmpeg_IS_CROSS_COMPILING TRUE)
endif()
endif()
if (PLATFORM_PS4 OR PLATFORM_MANAGARM)
# Doesn't support VA-API, don't go thru the embarrassment of trying to enable it
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi)
elseif (UNIX AND NOT DEFINED FFmpeg_IS_CROSS_COMPILING)
if (UNIX AND NOT ANDROID)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBVA libva)
pkg_check_modules(CUDA cuda)
pkg_check_modules(FFNVCODEC ffnvcodec)
pkg_check_modules(VDPAU vdpau)
if (NOT ANDROID)
pkg_check_modules(LIBVA libva)
pkg_check_modules(CUDA cuda)
pkg_check_modules(FFNVCODEC ffnvcodec)
pkg_check_modules(VDPAU vdpau)
endif()
find_package(X11)
if(X11_FOUND)
if (NOT APPLE)
# In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so
if(PLATFORM_SUN)
if (NOT APPLE)
# In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so
if(PLATFORM_SUN)
find_library(LIBDRM_LIB libdrm PATHS /usr/lib/64 /usr/lib/amd64 /usr/lib)
if(LIBDRM_LIB)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
X11
"${CMAKE_SYSROOT}/usr/lib/xorg/amd64/libdrm.so")
"${LIBDRM_LIB}")
message(STATUS "Found libdrm at: ${LIBDRM_LIB}")
else()
pkg_check_modules(LIBDRM libdrm REQUIRED)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
${LIBDRM_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${LIBDRM_INCLUDE_DIRS})
message(WARNING "libdrm not found, disabling libdrm support")
list(APPEND FFmpeg_HWACCEL_FLAGS
--disable-libdrm)
endif()
else()
pkg_check_modules(LIBDRM libdrm REQUIRED)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
${LIBDRM_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${LIBDRM_INCLUDE_DIRS})
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-libdrm)
endif()
if(LIBVA_FOUND)
pkg_check_modules(LIBVA-DRM libva-drm REQUIRED)
pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
${X11_LIBRARIES}
${LIBVA-DRM_LIBRARIES}
${LIBVA-X11_LIBRARIES}
${LIBVA_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-hwaccel=h264_vaapi
--enable-hwaccel=vp8_vaapi
--enable-hwaccel=vp9_vaapi)
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${X11_INCLUDE_DIRS}
${LIBVA-DRM_INCLUDE_DIRS}
${LIBVA-X11_INCLUDE_DIRS}
${LIBVA_INCLUDE_DIRS}
)
message(STATUS "ffmpeg: va-api libraries version ${LIBVA_VERSION} found")
else()
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi)
message(WARNING "ffmpeg: libva-dev not found, disabling Video Acceleration API (VA-API)...")
endif()
endif()
if(LIBVA_FOUND)
find_package(X11 REQUIRED)
pkg_check_modules(LIBVA-DRM libva-drm REQUIRED)
pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED)
list(APPEND FFmpeg_HWACCEL_LIBRARIES
${X11_LIBRARIES}
${LIBVA-DRM_LIBRARIES}
${LIBVA-X11_LIBRARIES}
${LIBVA_LIBRARIES})
list(APPEND FFmpeg_HWACCEL_FLAGS
--enable-hwaccel=h264_vaapi
--enable-hwaccel=vp8_vaapi
--enable-hwaccel=vp9_vaapi)
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${X11_INCLUDE_DIRS}
${LIBVA-DRM_INCLUDE_DIRS}
${LIBVA-X11_INCLUDE_DIRS}
${LIBVA_INCLUDE_DIRS}
)
message(STATUS "ffmpeg: va-api libraries version ${LIBVA_VERSION} found")
else()
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi)
message(WARNING "ffmpeg: X11 libraries not found, disabling VA-API...")
message(WARNING "ffmpeg: libva-dev not found, disabling Video Acceleration API (VA-API)...")
endif()
if (FFNVCODEC_FOUND)
@@ -153,28 +111,6 @@ elseif (UNIX AND NOT DEFINED FFmpeg_IS_CROSS_COMPILING)
endif()
endif()
if (PLATFORM_PS4)
list(APPEND FFmpeg_CROSS_COMPILE_LIBS
-lkernel
-lSceUserService
-lSceSysmodule
-lSceNet
-lSceLibcInternal
)
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
--disable-pthreads
--extra-cflags=${CMAKE_SYSROOT}/usr/include
--extra-cxxflags=${CMAKE_SYSROOT}/usr/include
--extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}"
)
elseif (PLATFORM_MANAGARM)
# Required for proper stuff
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
--disable-pthreads
--extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}"
)
endif()
if (YUZU_USE_BUNDLED_FFMPEG)
AddJsonPackage(ffmpeg-ci)
@@ -245,6 +181,24 @@ else()
find_program(BASH_PROGRAM bash REQUIRED)
set(FFmpeg_CROSS_COMPILE_FLAGS "")
if (ANDROID)
string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" FFmpeg_HOST_SYSTEM_NAME)
set(TOOLCHAIN "${ANDROID_NDK}/toolchains/llvm/prebuilt/${FFmpeg_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}")
set(SYSROOT "${TOOLCHAIN}/sysroot")
set(FFmpeg_CPU "armv8-a")
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
--arch=arm64
#--cpu=${FFmpeg_CPU}
--enable-cross-compile
--cross-prefix=${TOOLCHAIN}/bin/aarch64-linux-android-
--sysroot=${SYSROOT}
--target-os=android
--extra-ldflags="--ld-path=${TOOLCHAIN}/bin/ld.lld"
--extra-ldflags="-nostdlib"
)
endif()
# `configure` parameters builds only exactly what yuzu needs from FFmpeg
# `--disable-vdpau` is needed to avoid linking issues
set(FFmpeg_CC ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER})
@@ -267,12 +221,8 @@ else()
--enable-decoder=vp9
--enable-filter=yadif,scale
--enable-pic
--cc=${FFmpeg_CC}
--cxx=${FFmpeg_CXX}
--ld=${CMAKE_LINKER}
--extra-cflags=${CMAKE_C_FLAGS}
--extra-cxxflags=${CMAKE_CXX_FLAGS}
--extra-ldflags=${CMAKE_C_LINK_FLAGS}
--cc="${FFmpeg_CC}"
--cxx="${FFmpeg_CXX}"
${FFmpeg_HWACCEL_FLAGS}
${FFmpeg_CROSS_COMPILE_FLAGS}
WORKING_DIRECTORY
+6 -6
View File
@@ -192,6 +192,12 @@ android {
manifestPlaceholders += mapOf("appNameBase" to "Eden")
resValue("string", "app_name_suffixed", "Eden")
externalNativeBuild {
cmake {
arguments.add("-DGENSHIN_SPOOF=ON")
}
}
ndk {
abiFilters += listOf("arm64-v8a")
}
@@ -203,12 +209,6 @@ android {
resValue("string", "app_name_suffixed", "Eden Optimized")
applicationId = "com.miHoYo.Yuanshen"
externalNativeBuild {
cmake {
arguments.add("-DGENSHIN_SPOOF=ON")
}
}
ndk {
abiFilters += listOf("arm64-v8a")
}
@@ -18,7 +18,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
FIX_BLOOM_EFFECTS("fix_bloom_effects"),
EMULATE_BGR565("emulate_bgr565"),
RESCALE_HACK("rescale_hack"),
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
USE_DOCKED_MODE("use_docked_mode"),
USE_AUTO_STUB("use_auto_stub"),
@@ -747,13 +747,6 @@ abstract class SettingsItem(
descriptionId = R.string.fix_bloom_effects_description
)
)
put(
SwitchSetting(
BooleanSetting.RESCALE_HACK,
titleId = R.string.rescale_hack,
descriptionId = R.string.rescale_hack_description
)
)
put(
SwitchSetting(
BooleanSetting.EMULATE_BGR565,
@@ -293,7 +293,6 @@ class SettingsFragmentPresenter(
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
add(BooleanSetting.EMULATE_BGR565.key)
add(BooleanSetting.RESCALE_HACK.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key)
add(BooleanSetting.RENDERER_ASYNC_PRESENTATION.key)
@@ -413,9 +413,7 @@
<string name="frame_limit_slider">Limiter le pourcentage de vitesse</string>
<string name="frame_limit_slider_description">Spécifier le pourcentage pour limiter la vitesse d\'émulation. 100% correspond à la vitesse normale. Des valeurs plus élevées ou plus basses augmenteront ou diminueront la limite de vitesse.</string>
<string name="turbo_speed_limit">Vitesse turbo</string>
<string name="turbo_speed_limit_description">Lorsque le mode Turbo est activé, l\'émulation s\'exécute à cette vitesse.</string>
<string name="slow_speed_limit">Vitesse lente</string>
<string name="slow_speed_limit_description">Lorsque le mode Lent est activé, l\'émulation s\'exécute à cette vitesse.</string>
<string name="cpu_backend">Backend du CPU</string>
<string name="cpu_accuracy">Précision du CPU</string>
<string name="value_with_units">%1$s%2$s</string>
@@ -489,8 +489,6 @@
<string name="enable_buffer_history">Включить историю буфера</string>
<string name="enable_buffer_history_description">Позволяет обращаться к предыдущим состояниям буфера. Эта опция может повысить качество рендеринга и стабильность производительности в некоторых играх.</string>
<string name="use_optimized_vertex_buffers">Оптимизированные вершинные буферы</string>
<string name="use_optimized_vertex_buffers_description">Включает оптимизированную привязку вершинного буфера для повышения производительности. Требует Mesa Turnip 26.0+ / QCOM драйверы. Приводит к вылету на старых версиях Turnip.</string>
<string name="hacks">Хаки</string>
<string name="fast_gpu_time">Быстрое время ГПУ</string>
@@ -498,9 +496,6 @@
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
<string name="fix_bloom_effects">Исправить эффекты размытия</string>
<string name="fix_bloom_effects_description">Частично убирает размытие в LA/EOW (Adreno A6XX - A7XX/ Turnip), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх.</string>
<string name="emulate_bgr565">Эмулировать BGR565</string>
<string name="emulate_bgr565_description">Исправляет проблемы с инвертированными цветами в играх, а также со странными артефактами или некорректными тенями.</string>
<string name="renderer_asynchronous_shaders">Использовать асинхронные шейдеры</string>
<string name="renderer_asynchronous_shaders_description">Компилирует шейдеры асинхронно. Это может уменьшить подтормаживания, но также может вызвать графические артефакты.</string>
<string name="gpu_unswizzle_settings">Настройки распаковки текстур (Unswizzle)</string>
@@ -511,8 +511,6 @@
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno A6XX - A7XX/ Turnip), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
<string name="emulate_bgr565">Emulate BGR565</string>
<string name="emulate_bgr565_description">Fixes problems with inverted colors in games or strange artifacts or strange shadows.</string>
<string name="rescale_hack">Enable Legacy Rescale Pass</string>
<string name="rescale_hack_description">Fixes Luigi Mansion 3 artifact lines.</string>
<string name="renderer_asynchronous_shaders">Use asynchronous shaders</string>
<string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches.</string>
<string name="gpu_unswizzle_settings">GPU Unswizzle Settings</string>
+42 -16
View File
@@ -349,8 +349,35 @@ struct Impl {
// Well, I mean it's the default constructor!
explicit Impl() noexcept : filter(Level::Trace) {}
template<typename F>
void ForEachBackend(F&& lambda) noexcept {
void StartBackendThread() noexcept {
backend_thread = std::jthread([this](std::stop_token stop_token) {
Common::SetCurrentThreadName("Logger");
Entry entry;
const auto write_logs = [this, &entry]() {
ForEachBackend([&entry](Backend& backend) {
backend.Write(entry);
});
};
do {
message_queue.PopWait(entry, stop_token);
write_logs();
} while (!stop_token.stop_requested());
// Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a
// case where a system is repeatedly spamming logs even on close.
int max_logs_to_write = filter.IsDebug() ? INT_MAX : 100;
while (max_logs_to_write-- && message_queue.TryPop(entry))
write_logs();
});
}
void StopBackendThread() noexcept {
backend_thread.request_stop();
if (backend_thread.joinable())
backend_thread.join();
ForEachBackend([](Backend& backend) { backend.Flush(); });
}
void ForEachBackend(auto lambda) noexcept {
lambda(static_cast<Backend&>(color_console_backend));
#ifndef __OPENORBIS__
if (file_backend)
@@ -375,7 +402,9 @@ struct Impl {
#ifdef ANDROID
LogcatBackend lc_backend{};
#endif
MPSCQueue<Entry> message_queue{};
std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
std::jthread backend_thread;
};
} // namespace
@@ -399,11 +428,13 @@ void Initialize() {
}
void Start() {
if (logging_instance)
logging_instance->StartBackendThread();
}
void Stop() {
if (logging_instance)
logging_instance->ForEachBackend([](Backend& backend) { backend.Flush(); });
logging_instance->StopBackendThread();
}
void SetGlobalFilter(const Filter& filter) {
@@ -418,19 +449,14 @@ void SetColorConsoleBackendEnabled(bool enabled) {
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 (logging_instance && logging_instance->filter.CheckMessage(log_class, log_level)) {
auto const flush = ::Settings::values.log_flush_line.GetValue();
logging_instance->ForEachBackend([=](Backend& backend) {
backend.Write(Entry{
.message = fmt::vformat(format, args),
.timestamp = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - logging_instance->time_origin),
.log_class = log_class,
.log_level = log_level,
.filename = TrimSourcePath(filename),
.function = function,
.line_num = line_num,
});
if (flush)
backend.Flush();
logging_instance->message_queue.EmplaceWait(Entry{
.message = fmt::vformat(format, args),
.timestamp = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - logging_instance->time_origin),
.log_class = log_class,
.log_level = log_level,
.filename = TrimSourcePath(filename),
.function = function,
.line_num = line_num,
});
}
}
+1
View File
@@ -415,6 +415,7 @@ struct System::Impl {
cpu_manager.Shutdown();
debugger.reset();
kernel.Shutdown();
device_memory.reset();
stop_event = {};
Network::RestartSocketOperations();
+3 -10
View File
@@ -1,12 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <memory>
#include "common/alignment.h"
#include "common/literals.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/sdmc_factory.h"
#include "core/file_sys/vfs/vfs.h"
@@ -14,6 +9,8 @@
namespace FileSys {
constexpr u64 SDMC_TOTAL_SIZE = 0x10000000000; // 1 TiB
SDMCFactory::SDMCFactory(VirtualDir sd_dir_, VirtualDir sd_mod_dir_)
: sd_dir(std::move(sd_dir_)), sd_mod_dir(std::move(sd_mod_dir_)),
contents(std::make_unique<RegisteredCache>(
@@ -59,11 +56,7 @@ u64 SDMCFactory::GetSDMCFreeSpace() const {
}
u64 SDMCFactory::GetSDMCTotalSpace() const {
// Resize the SD space automatically, always leaving around 4GiB last from next chunk block
using namespace Common::Literals;
auto const bytes_per_sector = 512;
auto const size_block = (sd_dir->GetSize() + 4_GiB) / 4_GiB;
return Common::AlignUp(size_block * 4_GiB, bytes_per_sector);
return SDMC_TOTAL_SIZE;
}
} // namespace FileSys
@@ -15,76 +15,86 @@
namespace FileSys::SystemArchive {
constexpr u64 SYSTEM_ARCHIVE_BASE_TITLE_ID = 0x0100000000000800;
constexpr std::size_t SYSTEM_ARCHIVE_COUNT = 0x28;
using SystemArchiveSupplier = VirtualDir (*)();
struct SystemArchiveDescriptor {
u64 title_id;
const char* name;
VirtualDir (*supplier)();
SystemArchiveSupplier supplier;
};
constexpr inline SystemArchiveDescriptor GetSystemArchive(u64 title_id) {
switch (title_id) {
case 0x0100000000000800: return {"CertStore", nullptr};
case 0x0100000000000801: return {"ErrorMessage", nullptr};
case 0x0100000000000802: return {"MiiModel", &MiiModel};
case 0x0100000000000803: return {"BrowserDll", nullptr};
case 0x0100000000000804: return {"Help", nullptr};
case 0x0100000000000805: return {"SharedFont", nullptr};
case 0x0100000000000806: return {"NgWord", &NgWord1};
case 0x0100000000000807: return {"SsidList", nullptr};
case 0x0100000000000808: return {"Dictionary", nullptr};
case 0x0100000000000809: return {"SystemVersion", &SystemVersion};
case 0x010000000000080A: return {"AvatarImage", nullptr};
case 0x010000000000080B: return {"LocalNews", nullptr};
case 0x010000000000080C: return {"Eula", nullptr};
case 0x010000000000080D: return {"UrlBlackList", nullptr};
case 0x010000000000080E: return {"TimeZoneBinary", &TimeZoneBinary};
case 0x010000000000080F: return {"CertStoreCruiser", nullptr};
case 0x0100000000000810: return {"FontNintendoExtension", &FontNintendoExtension};
case 0x0100000000000811: return {"FontStandard", &FontStandard};
case 0x0100000000000812: return {"FontKorean", &FontKorean};
case 0x0100000000000813: return {"FontChineseTraditional", &FontChineseTraditional};
case 0x0100000000000814: return {"FontChineseSimple", &FontChineseSimple};
case 0x0100000000000815: return {"FontBfcpx", nullptr};
case 0x0100000000000816: return {"SystemUpdate", nullptr};
case 0x0100000000000817: return {"0100000000000817", nullptr};
case 0x0100000000000818: return {"FirmwareDebugSettings", nullptr};
case 0x0100000000000819: return {"BootImagePackage", nullptr};
case 0x010000000000081A: return {"BootImagePackageSafe", nullptr};
case 0x010000000000081B: return {"BootImagePackageExFat", nullptr};
case 0x010000000000081C: return {"BootImagePackageExFatSafe", nullptr};
case 0x010000000000081D: return {"FatalMessage", nullptr};
case 0x010000000000081E: return {"ControllerIcon", nullptr};
case 0x010000000000081F: return {"PlatformConfigIcosa", nullptr};
case 0x0100000000000820: return {"PlatformConfigCopper", nullptr};
case 0x0100000000000821: return {"PlatformConfigHoag", nullptr};
case 0x0100000000000822: return {"ControllerFirmware", nullptr};
case 0x0100000000000823: return {"NgWord2", &NgWord2};
case 0x0100000000000824: return {"PlatformConfigIcosaMariko", nullptr};
case 0x0100000000000825: return {"ApplicationBlackList", nullptr};
case 0x0100000000000826: return {"RebootlessSystemUpdateVersion", nullptr};
case 0x0100000000000827: return {"ContentActionTable", nullptr};
case 0x0100000000000828: return {"FunctionBlackList", nullptr};
case 0x0100000000000829: return {"PlatformConfigCalcio", nullptr};
case 0x0100000000000830: return {"NgWordT", nullptr};
case 0x0100000000000831: return {"PlatformConfigAula", nullptr};
case 0x0100000000000832: return {"CradleFirmware", nullptr};
case 0x0100000000000835: return {"ErrorMessageUtf8", nullptr};
case 0x0100000000000859: return {"ClientCertData", nullptr};
case 0x010000000000085C: return {"GameCardConfigurationData", nullptr};
default: return {nullptr, nullptr};
}
}
constexpr std::array<SystemArchiveDescriptor, SYSTEM_ARCHIVE_COUNT> SYSTEM_ARCHIVES{{
{0x0100000000000800, "CertStore", nullptr},
{0x0100000000000801, "ErrorMessage", nullptr},
{0x0100000000000802, "MiiModel", &MiiModel},
{0x0100000000000803, "BrowserDll", nullptr},
{0x0100000000000804, "Help", nullptr},
{0x0100000000000805, "SharedFont", nullptr},
{0x0100000000000806, "NgWord", &NgWord1},
{0x0100000000000807, "SsidList", nullptr},
{0x0100000000000808, "Dictionary", nullptr},
{0x0100000000000809, "SystemVersion", &SystemVersion},
{0x010000000000080A, "AvatarImage", nullptr},
{0x010000000000080B, "LocalNews", nullptr},
{0x010000000000080C, "Eula", nullptr},
{0x010000000000080D, "UrlBlackList", nullptr},
{0x010000000000080E, "TimeZoneBinary", &TimeZoneBinary},
{0x010000000000080F, "CertStoreCruiser", nullptr},
{0x0100000000000810, "FontNintendoExtension", &FontNintendoExtension},
{0x0100000000000811, "FontStandard", &FontStandard},
{0x0100000000000812, "FontKorean", &FontKorean},
{0x0100000000000813, "FontChineseTraditional", &FontChineseTraditional},
{0x0100000000000814, "FontChineseSimple", &FontChineseSimple},
{0x0100000000000815, "FontBfcpx", nullptr},
{0x0100000000000816, "SystemUpdate", nullptr},
{0x0100000000000817, "0100000000000817", nullptr},
{0x0100000000000818, "FirmwareDebugSettings", nullptr},
{0x0100000000000819, "BootImagePackage", nullptr},
{0x010000000000081A, "BootImagePackageSafe", nullptr},
{0x010000000000081B, "BootImagePackageExFat", nullptr},
{0x010000000000081C, "BootImagePackageExFatSafe", nullptr},
{0x010000000000081D, "FatalMessage", nullptr},
{0x010000000000081E, "ControllerIcon", nullptr},
{0x010000000000081F, "PlatformConfigIcosa", nullptr},
{0x0100000000000820, "PlatformConfigCopper", nullptr},
{0x0100000000000821, "PlatformConfigHoag", nullptr},
{0x0100000000000822, "ControllerFirmware", nullptr},
{0x0100000000000823, "NgWord2", &NgWord2},
{0x0100000000000824, "PlatformConfigIcosaMariko", nullptr},
{0x0100000000000825, "ApplicationBlackList", nullptr},
{0x0100000000000826, "RebootlessSystemUpdateVersion", nullptr},
{0x0100000000000827, "ContentActionTable", nullptr},
}};
VirtualFile SynthesizeSystemArchive(const u64 title_id) {
auto const desc = GetSystemArchive(title_id);
LOG_INFO(Service_FS, "Synthesizing system archive '{}' (0x{:016X}).", desc.name, title_id);
if (desc.supplier != nullptr) {
if (auto const dir = desc.supplier(); dir != nullptr) {
if (auto const romfs = CreateRomFS(dir); romfs != nullptr) {
LOG_INFO(Service_FS, " - System archive generation successful!");
return romfs;
}
}
if (title_id < SYSTEM_ARCHIVES.front().title_id || title_id > SYSTEM_ARCHIVES.back().title_id) {
return nullptr;
}
return nullptr;
const auto& desc = SYSTEM_ARCHIVES[title_id - SYSTEM_ARCHIVE_BASE_TITLE_ID];
LOG_INFO(Service_FS, "Synthesizing system archive '{}' (0x{:016X}).", desc.name, desc.title_id);
if (desc.supplier == nullptr) {
return nullptr;
}
const auto dir = desc.supplier();
if (dir == nullptr) {
return nullptr;
}
const auto romfs = CreateRomFS(dir);
if (romfs == nullptr) {
return nullptr;
}
LOG_INFO(Service_FS, " - System archive generation successful!");
return romfs;
}
} // namespace FileSys::SystemArchive
@@ -268,7 +268,6 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool
// Set other basic fields.
m_enable_aslr = enable_aslr;
m_enable_device_address_space_merge = enable_das_merge;
m_allowed_exec_device_mapping = false;
m_address_space_start = start;
m_address_space_end = end;
m_is_kernel = false;
-5
View File
@@ -223,7 +223,6 @@ private:
bool m_is_kernel{};
bool m_enable_aslr{};
bool m_enable_device_address_space_merge{};
bool m_allowed_exec_device_mapping{};
KMemoryBlockSlabManager* m_memory_block_slab_manager{};
KBlockInfoManager* m_block_info_manager{};
KResourceLimit* m_resource_limit{};
@@ -256,10 +255,6 @@ public:
return m_enable_aslr;
}
void AllowDeviceMappingOfExecPages() {
m_allowed_exec_device_mapping = true;
}
bool Contains(KProcessAddress addr) const {
return m_address_space_start <= addr && addr <= m_address_space_end - 1;
}
-13
View File
@@ -341,11 +341,6 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa
// Initialize capabilities.
R_TRY(m_capabilities.InitializeForKip(caps, std::addressof(m_page_table)));
// Enable mapping device pages as executable on legacy processes.
if (m_capabilities.GetIntendedKernelMajorVersion() < 26) {
m_page_table.AllowDeviceMappingOfExecPages();
}
// Initialize the process id.
m_process_id = m_kernel.CreateNewUserProcessID();
ASSERT(InitialProcessIdMin <= m_process_id);
@@ -442,11 +437,6 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params,
// Initialize capabilities.
R_TRY(m_capabilities.InitializeForUser(user_caps, std::addressof(m_page_table)));
// Enable mapping device pages as executable on legacy processes.
if (m_capabilities.GetIntendedKernelMajorVersion() < 26) {
m_page_table.AllowDeviceMappingOfExecPages();
}
// Initialize the process id.
m_process_id = m_kernel.CreateNewUserProcessID();
ASSERT(ProcessIdMin <= m_process_id);
@@ -999,9 +989,6 @@ Result KProcess::Run(s32 priority, size_t stack_size) {
main_thread->GetContext().r[0] = 0;
main_thread->GetContext().r[1] = thread_handle;
// Pass the thread handle to the thread local region.
this->GetMemory().Write32(GetInteger(main_thread->GetTlsAddress()) + 0x110, thread_handle);
// Update our state.
this->ChangeState((state == State::Created) ? State::Running : State::RunningAttached);
ON_RESULT_FAILURE_2 {
@@ -33,10 +33,6 @@ public:
m_page_table.Finalize();
}
void AllowDeviceMappingOfExecPages() {
m_page_table.AllowDeviceMappingOfExecPages();
}
[[nodiscard]] Core::Memory::Memory& GetMemory() noexcept { return m_page_table.GetMemory(); }
[[nodiscard]] Core::Memory::Memory const& GetMemory() const noexcept { return m_page_table.GetMemory(); }
[[nodiscard]] Common::PageTable& GetImpl() noexcept { return m_page_table.GetImpl(); }
+18 -20
View File
@@ -76,13 +76,11 @@ namespace Kernel {
std::atomic_uint16_t interrupt_flag;
std::atomic_uint8_t cache_maintenance_flag;
std::atomic_int64_t thread_cpu_time;
std::atomic_uint32_t current_thread_handle;
};
static_assert(offsetof(ThreadLocalRegion, disable_count) == 0x100);
static_assert(offsetof(ThreadLocalRegion, interrupt_flag) == 0x102);
static_assert(offsetof(ThreadLocalRegion, cache_maintenance_flag) == 0x104);
static_assert(offsetof(ThreadLocalRegion, thread_cpu_time) == 0x108);
static_assert(offsetof(ThreadLocalRegion, current_thread_handle) == 0x110);
class ThreadQueueImplForKThreadSleep final : public KThreadQueueWithoutEndWait {
public:
@@ -130,24 +128,24 @@ namespace Kernel {
// Next, assert things based on the type.
switch (type) {
case ThreadType::Main:
ASSERT(arg == 0);
[[fallthrough]];
case ThreadType::User:
ASSERT(((owner == nullptr) ||
(owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask()));
ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) ||
(owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask()));
break;
case ThreadType::HighPriority:
case ThreadType::Dummy:
break;
case ThreadType::Kernel:
UNIMPLEMENTED();
break;
default:
ASSERT_MSG(false, "KThread::Initialize: Unknown ThreadType {}", static_cast<u32>(type));
break;
case ThreadType::Main:
ASSERT(arg == 0);
[[fallthrough]];
case ThreadType::User:
ASSERT(((owner == nullptr) ||
(owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask()));
ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) ||
(owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask()));
break;
case ThreadType::HighPriority:
case ThreadType::Dummy:
break;
case ThreadType::Kernel:
UNIMPLEMENTED();
break;
default:
ASSERT_MSG(false, "KThread::Initialize: Unknown ThreadType {}", static_cast<u32>(type));
break;
}
m_thread_type = type;
+2 -7
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@@ -75,12 +75,7 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u
KThread::Register(kernel, thread);
// Add the thread to the handle table.
R_TRY(process.GetHandleTable().Add(out_handle, thread));
// Pass the thread handle to the thread local region.
process.GetMemory().Write32(GetInteger(thread->GetTlsAddress()) + 0x110, *out_handle);
R_SUCCEED();
R_RETURN(process.GetHandleTable().Add(out_handle, thread));
}
/// Starts the thread for the provided handle
+3 -3
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@@ -53,8 +53,8 @@ constexpr inline u32 RequiredKernelVersion =
// This is the highest SVC version supported, to be updated on new kernel releases.
// NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor.
constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(22);
constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion(2);
constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(20);
constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion(5);
constexpr inline u32 SupportedKernelVersion =
EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion);
-8
View File
@@ -1155,14 +1155,6 @@ void Module::Interface::StoreSaveDataThumbnailSystem(HLERequestContext& ctx) {
StoreSaveDataThumbnail(ctx, uuid, tid);
}
void Module::Interface::GetPinCodeLength(HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(0);
}
void Module::Interface::StoreSaveDataThumbnail(HLERequestContext& ctx, const Common::UUID& uuid,
const u64 tid) {
IPC::ResponseBuilder rb{ctx, 2};
+1 -2
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
@@ -48,7 +48,6 @@ public:
void StoreSaveDataThumbnailApplication(HLERequestContext& ctx);
void GetBaasAccountManagerForSystemService(HLERequestContext& ctx);
void StoreSaveDataThumbnailSystem(HLERequestContext& ctx);
void GetPinCodeLength(HLERequestContext& ctx);
private:
Result InitializeApplicationInfoBase();
+2 -2
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
@@ -60,7 +60,7 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager>
{291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"},
{299, nullptr, "SuspendBackgroundDaemon"},
{400, nullptr, "SetPinCode"}, // 18.0.0+
{401, &ACC_SU::GetPinCodeLength, "GetPinCodeLength"}, // 18.0.0+
{401, nullptr, "GetPinCodeLength"}, // 18.0.0+
{402, nullptr, "GetPinCode"}, // 18.0.0+
{410, nullptr, "GetPinCodeErrorCount"}, // 18.0.0+
{411, nullptr, "ResetPinCodeErrorCount"}, // 18.0.0+
+1 -4
View File
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -43,7 +40,7 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager>
{152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"},
{190, nullptr, "GetUserLastOpenedApplication"},
{191, nullptr, "ActivateOpenContextHolder"},
{401, &ACC_U1::GetPinCodeLength, "GetPinCodeLength"}, // 18.0.0+
{401, nullptr, "GetPinCodeLength"}, // 18.0.0+
{402, nullptr, "GetPinCode"}, // 18.0.0+
{997, nullptr, "DebugInvalidateTokenCacheForUser"},
{998, nullptr, "DebugSetUserStateClose"},
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
@@ -92,7 +92,7 @@ Result IApplicationCreator::CreateSystemApplication(
std::unique_ptr<Loader::AppLoader> loader;
auto process =
CreateProcess(system, application_id, 1, 22);
CreateProcess(system, application_id, 1, 21);
R_UNLESS(process != nullptr, ResultUnknown);
const auto applet = std::make_shared<Applet>(system, std::move(process), true);
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
@@ -75,8 +75,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Ap
{502, nullptr, "IsSleepEnabled"},
{503, nullptr, "IsDisablingSleepSuppressed"},
{600, nullptr, "Unknown600"}, //20.0.0+
{610, D<&ICommonStateGetter::Unknown610>, "Unknown610"}, //21.0.0+
{611, D<&ICommonStateGetter::Unknown611>, "Unknown611"}, //22.0.0+
{610, nullptr, "Unknown610"}, //21.0.0+
{900, D<&ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled>, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, //11.0.0+
{910, nullptr, "GetLaunchRequiredTick"}, //17.0.0+
{1000, nullptr, "BeginVrMode3d"}, //19.0.0+
@@ -363,14 +362,4 @@ Result ICommonStateGetter::SetHandlingHomeButtonShortPressedEnabled(bool enabled
R_SUCCEED();
}
Result ICommonStateGetter::Unknown610() {
LOG_WARNING(Service_AM, "(STUBBED) called");
R_SUCCEED();
}
Result ICommonStateGetter::Unknown611() {
LOG_WARNING(Service_AM, "(STUBBED) called");
R_SUCCEED();
}
} // namespace Service::AM
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
@@ -63,8 +63,6 @@ private:
Result SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled();
Result PushToGeneralChannel(SharedPointer<IStorage> storage); // cmd 20
Result SetHandlingHomeButtonShortPressedEnabled(bool enabled);
Result Unknown610();
Result Unknown611();
void SetCpuBoostMode(HLERequestContext& ctx);
@@ -78,7 +78,6 @@ ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_,
{120, nullptr, "GetLibraryAppletInfo"},
{150, nullptr, "RequestForAppletToGetForeground"},
{160, D<&ILibraryAppletAccessor::GetIndirectLayerConsumerHandle>, "GetIndirectLayerConsumerHandle"}, //2.0.0+
{170, D<&ILibraryAppletAccessor::Unknown170>, "Unknown170"}, //22.0.0+
};
// clang-format on
@@ -218,12 +217,6 @@ Result ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(Out<u64> out_handl
R_SUCCEED();
}
Result ILibraryAppletAccessor::Unknown170(OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_AM, "(STUBBED) called");
*out_event = m_applet->unknown_event.GetHandle();
R_SUCCEED();
}
void ILibraryAppletAccessor::FrontendExecute() {
if (m_applet->frontend) {
m_applet->frontend->Initialize();
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
@@ -37,7 +37,6 @@ private:
Result GetPopOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetPopInteractiveOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetIndirectLayerConsumerHandle(Out<u64> out_handle);
Result Unknown170(OutCopyHandle<Kernel::KReadableEvent> out_event);
void FrontendExecute();
void FrontendExecuteInteractive();
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
@@ -118,10 +118,9 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
Firmware1900 = 19,
Firmware2000 = 20,
Firmware2100 = 21,
Firmware2200 = 22,
};
auto process = CreateProcess(system, program_id, Firmware1400, Firmware2200);
auto process = CreateProcess(system, program_id, Firmware1400, Firmware2100);
if (!process) {
// Couldn't initialize the guest process
return {};
+19 -40
View File
@@ -53,53 +53,38 @@ public:
{20102, nullptr, "GetFriendDetailedInfo"},
{20103, nullptr, "SyncFriendList"},
{20104, &IFriendService::RequestSyncFriendList, "RequestSyncFriendList"},
{20105, &IFriendService::GetFriendListForViewer, "GetFriendListForViewerV1"},
{20106, nullptr, "UpdateFriendInfoForViewerV1"},
{20107, nullptr, "GetFriendDetailedInfoV2"}, // 20.0.0+
{20108, &IFriendService::GetFriendListForViewer, "GetFriendListForViewerV2"}, // 22.0.0+
{20109, nullptr, "UpdateFriendInfoForViewerV2"}, // 22.0.0+
{20110, nullptr, "LoadFriendSettingV1"},
{20111, nullptr, "LoadFriendSettingV2"}, // 22.0.0+
{20105, &IFriendService::GetFriendListForViewer, "GetFriendListForViewer"},
{20110, nullptr, "LoadFriendSetting"},
{20200, &IFriendService::GetReceivedFriendRequestCount, "GetReceivedFriendRequestCount"},
{20201, nullptr, "GetFriendRequestListV1"},
{20202, nullptr, "GetFriendRequestListV2"}, // 20.0.0+
{20203, nullptr, "GetFriendRequestReceivedNotificationCount"}, // 22.0.0+
{20201, nullptr, "GetFriendRequestList"},
{20300, nullptr, "GetFriendCandidateList"},
{20301, nullptr, "GetNintendoNetworkIdInfo"},
{20302, nullptr, "GetSnsAccountLinkage"}, // 5.0.0-19.0.1
{20303, nullptr, "GetSnsAccountProfile"}, // 5.0.0-19.0.1
{20304, nullptr, "GetSnsAccountFriendList"}, // 5.0.0-19.0.1
{20400, nullptr, "GetBlockedUserListV1"},
{20302, nullptr, "GetSnsAccountLinkage"},
{20303, nullptr, "GetSnsAccountProfile"},
{20304, nullptr, "GetSnsAccountFriendList"},
{20400, nullptr, "GetBlockedUserList"},
{20401, nullptr, "SyncBlockedUserList"},
{20402, nullptr, "GetBlockedUserListV2"}, // 20.0.0+
{20500, nullptr, "GetProfileExtraListV1"},
{20500, nullptr, "GetProfileExtraList"},
{20501, nullptr, "GetRelationship"},
{20502, nullptr, "GetProfileExtraListV2"}, // 19.0.0+
{20600, &IFriendService::GetUserPresenceView, "GetUserPresenceViewV1"},
{20601, &IFriendService::GetUserPresenceView, "GetUserPresenceViewV2"}, // 19.0.0+
{20700, nullptr, "GetPlayHistoryListV1"},
{20601, &IFriendService::GetUserPresenceView, "GetUserPresenceViewV2"},
{20700, nullptr, "GetPlayHistoryList"},
{20701, &IFriendService::GetPlayHistoryStatistics, "GetPlayHistoryStatistics"},
{20702, nullptr, "GetPlayHistoryListV2"}, // 19.0.0+
{20800, &IFriendService::LoadUserSetting, "LoadUserSettingV1"},
{20801, nullptr, "SyncUserSetting"},
{20802, &IFriendService::LoadUserSetting, "LoadUserSettingV2"}, // 19.0.0+
{20802, &IFriendService::LoadUserSetting, "LoadUserSettingV2"},
{20900, &IFriendService::RequestListSummaryOverlayNotification, "RequestListSummaryOverlayNotification"},
{21000, nullptr, "GetExternalApplicationCatalog"},
{22000, nullptr, "GetReceivedFriendInvitationListV1"},
{22001, nullptr, "GetReceivedFriendInvitationDetailedInfoV1"},
{22002, nullptr, "GetReceivedFriendInvitationListV2"}, // 19.0.0+
{22003, nullptr, "GetReceivedFriendInvitationDetailedInfoV2"}, // 19.0.0+
{22000, nullptr, "GetReceivedFriendInvitationList"},
{22001, nullptr, "GetReceivedFriendInvitationDetailedInfo"},
{22010, &IFriendService::GetReceivedFriendInvitationCountCache, "GetReceivedFriendInvitationCountCache"},
{30100, nullptr, "DropFriendNewlyFlags"},
{30101, nullptr, "DeleteFriend"},
{30110, nullptr, "DropFriendNewlyFlag"},
{30120, nullptr, "ChangeFriendFavoriteFlag"},
{30121, nullptr, "ChangeFriendOnlineNotificationFlag"},
{30130, nullptr, "SetFriendNote"}, // 22.0.0+
{30131, nullptr, "RequestUploadPendingNote"}, // 22.0.0+
{30190, nullptr, "RequestSyncLocalUpdates"}, // 22.0.0+
{30200, nullptr, "SendFriendRequest"},
{30201, nullptr, "SendFriendRequestWithApplicationInfoV1"},
{30201, nullptr, "SendFriendRequestWithApplicationInfo"},
{30202, nullptr, "CancelFriendRequest"},
{30203, nullptr, "AcceptFriendRequest"},
{30204, nullptr, "RejectFriendRequest"},
@@ -112,27 +97,21 @@ public:
{30215, nullptr, "SendFriendRequestWithExternalApplicationCatalogId"},
{30216, nullptr, "ResendFacedFriendRequest"},
{30217, nullptr, "SendFriendRequestWithNintendoNetworkIdInfo"},
{30218, nullptr, "SendFriendRequestWithApplicationInfoV2"}, // 20.0.0+
{30300, nullptr, "GetSnsAccountLinkPageUrl"}, // 5.0.0-19.0.1
{30301, nullptr, "UnlinkSnsAccount"}, // 5.0.0-19.0.1
{30300, nullptr, "GetSnsAccountLinkPageUrl"},
{30301, nullptr, "UnlinkSnsAccount"},
{30400, nullptr, "BlockUser"},
{30401, nullptr, "BlockUserWithApplicationInfoV1"},
{30401, nullptr, "BlockUserWithApplicationInfo"},
{30402, nullptr, "UnblockUser"},
{30403, nullptr, "BlockUserWithApplicationInfoV2"}, // 20.0.0+
{30500, nullptr, "GetProfileExtraFromFriendCodeV1"},
{30501, nullptr, "GetProfileExtraFromFriendCodeV2"}, // 19.0.0+
{30500, nullptr, "GetProfileExtraFromFriendCode"},
{30700, nullptr, "DeletePlayHistory"},
{30701, nullptr, "AddPlayHistoryWithApplication"}, // 19.0.0+
{30810, nullptr, "ChangePresencePermission"},
{30811, nullptr, "ChangeFriendRequestReception"},
{30812, nullptr, "ChangePlayLogPermission"},
{30820, nullptr, "IssueFriendCode"},
{30830, nullptr, "ClearPlayLog"},
{30900, nullptr, "SendFriendInvitationV1"},
{30901, nullptr, "SendFriendInvitationV2"}, // 19.0.0+
{30900, nullptr, "SendFriendInvitation"},
{30910, nullptr, "ReadFriendInvitation"},
{30911, nullptr, "ReadAllFriendInvitations"},
{31000, nullptr, "OpenUser"}, // 19.0.0+
{40100, nullptr, "DeleteFriendListCache"},
{40400, nullptr, "DeleteBlockedUserListCache"},
{49900, nullptr, "DeleteNetworkServiceAccountCache"},
@@ -199,28 +199,25 @@ NvResult nvhost_as_gpu::AllocateSpace(IoctlAllocSpace& params) {
return NvResult::Success;
}
bool nvhost_as_gpu::FreeMappingLocked(u64 offset) noexcept {
if (auto const it = mapping_map.find(offset); it != mapping_map.end()) {
auto const mapping = it->second;
if (!mapping.fixed) {
auto& allocator{mapping.big_page ? *vm.big_page_allocator : *vm.small_page_allocator};
u32 page_size_bits{mapping.big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS};
u32 page_size{mapping.big_page ? vm.big_page_size : VM::YUZU_PAGESIZE};
u64 aligned_size{Common::AlignUp(mapping.size, page_size)};
allocator.Free(u32(mapping.offset >> page_size_bits), u32(aligned_size >> page_size_bits));
}
nvmap.UnpinHandle(mapping.handle);
// Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
// Only FreeSpace can unmap them fully
if (mapping.sparse_alloc) {
gmmu->MapSparse(offset, mapping.size, mapping.big_page);
} else {
gmmu->Unmap(offset, mapping.size);
}
mapping_map.erase(offset);
return true;
void nvhost_as_gpu::FreeMappingLocked(u64 offset) {
auto const it = mapping_map.find(offset);
auto const mapping = it->second;
if (!mapping.fixed) {
auto& allocator{mapping.big_page ? *vm.big_page_allocator : *vm.small_page_allocator};
u32 page_size_bits{mapping.big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS};
u32 page_size{mapping.big_page ? vm.big_page_size : VM::YUZU_PAGESIZE};
u64 aligned_size{Common::AlignUp(mapping.size, page_size)};
allocator.Free(u32(mapping.offset >> page_size_bits), u32(aligned_size >> page_size_bits));
}
return false;
nvmap.UnpinHandle(mapping.handle);
// Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
// Only FreeSpace can unmap them fully
if (mapping.sparse_alloc) {
gmmu->MapSparse(offset, mapping.size, mapping.big_page);
} else {
gmmu->Unmap(offset, mapping.size);
}
mapping_map.erase(it);
}
NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) {
@@ -235,8 +232,7 @@ NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) {
return NvResult::BadValue;
for (const auto mapping_offset : allocation.mappings)
if (!FreeMappingLocked(mapping_offset))
return NvResult::BadValue;
FreeMappingLocked(mapping_offset);
// Unset sparse flag if required
if (allocation.sparse)
@@ -406,8 +402,8 @@ NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) {
}
nvmap.UnpinHandle(mapping.handle);
mapping_map.erase(params.offset);
map_buffer_offsets.erase(params.offset);
mapping_map.erase(it);
map_buffer_offsets.erase(offset_it);
}
return NvResult::Success;
}
@@ -157,7 +157,7 @@ private:
NvResult GetVARegions1(IoctlGetVaRegions& params);
NvResult GetVARegions3(IoctlGetVaRegions& params, std::span<VaRegion> regions);
[[nodiscard]] bool FreeMappingLocked(u64 offset) noexcept;
void FreeMappingLocked(u64 offset);
Module& module;
@@ -409,13 +409,6 @@ struct AccountNotificationSettings {
static_assert(sizeof(AccountNotificationSettings) == 0x18,
"AccountNotificationSettings is an invalid size");
/// This is nn::settings::system::AccountUserSettings (stubbed)
struct AccountUserSettings {
std::array<u8, 0x40> data;
};
static_assert(sizeof(AccountUserSettings) == 0x40,
"AccountUserSettings is an invalid size");
/// This is nn::settings::factory::BatteryLot
struct BatteryLot {
std::array<char, 0x18> lot_number;
@@ -340,9 +340,9 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
{306, nullptr, "GetPinCodeReregistrationGuideAccounts"}, //20.0.0+
{307, nullptr, "SetPinCodeReregistrationGuideAccounts"}, //20.0.0+
{315, C<&ISystemSettingsServer::GetHttpAuthConfigs>, "GetHttpAuthConfigs"}, //21.0.0+
{319, C<&ISystemSettingsServer::GetAccountUserSettings>, "GetAccountUserSettings"}, //21.0.0+
{319, nullptr, "GetAccountUserSettings"}, //21.0.0+
{320, nullptr, "SetAccountUserSettings"}, //21.0.0+
{321, C<&ISystemSettingsServer::GetDefaultAccountUserSettings>, "GetDefaultAccountUserSettings"}, //21.0.0+
{321, nullptr, "GetDefaultAccountUserSettings"}, //21.0.0+
};
// clang-format on
@@ -1428,23 +1428,6 @@ Result ISystemSettingsServer::GetHttpAuthConfigs(Out<s32> out_count, OutBuffer<B
R_SUCCEED();
}
Result ISystemSettingsServer::GetAccountUserSettings(
Out<u32> out_count,
OutLargeData<AccountUserSettings, BufferAttr_HipcMapAlias> out_settings) {
LOG_WARNING(Service_SET, "(STUBBED) called");
*out_count = 0;
*out_settings = {};
R_SUCCEED();
}
Result ISystemSettingsServer::GetDefaultAccountUserSettings(Out<AccountUserSettings> out_settings) {
LOG_WARNING(Service_SET, "(STUBBED) called");
*out_settings = {};
R_SUCCEED();
}
void ISystemSettingsServer::SetupSettings() {
auto system_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000050";
if (!LoadSettingsFile(system_dir, []() { return DefaultSystemSettings(); })) {
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
@@ -161,10 +161,6 @@ public:
Result GetPanelCrcMode(Out<s32> out_panel_crc_mode);
Result SetPanelCrcMode(s32 panel_crc_mode);
Result GetHttpAuthConfigs(Out<s32> out_count, OutBuffer<BufferAttr_HipcMapAlias> out_configs);
Result GetAccountUserSettings(
Out<u32> out_count,
OutLargeData<AccountUserSettings, BufferAttr_HipcMapAlias> out_settings);
Result GetDefaultAccountUserSettings(Out<AccountUserSettings> out_settings);
private:
bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func);
+9 -11
View File
@@ -67,24 +67,22 @@ public:
Result GetServicePort(Kernel::KClientPort** out_client_port, const std::string& name);
template <std::derived_from<SessionRequestHandler> T>
std::shared_ptr<T> GetService(const std::string& name, bool block = false) const {
std::unique_lock l{lock};
auto it = registered_services.find(name);
if (it == registered_services.end() && !block) {
LOG_DEBUG(Service, "Can't find service: {}", name);
std::shared_ptr<T> GetService(const std::string& service_name, bool block = false) const {
auto service = registered_services.find(service_name);
if (service == registered_services.end() && !block) {
LOG_DEBUG(Service, "Can't find service: {}", service_name);
return nullptr;
} else if (block) {
using namespace std::literals::chrono_literals;
while (it == registered_services.end()) {
l.unlock();
while (service == registered_services.end()) {
Kernel::Svc::SleepThread(
kernel.System(),
std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count());
l.lock();
it = registered_services.find(name);
service = registered_services.find(service_name);
}
}
return std::static_pointer_cast<T>(it->second());
return std::static_pointer_cast<T>(service->second());
}
void InvokeControlRequest(HLERequestContext& context);
@@ -98,7 +96,7 @@ private:
std::unique_ptr<Controller> controller_interface;
/// Map of registered services, retrieved using GetServicePort.
mutable std::mutex lock;
std::mutex lock;
ankerl::unordered_dense::map<std::string, SessionRequestHandlerFactory> registered_services;
ankerl::unordered_dense::map<std::string, Kernel::KClientPort*> service_ports;
@@ -866,10 +866,10 @@ void EmitIR<IR::Opcode::VectorMaxS32>(oaknut::CodeGenerator& code, EmitContext&
template<>
void EmitIR<IR::Opcode::VectorMaxS64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
code.CMGT(Qresult->D2(), Qa->D2(), Qb->D2());
code.BSL(Qresult->B16(), Qa->B16(), Qb->B16());
});
(void)code;
(void)ctx;
(void)inst;
UNREACHABLE();
}
template<>
@@ -889,10 +889,10 @@ void EmitIR<IR::Opcode::VectorMaxU32>(oaknut::CodeGenerator& code, EmitContext&
template<>
void EmitIR<IR::Opcode::VectorMaxU64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
code.CMHI(Qresult->D2(), Qa->D2(), Qb->D2());
code.BSL(Qresult->B16(), Qa->B16(), Qb->B16());
});
(void)code;
(void)ctx;
(void)inst;
UNREACHABLE();
}
template<>
@@ -912,10 +912,10 @@ void EmitIR<IR::Opcode::VectorMinS32>(oaknut::CodeGenerator& code, EmitContext&
template<>
void EmitIR<IR::Opcode::VectorMinS64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
code.CMGT(Qresult->D2(), Qb->D2(), Qa->D2());
code.BSL(Qresult->B16(), Qa->B16(), Qb->B16());
});
(void)code;
(void)ctx;
(void)inst;
UNREACHABLE();
}
template<>
@@ -935,10 +935,10 @@ void EmitIR<IR::Opcode::VectorMinU32>(oaknut::CodeGenerator& code, EmitContext&
template<>
void EmitIR<IR::Opcode::VectorMinU64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
code.CMHI(Qresult->D2(), Qb->D2(), Qa->D2());
code.BSL(Qresult->B16(), Qa->B16(), Qb->B16());
});
(void)code;
(void)ctx;
(void)inst;
UNREACHABLE();
}
template<>
File diff suppressed because one or more lines are too long
@@ -14,38 +14,6 @@
namespace Shader::Backend::SPIRV {
namespace {
class DescriptorIndex {
public:
explicit DescriptorIndex(EmitContext& ctx, const IR::Value& index)
: id{index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index)},
is_non_uniform{ctx.profile.support_sampled_image_array_nonuniform_indexing &&
!index.IsImmediate()} {
if (!is_non_uniform) {
return;
}
if (ctx.profile.supported_spirv < 0x00010400) {
ctx.AddExtension("SPV_EXT_descriptor_indexing");
}
ctx.AddCapability(spv::Capability::ShaderNonUniform);
ctx.AddCapability(spv::Capability::SampledImageArrayNonUniformIndexing);
Decorate(ctx, id);
}
Id Value() const {
return id;
}
void Decorate(EmitContext& ctx, Id object) const {
if (is_non_uniform) {
ctx.Decorate(object, spv::Decoration::NonUniform);
}
}
private:
Id id;
bool is_non_uniform;
};
class ImageOperands {
public:
[[maybe_unused]] static constexpr bool ImageSampleOffsetAllowed = false;
@@ -221,12 +189,8 @@ private:
Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR::Value& index) {
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
if (def.count > 1) {
const DescriptorIndex idx{ctx, index};
const Id pointer{ctx.OpAccessChain(def.pointer_type, def.id, idx.Value())};
idx.Decorate(ctx, pointer);
const Id object{ctx.OpLoad(def.sampled_type, pointer)};
idx.Decorate(ctx, object);
return object;
const Id pointer{ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index))};
return ctx.OpLoad(def.sampled_type, pointer);
} else {
return ctx.OpLoad(def.sampled_type, def.id);
}
@@ -244,14 +208,9 @@ Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& ind
} else {
const TextureDefinition& def{ctx.textures.at(info.descriptor_index)};
if (def.count > 1) {
const DescriptorIndex idx{ctx, index};
const Id ptr{ctx.OpAccessChain(def.pointer_type, def.id, idx.Value())};
idx.Decorate(ctx, ptr);
const Id object{ctx.OpLoad(def.sampled_type, ptr)};
idx.Decorate(ctx, object);
const Id image{ctx.OpImage(def.image_type, object)};
idx.Decorate(ctx, image);
return image;
const Id idx{index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index)};
const Id ptr{ctx.OpAccessChain(def.pointer_type, def.id, idx)};
return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, ptr));
}
return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id));
}
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 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
@@ -20,9 +17,6 @@ struct HostTranslateInfo {
bool support_snorm_render_buffer{}; ///< True when the device supports SNORM render buffers
bool support_viewport_index_layer{}; ///< True when the device supports gl_Layer in VS
u32 min_ssbo_alignment{}; ///< Minimum alignment supported by the device for SSBOs
u32 max_per_stage_descriptor_sampled_images{1024}; ///< maximum sampled descriptors per stage
u32 max_per_stage_resources{4096}; ///< maximum resources per stage
u32 max_descriptor_set_sampled_images{1024}; ///< maximum sampled descriptors per set
bool support_geometry_shader_passthrough{}; ///< True when the device supports geometry
///< passthrough shaders
bool support_conditional_barrier{}; ///< True when the device supports barriers in conditional
+12 -117
View File
@@ -32,71 +32,6 @@ using TextureInstVector = boost::container::small_vector<TextureInst, 24>;
constexpr u32 DESCRIPTOR_SIZE = 8;
constexpr u32 DESCRIPTOR_SIZE_SHIFT = static_cast<u32>(std::countr_zero(DESCRIPTOR_SIZE));
constexpr u32 DYNAMIC_DESCRIPTOR_CBUF_BYTES = 16 * 1024;
constexpr u32 MAX_DYNAMIC_DESCRIPTOR_COUNT = 1024;
u32 DynamicDescriptorSizeShift(const IR::U32& dynamic_offset) {
const IR::Inst* const inst{dynamic_offset.InstRecursive()};
if (!inst || inst->GetOpcode() != IR::Opcode::ShiftLeftLogical32) {
return DESCRIPTOR_SIZE_SHIFT;
}
const IR::Value shift{inst->Arg(1)};
if (!shift.IsImmediate()) {
return DESCRIPTOR_SIZE_SHIFT;
}
const u32 size_shift{shift.U32()};
return size_shift >= DESCRIPTOR_SIZE_SHIFT && size_shift < 31 ? size_shift
: DESCRIPTOR_SIZE_SHIFT;
}
u32 DynamicDescriptorCount(u32 base_offset, u32 size_shift) {
if (size_shift >= 31 || base_offset >= DYNAMIC_DESCRIPTOR_CBUF_BYTES) {
return 1;
}
const u32 stride{1U << size_shift};
const u32 available{DYNAMIC_DESCRIPTOR_CBUF_BYTES - base_offset};
if (available < DESCRIPTOR_SIZE) {
return 1;
}
const u32 available_count{1U + (available - DESCRIPTOR_SIZE) / stride};
return std::min(MAX_DYNAMIC_DESCRIPTOR_COUNT, available_count);
}
u32 SaturatingSub(u32 lhs, u32 rhs) {
return lhs > rhs ? lhs - rhs : 0;
}
template <typename Descriptors>
u32 StaticDescriptorCount(const Descriptors& descriptors) {
u32 count{};
for (const auto& desc : descriptors) {
if (desc.count <= 1) {
count += desc.count;
}
}
return count;
}
u32 DynamicSampledTextureCap(const Info& info, const HostTranslateInfo& host_info,
u32 dynamic_arrays) {
if (dynamic_arrays == 0) {
return MAX_DYNAMIC_DESCRIPTOR_COUNT;
}
const u32 sampled_static_count{StaticDescriptorCount(info.texture_buffer_descriptors) +
StaticDescriptorCount(info.texture_descriptors)};
const u32 resource_static_count{
NumDescriptors(info.constant_buffer_descriptors) +
NumDescriptors(info.storage_buffers_descriptors) + sampled_static_count +
NumDescriptors(info.image_buffer_descriptors) + NumDescriptors(info.image_descriptors)};
const u32 sampled_limit{std::min(host_info.max_per_stage_descriptor_sampled_images,
host_info.max_descriptor_set_sampled_images)};
const u32 sampled_budget{SaturatingSub(sampled_limit, sampled_static_count)};
const u32 resource_budget{SaturatingSub(host_info.max_per_stage_resources,
resource_static_count)};
const u32 sampled_cap{sampled_budget / dynamic_arrays};
const u32 resource_cap{resource_budget / dynamic_arrays};
return std::max(1U, std::min({MAX_DYNAMIC_DESCRIPTOR_COUNT, sampled_cap, resource_cap}));
}
IR::Opcode IndexedInstruction(const IR::Inst& inst) {
switch (inst.GetOpcode()) {
@@ -174,39 +109,6 @@ IR::Opcode IndexedInstruction(const IR::Inst& inst) {
}
}
bool IsStorageImageOpcode(IR::Opcode opcode) {
switch (opcode) {
case IR::Opcode::ImageRead:
case IR::Opcode::ImageAtomicIAdd32:
case IR::Opcode::ImageAtomicSMin32:
case IR::Opcode::ImageAtomicUMin32:
case IR::Opcode::ImageAtomicSMax32:
case IR::Opcode::ImageAtomicUMax32:
case IR::Opcode::ImageAtomicInc32:
case IR::Opcode::ImageAtomicDec32:
case IR::Opcode::ImageAtomicAnd32:
case IR::Opcode::ImageAtomicOr32:
case IR::Opcode::ImageAtomicXor32:
case IR::Opcode::ImageAtomicExchange32:
case IR::Opcode::ImageWrite:
return true;
default:
return false;
}
}
u32 DynamicSampledTextureArrayCount(const TextureInstVector& to_replace) {
u32 count{};
for (const TextureInst& inst : to_replace) {
const auto flags{inst.inst->Flags<IR::TextureInstInfo>()};
if (inst.cbuf.count > 1 && !IsStorageImageOpcode(IndexedInstruction(*inst.inst)) &&
flags.type != TextureType::Buffer) {
++count;
}
}
return count;
}
bool IsBindless(const IR::Inst& inst) {
switch (inst.GetOpcode()) {
case IR::Opcode::BindlessImageSampleImplicitLod:
@@ -452,7 +354,6 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst, Environme
} else {
return std::nullopt;
}
const u32 size_shift{DynamicDescriptorSizeShift(dynamic_offset)};
return ConstBufferAddr{
.index = index.U32(),
.offset = base_offset,
@@ -461,7 +362,7 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst, Environme
.secondary_offset = 0,
.secondary_shift_left = 0,
.dynamic_offset = dynamic_offset,
.count = DynamicDescriptorCount(base_offset, size_shift),
.count = 8,
.has_secondary = false,
};
}
@@ -688,8 +589,6 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
program.info.texture_descriptors,
program.info.image_descriptors,
};
const u32 sampled_dynamic_cap{
DynamicSampledTextureCap(program.info, host_info, DynamicSampledTextureArrayCount(to_replace))};
for (TextureInst& texture_inst : to_replace) {
// TODO: Handle arrays
IR::Inst* const inst{texture_inst.inst};
@@ -733,9 +632,6 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
break;
}
u32 index;
const u32 size_shift{cbuf.count > 1 ? DynamicDescriptorSizeShift(cbuf.dynamic_offset)
: DESCRIPTOR_SIZE_SHIFT};
u32 count{cbuf.count};
switch (inst->GetOpcode()) {
case IR::Opcode::ImageRead:
case IR::Opcode::ImageAtomicIAdd32:
@@ -764,8 +660,8 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
.is_integer = is_integer,
.cbuf_index = cbuf.index,
.cbuf_offset = cbuf.offset,
.count = count,
.size_shift = size_shift,
.count = cbuf.count,
.size_shift = DESCRIPTOR_SIZE_SHIFT,
});
} else {
index = descriptors.Add(ImageDescriptor{
@@ -776,8 +672,8 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
.is_integer = is_integer,
.cbuf_index = cbuf.index,
.cbuf_offset = cbuf.offset,
.count = count,
.size_shift = size_shift,
.count = cbuf.count,
.size_shift = DESCRIPTOR_SIZE_SHIFT,
});
}
break;
@@ -792,11 +688,10 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
.secondary_cbuf_index = cbuf.secondary_index,
.secondary_cbuf_offset = cbuf.secondary_offset,
.secondary_shift_left = cbuf.secondary_shift_left,
.count = count,
.size_shift = size_shift,
.count = cbuf.count,
.size_shift = DESCRIPTOR_SIZE_SHIFT,
});
} else {
count = std::min(count, sampled_dynamic_cap);
index = descriptors.Add(TextureDescriptor{
.type = flags.type,
.is_depth = flags.is_depth != 0,
@@ -808,8 +703,8 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
.secondary_cbuf_index = cbuf.secondary_index,
.secondary_cbuf_offset = cbuf.secondary_offset,
.secondary_shift_left = cbuf.secondary_shift_left,
.count = count,
.size_shift = size_shift,
.count = cbuf.count,
.size_shift = DESCRIPTOR_SIZE_SHIFT,
});
}
break;
@@ -817,12 +712,12 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
flags.descriptor_index.Assign(index);
inst->SetFlags(flags);
if (count > 1) {
if (cbuf.count > 1) {
const auto insert_point{IR::Block::InstructionList::s_iterator_to(*inst)};
IR::IREmitter ir{*texture_inst.block, insert_point};
const IR::U32 shift{ir.Imm32(size_shift)};
const IR::U32 shift{ir.Imm32(DESCRIPTOR_SIZE_SHIFT)};
inst->SetArg(0, ir.UMin(ir.ShiftRightLogical(cbuf.dynamic_offset, shift),
ir.Imm32(count - 1)));
ir.Imm32(DESCRIPTOR_SIZE - 1)));
} else {
inst->SetArg(0, IR::Value{});
}
-4
View File
@@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 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
@@ -48,7 +45,6 @@ struct Profile {
bool support_scaled_attributes{};
bool support_multi_viewport{};
bool support_geometry_streams{};
bool support_sampled_image_array_nonuniform_indexing{};
bool warp_size_potentially_larger_than_guest{};
+1 -4
View File
@@ -323,10 +323,7 @@ if (ENABLE_OPENGL)
endif()
target_link_libraries(video_core PUBLIC common core)
target_link_libraries(video_core PUBLIC shader_recompiler stb bc_decoder gpu_logging)
if (ENABLE_OPENGL)
target_link_libraries(video_core PUBLIC glad)
endif()
target_link_libraries(video_core PUBLIC glad shader_recompiler stb bc_decoder gpu_logging)
if (YUZU_USE_EXTERNAL_FFMPEG)
add_dependencies(video_core ffmpeg-build)
@@ -189,7 +189,6 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
views += num_texture_buffers;
views += num_image_buffers;
for (const auto& desc : info.texture_descriptors) {
bool is_rescaled{};
for (u32 index = 0; index < desc.count; ++index) {
const VideoCommon::ImageViewId image_view_id{(views++)->id};
const VideoCommon::SamplerId sampler_id{*(samplers++)};
@@ -201,13 +200,10 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy()
: sampler.Handle()};
guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler);
const bool element_rescaled{texture_cache.IsRescaling(image_view)};
is_rescaled |= element_rescaled;
rescaling.PushTexture(texture_cache.IsRescaling(image_view));
}
rescaling.PushTexture(is_rescaled);
}
for (const auto& desc : info.image_descriptors) {
bool is_rescaled{};
for (u32 index = 0; index < desc.count; ++index) {
ImageView& image_view{texture_cache.GetImageView((views++)->id)};
if (desc.is_written) {
@@ -215,10 +211,8 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
}
const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)};
guest_descriptor_queue.AddImage(vk_image_view);
const bool element_rescaled{texture_cache.IsRescaling(image_view)};
is_rescaled |= element_rescaled;
rescaling.PushImage(texture_cache.IsRescaling(image_view));
}
rescaling.PushImage(is_rescaled);
}
}
@@ -127,8 +127,9 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
texture_cache.SynchronizeComputeDescriptors();
boost::container::small_vector<VideoCommon::ImageViewInOut, 64> views;
boost::container::small_vector<VideoCommon::SamplerId, 64> samplers;
static constexpr size_t max_elements = 64;
boost::container::static_vector<VideoCommon::ImageViewInOut, max_elements> views;
boost::container::static_vector<VideoCommon::SamplerId, max_elements> samplers;
const auto& qmd{kepler_compute.launch_description};
const auto& cbufs{qmd.const_buffer_config};
@@ -412,8 +412,6 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
.support_scaled_attributes = !device.MustEmulateScaledFormats(),
.support_multi_viewport = device.SupportsMultiViewport(),
.support_geometry_streams = device.AreTransformFeedbackGeometryStreamsSupported(),
.support_sampled_image_array_nonuniform_indexing =
device.IsSampledImageArrayNonUniformIndexingSupported(),
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),
@@ -449,9 +447,6 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
.support_snorm_render_buffer = true,
.support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(),
.min_ssbo_alignment = static_cast<u32>(device.GetStorageBufferAlignment()),
.max_per_stage_descriptor_sampled_images = device.GetMaxPerStageDescriptorSampledImages(),
.max_per_stage_resources = device.GetMaxPerStageResources(),
.max_descriptor_set_sampled_images = device.GetMaxDescriptorSetSampledImages(),
.support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),
.support_conditional_barrier = device.SupportsConditionalBarriers(),
};
+132 -17
View File
@@ -70,10 +70,14 @@ TextureCache<P>::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag
(std::max)((std::min)(device_local_memory - min_vacancy_critical, min_spacing_critical),
DEFAULT_CRITICAL_MEMORY));
minimum_memory = static_cast<u64>((device_local_memory - mem_threshold) / 2);
lowmemorydevice = false;
} else {
expected_memory = DEFAULT_EXPECTED_MEMORY + 512_MiB;
critical_memory = DEFAULT_CRITICAL_MEMORY + 1_GiB;
minimum_memory = 0;
lowmemorydevice = true;
}
const bool gpu_unswizzle_enabled = Settings::values.gpu_unswizzle_enabled.GetValue();
@@ -118,48 +122,102 @@ void TextureCache<P>::RunGarbageCollector() {
bool aggressive_mode = false;
u64 ticks_to_destroy = 0;
size_t num_iterations = 0;
const auto Configure = [&](bool allow_aggressive) {
high_priority_mode = total_used_memory >= expected_memory;
aggressive_mode = allow_aggressive && total_used_memory >= critical_memory;
ticks_to_destroy = aggressive_mode ? 10ULL : high_priority_mode ? 25ULL : 50ULL;
num_iterations = aggressive_mode ? 40 : (high_priority_mode ? 20 : 10);
};
const auto Cleanup = [this, &num_iterations, &high_priority_mode, &aggressive_mode](ImageId image_id) {
const auto Cleanup = [this, &num_iterations, &high_priority_mode,
&aggressive_mode](ImageId image_id) {
if (num_iterations == 0) {
return true;
}
auto& image = slot_images[image_id];
if (True(image.flags & ImageFlagBits::IsDecoding)) {
return false;
}
const bool must_download = image.IsSafeDownload() && False(image.flags & ImageFlagBits::BadOverlap);
if ((!aggressive_mode && True(image.flags & ImageFlagBits::CostlyLoad)) || (!high_priority_mode && must_download)) {
return false;
}
--num_iterations;
if (must_download) {
auto& image = slot_images[image_id];
// Never delete recently allocated sparse textures (within 3 frames)
const bool is_recently_allocated = image.allocation_tick >= frame_tick - 3;
if (is_recently_allocated && image.info.is_sparse) {
return false;
}
if (True(image.flags & ImageFlagBits::IsDecoding)) {
// This image is still being decoded, deleting it will invalidate the slot
// used by the async decoder thread.
return false;
}
// Prioritize large sparse textures for cleanup
const bool is_large_sparse = lowmemorydevice &&
image.info.is_sparse &&
image.guest_size_bytes >= 256_MiB;
if (!aggressive_mode && !is_large_sparse &&
True(image.flags & ImageFlagBits::CostlyLoad)) {
return false;
}
const bool must_download =
image.IsSafeDownload() && False(image.flags & ImageFlagBits::BadOverlap);
if (!high_priority_mode && !is_large_sparse && must_download) {
return false;
}
if (must_download && !is_large_sparse) {
auto map = runtime.DownloadStagingBuffer(image.unswizzled_size_bytes);
const auto copies = FixSmallVectorADL(FullDownloadCopies(image.info));
image.DownloadMemory(map, copies);
runtime.Finish();
SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span, swizzle_data_buffer);
SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span,
swizzle_data_buffer);
}
if (True(image.flags & ImageFlagBits::Tracked)) {
UntrackImage(image, image_id);
}
UnregisterImage(image_id);
DeleteImage(image_id, image.scale_tick > frame_tick + 5);
if (aggressive_mode && total_used_memory < critical_memory) {
num_iterations >>= 2;
aggressive_mode = false;
} else if (high_priority_mode && total_used_memory < expected_memory) {
num_iterations >>= 1;
high_priority_mode = false;
if (total_used_memory < critical_memory) {
if (aggressive_mode) {
// Sink the aggresiveness.
num_iterations >>= 2;
aggressive_mode = false;
return false;
}
if (high_priority_mode && total_used_memory < expected_memory) {
num_iterations >>= 1;
high_priority_mode = false;
}
}
return false;
};
// Aggressively clear massive sparse textures
if (total_used_memory >= expected_memory) {
lru_cache.ForEachItemBelow(frame_tick, [&](ImageId image_id) {
auto& image = slot_images[image_id];
// Only target sparse textures that are old enough
if (lowmemorydevice &&
image.info.is_sparse &&
image.guest_size_bytes >= 256_MiB &&
image.allocation_tick < frame_tick - 3) {
LOG_DEBUG(HW_GPU, "GC targeting old sparse texture at 0x{:X} ({} MiB, age: {} frames)",
image.gpu_addr, image.guest_size_bytes / (1024 * 1024),
frame_tick - image.allocation_tick);
return Cleanup(image_id);
}
return false;
});
}
Configure(false);
lru_cache.ForEachItemBelow(frame_tick - ticks_to_destroy, Cleanup);
// If pressure is still too high, prune aggressively.
if (total_used_memory >= critical_memory) {
Configure(true);
lru_cache.ForEachItemBelow(frame_tick - ticks_to_destroy, Cleanup);
@@ -1138,6 +1196,9 @@ void TextureCache<P>::RefreshContents(Image& image, ImageId image_id) {
}
image.flags &= ~ImageFlagBits::CpuModified;
if( lowmemorydevice && image.info.format == PixelFormat::BC1_RGBA_UNORM && MapSizeBytes(image) >= 256_MiB ) {
return;
}
TrackImage(image, image_id);
@@ -1558,6 +1619,39 @@ ImageId TextureCache<P>::InsertImage(const ImageInfo& info, GPUVAddr gpu_addr,
}
}
ASSERT_MSG(cpu_addr, "Tried to insert an image to an invalid gpu_addr=0x{:x}", gpu_addr);
// For large sparse textures, aggressively clean up old allocations at same address
if (lowmemorydevice && info.is_sparse && CalculateGuestSizeInBytes(info) >= 256_MiB) {
const auto alloc_it = image_allocs_table.find(gpu_addr);
if (alloc_it != image_allocs_table.end()) {
const ImageAllocId alloc_id = alloc_it->second;
auto& alloc_images = slot_image_allocs[alloc_id].images;
// Collect old images at this address that were created more than 2 frames ago
boost::container::small_vector<ImageId, 4> to_delete;
for (ImageId old_image_id : alloc_images) {
Image& old_image = slot_images[old_image_id];
if (old_image.info.is_sparse &&
old_image.gpu_addr == gpu_addr &&
old_image.allocation_tick < frame_tick - 2) { // Try not to delete fresh textures
to_delete.push_back(old_image_id);
}
}
// Delete old images immediately
for (ImageId old_id : to_delete) {
Image& old_image = slot_images[old_id];
LOG_DEBUG(HW_GPU, "Immediately deleting old sparse texture at 0x{:X} ({} MiB)",
gpu_addr, old_image.guest_size_bytes / (1024 * 1024));
if (True(old_image.flags & ImageFlagBits::Tracked)) {
UntrackImage(old_image, old_id);
}
UnregisterImage(old_id);
DeleteImage(old_id, true);
}
}
}
const ImageId image_id = JoinImages(info, gpu_addr, *cpu_addr);
const Image& image = slot_images[image_id];
// Using "image.gpu_addr" instead of "gpu_addr" is important because it might be different
@@ -1573,6 +1667,27 @@ template <class P>
ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DAddr cpu_addr) {
ImageInfo new_info = info;
const size_t size_bytes = CalculateGuestSizeInBytes(new_info);
// Proactive cleanup for large sparse texture allocations
if (lowmemorydevice && new_info.is_sparse && size_bytes >= 256_MiB) {
const u64 estimated_alloc_size = size_bytes;
if (total_used_memory + estimated_alloc_size >= critical_memory) {
LOG_DEBUG(HW_GPU, "Large sparse texture allocation ({} MiB) - running aggressive GC. "
"Current memory: {} MiB, Critical: {} MiB",
size_bytes / (1024 * 1024),
total_used_memory / (1024 * 1024),
critical_memory / (1024 * 1024));
RunGarbageCollector();
// If still over threshold after GC, try one more aggressive pass
if (total_used_memory + estimated_alloc_size >= critical_memory) {
LOG_DEBUG(HW_GPU, "Still critically low on memory, running second GC pass");
RunGarbageCollector();
}
}
}
const bool broken_views = runtime.HasBrokenTextureViewFormats();
const bool native_bgr = runtime.HasNativeBgr();
join_overlap_ids.clear();
@@ -478,6 +478,7 @@ private:
u64 minimum_memory;
u64 expected_memory;
u64 critical_memory;
bool lowmemorydevice = false;
size_t gpu_unswizzle_maxsize = 0;
size_t swizzle_chunk_size = 0;
u32 swizzle_slices_per_batch = 0;
@@ -33,7 +33,6 @@ VK_DEFINE_HANDLE(VmaAllocator)
FEATURE(KHR, VariablePointer, VARIABLE_POINTERS, variable_pointer)
#define FOR_EACH_VK_FEATURE_1_2(FEATURE) \
FEATURE(EXT, DescriptorIndexing, DESCRIPTOR_INDEXING, descriptor_indexing) \
FEATURE(EXT, HostQueryReset, HOST_QUERY_RESET, host_query_reset) \
FEATURE(KHR, 8BitStorage, 8BIT_STORAGE, bit8_storage) \
FEATURE(KHR, TimelineSemaphore, TIMELINE_SEMAPHORE, timeline_semaphore)
@@ -336,18 +335,6 @@ public:
return properties.properties.limits.maxDescriptorSetUniformBuffersDynamic;
}
u32 GetMaxPerStageDescriptorSampledImages() const {
return properties.properties.limits.maxPerStageDescriptorSampledImages;
}
u32 GetMaxPerStageResources() const {
return properties.properties.limits.maxPerStageResources;
}
u32 GetMaxDescriptorSetSampledImages() const {
return properties.properties.limits.maxDescriptorSetSampledImages;
}
/// Returns float control properties of the device.
const VkPhysicalDeviceFloatControlsPropertiesKHR& FloatControlProperties() const {
return properties.float_controls;
@@ -368,10 +355,6 @@ public:
return GetDriverID() != VK_DRIVER_ID_QUALCOMM_PROPRIETARY;
}
bool IsSampledImageArrayNonUniformIndexingSupported() const {
return features.descriptor_indexing.shaderSampledImageArrayNonUniformIndexing;
}
/// Returns true if the device supports float64 natively.
bool IsFloat64Supported() const {
return features.features.shaderFloat64;
+1 -4
View File
@@ -411,11 +411,8 @@ endif()
target_link_libraries(yuzu PRIVATE nlohmann_json::nlohmann_json)
target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core qt_common)
target_link_libraries(yuzu PRIVATE Boost::headers Qt6::Widgets Qt6::Charts Qt6::Concurrent)
target_link_libraries(yuzu PRIVATE Boost::headers glad Qt6::Widgets Qt6::Charts Qt6::Concurrent)
target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
if (ENABLE_OPENGL)
target_link_libraries(yuzu PRIVATE glad)
endif()
if (UNIX AND NOT APPLE)
target_link_libraries(yuzu PRIVATE Qt6::DBus)
+9 -25
View File
@@ -8,17 +8,11 @@
#include <string>
#include <tuple>
#include <type_traits>
#ifdef HAS_OPENGL
#include <glad/glad.h>
#endif
#include <QtCore/qglobal.h>
#include "common/settings_enums.h"
#include "qt_common/config/uisettings.h"
#include "qt_common/abstract/frontend.h"
#if YUZU_USE_QT_MULTIMEDIA
#include <QCamera>
#include <QImageCapture>
@@ -1045,12 +1039,11 @@ void GRenderWindow::InitializeNull() {
}
bool GRenderWindow::LoadOpenGL() {
#ifdef HAS_OPENGL
auto context = CreateSharedContext();
auto scope = context->Acquire();
if (!gladLoadGL()) {
QtCommon::Frontend::Warning(
tr("Error while initializing OpenGL!"),
QMessageBox::warning(
this, tr("Error while initializing OpenGL!"),
tr("Your GPU may not support OpenGL, or you do not have the latest graphics driver."));
return false;
}
@@ -1059,16 +1052,15 @@ bool GRenderWindow::LoadOpenGL() {
const QString renderer =
QString::fromUtf8(reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
if (!GLAD_GL_VERSION_4_6) {
QtCommon::Frontend::Warning(
tr("Error while initializing OpenGL 4.6!"),
tr("Your GPU may not support OpenGL 4.6, or you do not have the "
"latest graphics driver.<br><br>GL Renderer:<br>%1")
.arg(renderer));
QMessageBox::warning(this, tr("Error while initializing OpenGL 4.6!"),
tr("Your GPU may not support OpenGL 4.6, or you do not have the "
"latest graphics driver.<br><br>GL Renderer:<br>%1")
.arg(renderer));
return false;
}
if (QStringList missing_ext = GetUnsupportedGLExtensions(); !missing_ext.empty()) {
QtCommon::Frontend::Warning(
tr("Error while initializing OpenGL!"),
QMessageBox::warning(
this, tr("Error while initializing OpenGL!"),
tr("Your GPU may not support one or more required OpenGL extensions. Please ensure you "
"have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported "
"extensions:<br>%2")
@@ -1077,17 +1069,10 @@ bool GRenderWindow::LoadOpenGL() {
// Non fatal
}
return true;
#else
QtCommon::Frontend::Warning(
tr("Error while initializing OpenGL!"),
tr("This build doesn't have OpenGL support."));
return false;
#endif
}
QStringList GRenderWindow::GetUnsupportedGLExtensions() const {
QStringList missing_ext{};
#ifdef HAS_OPENGL
QStringList missing_ext;
// Extensions required to support some texture formats.
if (!GLAD_GL_EXT_texture_compression_s3tc)
missing_ext.append(QStringLiteral("EXT_texture_compression_s3tc"));
@@ -1097,7 +1082,6 @@ QStringList GRenderWindow::GetUnsupportedGLExtensions() const {
LOG_ERROR(Frontend, "GPU does not support all required extensions");
for (const QString& ext : missing_ext)
LOG_ERROR(Frontend, "Unsupported GL extension: {}", ext.toStdString());
#endif
return missing_ext;
}
+3 -13
View File
@@ -15,18 +15,11 @@ function(create_resource file output filename)
file(WRITE "${PROJECT_BINARY_DIR}/dist/${output}" "const unsigned char ${filename}[] = {${filedata}};\nconst unsigned ${filename}_size = sizeof(${filename});\n")
endfunction()
if (ENABLE_OPENGL)
list(APPEND OPENGL_SOURCES
emu_window/emu_window_sdl2_gl.cpp
emu_window/emu_window_sdl2_gl.h
)
else()
set(OPENGL_SOURCES "")
endif()
add_executable(yuzu-cmd
emu_window/emu_window_sdl2.cpp
emu_window/emu_window_sdl2.h
emu_window/emu_window_sdl2_gl.cpp
emu_window/emu_window_sdl2_gl.h
emu_window/emu_window_sdl2_null.cpp
emu_window/emu_window_sdl2_null.h
emu_window/emu_window_sdl2_vk.cpp
@@ -35,13 +28,10 @@ add_executable(yuzu-cmd
sdl_config.h
yuzu.cpp
yuzu.rc
${OPENGL_SOURCES}
)
target_link_libraries(yuzu-cmd PRIVATE common core input_common frontend_common video_core)
if (ENABLE_OPENGL)
target_link_libraries(yuzu-cmd PRIVATE glad)
endif()
target_link_libraries(yuzu-cmd PRIVATE glad)
if (MSVC)
target_link_libraries(yuzu-cmd PRIVATE getopt)
endif()
+10 -6
View File
@@ -59,16 +59,20 @@ private:
};
bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() {
std::vector<std::string_view> unsupported_ext{};
#ifdef HAS_OPENGL
std::vector<std::string_view> unsupported_ext;
// Extensions required to support some texture formats.
if (!GLAD_GL_EXT_texture_compression_s3tc)
if (!GLAD_GL_EXT_texture_compression_s3tc) {
unsupported_ext.push_back("EXT_texture_compression_s3tc");
if (!GLAD_GL_ARB_texture_compression_rgtc)
}
if (!GLAD_GL_ARB_texture_compression_rgtc) {
unsupported_ext.push_back("ARB_texture_compression_rgtc");
for (const auto& extension : unsupported_ext)
}
for (const auto& extension : unsupported_ext) {
LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", extension);
#endif
}
return unsupported_ext.empty();
}
-7
View File
@@ -31,9 +31,7 @@
#include "sdl_config.h"
#include "video_core/renderer_base.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
#ifdef HAS_OPENGL
#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h"
#endif
#include "yuzu_cmd/emu_window/emu_window_sdl2_null.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h"
@@ -351,22 +349,17 @@ int main(int argc, char** argv) {
std::unique_ptr<EmuWindow_SDL2> emu_window;
switch (Settings::values.renderer_backend.GetValue()) {
#ifdef HAS_OPENGL
case Settings::RendererBackend::OpenGL_GLSL:
case Settings::RendererBackend::OpenGL_GLASM:
case Settings::RendererBackend::OpenGL_SPIRV:
emu_window = std::make_unique<EmuWindow_SDL2_GL>(&input_subsystem, system, fullscreen);
break;
#endif
case Settings::RendererBackend::Vulkan:
emu_window = std::make_unique<EmuWindow_SDL2_VK>(&input_subsystem, system, fullscreen);
break;
case Settings::RendererBackend::Null:
emu_window = std::make_unique<EmuWindow_SDL2_Null>(&input_subsystem, system, fullscreen);
break;
default:
LOG_CRITICAL(Frontend, "Invalid renderer backend");
return -1;
}
#ifdef _WIN32