Compare commits

...

16 commits

Author SHA1 Message Date
e8d03a13e7 [license] keep hacky way under UPDATE
All checks were successful
eden-license / license-header (pull_request) Successful in 42s
Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-09-18 02:29:28 +02:00
3ffaa7c19c [license] reduce usage of while and improve template usage
Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-09-18 02:29:28 +02:00
ca7001639b [license] include .ps1, improve commit message and shebang first
Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-09-18 02:29:28 +02:00
13ab0d3fcb [license] Fix license headers [script] 2025-09-18 02:29:28 +02:00
80a8d71551 license-header.sh: This is complete refactor
* It now fix in-place header with the same owner, see next commit

Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-09-18 02:29:28 +02:00
3c1174cc64 [ci] Make it POSIX-compliant
* tested on Ubuntu 25.04

Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-09-18 02:29:28 +02:00
eb1140568e use better license-header impl that is not as cursed
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-09-18 02:29:28 +02:00
1d43b20312 [ci, tools] shellcheck-ed
* now license-header.sh is POSIX compliant
* update-icons now checks for dependencies the correct way
* add --help to license-header
* nuke reset-submodules
* add missing shebang to .ci/windows/package.sh

* Below the error/warnings/infos from shellcheck:
-- SC2068 (error): Double quote array expansions to avoid re-splitting elements.

-- SC3054 (warning): In POSIX sh, array references are undefined.
-- SC2155 (warning): Declare and assign separately to avoid masking return values.
-- SC2046 (warning): Quote this to prevent word splitting.

-- SC2236 (style): Use -n instead of ! -z.
-- SC2006 (style): Use $(...) notation instead of legacy backticks `...`.
-- SC2001 (style): See if you can use ${variable//search/replace} instead.

-- SC2086 (info): Double quote to prevent globbing and word splitting.
-- SC2185 (info): Some finds don't have a default path. Specify '.' explicitly.

Signed-off-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
2025-09-18 02:29:28 +02:00
249e006667
[VMA] Use Host cached and Host coherent for Download operations (#482)
Increase read speeds by using appropriate usage flags

Reviewed-on: #482
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: wildcard <wildcard@eden-emu.dev>
Co-committed-by: wildcard <wildcard@eden-emu.dev>
2025-09-17 21:40:09 +02:00
8ac495acee
[fs] Remove remaining files from NCA bypass and fix some asserts (#2502)
Reviewed-on: #2502
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-09-17 17:45:52 +02:00
cda6958111
[host_memory] decrease latency of mapping on linux (#232)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: #232
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-17 02:31:44 +02:00
dac2efc4c8
[Shader Recompiler] Caching optimization for Texture_Pass (#481)
Add Caching per texture_pass and optimize sorting to single pass.
Use Logical shift instead of arithmetic shift.

Reviewed-on: #481
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: wildcard <wildcard@eden-emu.dev>
Co-committed-by: wildcard <wildcard@eden-emu.dev>
2025-09-17 02:27:03 +02:00
3b3278f44b
[jit, exception] use shared mutex to reduce thread contention of cached code blocks in fastmem trap handler (#320)
ankerl::unordered_dense::map will provide better lookup times, theoretically.
fastmem trap handler usually had mutex contention for non-linkable series of blocks (block linking failures); so just use shared_mutex

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

Reviewed-on: #320
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-09-16 20:54:00 +02:00
3ca0bde0e9
[core/nvnflinger] Rewrite GetBufferHistory (#528)
This rewrite should improve performance with the buffer history by changing the complexity level to O(1).
Replace std::vector with std::array to ensure that elements are allocated on the stack rather than on the free store.
Avoid expensive resizing at runtime.
Adjust buffer states at the right locations.
Tightly pack the BufferHistoryInfo struct to ensure that it only occupies 28 bytes.

Reviewed-on: #528
Co-authored-by: SDK-Chan <sdkchan@eden-emu.dev>
Co-committed-by: SDK-Chan <sdkchan@eden-emu.dev>
2025-09-16 19:41:52 +02:00
6699361b7e
[cmake] fix freebsd and openbsd, remove CPMUtil Eden copyright (#496)
CPMUtil is technically a completely separate project created and maintained solely by me, so it should actually be copyrighted to me

Reviewed-on: #496
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2025-09-16 18:44:19 +02:00
19036c59b5
[video_core] Simplify DMA options (#525)
This simplifies DMA options in a clearer and more objective way.

Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Reviewed-on: #525
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
2025-09-16 18:42:48 +02:00
67 changed files with 845 additions and 674 deletions

View file

@ -1,11 +1,12 @@
#!/bin/bash -e
# SPDX-FileCopyrightText: 2025 eden Emulator Project
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
export NDK_CCACHE=$(which ccache)
NDK_CCACHE=$(which ccache)
export NDK_CCACHE
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
if [ -n "${ANDROID_KEYSTORE_B64}" ]; then
export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
fi
@ -16,6 +17,6 @@ chmod +x ./gradlew
./gradlew assembleRelease
./gradlew bundleRelease
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
if [ -n "${ANDROID_KEYSTORE_B64}" ]; then
rm "${ANDROID_KEYSTORE_FILE}"
fi

View file

@ -1,6 +1,6 @@
#!/bin/sh
# SPDX-FileCopyrightText: 2025 eden Emulator Project
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
GITDATE="$(git show -s --date=short --format='%ad' | sed 's/-//g')"

View file

@ -1,146 +1,208 @@
#!/bin/sh -e
HEADER="$(cat "$PWD/.ci/license/header.txt")"
HEADER_HASH="$(cat "$PWD/.ci/license/header-hash.txt")"
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
echo "Getting branch changes"
COPYRIGHT_YEAR="2025"
COPYRIGHT_OWNER="Eden Emulator Project"
COPYRIGHT_LICENSE="GPL-3.0-or-later"
# BRANCH=`git rev-parse --abbrev-ref HEAD`
# COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"`
# RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}"
# FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r`
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
echo
echo "license-header.sh: Eden License Headers Accreditation Script"
echo
echo "This script checks and optionally fixes license headers in source, CMake and shell script files."
echo
echo "Environment Variables:"
echo " FIX=true | Automatically add the correct license headers to offending files."
echo " UPDATE=true | Automatically update current license headers of offending files."
echo " COMMIT=true | If FIX=true, commit the changes automatically."
echo
echo "Usage Examples:"
echo " # Just check headers (will fail if headers are missing)"
echo " .ci/license-header.sh"
echo
echo " # Fix headers only"
echo " FIX=true .ci/license-header.sh"
echo
echo " # Update headers only"
echo " # if COPYRIGHT_OWNER is '$COPYRIGHT_OWNER'"
echo " # or else will have 'FIX=true' behavior)"
echo " UPDATE=true .ci/license-header.sh"
echo
echo " # Fix headers and commit changes"
echo " FIX=true COMMIT=true .ci/license-header.sh"
echo
echo " # Update headers and commit changes"
echo " # if COPYRIGHT_OWNER is '$COPYRIGHT_OWNER'"
echo " # or else will have 'FIX=true' behavior)"
echo " UPDATE=true COMMIT=true .ci/license-header.sh"
exit 0
fi
BASE=`git merge-base master HEAD`
FILES=`git diff --name-only $BASE`
SRC_FILES=""
OTHER_FILES=""
#FILES=$(git diff --name-only master)
BASE=$(git merge-base master HEAD)
if git diff --quiet "$BASE"..HEAD; then
echo
echo "license-header.sh: No commits on this branch different from master."
exit 0
fi
FILES=$(git diff --name-only "$BASE")
echo "Done"
check_header() {
CONTENT="`head -n3 < $1`"
case "$CONTENT" in
"$HEADER"*) ;;
*) BAD_FILES="$BAD_FILES $1" ;;
esac
echo_header() {
COMMENT_TYPE="$1"
echo "$COMMENT_TYPE SPDX-FileCopyrightText: Copyright $COPYRIGHT_YEAR $COPYRIGHT_OWNER"
echo "$COMMENT_TYPE SPDX-License-Identifier: $COPYRIGHT_LICENSE"
}
check_cmake_header() {
CONTENT="`head -n3 < $1`"
case "$CONTENT" in
"$HEADER_HASH"*) ;;
*)
BAD_CMAKE="$BAD_CMAKE $1" ;;
esac
}
for file in $FILES; do
[ -f "$file" ] || continue
if [ `basename -- "$file"` = "CMakeLists.txt" ]; then
check_cmake_header "$file"
case "$(basename "$file")" in
CMakeLists.txt)
COMMENT_TYPE="#" ;;
*)
EXT="${file##*.}"
case "$EXT" in
kts|kt|cpp|h) COMMENT_TYPE="//" ;;
cmake|sh|ps1) COMMENT_TYPE="#" ;;
*) continue ;;
esac ;;
esac
HEADER=$(echo_header "$COMMENT_TYPE")
HEAD_LINES=$(head -n5 "$file")
CORRECT_COPYRIGHT=$(echo "$HEAD_LINES" | awk \
-v line1="$(echo "$HEADER" | sed -n '1p')" \
-v line2="$(echo "$HEADER" | sed -n '2p')" \
'($0==line1){getline; if($0==line2){f=1}else{f=0}} END{print (f?f:0)}')
if [ "$CORRECT_COPYRIGHT" != "1" ]; then
case "$COMMENT_TYPE" in
"//") SRC_FILES="$SRC_FILES $file" ;;
"#") OTHER_FILES="$OTHER_FILES $file" ;;
esac
fi
done
if [ -z "$SRC_FILES" ] && [ -z "$OTHER_FILES" ]; then
echo
echo "license-header.sh: All good!"
exit 0
fi
for TYPE in "SRC" "OTHER"; do
if [ "$TYPE" = "SRC" ] && [ -n "$SRC_FILES" ]; then
FILES_LIST="$SRC_FILES"
COMMENT_TYPE="//"
DESC="Source"
elif [ "$TYPE" = "OTHER" ] && [ -n "$OTHER_FILES" ]; then
FILES_LIST="$OTHER_FILES"
COMMENT_TYPE="#"
DESC="CMake and shell script"
else
continue
fi
EXTENSION="${file##*.}"
case "$EXTENSION" in
kts|kt|cpp|h)
check_header "$file"
;;
cmake)
check_cmake_header "$file"
;;
esac
echo
echo "------------------------------------------------------------"
echo "$DESC files"
echo "------------------------------------------------------------"
echo
echo " The following files contain incorrect license headers:"
for file in $FILES_LIST; do
echo " - $file"
done
echo
echo " The correct license header to be added to all affected"
echo " '$DESC' files is:"
echo
echo "=== BEGIN ==="
echo_header "$COMMENT_TYPE"
echo "=== END ==="
done
if [ "$BAD_FILES" = "" ] && [ "$BAD_CMAKE" = "" ]; then
echo
echo "All good."
exit
fi
if [ "$BAD_FILES" != "" ]; then
echo "The following source files have incorrect license headers:"
echo
for file in $BAD_FILES; do echo $file; done
cat << EOF
The following license header should be added to the start of all offending SOURCE files:
=== BEGIN ===
$HEADER
=== END ===
EOF
fi
if [ "$BAD_CMAKE" != "" ]; then
echo "The following CMake files have incorrect license headers:"
echo
for file in $BAD_CMAKE; do echo $file; done
cat << EOF
The following license header should be added to the start of all offending CMake files:
=== BEGIN ===
$HEADER_HASH
=== END ===
EOF
fi
cat << EOF
If some of the code in this PR is not being contributed by the original author,
the files which have been exclusively changed by that code can be ignored.
If this happens, this PR requirement can be bypassed once all other files are addressed.
------------------------------------------------------------
If some of the code in this pull request was not contributed by the original
author, the files that have been modified exclusively by that code can be
safely ignored. In such cases, this PR requirement may be bypassed once all
other files have been reviewed and addressed.
EOF
if [ "$FIX" = "true" ]; then
echo
echo "FIX set to true. Fixing headers."
TMP_DIR=$(mktemp -d /tmp/license-header.XXXXXX) || exit 1
if [ "$FIX" = "true" ] || [ "$UPDATE" = "true" ]; then
echo
echo "license-header.sh: FIX set to true, fixing headers..."
for file in $BAD_FILES; do
cat $file > $file.bak
for file in $SRC_FILES $OTHER_FILES; do
BASENAME=$(basename "$file")
cat .ci/license/header.txt > $file
echo >> $file
cat $file.bak >> $file
case "$BASENAME" in
CMakeLists.txt) COMMENT_TYPE="#" ;;
*)
EXT="${file##*.}"
case "$EXT" in
kts|kt|cpp|h) COMMENT_TYPE="//" ;;
cmake|sh|ps1) COMMENT_TYPE="#" ;;
*) continue ;;
esac
;;
esac
rm $file.bak
TMP="$TMP_DIR/$BASENAME.tmp"
UPDATED=0
cp -p "$file" "$TMP"
> "$TMP"
git add $file
# this logic is bit hacky but sed don't work well with $VARIABLES
# it's this or complete remove this logic and keep only the old way
if [ "$UPDATE" = "true" ]; then
while IFS= read -r line || [ -n "$line" ]; do
if [ "$UPDATED" -eq 0 ] && echo "$line" | grep "$COPYRIGHT_OWNER" >/dev/null 2>&1; then
echo_header "$COMMENT_TYPE" >> "$TMP"
IFS= read -r _ || true
UPDATED=1
else
echo "$line" >> "$TMP"
fi
done < "$file"
fi
if [ "$UPDATED" -eq 0 ]; then
{
echo_header "$COMMENT_TYPE"
echo
cat "$TMP"
} > "$file"
else
mv "$TMP" "$file"
fi
git add "$file"
done
for file in $BAD_CMAKE; do
cat $file > $file.bak
rm -rf "$TMP_DIR"
cat .ci/license/header-hash.txt > $file
echo >> $file
cat $file.bak >> $file
rm $file.bak
git add $file
done
echo "License headers fixed."
echo
echo "license-header.sh: License headers fixed!"
if [ "$COMMIT" = "true" ]; then
echo
echo "COMMIT set to true. Committing changes."
echo "license-header.sh: COMMIT set to true, committing changes..."
git commit -m "[license] Fix license headers [script]"
echo
git commit -m "Fix license headers"
echo "Changes committed. You may now push."
echo "license-header.sh: Changes committed. You may now push."
fi
else
exit 1
fi

View file

@ -1,2 +0,0 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later

View file

@ -1,2 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later

View file

@ -1,6 +1,6 @@
#!/bin/bash -e
# SPDX-FileCopyrightText: 2025 eden Emulator Project
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
case "$1" in
@ -87,7 +87,7 @@ if [ -z "$BUILD_TYPE" ]; then
export BUILD_TYPE="Release"
fi
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" $@)
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" "$@")
mkdir -p build && cd build
cmake .. -G Ninja \
@ -107,7 +107,7 @@ cmake .. -G Ninja \
-DDYNARMIC_ENABLE_LTO=ON \
"${EXTRA_CMAKE_FLAGS[@]}"
ninja -j${NPROC}
ninja -j"${NPROC}"
if [ -d "bin/Release" ]; then
strip -s bin/Release/*

View file

@ -1,12 +1,13 @@
#!/bin/sh -e
# SPDX-FileCopyrightText: 2025 eden Emulator Project
# 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)"
BASE_ARCH="$(uname -m)"
export BASE_ARCH
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}"
@ -36,24 +37,26 @@ case "$1" in
echo "Packaging armv9-a build of Eden"
ARCH=armv9
;;
native)
native)
echo "Packaging native build of Eden"
ARCH="$BASE_ARCH"
;;
*)
echo "Unknown target: $1"
exit 1
;;
esac
export BUILDDIR="$2"
if [ "$BUILDDIR" = '' ]
then
BUILDDIR=build
if [ -z "$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")"
VERSION="$EDEN_TAG"
# NOW MAKE APPIMAGE
mkdir -p ./AppDir
@ -67,21 +70,19 @@ 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|')"
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"
if [ ! -d "$LIBDIR/qt6" ]; then
LIBDIR="/usr/lib64"
fi
# Workaround for Debian
if [ ! -d "$LIBDIR/qt6" ]
then
if [ ! -d "$LIBDIR/qt6" ]; then
LIBDIR="/usr/lib/${BASE_ARCH}-linux-gnu"
fi
@ -90,40 +91,38 @@ fi
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
../"$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/*
# 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
# 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/
cp shared/libproxy/* lib/
fi
ln -f ./sharun ./AppRun
@ -134,20 +133,20 @@ cd ..
wget -q "$URUNTIME" -O ./uruntime
chmod +x ./uruntime
#Add udpate info to runtime
# Add update 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 \
--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
-i ./AppDir -o "Eden-$VERSION-$ARCH.AppImage"
echo "Generating zsync file..."
zsyncmake *.AppImage -u *.AppImage
echo "All Done!"
zsyncmake ./*.AppImage -u ./*.AppImage
echo "All Done!"

View file

@ -1,22 +1,59 @@
#!/bin/bash -ex
#!/bin/sh -e
# git-archive-all
export PATH="$PATH:/home/$USER/.local/bin"
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
GITREV="`git show -s --format='%h'`"
GITDATE=$(git show -s --date=short --format='%ad' | sed 's/-//g')
GITREV=$(git show -s --format='%h')
REV_NAME="eden-unified-source-${GITDATE}-${GITREV}"
COMPAT_LIST='dist/compatibility_list/compatibility_list.json'
COMPAT_LIST="dist/compatibility_list/compatibility_list.json"
ARTIFACT_DIR="artifacts"
ARCHIVE_PATH="${ARTIFACT_DIR}/${REV_NAME}.tar"
XZ_PATH="${ARCHIVE_PATH}.xz"
SHA_PATH="${XZ_PATH}.sha256sum"
mkdir artifacts
# Abort if archive already exists
if [ -e "$XZ_PATH" ]; then
echo "Error: Archive '$XZ_PATH' already exists. Aborting."
exit 1
fi
touch "${COMPAT_LIST}"
git describe --abbrev=0 --always HEAD > GIT-COMMIT
git describe --tags HEAD > GIT-TAG || echo 'unknown' > GIT-TAG
git-archive-all --include "${COMPAT_LIST}" --include GIT-COMMIT --include GIT-TAG --force-submodules artifacts/"${REV_NAME}.tar"
# Create output directory
mkdir -p "$ARTIFACT_DIR"
# Create temporary directory
TMPDIR=$(mktemp -d)
# Ensure compatibility list file exists
touch "$COMPAT_LIST"
cp "$COMPAT_LIST" "$TMPDIR/"
# Create base archive from git
git archive --format=tar --prefix="${REV_NAME}/" HEAD > "$ARCHIVE_PATH"
# Create commit and tag files with correct names
git describe --abbrev=0 --always HEAD > "$TMPDIR/GIT-COMMIT"
if ! git describe --tags HEAD > "$TMPDIR/GIT-TAG" 2>/dev/null; then
echo "unknown" > "$TMPDIR/GIT-TAG"
fi
# Append extra files to archive
tar --append --file="$ARCHIVE_PATH" -C "$TMPDIR" "$(basename "$COMPAT_LIST")" GIT-COMMIT GIT-TAG
# Remove temporary directory
rm -rf "$TMPDIR"
# Compress using xz
xz -9 "$ARCHIVE_PATH"
# Generate SHA-256 checksum (GNU vs BSD/macOS)
if command -v sha256sum >/dev/null 2>&1; then
sha256sum "$XZ_PATH" > "$SHA_PATH"
elif command -v shasum >/dev/null 2>&1; then
shasum -a 256 "$XZ_PATH" > "$SHA_PATH"
else
echo "No SHA-256 tool found (sha256sum or shasum required)" >&2
exit 1
fi
cd artifacts/
xz -T0 -9 "${REV_NAME}.tar"
sha256sum "${REV_NAME}.tar.xz" > "${REV_NAME}.tar.xz.sha256sum"
cd ..

View file

@ -1,11 +1,12 @@
#!/bin/sh
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
for i in dist/languages/*.ts; do
SRC=en_US
TARGET=`head -n1 $i | awk -F 'language="' '{split($2, a, "\""); print a[1]}'`
TARGET=$(head -n1 "$i" | awk -F 'language="' '{split($2, a, "\""); print a[1]}')
SOURCES=$(find src/yuzu -type f \( -name '*.ui' -o -name '*.cpp' -o -name '*.h' -o -name '*.plist' \))
# requires fd
SOURCES=`fd . src/yuzu -tf -e ui -e cpp -e h -e plist`
lupdate -source-language $SRC -target-language $TARGET $SOURCES -ts /data/code/eden/$i
lupdate -source-language $SRC -target-language "$TARGET" "$SOURCES" -ts /data/code/eden/"$i"
done

View file

@ -1,21 +1,47 @@
#!/bin/sh -e
# SPDX-FileCopyrightText: 2025 eden Emulator Project
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
which png2icns || [ which yay && yay libicns ] || exit
which magick || exit
# Check dependencies
for cmd in png2icns magick svgo; do
if ! command -v "$cmd" >/dev/null 2>&1; then
pkg="$cmd"
case "$cmd" in
png2icns) pkg="icnsutils" ;;
magick) pkg="imagemagick" ;;
esac
echo "Error: command '$cmd' not found. Install the package '$pkg'."
exit 1
fi
done
export EDEN_SVG_ICO="dist/dev.eden_emu.eden.svg"
svgo --multipass $EDEN_SVG_ICO
EDEN_SVG_ICO="dist/dev.eden_emu.eden.svg"
magick -density 256x256 -background transparent $EDEN_SVG_ICO \
-define icon:auto-resize -colors 256 dist/eden.ico || exit
convert -density 256x256 -resize 256x256 -background transparent $EDEN_SVG_ICO \
dist/yuzu.bmp || exit
# Create temporary PNG file safely (and POSIX-compliant)
TMP_PNG=$(mktemp /tmp/eden-tmp-XXXXXX)
TMP_PNG="${TMP_PNG}.png"
# Optimize SVG
svgo --multipass "$EDEN_SVG_ICO"
# Generate ICO
magick \
-density 256x256 -background transparent "$EDEN_SVG_ICO" \
-define icon:auto-resize -colors 256 "dist/eden.ico"
# Generate BMP
magick "$EDEN_SVG_ICO" -resize 256x256 -background transparent "dist/yuzu.bmp"
# Generate PNG for ICNS
magick -size 1024x1024 -background transparent "$EDEN_SVG_ICO" "$TMP_PNG"
# Generate ICNS
png2icns "dist/eden.icns" "$TMP_PNG"
# Copy ICNS to Yuzu file
cp "dist/eden.icns" "dist/yuzu.icns"
# Remove temporary PNG
rm -f "$TMP_PNG"
export TMP_PNG="dist/eden-tmp.png"
magick -size 1024x1024 -background transparent $EDEN_SVG_ICO $TMP_PNG || exit
png2icns dist/eden.icns $TMP_PNG || exit
cp dist/eden.icns dist/yuzu.icns
rm $TMP_PNG

View file

@ -1,6 +1,6 @@
#!/bin/bash -ex
# SPDX-FileCopyrightText: 2025 Eden Emulator Project
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
if [ "$COMPILER" == "clang" ]
@ -17,12 +17,12 @@ fi
[ -z "$WINDEPLOYQT" ] && { echo "WINDEPLOYQT environment variable required."; exit 1; }
echo $EXTRA_CMAKE_FLAGS
echo "${EXTRA_CMAKE_FLAGS[@]}"
mkdir -p build && cd build
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE:-Release}" \
-DENABLE_QT_TRANSLATION=ON \
-DENABLE_QT_TRANSLATION=ON \
-DUSE_DISCORD_PRESENCE=ON \
-DYUZU_USE_BUNDLED_SDL2=ON \
-DBUILD_TESTING=OFF \
@ -30,14 +30,14 @@ cmake .. -G Ninja \
-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} \
-DYUZU_USE_QT_MULTIMEDIA="${USE_MULTIMEDIA:-false}" \
-DYUZU_USE_QT_WEB_ENGINE="${USE_WEBENGINE:-false}" \
-DYUZU_ENABLE_LTO=ON \
-DCMAKE_EXE_LINKER_FLAGS=" /LTCG" \
-DCMAKE_EXE_LINKER_FLAGS=" /LTCG" \
-DDYNARMIC_ENABLE_LTO=ON \
-DYUZU_USE_BUNDLED_QT=${BUNDLE_QT:-false} \
-DUSE_CCACHE=${CCACHE:-false} \
-DENABLE_QT_UPDATE_CHECKER=${DEVEL:-true} \
-DYUZU_USE_BUNDLED_QT="${BUNDLE_QT:-false}" \
-DUSE_CCACHE="${CCACHE:-false}" \
-DENABLE_QT_UPDATE_CHECKER="${DEVEL:-true}" \
"${EXTRA_CMAKE_FLAGS[@]}" \
"$@"

View file

@ -1,3 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
@ -36,4 +39,4 @@ echo "Finished installing Vulkan SDK $VulkanSDKVer"
if ("$env:GITHUB_ACTIONS" -eq "true") {
echo "VULKAN_SDK=$VULKAN_SDK" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "$VULKAN_SDK/Bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
}
}

View file

@ -1,3 +1,8 @@
#!/bin/bash -e
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
GITDATE=$(git show -s --date=short --format='%ad' | tr -d "-")
GITREV=$(git show -s --format='%h')
@ -15,4 +20,4 @@ cp LICENSE* README* "$TMP_DIR"/
7z a -tzip "$ARTIFACTS_DIR/$ZIP_NAME" "$TMP_DIR"/*
rm -rf "$TMP_DIR"
rm -rf "$TMP_DIR"

View file

@ -44,6 +44,13 @@ if (PLATFORM_SUN)
endif()
endif()
# Needed for FFmpeg w/ VAAPI and DRM
if (PLATFORM_OPENBSD)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/X11R6/include")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/X11R6/include")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/X11R6/lib")
endif()
# Detect current compilation architecture and create standard definitions
# =======================================================================
@ -88,7 +95,7 @@ message(STATUS "Target architecture: ${ARCHITECTURE}")
if (MSVC AND ARCHITECTURE_x86)
message(FATAL_ERROR "Attempting to build with the x86 environment is not supported. \
This can typically happen if you used the Developer Command Prompt from the start menu;\
This can typically happen if you used the Developer Command Prompt from the start menu; \
instead, run vcvars64.bat directly, located at C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat")
endif()
@ -122,7 +129,7 @@ include(CMakeDependentOption)
include(CTest)
# Disable Warnings as Errors for MSVC
if (CXX_CL)
if (MSVC AND NOT CXX_CLANG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX-")
endif()
@ -485,13 +492,32 @@ else()
find_package(Opus 1.3 MODULE REQUIRED)
find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED MODULE)
find_package(Boost 1.57.0 REQUIRED context system fiber)
find_package(MbedTLS 3)
# wow
if (PLATFORM_LINUX)
find_package(Boost 1.57.0 REQUIRED headers context system fiber)
else()
find_package(Boost 1.57.0 REQUIRED)
endif()
# OpenBSD does not package mbedtls3 (only 2)
if (PLATFORM_OPENBSD)
AddJsonPackage(mbedtls)
else()
find_package(MbedTLS 3 REQUIRED)
endif()
find_package(VulkanUtilityLibraries REQUIRED)
find_package(VulkanHeaders 1.3.274 REQUIRED)
# FreeBSD does not package spirv-headers
if (PLATFORM_FREEBSD)
AddJsonPackage(spirv-headers)
else()
find_package(SPIRV-Headers 1.3.274 REQUIRED)
endif()
find_package(SPIRV-Tools MODULE REQUIRED)
find_package(SPIRV-Headers 1.3.274 REQUIRED)
if (YUZU_TESTS)
find_package(Catch2 3.0.1 REQUIRED)

View file

@ -1,17 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Copyright 2025 crueter
# SPDX-License-Identifier: GPL-3.0-or-later
# Created-By: crueter
# Docs will come at a later date, mostly this is to just reduce boilerplate
# and some cmake magic to allow for runtime viewing of dependency versions
# Future crueter: Wow this was a lie and a half, at this point I might as well make my own CPN
# haha just kidding... unless?
# TODO(crueter): Remember to get more than 6 hours of sleep whenever making giant cmake changes
if (MSVC OR ANDROID)
set(BUNDLED_DEFAULT ON)
else()
@ -27,6 +16,7 @@ option(CPMUTIL_FORCE_SYSTEM
cmake_minimum_required(VERSION 3.22)
include(CPM)
# cpmfile parsing
set(CPMUTIL_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cpmfile.json")
if (EXISTS ${CPMUTIL_JSON_FILE})
@ -35,12 +25,11 @@ else()
message(WARNING "[CPMUtil] cpmfile ${CPMUTIL_JSON_FILE} does not exist, AddJsonPackage will be a no-op")
endif()
# utility
# Utility stuff
function(cpm_utils_message level name message)
message(${level} "[CPMUtil] ${name}: ${message}")
endfunction()
# utility
function(array_to_list array length out)
math(EXPR range "${length} - 1")
@ -53,7 +42,6 @@ function(array_to_list array length out)
set("${out}" "${NEW_LIST}" PARENT_SCOPE)
endfunction()
# utility
function(get_json_element object out member default)
string(JSON out_type ERROR_VARIABLE err TYPE "${object}" ${member})
@ -73,14 +61,13 @@ function(get_json_element object out member default)
set("${out}" "${outvar}" PARENT_SCOPE)
endfunction()
# Kinda cancerous but whatever
# The preferred usage
function(AddJsonPackage)
set(oneValueArgs
NAME
# these are overrides that can be generated at runtime, so can be defined separately from the json
DOWNLOAD_ONLY
SYSTEM_PACKAGE
BUNDLED_PACKAGE
)
@ -90,6 +77,7 @@ function(AddJsonPackage)
"${ARGN}")
list(LENGTH ARGN argnLength)
# single name argument
if(argnLength EQUAL 1)
set(JSON_NAME "${ARGV0}")
@ -199,7 +187,6 @@ function(AddJsonPackage)
endif()
set(options ${options} ${JSON_OPTIONS})
# end options
# system/bundled
@ -241,7 +228,7 @@ endfunction()
function(AddPackage)
cpm_set_policies()
# TODO(crueter): docs, git clone
# TODO(crueter): git clone?
#[[
URL configurations, descending order of precedence:

View file

@ -1,15 +1,19 @@
# SPDX-FileCopyrightText: 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2020 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
include(CPMUtil)
if (PLATFORM_SUN OR PLATFORM_OPENBSD OR PLATFORM_FREEBSD)
# we love our libraries don't we folks
if (PLATFORM_SUN)
set(libusb_bundled ON)
else()
set(libusb_bundled OFF)
endif()
# TODO(crueter): Fix on *BSD/Solaris
# TODO(crueter): Fix on Solaris
AddJsonPackage(
NAME libusb
BUNDLED_PACKAGE ${libusb_bundled}
@ -19,6 +23,7 @@ if (NOT libusb_ADDED)
return()
endif()
# TODO: *BSD fails to compile--may need different configs/symbols
if (MINGW OR PLATFORM_LINUX OR APPLE)
set(LIBUSB_FOUND ON CACHE BOOL "libusb is present" FORCE)
set(LIBUSB_VERSION "1.0.24" CACHE STRING "libusb version string" FORCE)

View file

@ -119,8 +119,8 @@
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقت أثناء تحديثات الذاكرة، مما يقلل استخدام المعالج ويحسن أدائه. قد يسبب هذا أعطالاً أو تعطلًا في بعض الألعاب.</string>
<string name="cpuopt_unsafe_host_mmu">تمكين محاكاة MMU المضيف</string>
<string name="cpuopt_unsafe_host_mmu_description">يعمل هذا التحسين على تسريع وصول الذاكرة بواسطة البرنامج الضيف. يؤدي تمكينه إلى إجراء عمليات قراءة/كتابة ذاكرة الضيف مباشرة في الذاكرة والاستفادة من MMU المضيف. يؤدي تعطيل هذا إلى إجبار جميع عمليات الوصول إلى الذاكرة على استخدام محاكاة MMU البرمجية.</string>
<string name="dma_accuracy">مستوى DMA</string>
<string name="dma_accuracy_description">يتحكم في دقة تحديد مستوى DMA. الدقة الأعلى يمكنها إصلاح بعض المشاكل في بعض الألعاب، ولكنها قد تؤثر أيضًا على الأداء في بعض الحالات. إذا كنت غير متأكد، اتركه على الوضع الافتراضي.</string>
<string name="dma_accuracy">دقة DMA</string>
<string name="dma_accuracy_description">يتحكم في دقة تحديد DMA. يمكن أن تصلح الدقة الآمنة المشاكل في بعض الألعاب، ولكنها قد تؤثر أيضًا على الأداء في بعض الحالات. إذا كنت غير متأكد، اترك هذا على الوضع الافتراضي.</string>
<!-- Memory Layouts -->
<string name="memory_4gb">4 جيجابايت (موصى به)</string>
@ -792,9 +792,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">افتراضي</string>
<string name="dma_accuracy_normal">عادي</string>
<string name="dma_accuracy_high">عالي</string>
<string name="dma_accuracy_extreme">مفرط</string>
<string name="dma_accuracy_unsafe">غير آمن (سريع)</string>
<string name="dma_accuracy_safe">آمن (مستقر)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">هەندێک لە بازنەکردنەکانی هەڵگر لە کاتی نوێکردنەوەی بیرگە دەنێرێت، کەمکردنەوەی بەکارهێنانی CPU و باشترکردنی کارایی. لەوانەیە لە هەندێک یاری کێشە درووست بکات.</string>
<string name="cpuopt_unsafe_host_mmu">چالاککردنی میمیکردنی MMU میواندە</string>
<string name="cpuopt_unsafe_host_mmu_description">ئەم باشکردنە خێرایی دەستکەوتنی بیرگە لەلایەن پرۆگرامی میوانەکە زیاد دەکات. چالاککردنی وای لێدەکات کە خوێندنەوە/نووسینەکانی بیرگەی میوانەکە ڕاستەوخۆ لە بیرگە ئەنجام بدرێت و میمیکردنی MMU میواندە بەکاربهێنێت. ناچالاککردنی ئەمە هەموو دەستکەوتنەکانی بیرگە ڕەت دەکاتەوە لە بەکارهێنانی میمیکردنی MMU نەرمەکاڵا.</string>
<string name="dma_accuracy">ئاستی DMA</string>
<string name="dma_accuracy_description">کۆنتڕۆڵی وردی ڕێکخستنی DMA دەکات. وردی زیاتر دەتوانێ هەندێک کێشە لە هەندێک یاری چارەسەر بکات، بەڵام لە هەندێک حاڵەتدا کاریگەری لەسەر کارایی هەیە. ئەگەر دڵنیا نیت، بە ڕێکخستنی بنەڕەتی بێڵە.</string>
<string name="dma_accuracy">وردیی DMA</string>
<string name="dma_accuracy_description">کۆنتڕۆڵی وردیی وردیی DMA دەکات. وردییی پارێزراو دەتوانێت کێشەکان لە هەندێک یاری چارەسەر بکات، بەڵام لە هەندێک حاڵەتدا کاریگەری لەسەر کارایی هەیە. ئەگەر دڵنیا نیت، ئەمە بە سەر ڕەھەوادا بهێڵە.</string>
<string name="memory_4gb">4GB (پێشنیارکراو)</string>
<string name="memory_6gb">6GB (نائاسایش)</string>
@ -761,9 +761,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">بنەڕەتی</string>
<string name="dma_accuracy_normal">ئاسایی</string>
<string name="dma_accuracy_high">بەرز</string>
<string name="dma_accuracy_extreme">زۆر بەرز</string>
<string name="dma_accuracy_unsafe">نەپارێزراو (خێرا)</string>
<string name="dma_accuracy_safe">پارێزراو (جێگیر)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -127,8 +127,8 @@
<string name="skip_cpu_inner_invalidation_description">Přeskočí některé invalidace mezipaměti na straně CPU během aktualizací paměti, čímž sníží zatížení CPU a zlepší jeho výkon. Může způsobit chyby nebo pády v některých hrách.</string>
<string name="cpuopt_unsafe_host_mmu">Povolit emulaci hostitelské MMU</string>
<string name="cpuopt_unsafe_host_mmu_description">Tato optimalizace zrychluje přístup do paměti hostovaného programu. Její povolení způsobí, že čtení a zápisy do paměti hosta se provádějí přímo v paměti a využívají hostitelskou MMU. Zakázání této funkce vynutí použití softwarové emulace MMU pro všechny přístupy do paměti.</string>
<string name="dma_accuracy">Úroveň DMA</string>
<string name="dma_accuracy_description">Ovládá přesnost DMA. Vyšší přesnost může opravit problémy v některých hrách, ale může také ovlivnit výkon. Pokud si nejste jisti, ponechejte výchozí nastavení.</string>
<string name="dma_accuracy">Přesnost DMA</string>
<string name="dma_accuracy_description">Ovládá přesnost DMA. Bezpečná přesnost může opravit problémy v některých hrách, ale v některých případech může také ovlivnit výkon. Pokud si nejste jisti, ponechte to na výchozím nastavení.</string>
<string name="memory_4gb">4GB (Doporučeno)</string>
<string name="memory_6gb">6GB (Nebezpečné)</string>
@ -735,9 +735,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Výchozí</string>
<string name="dma_accuracy_normal">Normální</string>
<string name="dma_accuracy_high">Vysoká</string>
<string name="dma_accuracy_extreme">Extrémní</string>
<string name="dma_accuracy_unsafe">Nebezpečné (rychlé)</string>
<string name="dma_accuracy_safe">Bezpečné (stabilní)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Überspringt bestimmte Cache-Invalidierungen auf CPU-Seite während Speicherupdates, reduziert die CPU-Auslastung und verbessert die Leistung. Kann in einigen Spielen zu Fehlern oder Abstürzen führen.</string>
<string name="cpuopt_unsafe_host_mmu">Host-MMU-Emulation aktivieren</string>
<string name="cpuopt_unsafe_host_mmu_description">Diese Optimierung beschleunigt Speicherzugriffe durch das Gastprogramm. Wenn aktiviert, erfolgen Speicherlese- und -schreibvorgänge des Gastes direkt im Speicher und nutzen die MMU des Hosts. Das Deaktivieren erzwingt die Verwendung der Software-MMU-Emulation für alle Speicherzugriffe.</string>
<string name="dma_accuracy">DMA-Level</string>
<string name="dma_accuracy_description">Steuert die DMA-Präzisionsgenauigkeit. Eine höhere Präzision kann Probleme in einigen Spielen beheben, kann aber in einigen Fällen auch die Leistung beeinträchtigen. Im Zweifel auf „Standard“ belassen.</string>
<string name="dma_accuracy">DMA-Genauigkeit</string>
<string name="dma_accuracy_description">Steuert die DMA-Präzisionsgenauigkeit. Sichere Präzision kann Probleme in einigen Spielen beheben, kann aber in einigen Fällen auch die Leistung beeinträchtigen. Im Zweifel lassen Sie dies auf Standard stehen.</string>
<string name="memory_4gb">4 GB (Empfohlen)</string>
<string name="memory_6gb">6 GB (Unsicher)</string>
@ -827,9 +827,8 @@ Wirklich fortfahren?</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Standard</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Hoch</string>
<string name="dma_accuracy_extreme">Extrem</string>
<string name="dma_accuracy_unsafe">Unsicher (schnell)</string>
<string name="dma_accuracy_safe">Sicher (stabil)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché durante actualizaciones de memoria, reduciendo el uso de CPU y mejorando su rendimiento. Puede causar fallos en algunos juegos.</string>
<string name="cpuopt_unsafe_host_mmu">Habilitar emulación de MMU del host</string>
<string name="cpuopt_unsafe_host_mmu_description">Esta optimización acelera los accesos a la memoria por parte del programa invitado. Al habilitarla, las lecturas/escrituras de memoria del invitado se realizan directamente en la memoria y utilizan la MMU del host. Deshabilitar esto obliga a que todos los accesos a la memoria utilicen la emulación de MMU por software.</string>
<string name="dma_accuracy">Nivel de DMA</string>
<string name="dma_accuracy_description">Controla la precisión del DMA. Una mayor precisión puede solucionar problemas en algunos juegos, pero también puede afectar el rendimiento en algunos casos. Si no está seguro, déjelo en Predeterminado.</string>
<string name="dma_accuracy">Precisión de DMA</string>
<string name="dma_accuracy_description">Controla la precisión de DMA. La precisión segura puede solucionar problemas en algunos juegos, pero también puede afectar al rendimiento en algunos casos. Si no está seguro, déjelo en Predeterminado.</string>
<string name="memory_4gb">4GB (Recomendado)</string>
<string name="memory_6gb">6GB (Inseguro)</string>
@ -870,9 +870,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Predeterminado</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Alto</string>
<string name="dma_accuracy_extreme">Extremo</string>
<string name="dma_accuracy_unsafe">Inseguro (rápido)</string>
<string name="dma_accuracy_safe">Seguro (estable)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">بعضی ابطال‌های حافظه نهان در هنگام به‌روزرسانی‌های حافظه را رد می‌کند، استفاده از CPU را کاهش داده و عملکرد آن را بهبود می‌بخشد. ممکن است در برخی بازی‌ها باعث مشکلات یا خرابی شود.</string>
<string name="cpuopt_unsafe_host_mmu">فعال‌سازی شبیه‌سازی MMU میزبان</string>
<string name="cpuopt_unsafe_host_mmu_description">این بهینه‌سازی دسترسی‌های حافظه توسط برنامه میهمان را تسریع می‌کند. فعال‌سازی آن باعث می‌شود خواندن/نوشتن حافظه میهمان مستقیماً در حافظه انجام شود و از MMU میزبان استفاده کند. غیرفعال کردن این قابلیت، همه دسترسی‌های حافظه را مجبور به استفاده از شبیه‌سازی نرم‌افزاری MMU می‌کند.</string>
<string name="dma_accuracy">سطح DMA</string>
<string name="dma_accuracy_description">دقت صحت DMA را کنترل می کند. دقت بالاتر می تواند مشکلات برخی بازی ها را برطرف کند، اما در برخی موارد نیز می تواند بر عملکرد تأثیر بگذارد. اگر مطمئن نیستید، آن را روی پیش فرض بگذارید.</string>
<string name="dma_accuracy">دقت DMA</string>
<string name="dma_accuracy_description">دقت صحت DMA را کنترل می کند. دقت ایمن می تواند مشکلات برخی بازی ها را برطرف کند، اما در برخی موارد نیز ممکن است بر عملکرد تأثیر بگذارد. اگر مطمئن نیستید، این گزینه را روی پیش فرض بگذارید.</string>
<string name="memory_4gb">4 گیگابایت (توصیه شده)</string>
<string name="memory_6gb">6 گیگابایت (ناامن)</string>
@ -869,9 +869,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">پیش فرض</string>
<string name="dma_accuracy_normal">معمولی</string>
<string name="dma_accuracy_high">بالا</string>
<string name="dma_accuracy_extreme">فوق العاده</string>
<string name="dma_accuracy_unsafe">ناایمن (سریع)</string>
<string name="dma_accuracy_safe">ایمن (پایدار)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Ignore certaines invalidations de cache côté CPU lors des mises à jour mémoire, réduisant l\'utilisation du CPU et améliorant ses performances. Peut causer des bugs ou plantages sur certains jeux.</string>
<string name="cpuopt_unsafe_host_mmu">Activer l\'émulation de la MMU hôte</string>
<string name="cpuopt_unsafe_host_mmu_description">Cette optimisation accélère les accès mémoire par le programme invité. L\'activer entraîne que les lectures/écritures mémoire de l\'invité sont effectuées directement en mémoire et utilisent la MMU de l\'hôte. Désactiver cela force tous les accès mémoire à utiliser l\'émulation logicielle de la MMU.</string>
<string name="dma_accuracy">Niveau DMA</string>
<string name="dma_accuracy_description">Contrôle la précision du DMA. Une précision plus élevée peut résoudre les problèmes dans certains jeux, mais peut aussi affecter les performances dans certains cas. Si vous n\'êtes pas sûr, laissez-la sur Défaut.</string>
<string name="dma_accuracy">Précision DMA</string>
<string name="dma_accuracy_description">Contrôle la précision du DMA. Une précision sûre peut résoudre les problèmes dans certains jeux, mais peut aussi affecter les performances dans certains cas. Si vous n\'êtes pas sûr, laissez ce paramètre sur Par défaut.</string>
<string name="memory_4gb">4 Go (Recommandé)</string>
<string name="memory_6gb">6 Go (Dangereux)</string>
@ -918,9 +918,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Défaut</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Élevé</string>
<string name="dma_accuracy_extreme">Extrême</string>
<string name="dma_accuracy_unsafe">Dangereux (rapide)</string>
<string name="dma_accuracy_safe">Sûr (stable)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -129,8 +129,8 @@
<string name="skip_cpu_inner_invalidation_description">מדלג על איפוסי מטמון מסוימים במהלך עדכוני זיכרון, מפחית שימוש במעבד ומשפר ביצועים. עלול לגרום לתקלות או קריסות בחלק מהמשחקים.</string>
<string name="cpuopt_unsafe_host_mmu">הפעל אמולציית MMU מארח</string>
<string name="cpuopt_unsafe_host_mmu_description">אופטימיזציה זו מאיצה את גישת הזיכרון על ידי התוכנית האורחת. הפעלתה גורמת לכך שפעולות קריאה/כתיבה לזיכרון האורח מתבצעות ישירות לזיכרון ומשתמשות ב-MMU של המארח. השבתת זאת מאלצת את כל גישות הזיכרון להשתמש באמולציית MMU תוכנתית.</string>
<string name="dma_accuracy">רמת DMA</string>
<string name="dma_accuracy_description">שולטת בדיוק הדיוק של DMA. דיוק גבוה יותר יכול לתקן בעיות בחלק מהמשחקים, אך הוא עלול גם להשפיע על הביצועים במקרים מסוימים. אם אינך בטוח, השאר ברירת מחדל.</string>
<string name="dma_accuracy">דיוק DMA</string>
<string name="dma_accuracy_description">שולט בדיוק הדיוק של DMA. דיוק בטוח יכול לתקן בעיות בחלק מהמשחקים, אך הוא עלול גם להשפיע על הביצועים במקרים מסוימים. אם אינך בטוח, השאר זאת על ברירת מחדל.</string>
<string name="memory_4gb">4GB (מומלץ)</string>
<string name="memory_6gb">6GB (לא בטוח)</string>
@ -800,9 +800,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">ברירת מחדל</string>
<string name="dma_accuracy_normal">רגיל</string>
<string name="dma_accuracy_high">גבוה</string>
<string name="dma_accuracy_extreme">קיצוני</string>
<string name="dma_accuracy_unsafe">לא בטוח (מהיר)</string>
<string name="dma_accuracy_safe">בטוח (יציב)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Kihagy néhány CPU-oldali gyorsítótár-érvénytelenítést memóriafrissítések közben, csökkentve a CPU használatát és javítva a teljesítményt. Néhány játékban hibákat vagy összeomlást okozhat.</string>
<string name="cpuopt_unsafe_host_mmu">Gazda MMU emuláció engedélyezése</string>
<string name="cpuopt_unsafe_host_mmu_description">Ez az optimalizáció gyorsítja a vendégprogram memória-hozzáférését. Engedélyezése esetén a vendég memóriaolvasási/írási műveletei közvetlenül a memóriában történnek, és kihasználják a gazda MMU-ját. Letiltás esetén minden memória-hozzáférés a szoftveres MMU emulációt használja.</string>
<string name="dma_accuracy">DMA szint</string>
<string name="dma_accuracy_description">Szabályozza a DMA pontosságát. A magasabb pontosság megoldhat néhány játék problémáit, de bizonyos esetekben befolyásolhatja a teljesítményt. Ha bizonytalan, hagyja Alapértelmezett beállításnál.</string>
<string name="dma_accuracy">DMA pontosság</string>
<string name="dma_accuracy_description">Szabályozza a DMA pontosságát. A biztonságos pontosság megoldhat néhány játék problémáit, de bizonyos esetekben befolyásolhatja a teljesítményt. Ha bizonytalan, hagyja Alapértelmezett beállításon.</string>
<string name="memory_4gb">4GB (Ajánlott)</string>
<string name="memory_6gb">6GB (Nem biztonságos)</string>
@ -907,9 +907,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Alapértelmezett</string>
<string name="dma_accuracy_normal">Normál</string>
<string name="dma_accuracy_high">Magas</string>
<string name="dma_accuracy_extreme">Extrém</string>
<string name="dma_accuracy_unsafe">Nem biztonságos (gyors)</string>
<string name="dma_accuracy_safe">Biztonságos (stabil)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Melewati beberapa pembatalan cache sisi CPU selama pembaruan memori, mengurangi penggunaan CPU dan meningkatkan kinerjanya. Mungkin menyebabkan gangguan atau crash pada beberapa game.</string>
<string name="cpuopt_unsafe_host_mmu">Aktifkan Emulasi MMU Host</string>
<string name="cpuopt_unsafe_host_mmu_description">Optimasi ini mempercepat akses memori oleh program tamu. Mengaktifkannya menyebabkan pembacaan/penulisan memori tamu dilakukan langsung ke memori dan memanfaatkan MMU Host. Menonaktifkan ini memaksa semua akses memori menggunakan Emulasi MMU Perangkat Lunak.</string>
<string name="dma_accuracy">Level DMA</string>
<string name="dma_accuracy_description">Mengontrol akurasi presisi DMA. Presisi yang lebih tinggi dapat memperbaiki masalah di beberapa game, tetapi juga dapat memengaruhi performa dalam beberapa kasus. Jika tidak yakin, biarkan di Bawaan.</string>
<string name="dma_accuracy">Akurasi DMA</string>
<string name="dma_accuracy_description">Mengontrol keakuratan presisi DMA. Presisi aman dapat memperbaiki masalah di beberapa game, tetapi juga dapat memengaruhi kinerja dalam beberapa kasus. Jika tidak yakin, biarkan ini pada Bawaan.</string>
<string name="memory_4gb">4GB (Direkomendasikan)</string>
<string name="memory_6gb">6GB (Tidak Aman)</string>
@ -862,9 +862,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Bawaan</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Tinggi</string>
<string name="dma_accuracy_extreme">Ekstrem</string>
<string name="dma_accuracy_unsafe">Tidak Aman (cepat)</string>
<string name="dma_accuracy_safe">Aman (stabil)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Salta alcuni invalidamenti della cache lato CPU durante gli aggiornamenti di memoria, riducendo l\'uso della CPU e migliorandone le prestazioni. Potrebbe causare glitch o crash in alcuni giochi.</string>
<string name="cpuopt_unsafe_host_mmu">Abilita emulazione MMU host</string>
<string name="cpuopt_unsafe_host_mmu_description">Questa ottimizzazione accelera gli accessi alla memoria da parte del programma guest. Abilitandola, le letture/scritture della memoria guest vengono eseguite direttamente in memoria e sfruttano la MMU host. Disabilitandola, tutti gli accessi alla memoria sono costretti a utilizzare l\'emulazione software della MMU.</string>
<string name="dma_accuracy">Livello DMA</string>
<string name="dma_accuracy_description">Controlla la precisione del DMA. Una precisione più alta può risolvere problemi in alcuni giochi, ma in alcuni casi può influire sulle prestazioni. Se non sei sicuro, lascia su Predefinito.</string>
<string name="dma_accuracy">Precisione DMA</string>
<string name="dma_accuracy_description">Controlla la precisione del DMA. La precisione sicura può risolvere problemi in alcuni giochi, ma in alcuni casi può anche influire sulle prestazioni. In caso di dubbi, lascia questo su Predefinito.</string>
<string name="memory_4gb">4GB (Consigliato)</string>
<string name="memory_6gb">6GB (Non sicuro)</string>
@ -831,9 +831,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Predefinito</string>
<string name="dma_accuracy_normal">Normale</string>
<string name="dma_accuracy_high">Alto</string>
<string name="dma_accuracy_extreme">Estremo</string>
<string name="dma_accuracy_unsafe">Non sicuro (veloce)</string>
<string name="dma_accuracy_safe">Sicuro (stabile)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">メモリ更新時のCPU側キャッシュ無効化をスキップし、CPU使用率を減らして性能を向上させます。一部のゲームで不具合やクラッシュが発生する可能性があります。</string>
<string name="cpuopt_unsafe_host_mmu">ホストMMUエミュレーションを有効化</string>
<string name="cpuopt_unsafe_host_mmu_description">この最適化により、ゲストプログラムによるメモリアクセスが高速化されます。有効にすると、ゲストのメモリ読み書きが直接メモリ内で実行され、ホストのMMUを利用します。無効にすると、すべてのメモリアクセスでソフトウェアMMUエミュレーションが使用されます。</string>
<string name="dma_accuracy">DMAレベル</string>
<string name="dma_accuracy_description">DMAの精度を制御します。精度を高くすると一部のゲームの問題が修正される場合がありますが、場合によってはパフォーマンスに影響を与える可能性もあります。不明な場合は、デフォルトのままにしてください。</string>
<string name="dma_accuracy">DMA精度</string>
<string name="dma_accuracy_description">DMAの精度を制御します。安全な精度は一部のゲームの問題を修正できる場合がありますが、場合によってはパフォーマンスに影響を与える可能性もあります。不明な場合は、これをデフォルトのままにしてください。</string>
<string name="memory_4gb">4GB (推奨)</string>
<string name="memory_6gb">6GB (安全でない)</string>
@ -790,9 +790,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">デフォルト</string>
<string name="dma_accuracy_normal">標準</string>
<string name="dma_accuracy_high"></string>
<string name="dma_accuracy_extreme">最高</string>
<string name="dma_accuracy_unsafe">安全でない(高速)</string>
<string name="dma_accuracy_safe">安全(安定)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">메모리 업데이트 시 일부 CPU 측 캐시 무효화를 건너뛰어 CPU 사용량을 줄이고 성능을 향상시킵니다. 일부 게임에서 오류 또는 충돌을 일으킬 수 있습니다.</string>
<string name="cpuopt_unsafe_host_mmu">호스트 MMU 에뮬레이션 사용</string>
<string name="cpuopt_unsafe_host_mmu_description">이 최적화는 게스트 프로그램의 메모리 접근 속도를 높입니다. 활성화하면 게스트의 메모리 읽기/쓰기가 메모리에서 직접 수행되고 호스트의 MMU를 활용합니다. 비활성화하면 모든 메모리 접근에 소프트웨어 MMU 에뮬레이션을 사용하게 됩니다.</string>
<string name="dma_accuracy">DMA 수준</string>
<string name="dma_accuracy_description">DMA 정밀도를 제어합니다. 높은 정밀도는 일부 게임의 문제를 해결할 수 있지만 경우에 따라 성능에 영향을 미칠 수도 있습니다. 확실하지 않다면 기본값으로 두세요.</string>
<string name="dma_accuracy">DMA 정확도</string>
<string name="dma_accuracy_description">DMA 정밀도 정확도를 제어합니다. 안전한 정밀도는 일부 게임의 문제를 해결할 수 있지만 경우에 따라 성능에 영향을 미칠 수도 있습니다. 확실하지 않은 경우 기본값으로 두십시오.</string>
<string name="memory_4gb">4GB (권장)</string>
<string name="memory_6gb">6GB (안전하지 않음)</string>
@ -861,9 +861,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">기본값</string>
<string name="dma_accuracy_normal">보통</string>
<string name="dma_accuracy_high">높음</string>
<string name="dma_accuracy_extreme">극단적</string>
<string name="dma_accuracy_unsafe">안전하지 않음(빠름)</string>
<string name="dma_accuracy_safe">안전함(안정적)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Hopper over enkelte CPU-side cache-invalideringer under minneoppdateringer, reduserer CPU-bruk og forbedrer ytelsen. Kan forårsake feil eller krasj i noen spill.</string>
<string name="cpuopt_unsafe_host_mmu">Aktiver verts-MMU-emulering</string>
<string name="cpuopt_unsafe_host_mmu_description">Denne optimaliseringen fremskynder minnetilgang av gjesteprogrammet. Hvis aktivert, utføres gjestens minnelesing/skriving direkte i minnet og bruker vertens MMU. Deaktivering tvinger alle minnetilganger til å bruke programvarebasert MMU-emulering.</string>
<string name="dma_accuracy">DMA-nivå</string>
<string name="dma_accuracy_description">Styrer DMA-presisjonsnøyaktigheten. Høyere presisjon kan fikse problemer i noen spill, men kan også påvirke ytelsen i noen tilfeller. Hvis du er usikker, la den stå på Standard.</string>
<string name="dma_accuracy">DMA-nøyaktighet</string>
<string name="dma_accuracy_description">Kontrollerer DMA-presisjonsnøyaktigheten. Sikker presisjon kan fikse problemer i noen spill, men kan også påvirke ytelsen i noen tilfeller. Hvis du er usikker, la dette stå på Standard.</string>
<string name="memory_4gb">4GB (Anbefalt)</string>
<string name="memory_6gb">6GB (Usikkert)</string>
@ -771,9 +771,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Standard</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Høy</string>
<string name="dma_accuracy_extreme">Ekstrem</string>
<string name="dma_accuracy_unsafe">Usikker (rask)</string>
<string name="dma_accuracy_safe">Sikker (stabil)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Pomija niektóre unieważnienia pamięci podręcznej po stronie CPU podczas aktualizacji pamięci, zmniejszając użycie CPU i poprawiając jego wydajność. Może powodować błędy lub awarie w niektórych grach.</string>
<string name="cpuopt_unsafe_host_mmu">Włącz emulację MMU hosta</string>
<string name="cpuopt_unsafe_host_mmu_description">Ta optymalizacja przyspiesza dostęp do pamięci przez program gościa. Włączenie powoduje, że odczyty/zapisy pamięci gościa są wykonywane bezpośrednio w pamięci i wykorzystują MMU hosta. Wyłączenie wymusza użycie programowej emulacji MMU dla wszystkich dostępów do pamięci.</string>
<string name="dma_accuracy">Poziom DMA</string>
<string name="dma_accuracy_description">Kontroluje dokładność precyzji DMA. Wyższy poziom może naprawić problemy w niektórych grach, ale może również wpłynąć na wydajność. Jeśli nie jesteś pewien, pozostaw wartość «Domyślny».</string>
<string name="dma_accuracy">Dokładność DMA</string>
<string name="dma_accuracy_description">Kontroluje dokładność precyzji DMA. Bezpieczna precyzja może naprawić problemy w niektórych grach, ale w niektórych przypadkach może również wpłynąć na wydajność. Jeśli nie jesteś pewien, pozostaw wartość Domyślną.</string>
<string name="memory_4gb">4GB (Zalecane)</string>
<string name="memory_6gb">6GB (Niebezpieczne)</string>
@ -768,9 +768,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">預設</string>
<string name="dma_accuracy_normal">普通</string>
<string name="dma_accuracy_high"></string>
<string name="dma_accuracy_extreme">極高</string>
<string name="dma_accuracy_unsafe">Niezabezpieczone (szybkie)</string>
<string name="dma_accuracy_safe">Bezpieczne (stabilne)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Ignora algumas invalidações de cache do lado da CPU durante atualizações de memória, reduzindo o uso da CPU e melhorando seu desempenho. Pode causar falhas ou travamentos em alguns jogos.</string>
<string name="cpuopt_unsafe_host_mmu">Ativar Emulação de MMU do Host</string>
<string name="cpuopt_unsafe_host_mmu_description">Esta otimização acelera os acessos à memória pelo programa convidado. Ativar isso faz com que as leituras/gravações de memória do convidado sejam feitas diretamente na memória e utilizem a MMU do Host. Desativar isso força todos os acessos à memória a usarem a Emulação de MMU por Software.</string>
<string name="dma_accuracy">Nível DMA</string>
<string name="dma_accuracy_description">Controla a precisão do DMA. Maior precisão pode corrigir problemas em alguns jogos, mas também pode impactar o desempenho em alguns casos. Se não tiver certeza, deixe em Padrão.</string>
<string name="dma_accuracy">Precisão de DMA</string>
<string name="dma_accuracy_description">Controla a precisão do DMA. A precisão segura pode corrigir problemas em alguns jogos, mas também pode afetar o desempenho em alguns casos. Se não tiver certeza, deixe isso como Padrão.</string>
<string name="memory_4gb">4GB (Recomendado)</string>
<string name="memory_6gb">6GB (Inseguro)</string>
@ -919,9 +919,8 @@ uma tentativa de mapeamento automático</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Padrão</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Alto</string>
<string name="dma_accuracy_extreme">Extremo</string>
<string name="dma_accuracy_unsafe">Inseguro (rápido)</string>
<string name="dma_accuracy_safe">Seguro (estável)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Ignora algumas invalidações de cache do lado da CPU durante atualizações de memória, reduzindo a utilização da CPU e melhorando o desempenho. Pode causar falhas ou crashes em alguns jogos.</string>
<string name="cpuopt_unsafe_host_mmu">Ativar Emulação de MMU do Anfitrião</string>
<string name="cpuopt_unsafe_host_mmu_description">Esta otimização acelera os acessos à memória pelo programa convidado. Ativar faz com que as leituras/escritas de memória do convidado sejam efetuadas diretamente na memória e utilizem a MMU do Anfitrião. Desativar força todos os acessos à memória a usar a Emulação de MMU por Software.</string>
<string name="dma_accuracy">Nível DMA</string>
<string name="dma_accuracy_description">Controla a precisão do DMA. Maior precisão pode corrigir problemas em alguns jogos, mas também pode afetar o desempenho nalguns casos. Se não tiver a certeza, deixe em Predefinido.</string>
<string name="dma_accuracy">Precisão da DMA</string>
<string name="dma_accuracy_description">Controla a precisão da DMA. A precisão segura pode resolver problemas em alguns jogos, mas também pode afetar o desempenho nalguns casos. Se não tiver a certeza, deixe esta opção em Predefinido.</string>
<string name="memory_4gb">4GB (Recomendado)</string>
<string name="memory_6gb">6GB (Inseguro)</string>
@ -919,9 +919,8 @@ uma tentativa de mapeamento automático</string>
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Predefinido</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">Alto</string>
<string name="dma_accuracy_extreme">Extremo</string>
<string name="dma_accuracy_unsafe">Inseguro (rápido)</string>
<string name="dma_accuracy_safe">Seguro (estável)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
<string name="cpuopt_unsafe_host_mmu">Включить эмуляцию MMU хоста</string>
<string name="cpuopt_unsafe_host_mmu_description">Эта оптимизация ускоряет доступ к памяти гостевой программой. При включении операции чтения/записи памяти гостя выполняются напрямую в памяти с использованием MMU хоста. Отключение заставляет все обращения к памяти использовать программную эмуляцию MMU.</string>
<string name="dma_accuracy">Уровень DMA</string>
<string name="dma_accuracy_description">Управляет точностью DMA. Более высокий уровень может исправить проблемы в некоторых играх, но также может повлиять на производительность. Если не уверены, оставьте значение «По умолчанию».</string>
<string name="dma_accuracy">Точность DMA</string>
<string name="dma_accuracy_description">Управляет точностью DMA. Безопасная точность может исправить проблемы в некоторых играх, но в некоторых случаях также может повлиять на производительность. Если не уверены, оставьте значение По умолчанию.</string>
<string name="memory_4gb">4 ГБ (Рекомендуется)</string>
<string name="memory_6gb">6 ГБ (Небезопасно)</string>
@ -920,9 +920,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">По умолчанию</string>
<string name="dma_accuracy_normal">Нормальный</string>
<string name="dma_accuracy_high">Высокий</string>
<string name="dma_accuracy_extreme">Экстремальный</string>
<string name="dma_accuracy_unsafe">Небезопасно (быстро)</string>
<string name="dma_accuracy_safe">Безопасно (стабильно)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>
@ -956,7 +955,7 @@
<!-- Screen Layouts -->
<string name="screen_layout_auto">Авто</string>
<string name="screen_layout_sensor_landscape">Альбомная (сенсор)</string>
<string name="screen_layout_landscape">Пейзаж</string>
<string name="screen_layout_landscape">Альбомная</string>
<string name="screen_layout_reverse_landscape">Обратная альбомная</string>
<string name="screen_layout_sensor_portrait">Портретная (сенсор)</string>
<string name="screen_layout_portrait">Портрет</string>

View file

@ -121,8 +121,8 @@
<string name="skip_cpu_inner_invalidation_description">Preskače određena poništavanja keša na strani CPU-a tokom ažuriranja memorije, smanjujući opterećenje procesora i poboljšavajući performanse. Može izazvati greške u nekim igrama.</string>
<string name="cpuopt_unsafe_host_mmu">Омогући емулацију MMU домаћина</string>
<string name="cpuopt_unsafe_host_mmu_description">Ова оптимизација убрзава приступ меморији од стране гостујућег програма. Укључивање изазива да се читања/уписа меморије госта обављају директно у меморији и користе MMU домаћина. Искључивање присиљава све приступе меморији да користе софтверску емулацију MMU.</string>
<string name="dma_accuracy">DMA ниво</string>
<string name="dma_accuracy_description">Контролише тачност DMA прецизности. Виши ниво може да поправи проблеме у неким играма, али може и да утиче на перформансе. Ако нисте сигурни, оставите на «Подразумевано».</string>
<string name="dma_accuracy">DMA тачност</string>
<string name="dma_accuracy_description">Управља прецизношћу DMA-а. Сигурна прецизност може да исправи проблеме у неким играма, али у неким случајевима може да утиче и на перформансе. Ако нисте сигурни, оставите ово на Подразумевано.</string>
<!-- Shader Backend -->
<string name="shader_backend">Схадер Бацкенд</string>
@ -915,9 +915,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Подразумевано</string>
<string name="dma_accuracy_normal">Нормално</string>
<string name="dma_accuracy_high">Високо</string>
<string name="dma_accuracy_extreme">Екстремно</string>
<string name="dma_accuracy_unsafe">Небезбедно (брзо)</string>
<string name="dma_accuracy_safe">Безбедно (стабилно)</string>
<!-- ASTC Decoding Method -->
<string name="accelerate_astc">АСТЦ метода декодирања</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
<string name="cpuopt_unsafe_host_mmu">Увімкнути емуляцію MMU хоста</string>
<string name="cpuopt_unsafe_host_mmu_description">Ця оптимізація пришвидшує доступ до пам\'яті гостьовою програмою. Увімкнення призводить до того, що читання/запис пам\'яті гостя виконуються безпосередньо в пам\'яті та використовують MMU хоста. Вимкнення змушує всі звернення до пам\'яті використовувати програмну емуляцію MMU.</string>
<string name="dma_accuracy">Рівень DMA</string>
<string name="dma_accuracy_description">Керує точністю DMA. Вищий рівень може виправити проблеми в деяких іграх, але також може вплинути на продуктивність. Якщо не впевнені, залиште значення «Типово».</string>
<string name="dma_accuracy">Точність DMA</string>
<string name="dma_accuracy_description">Керує точністю DMA. Безпечна точність може виправити проблеми в деяких іграх, але в деяких випадках також може вплинути на продуктивність. Якщо не впевнені, залиште це значення за замовчуванням.</string>
<string name="memory_4gb">4 ГБ (Рекомендовано)</string>
<string name="memory_6gb">6 ГБ (Небезпечно)</string>
@ -809,9 +809,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Типово</string>
<string name="dma_accuracy_normal">Нормальний</string>
<string name="dma_accuracy_high">Високий</string>
<string name="dma_accuracy_extreme">Екстремальний</string>
<string name="dma_accuracy_unsafe">Небезпечно (швидко)</string>
<string name="dma_accuracy_safe">Безпечно (стабільно)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -128,8 +128,8 @@
<string name="skip_cpu_inner_invalidation_description">Bỏ qua một số lần vô hiệu hóa bộ nhớ đệm phía CPU trong khi cập nhật bộ nhớ, giảm mức sử dụng CPU và cải thiện hiệu suất. Có thể gây ra lỗi hoặc treo máy trong một số trò chơi.</string>
<string name="cpuopt_unsafe_host_mmu">Bật giả lập MMU Máy chủ</string>
<string name="cpuopt_unsafe_host_mmu_description">Tối ưu hóa này tăng tốc độ truy cập bộ nhớ của chương trình khách. Bật nó lên khiến các thao tác đọc/ghi bộ nhớ khách được thực hiện trực tiếp vào bộ nhớ và sử dụng MMU của Máy chủ. Tắt tính năng này buộc tất cả quyền truy cập bộ nhớ phải sử dụng Giả lập MMU Phần mềm.</string>
<string name="dma_accuracy">Cấp độ DMA</string>
<string name="dma_accuracy_description">Điều khiển độ chính xác của DMA. Độ chính xác cao hơn có thể sửa lỗi trong một số trò chơi, nhưng cũng có thể ảnh hưởng đến hiệu suất trong một số trường hợp. Nếu không chắc chắn, hãy để ở Mặc định.</string>
<string name="dma_accuracy">Độ chính xác DMA</string>
<string name="dma_accuracy_description">Điều khiển độ chính xác của DMA. Độ chính xác an toàn có thể khắc phục sự cố trong một số trò chơi, nhưng trong một số trường hợp cũng có thể ảnh hưởng đến hiệu suất. Nếu không chắc chắn, hãy để giá trị này ở Mặc định.</string>
<string name="memory_4gb">4GB (Được đề xuất)</string>
<string name="memory_6gb">6GB (Không an toàn)</string>
@ -774,9 +774,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Mặc định</string>
<string name="dma_accuracy_normal">Bình thường</string>
<string name="dma_accuracy_high">Cao</string>
<string name="dma_accuracy_extreme">Cực cao</string>
<string name="dma_accuracy_unsafe">Không an toàn (nhanh)</string>
<string name="dma_accuracy_safe">An toàn (ổn định)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -127,8 +127,8 @@
<string name="skip_cpu_inner_invalidation_description">在内存更新期间跳过某些CPU端缓存无效化减少CPU使用率并提高其性能。可能会导致某些游戏出现故障或崩溃。</string>
<string name="cpuopt_unsafe_host_mmu">启用主机 MMU 模拟</string>
<string name="cpuopt_unsafe_host_mmu_description">此优化可加速来宾程序的内存访问。启用后,来宾内存读取/写入将直接在内存中执行并利用主机的 MMU。禁用此功能将强制所有内存访问使用软件 MMU 模拟。</string>
<string name="dma_accuracy">DMA 级别</string>
<string name="dma_accuracy_description">控制 DMA 精度。更高的精度可以修复某些游戏中的问题,但在某些情况下也可能影响性能。如果不确定,请保留为“默认”。</string>
<string name="dma_accuracy">DMA 精度</string>
<string name="dma_accuracy_description">控制 DMA 精度。安全精度可以修复某些游戏中的问题,但在某些情况下也可能影响性能。如果不确定,请保留为“默认”。</string>
<string name="memory_4gb">4GB (推荐)</string>
<string name="memory_6gb">6GB (不安全)</string>
@ -912,9 +912,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">默认</string>
<string name="dma_accuracy_normal">普通</string>
<string name="dma_accuracy_high"></string>
<string name="dma_accuracy_extreme">极高</string>
<string name="dma_accuracy_unsafe">不安全(快速)</string>
<string name="dma_accuracy_safe">安全(稳定)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -120,8 +120,8 @@
<string name="skip_cpu_inner_invalidation_description">在記憶體更新期間跳過某些CPU端快取無效化減少CPU使用率並提高其性能。可能會導致某些遊戲出現故障或崩潰。</string>
<string name="cpuopt_unsafe_host_mmu">啟用主機 MMU 模擬</string>
<string name="cpuopt_unsafe_host_mmu_description">此最佳化可加速來賓程式的記憶體存取。啟用後,來賓記憶體讀取/寫入將直接在記憶體中執行並利用主機的 MMU。停用此功能將強制所有記憶體存取使用軟體 MMU 模擬。</string>
<string name="dma_accuracy">DMA 級別</string>
<string name="dma_accuracy_description">控制 DMA 精確度。更高的精確度可以修復某些遊戲中的問題,但在某些情況下也可能影響效能。如果不確定,請保留為「預設」。</string>
<string name="dma_accuracy">DMA 精度</string>
<string name="dma_accuracy_description">控制 DMA 精度。安全精度可以修復某些遊戲中的問題,但在某些情況下也可能影響效能。如果不確定,請保留為「預設」。</string>
<!-- Memory Layouts -->
<string name="memory_4gb">4GB (推薦)</string>
@ -917,9 +917,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">預設</string>
<string name="dma_accuracy_normal">普通</string>
<string name="dma_accuracy_high"></string>
<string name="dma_accuracy_extreme">極高</string>
<string name="dma_accuracy_unsafe">不安全(快速)</string>
<string name="dma_accuracy_safe">安全(穩定)</string>
<!-- Resolutions -->
<string name="resolution_quarter">0.25X (180p/270p)</string>

View file

@ -454,15 +454,13 @@
<string-array name="dmaAccuracyNames">
<item>@string/dma_accuracy_default</item>
<item>@string/dma_accuracy_normal</item>
<item>@string/dma_accuracy_high</item>
<item>@string/dma_accuracy_extreme</item>
<item>@string/dma_accuracy_unsafe</item>
<item>@string/dma_accuracy_safe</item>
</string-array>
<integer-array name="dmaAccuracyValues">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</integer-array>
<string-array name="appletEntries">

View file

@ -115,8 +115,8 @@
<string name="fast_cpu_time_description">Use Boost (1700MHz) to run at the Switch\'s highest native clock, or Fast (2000MHz) to run at 2x clock.</string>
<string name="memory_layout">Memory Layout</string>
<string name="memory_layout_description">(EXPERIMENTAL) Change the emulated memory layout. This setting will not increase performance, but may help with games utilizing high resolutions via mods. Do not use on phones with 8GB of RAM or less. Only works on the Dynarmic (JIT) backend.</string>
<string name="dma_accuracy">DMA Level</string>
<string name="dma_accuracy_description">Controls the DMA precision accuracy. Higher precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave it at Default.</string>
<string name="dma_accuracy">DMA Accuracy</string>
<string name="dma_accuracy_description">Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases. If unsure, leave this on Default.</string>
<!-- Shader Backend -->
<string name="shader_backend">Shader Backend</string>
@ -940,9 +940,8 @@
<!-- DMA Accuracy -->
<string name="dma_accuracy_default">Default</string>
<string name="dma_accuracy_normal">Normal</string>
<string name="dma_accuracy_high">High</string>
<string name="dma_accuracy_extreme">Extreme</string>
<string name="dma_accuracy_unsafe">Unsafe (fast)</string>
<string name="dma_accuracy_safe">Safe (stable)</string>
<!-- ASTC Decoding Method -->
<string name="accelerate_astc">ASTC Decoding Method</string>

View file

@ -598,12 +598,17 @@ public:
bool ClearBackingRegion(size_t physical_offset, size_t length) {
#ifdef __linux__
// Set MADV_REMOVE on backing map to destroy it instantly.
// This also deletes the area from the backing file.
int ret = madvise(backing_base + physical_offset, length, MADV_REMOVE);
ASSERT_MSG(ret == 0, "madvise failed: {}", strerror(errno));
return true;
// Only incur syscall cost IF memset would be slower (theshold = 16MiB)
// TODO(lizzie): Smarter way to dynamically get this threshold (broadwell != raptor lake) for example
if (length >= 2097152UL * 8) {
// Set MADV_REMOVE on backing map to destroy it instantly.
// This also deletes the area from the backing file.
int ret = madvise(backing_base + physical_offset, length, MADV_REMOVE);
ASSERT_MSG(ret == 0, "madvise failed: {}", strerror(errno));
return true;
} else {
return false;
}
#else
return false;
#endif

View file

@ -154,11 +154,19 @@ bool IsGPULevelHigh() {
values.current_gpu_accuracy == GpuAccuracy::High;
}
bool IsDMALevelDefault() {
return values.dma_accuracy.GetValue() == DmaAccuracy::Default;
}
bool IsDMALevelSafe() {
return values.dma_accuracy.GetValue() == DmaAccuracy::Safe;
}
bool IsFastmemEnabled() {
if (values.cpu_debug_mode) {
return static_cast<bool>(values.cpuopt_fastmem);
}
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) {
if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe) {
return static_cast<bool>(values.cpuopt_unsafe_host_mmu);
}
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__)

View file

@ -443,7 +443,7 @@ struct Values {
SwitchableSetting<DmaAccuracy, true> dma_accuracy{linkage,
DmaAccuracy::Default,
DmaAccuracy::Default,
DmaAccuracy::Extreme,
DmaAccuracy::Safe,
"dma_accuracy",
Category::RendererAdvanced,
Specialization::Default,
@ -783,6 +783,9 @@ void UpdateGPUAccuracy();
bool IsGPULevelExtreme();
bool IsGPULevelHigh();
bool IsDMALevelDefault();
bool IsDMALevelSafe();
bool IsFastmemEnabled();
void SetNceEnabled(bool is_64bit);
bool IsNceEnabled();

View file

@ -136,7 +136,7 @@ ENUM(ShaderBackend, Glsl, Glasm, SpirV);
ENUM(GpuAccuracy, Normal, High, Extreme);
ENUM(DmaAccuracy, Default, Normal, High, Extreme);
ENUM(DmaAccuracy, Default, Unsafe, Safe);
ENUM(CpuBackend, Dynarmic, Nce);

View file

@ -107,7 +107,6 @@ add_library(core STATIC
file_sys/fssystem/fssystem_nca_header.cpp
file_sys/fssystem/fssystem_nca_header.h
file_sys/fssystem/fssystem_nca_reader.cpp
file_sys/fssystem/fssystem_passthrough_storage.h
file_sys/fssystem/fssystem_pooled_buffer.cpp
file_sys/fssystem/fssystem_pooled_buffer.h
file_sys/fssystem/fssystem_sparse_storage.cpp

View file

@ -305,7 +305,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ArmDynarmic32::MakeJit(Common::PageTable* pa
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
}
// Paranoid mode for debugging optimizations
// Paranoia mode for debugging optimizations
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) {
config.unsafe_optimizations = false;
config.optimizations = Dynarmic::no_optimizations;

View file

@ -4,7 +4,6 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/settings.h"
#include "core/file_sys/errors.h"
#include "core/file_sys/fssystem/fssystem_bucket_tree.h"
#include "core/file_sys/fssystem/fssystem_bucket_tree_utils.h"

View file

@ -4,7 +4,6 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/settings.h"
#include "core/file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.h"
#include "core/file_sys/fssystem/fssystem_aes_ctr_storage.h"
#include "core/file_sys/fssystem/fssystem_aes_xts_storage.h"
@ -14,7 +13,6 @@
#include "core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.h"
#include "core/file_sys/fssystem/fssystem_indirect_storage.h"
#include "core/file_sys/fssystem/fssystem_integrity_romfs_storage.h"
#include "core/file_sys/fssystem/fssystem_passthrough_storage.h"
#include "core/file_sys/fssystem/fssystem_memory_resource_buffer_hold_storage.h"
#include "core/file_sys/fssystem/fssystem_nca_file_system_driver.h"
#include "core/file_sys/fssystem/fssystem_sparse_storage.h"

View file

@ -13,13 +13,11 @@ u8 NcaHeader::GetProperKeyGeneration() const {
}
bool NcaPatchInfo::HasIndirectTable() const {
static constexpr unsigned char BKTR[4] = {'B', 'K', 'T', 'R'};
return std::memcmp(indirect_header.data(), BKTR, sizeof(BKTR)) == 0;
return this->indirect_size != 0;
}
bool NcaPatchInfo::HasAesCtrExTable() const {
static constexpr unsigned char BKTR[4] = {'B', 'K', 'T', 'R'};
return std::memcmp(aes_ctr_ex_header.data(), BKTR, sizeof(BKTR)) == 0;
return this->aes_ctr_ex_size != 0;
}
} // namespace FileSys

View file

@ -1,32 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/file_sys/fssystem/fs_i_storage.h"
#include "core/file_sys/vfs/vfs.h"
namespace FileSys {
//TODO: No integrity verification.
class PassthroughStorage final : public IReadOnlyStorage {
YUZU_NON_COPYABLE(PassthroughStorage);
YUZU_NON_MOVEABLE(PassthroughStorage);
public:
explicit PassthroughStorage(VirtualFile base) : base_(std::move(base)) {}
~PassthroughStorage() override = default;
size_t Read(u8* buffer, size_t size, size_t offset) const override {
if (!base_ || size == 0)
return 0;
return base_->Read(buffer, size, offset);
}
size_t GetSize() const override {
return base_ ? base_->GetSize() : 0;
}
private:
VirtualFile base_{};
};
} // namespace FileSys

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -97,18 +100,18 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
slots[slot].needs_cleanup_on_release = false;
slots[slot].buffer_state = BufferState::Acquired;
// Mark tracked buffer history records as acquired
for (auto& buffer_history_record : core->buffer_history) {
if (buffer_history_record.frame_number == core->frame_counter) {
buffer_history_record.state = BufferState::Acquired;
break;
}
}
// TODO: for now, avoid resetting the fence, so that when we next return this
// slot to the producer, it will wait for the fence to pass. We should fix this
// by properly waiting for the fence in the BufferItemConsumer.
// slots[slot].fence = Fence::NoFence();
const auto target_frame_number = slots[slot].frame_number;
for (size_t i = 0; i < core->history.size(); i++) {
if (core->history[i].frame_number == target_frame_number) {
core->history[i].state = BufferState::Acquired;
break;
}
}
}
// If the buffer has previously been acquired by the consumer, set graphic_buffer to nullptr to

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -10,12 +13,19 @@
namespace Service::android {
BufferQueueCore::BufferQueueCore() {
history.resize(8);
};
BufferQueueCore::BufferQueueCore() = default;
BufferQueueCore::~BufferQueueCore() = default;
void BufferQueueCore::PushHistory(u64 frame_number, s64 queue_time, s64 presentation_time, BufferState state) {
buffer_history_pos = (buffer_history_pos + 1) % BUFFER_HISTORY_SIZE;
buffer_history[buffer_history_pos] = BufferHistoryInfo{
.frame_number = frame_number,
.queue_time = queue_time,
.presentation_time = presentation_time,
.state = state,
};
}
void BufferQueueCore::SignalDequeueCondition() {
dequeue_possible.store(true);
dequeue_condition.notify_all();
@ -47,7 +57,7 @@ s32 BufferQueueCore::GetMinMaxBufferCountLocked(bool async) const {
s32 BufferQueueCore::GetMaxBufferCountLocked(bool async) const {
const auto min_buffer_count = GetMinMaxBufferCountLocked(async);
auto max_buffer_count = (std::max)(default_max_buffer_count, min_buffer_count);
auto max_buffer_count = std::max(default_max_buffer_count, min_buffer_count);
if (override_max_buffer_count != 0) {
ASSERT(override_max_buffer_count >= min_buffer_count);

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -15,6 +18,7 @@
#include "core/hle/service/nvnflinger/buffer_item.h"
#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
#include "core/hle/service/nvnflinger/buffer_slot.h"
#include "core/hle/service/nvnflinger/pixel_format.h"
#include "core/hle/service/nvnflinger/status.h"
#include "core/hle/service/nvnflinger/window.h"
@ -23,22 +27,19 @@ namespace Service::android {
#ifdef _MSC_VER
#pragma pack(push, 1)
struct BufferHistoryInfo {
#elif defined(__GNUC__) || defined(__clang__)
struct __attribute__((packed)) BufferHistoryInfo {
#endif
struct BufferInfo {
u64 frame_number;
s64 queue_time;
s64 presentation_time{};
BufferState state{BufferState::Free};
}
#if defined(__GNUC__) || defined(__clang__)
__attribute__((packed))
#endif
;
s64 presentation_time;
BufferState state;
};
#ifdef _MSC_VER
#pragma pack(pop)
#endif
static_assert(sizeof(BufferInfo) == 0x1C,
"BufferInfo is an invalid size");
static_assert(sizeof(BufferHistoryInfo) == 0x1C, "BufferHistoryInfo must be 28 bytes");
class IConsumerListener;
class IProducerListener;
@ -49,10 +50,13 @@ class BufferQueueCore final {
public:
static constexpr s32 INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT;
static constexpr u32 BUFFER_HISTORY_SIZE = 8;
BufferQueueCore();
~BufferQueueCore();
void PushHistory(u64 frame_number, s64 queue_time, s64 presentation_time, BufferState state);
private:
void SignalDequeueCondition();
bool WaitForDequeueCondition(std::unique_lock<std::mutex>& lk);
@ -88,11 +92,11 @@ private:
const s32 max_acquired_buffer_count{}; // This is always zero on HOS
bool buffer_has_been_queued{};
u64 frame_counter{};
std::array<BufferHistoryInfo, BUFFER_HISTORY_SIZE> buffer_history{};
u32 buffer_history_pos{BUFFER_HISTORY_SIZE-1};
u32 transform_hint{};
bool is_allocating{};
mutable std::condition_variable_any is_allocating_condition;
std::vector<BufferInfo> history{8};
};
} // namespace Service::android

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -530,11 +533,6 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
item.is_droppable = core->dequeue_buffer_cannot_block || async;
item.swap_interval = swap_interval;
position = (position + 1) % 8;
core->history[position] = {.frame_number = core->frame_counter,
.queue_time = slots[slot].queue_time,
.state = BufferState::Queued};
sticky_transform = sticky_transform_;
if (core->queue.empty()) {
@ -551,6 +549,15 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
// mark it as freed
if (core->StillTracking(*front)) {
slots[front->slot].buffer_state = BufferState::Free;
// Mark tracked buffer history records as free
for (auto& buffer_history_record : core->buffer_history) {
if (buffer_history_record.frame_number == front->frame_number) {
buffer_history_record.state = BufferState::Free;
break;
}
}
// Reset the frame number of the freed buffer so that it is the first in line to
// be dequeued again
slots[front->slot].frame_number = 0;
@ -564,6 +571,7 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
}
}
core->PushHistory(core->frame_counter, slots[slot].queue_time, slots[slot].presentation_time, BufferState::Queued);
core->buffer_has_been_queued = true;
core->SignalDequeueCondition();
output->Inflate(core->default_width, core->default_height, core->transform_hint,
@ -938,33 +946,46 @@ void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
break;
}
case TransactionId::GetBufferHistory: {
LOG_WARNING(Service_Nvnflinger, "called, transaction=GetBufferHistory");
LOG_DEBUG(Service_Nvnflinger, "called, transaction=GetBufferHistory");
std::scoped_lock lock{core->mutex};
auto buffer_history_count = (std::min)(parcel_in.Read<s32>(), (s32)core->history.size());
if (buffer_history_count <= 0) {
const s32 request = parcel_in.Read<s32>();
if (request <= 0) {
parcel_out.Write(Status::BadValue);
parcel_out.Write<s32>(0);
status = Status::None;
break;
}
auto info = new BufferInfo[buffer_history_count];
auto pos = position;
for (int i = 0; i < buffer_history_count; i++) {
info[i] = core->history[(pos - i) % core->history.size()];
LOG_WARNING(Service_Nvnflinger, "frame_number={}, state={}",
core->history[(pos - i) % core->history.size()].frame_number,
(u32)core->history[(pos - i) % core->history.size()].state);
pos--;
constexpr u32 history_max = BufferQueueCore::BUFFER_HISTORY_SIZE;
std::array<BufferHistoryInfo, history_max> buffer_history_snapshot{};
s32 valid_index{};
{
std::scoped_lock lk(core->mutex);
const u32 current_history_pos = core->buffer_history_pos;
u32 index_reversed{};
for (u32 i = 0; i < history_max; ++i) {
// Wrap values backwards e.g. 7, 6, 5, etc. in the range of 0-7
index_reversed = (current_history_pos + history_max - i) % history_max;
const auto& current_history_buffer = core->buffer_history[index_reversed];
// Here we use the frame number as a terminator.
// Because a buffer without frame_number is not considered complete
if (current_history_buffer.frame_number == 0) {
break;
}
buffer_history_snapshot[valid_index] = current_history_buffer;
++valid_index;
}
}
const s32 limit = std::min(request, valid_index);
parcel_out.Write(Status::NoError);
parcel_out.Write(buffer_history_count);
parcel_out.WriteFlattenedObject<BufferInfo>(info);
status = Status::None;
parcel_out.Write<s32>(limit);
for (s32 i = 0; i < limit; ++i) {
parcel_out.Write(buffer_history_snapshot[i]);
}
break;
}
default:
@ -972,9 +993,7 @@ void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
break;
}
if (status != Status::None) {
parcel_out.Write(status);
}
parcel_out.Write(status);
const auto serialized = parcel_out.Serialize();
std::memcpy(parcel_reply.data(), serialized.data(),

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project
// SPDX-License-Identifier: GPL-3.0-or-later
@ -15,7 +18,7 @@ namespace Service::android {
class GraphicBuffer;
enum class BufferState : s32 {
enum class BufferState : u32 {
Free = 0,
Dequeued = 1,
Queued = 2,

View file

@ -6,8 +6,13 @@
* SPDX-License-Identifier: 0BSD
*/
#include "dynarmic/backend/exception_handler.h"
#include <cstring>
#include <functional>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <optional>
#include <sys/mman.h>
#ifdef __APPLE__
# include <signal.h>
# include <sys/ucontext.h>
@ -21,17 +26,10 @@
# endif
#endif
#include <cstring>
#include <functional>
#include <memory>
#include <mutex>
#include <optional>
#include <vector>
#include <ankerl/unordered_dense.h>
#include "dynarmic/common/assert.h"
#include <mcl/bit_cast.hpp>
#include "dynarmic/backend/exception_handler.h"
#include "dynarmic/common/common_types.h"
#if defined(MCL_ARCHITECTURE_X86_64)
# include "dynarmic/backend/x64/block_of_code.h"
#elif defined(MCL_ARCHITECTURE_ARM64)
@ -43,42 +41,80 @@
#else
# error "Invalid architecture"
#endif
#include <mcl/bit_cast.hpp>
namespace Dynarmic::Backend {
namespace {
struct CodeBlockInfo {
u64 code_begin, code_end;
u64 size;
std::function<FakeCall(u64)> cb;
};
class SigHandler {
public:
SigHandler();
~SigHandler();
void AddCodeBlock(CodeBlockInfo info);
void RemoveCodeBlock(u64 host_pc);
bool SupportsFastmem() const { return supports_fast_mem; }
private:
auto FindCodeBlockInfo(u64 host_pc) {
return std::find_if(code_block_infos.begin(), code_block_infos.end(), [&](const auto& x) { return x.code_begin <= host_pc && x.code_end > host_pc; });
auto FindCodeBlockInfo(u64 offset) noexcept {
return std::find_if(code_block_infos.begin(), code_block_infos.end(), [&](auto const& e) {
return e.first <= offset && e.first + e.second.size > offset;
});
}
static void SigAction(int sig, siginfo_t* info, void* raw_context);
bool supports_fast_mem = true;
void* signal_stack_memory = nullptr;
std::vector<CodeBlockInfo> code_block_infos;
std::mutex code_block_infos_mutex;
ankerl::unordered_dense::map<u64, CodeBlockInfo> code_block_infos;
std::shared_mutex code_block_infos_mutex;
struct sigaction old_sa_segv;
struct sigaction old_sa_bus;
std::size_t signal_stack_size;
public:
SigHandler() noexcept {
signal_stack_size = std::max<size_t>(SIGSTKSZ, 2 * 1024 * 1024);
signal_stack_memory = mmap(nullptr, signal_stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
static void SigAction(int sig, siginfo_t* info, void* raw_context);
stack_t signal_stack{};
signal_stack.ss_sp = signal_stack_memory;
signal_stack.ss_size = signal_stack_size;
signal_stack.ss_flags = 0;
if (sigaltstack(&signal_stack, nullptr) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: init failure at sigaltstack\n");
supports_fast_mem = false;
return;
}
struct sigaction sa{};
sa.sa_handler = nullptr;
sa.sa_sigaction = &SigHandler::SigAction;
sa.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGSEGV, &sa, &old_sa_segv) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGSEGV handler\n");
supports_fast_mem = false;
return;
}
#ifdef __APPLE__
if (sigaction(SIGBUS, &sa, &old_sa_bus) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGBUS handler\n");
supports_fast_mem = false;
return;
}
#endif
}
~SigHandler() noexcept {
munmap(signal_stack_memory, signal_stack_size);
}
void AddCodeBlock(u64 offset, CodeBlockInfo cbi) noexcept {
std::unique_lock guard(code_block_infos_mutex);
code_block_infos.insert_or_assign(offset, cbi);
}
void RemoveCodeBlock(u64 offset) noexcept {
std::unique_lock guard(code_block_infos_mutex);
code_block_infos.erase(offset);
}
bool SupportsFastmem() const noexcept { return supports_fast_mem; }
};
std::mutex handler_lock;
@ -91,64 +127,8 @@ void RegisterHandler() {
}
}
SigHandler::SigHandler() {
const size_t signal_stack_size = std::max<size_t>(SIGSTKSZ, 2 * 1024 * 1024);
signal_stack_memory = std::malloc(signal_stack_size);
stack_t signal_stack;
signal_stack.ss_sp = signal_stack_memory;
signal_stack.ss_size = signal_stack_size;
signal_stack.ss_flags = 0;
if (sigaltstack(&signal_stack, nullptr) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: init failure at sigaltstack\n");
supports_fast_mem = false;
return;
}
struct sigaction sa;
sa.sa_handler = nullptr;
sa.sa_sigaction = &SigHandler::SigAction;
sa.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGSEGV, &sa, &old_sa_segv) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGSEGV handler\n");
supports_fast_mem = false;
return;
}
#ifdef __APPLE__
if (sigaction(SIGBUS, &sa, &old_sa_bus) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGBUS handler\n");
supports_fast_mem = false;
return;
}
#endif
}
SigHandler::~SigHandler() {
std::free(signal_stack_memory);
}
void SigHandler::AddCodeBlock(CodeBlockInfo cbi) {
std::lock_guard<std::mutex> guard(code_block_infos_mutex);
if (auto iter = FindCodeBlockInfo(cbi.code_begin); iter != code_block_infos.end()) {
code_block_infos.erase(iter);
}
code_block_infos.push_back(cbi);
}
void SigHandler::RemoveCodeBlock(u64 host_pc) {
std::lock_guard<std::mutex> guard(code_block_infos_mutex);
const auto iter = FindCodeBlockInfo(host_pc);
if (iter == code_block_infos.end()) {
return;
}
code_block_infos.erase(iter);
}
void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
ASSERT(sig == SIGSEGV || sig == SIGBUS);
DEBUG_ASSERT(sig == SIGSEGV || sig == SIGBUS);
#ifndef MCL_ARCHITECTURE_RISCV
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context);
#ifndef __OpenBSD__
@ -157,7 +137,6 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
#endif
#if defined(MCL_ARCHITECTURE_X86_64)
# if defined(__APPLE__)
# define CTX_RIP (mctx->__ss.__rip)
# define CTX_RSP (mctx->__ss.__rsp)
@ -179,26 +158,18 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
# else
# error "Unknown platform"
# endif
{
std::lock_guard<std::mutex> guard(sig_handler->code_block_infos_mutex);
const auto iter = sig_handler->FindCodeBlockInfo(CTX_RIP);
if (iter != sig_handler->code_block_infos.end()) {
FakeCall fc = iter->cb(CTX_RIP);
std::shared_lock guard(sig_handler->code_block_infos_mutex);
if (auto const iter = sig_handler->FindCodeBlockInfo(CTX_RIP); iter != sig_handler->code_block_infos.end()) {
FakeCall fc = iter->second.cb(CTX_RIP);
CTX_RSP -= sizeof(u64);
*mcl::bit_cast<u64*>(CTX_RSP) = fc.ret_rip;
CTX_RIP = fc.call_rip;
return;
}
}
fmt::print(stderr, "Unhandled {} at rip {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_RIP);
#elif defined(MCL_ARCHITECTURE_ARM64)
# if defined(__APPLE__)
# define CTX_PC (mctx->__ss.__pc)
# define CTX_SP (mctx->__ss.__sp)
@ -240,30 +211,19 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
# else
# error "Unknown platform"
# endif
{
std::lock_guard<std::mutex> guard(sig_handler->code_block_infos_mutex);
const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC);
if (iter != sig_handler->code_block_infos.end()) {
FakeCall fc = iter->cb(CTX_PC);
std::shared_lock guard(sig_handler->code_block_infos_mutex);
if (const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC); iter != sig_handler->code_block_infos.end()) {
FakeCall fc = iter->second.cb(CTX_PC);
CTX_PC = fc.call_pc;
return;
}
}
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
#elif defined(MCL_ARCHITECTURE_RISCV)
ASSERT_FALSE("Unimplemented");
#else
# error "Invalid architecture"
#endif
struct sigaction* retry_sa = sig == SIGSEGV ? &sig_handler->old_sa_segv : &sig_handler->old_sa_bus;
@ -284,26 +244,26 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
} // anonymous namespace
struct ExceptionHandler::Impl final {
Impl(u64 code_begin_, u64 code_end_)
: code_begin(code_begin_)
, code_end(code_end_) {
Impl(u64 offset_, u64 size_)
: offset(offset_)
, size(size_) {
RegisterHandler();
}
void SetCallback(std::function<FakeCall(u64)> cb) {
CodeBlockInfo cbi;
cbi.code_begin = code_begin;
cbi.code_end = code_end;
cbi.cb = cb;
sig_handler->AddCodeBlock(cbi);
sig_handler->AddCodeBlock(offset, CodeBlockInfo{
.size = size,
.cb = cb
});
}
~Impl() {
sig_handler->RemoveCodeBlock(code_begin);
sig_handler->RemoveCodeBlock(offset);
}
private:
u64 code_begin, code_end;
u64 offset;
u64 size;
};
ExceptionHandler::ExceptionHandler() = default;
@ -311,28 +271,22 @@ ExceptionHandler::~ExceptionHandler() = default;
#if defined(MCL_ARCHITECTURE_X86_64)
void ExceptionHandler::Register(X64::BlockOfCode& code) {
const u64 code_begin = mcl::bit_cast<u64>(code.getCode());
const u64 code_end = code_begin + code.GetTotalCodeSize();
impl = std::make_unique<Impl>(code_begin, code_end);
impl = std::make_unique<Impl>(mcl::bit_cast<u64>(code.getCode()), code.GetTotalCodeSize());
}
#elif defined(MCL_ARCHITECTURE_ARM64)
void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) {
const u64 code_begin = mcl::bit_cast<u64>(mem.ptr());
const u64 code_end = code_begin + size;
impl = std::make_unique<Impl>(code_begin, code_end);
impl = std::make_unique<Impl>(mcl::bit_cast<u64>(mem.ptr()), size);
}
#elif defined(MCL_ARCHITECTURE_RISCV)
void ExceptionHandler::Register(RV64::CodeBlock& mem, std::size_t size) {
const u64 code_begin = mcl::bit_cast<u64>(mem.ptr<u64>());
const u64 code_end = code_begin + size;
impl = std::make_unique<Impl>(code_begin, code_end);
impl = std::make_unique<Impl>(mcl::bit_cast<u64>(mem.ptr<u64>()), size);
}
#else
# error "Invalid architecture"
#endif
bool ExceptionHandler::SupportsFastmem() const noexcept {
return static_cast<bool>(impl) && sig_handler->SupportsFastmem();
return bool(impl) && sig_handler->SupportsFastmem();
}
void ExceptionHandler::SetFastmemCallback(std::function<FakeCall(u64)> cb) {

View file

@ -288,16 +288,14 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
"and safe to set at 16x on most GPUs."));
INSERT(Settings,
gpu_accuracy,
tr("GPU Level:"),
tr("GPU Accuracy:"),
tr("Controls the GPU emulation accuracy.\nMost games render fine with Normal, but High is still "
"required for some.\nParticles tend to only render correctly with High "
"accuracy.\nExtreme should only be used for debugging.\nThis option can "
"be changed while playing.\nSome games may require booting on high to render "
"properly."));
"accuracy.\nExtreme should only be used as a last resort."));
INSERT(Settings,
dma_accuracy,
tr("DMA Level:"),
tr("Controls the DMA precision accuracy. Higher precision can fix issues in some games, but it can also impact performance in some cases.\nIf unsure, leave it at Default."));
tr("DMA Accuracy:"),
tr("Controls the DMA precision accuracy. Safe precision can fix issues in some games, but it can also impact performance in some cases.\nIf unsure, leave this on Default."));
INSERT(Settings,
use_asynchronous_shaders,
tr("Use asynchronous shader building (Hack)"),
@ -529,9 +527,8 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
translations->insert({Settings::EnumMetadata<Settings::DmaAccuracy>::Index(),
{
PAIR(DmaAccuracy, Default, tr("Default")),
PAIR(DmaAccuracy, Normal, tr("Normal")),
PAIR(DmaAccuracy, High, tr("High")),
PAIR(DmaAccuracy, Extreme, tr("Extreme")),
PAIR(DmaAccuracy, Unsafe, tr("Unsafe (fast)")),
PAIR(DmaAccuracy, Safe, tr("Safe (stable)")),
}});
translations->insert(
{Settings::EnumMetadata<Settings::CpuAccuracy>::Index(),

View file

@ -7,7 +7,9 @@
#include <algorithm>
#include <bit>
#include <optional>
#include <unordered_map>
#include <tuple>
#include <limits>
#include <boost/container/small_vector.hpp>
#include "shader_recompiler/environment.h"
@ -177,6 +179,93 @@ bool IsBindless(const IR::Inst& inst) {
bool IsTextureInstruction(const IR::Inst& inst) {
return IndexedInstruction(inst) != IR::Opcode::Void;
}
// Per-pass caches
struct CbufWordKey {
u32 index;
u32 offset;
bool operator==(const CbufWordKey& o) const noexcept {
return index == o.index && offset == o.offset;
}
};
struct CbufWordKeyHash {
size_t operator()(const CbufWordKey& k) const noexcept {
return (static_cast<size_t>(k.index) << 32) ^ k.offset;
}
};
struct HandleKey {
u32 index, offset, shift_left;
u32 sec_index, sec_offset, sec_shift_left;
bool has_secondary;
bool operator==(const HandleKey& o) const noexcept {
return std::tie(index, offset, shift_left,
sec_index, sec_offset, sec_shift_left, has_secondary)
== std::tie(o.index, o.offset, o.shift_left,
o.sec_index, o.sec_offset, o.sec_shift_left, o.has_secondary);
}
};
struct HandleKeyHash {
size_t operator()(const HandleKey& k) const noexcept {
size_t h = (static_cast<size_t>(k.index) << 32) ^ k.offset;
h ^= (static_cast<size_t>(k.shift_left) << 1);
h ^= (static_cast<size_t>(k.sec_index) << 33) ^ (static_cast<size_t>(k.sec_offset) << 2);
h ^= (static_cast<size_t>(k.sec_shift_left) << 3);
h ^= k.has_secondary ? 0x9e3779b97f4a7c15ULL : 0ULL;
return h;
}
};
// Thread-local(may implement multithreading in future *wink*)
thread_local std::unordered_map<CbufWordKey, u32, CbufWordKeyHash> g_cbuf_word_cache;
thread_local std::unordered_map<HandleKey, u32, HandleKeyHash> g_handle_cache;
thread_local std::unordered_map<const IR::Inst*, ConstBufferAddr> g_track_cache;
static inline u32 ReadCbufCached(Environment& env, u32 index, u32 offset) {
const CbufWordKey k{index, offset};
if (auto it = g_cbuf_word_cache.find(k); it != g_cbuf_word_cache.end()) return it->second;
const u32 v = env.ReadCbufValue(index, offset);
g_cbuf_word_cache.emplace(k, v);
return v;
}
static inline u32 GetTextureHandleCached(Environment& env, const ConstBufferAddr& cbuf) {
const u32 sec_idx = cbuf.has_secondary ? cbuf.secondary_index : cbuf.index;
const u32 sec_off = cbuf.has_secondary ? cbuf.secondary_offset : cbuf.offset;
const HandleKey hk{cbuf.index, cbuf.offset, cbuf.shift_left,
sec_idx, sec_off, cbuf.secondary_shift_left, cbuf.has_secondary};
if (auto it = g_handle_cache.find(hk); it != g_handle_cache.end()) return it->second;
const u32 lhs = ReadCbufCached(env, cbuf.index, cbuf.offset) << cbuf.shift_left;
const u32 rhs = ReadCbufCached(env, sec_idx, sec_off) << cbuf.secondary_shift_left;
const u32 handle = lhs | rhs;
g_handle_cache.emplace(hk, handle);
return handle;
}
// Cached variants of existing helpers
static inline TextureType ReadTextureTypeCached(Environment& env, const ConstBufferAddr& cbuf) {
return env.ReadTextureType(GetTextureHandleCached(env, cbuf));
}
static inline TexturePixelFormat ReadTexturePixelFormatCached(Environment& env,
const ConstBufferAddr& cbuf) {
return env.ReadTexturePixelFormat(GetTextureHandleCached(env, cbuf));
}
static inline bool IsTexturePixelFormatIntegerCached(Environment& env,
const ConstBufferAddr& cbuf) {
return env.IsTexturePixelFormatInteger(GetTextureHandleCached(env, cbuf));
}
std::optional<ConstBufferAddr> Track(const IR::Value& value, Environment& env);
static inline std::optional<ConstBufferAddr> TrackCached(const IR::Value& v, Environment& env) {
if (const IR::Inst* key = v.InstRecursive()) {
if (auto it = g_track_cache.find(key); it != g_track_cache.end()) return it->second;
auto found = Track(v, env);
if (found) g_track_cache.emplace(key, *found);
return found;
}
return Track(v, env);
}
std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst, Environment& env);
@ -203,7 +292,7 @@ std::optional<u32> TryGetConstant(IR::Value& value, Environment& env) {
return std::nullopt;
}
const auto offset_number = offset.U32();
return env.ReadCbufValue(index_number, offset_number);
return ReadCbufCached(env, index_number, offset_number);
}
std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst, Environment& env) {
@ -211,8 +300,8 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst, Environme
default:
return std::nullopt;
case IR::Opcode::BitwiseOr32: {
std::optional lhs{Track(inst->Arg(0), env)};
std::optional rhs{Track(inst->Arg(1), env)};
std::optional lhs{TrackCached(inst->Arg(0), env)};
std::optional rhs{TrackCached(inst->Arg(1), env)};
if (!lhs || !rhs) {
return std::nullopt;
}
@ -242,7 +331,7 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst, Environme
if (!shift.IsImmediate()) {
return std::nullopt;
}
std::optional lhs{Track(inst->Arg(0), env)};
std::optional lhs{TrackCached(inst->Arg(0), env)};
if (lhs) {
lhs->shift_left = shift.U32();
}
@ -271,7 +360,7 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst, Environme
return std::nullopt;
} while (false);
}
std::optional lhs{Track(op1, env)};
std::optional lhs{TrackCached(op1, env)};
if (lhs) {
lhs->shift_left = static_cast<u32>(std::countr_zero(op2.U32()));
}
@ -346,7 +435,7 @@ static ConstBufferAddr last_valid_addr = ConstBufferAddr{
TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
ConstBufferAddr addr;
if (IsBindless(inst)) {
const std::optional<ConstBufferAddr> track_addr{Track(inst.Arg(0), env)};
const std::optional<ConstBufferAddr> track_addr{TrackCached(inst.Arg(0), env)};
if (!track_addr) {
//throw NotImplementedException("Failed to track bindless texture constant buffer");
@ -384,15 +473,15 @@ u32 GetTextureHandle(Environment& env, const ConstBufferAddr& cbuf) {
return lhs_raw | rhs_raw;
}
TextureType ReadTextureType(Environment& env, const ConstBufferAddr& cbuf) {
[[maybe_unused]]TextureType ReadTextureType(Environment& env, const ConstBufferAddr& cbuf) {
return env.ReadTextureType(GetTextureHandle(env, cbuf));
}
TexturePixelFormat ReadTexturePixelFormat(Environment& env, const ConstBufferAddr& cbuf) {
[[maybe_unused]]TexturePixelFormat ReadTexturePixelFormat(Environment& env, const ConstBufferAddr& cbuf) {
return env.ReadTexturePixelFormat(GetTextureHandle(env, cbuf));
}
bool IsTexturePixelFormatInteger(Environment& env, const ConstBufferAddr& cbuf) {
[[maybe_unused]]bool IsTexturePixelFormatInteger(Environment& env, const ConstBufferAddr& cbuf) {
return env.IsTexturePixelFormatInteger(GetTextureHandle(env, cbuf));
}
@ -543,6 +632,10 @@ void PatchTexelFetch(IR::Block& block, IR::Inst& inst, TexturePixelFormat pixel_
} // Anonymous namespace
void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo& host_info) {
// reset per-pass caches
g_cbuf_word_cache.clear();
g_handle_cache.clear();
g_track_cache.clear();
TextureInstVector to_replace;
for (IR::Block* const block : program.post_order_blocks) {
for (IR::Inst& inst : block->Instructions()) {
@ -553,11 +646,9 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
}
}
// Sort instructions to visit textures by constant buffer index, then by offset
std::ranges::sort(to_replace, [](const auto& lhs, const auto& rhs) {
return lhs.cbuf.offset < rhs.cbuf.offset;
});
std::stable_sort(to_replace.begin(), to_replace.end(), [](const auto& lhs, const auto& rhs) {
return lhs.cbuf.index < rhs.cbuf.index;
std::ranges::sort(to_replace, [](const auto& a, const auto& b) {
if (a.cbuf.index != b.cbuf.index) return a.cbuf.index < b.cbuf.index;
return a.cbuf.offset < b.cbuf.offset;
});
Descriptors descriptors{
program.info.texture_buffer_descriptors,
@ -575,14 +666,14 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
bool is_multisample{false};
switch (inst->GetOpcode()) {
case IR::Opcode::ImageQueryDimensions:
flags.type.Assign(ReadTextureType(env, cbuf));
flags.type.Assign(ReadTextureTypeCached(env, cbuf));
inst->SetFlags(flags);
break;
case IR::Opcode::ImageSampleImplicitLod:
if (flags.type != TextureType::Color2D) {
break;
}
if (ReadTextureType(env, cbuf) == TextureType::Color2DRect) {
if (ReadTextureTypeCached(env, cbuf) == TextureType::Color2DRect) {
PatchImageSampleImplicitLod(*texture_inst.block, *texture_inst.inst);
}
break;
@ -596,7 +687,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
if (flags.type != TextureType::Color1D) {
break;
}
if (ReadTextureType(env, cbuf) == TextureType::Buffer) {
if (ReadTextureTypeCached(env, cbuf) == TextureType::Buffer) {
// Replace with the bound texture type only when it's a texture buffer
// If the instruction is 1D and the bound type is 2D, don't change the code and let
// the rasterizer robustness handle it
@ -627,7 +718,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
}
const bool is_written{inst->GetOpcode() != IR::Opcode::ImageRead};
const bool is_read{inst->GetOpcode() != IR::Opcode::ImageWrite};
const bool is_integer{IsTexturePixelFormatInteger(env, cbuf)};
const bool is_integer{IsTexturePixelFormatIntegerCached(env, cbuf)};
if (flags.type == TextureType::Buffer) {
index = descriptors.Add(ImageBufferDescriptor{
.format = flags.image_format,
@ -691,16 +782,16 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo
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(std::countr_zero(DESCRIPTOR_SIZE))};
inst->SetArg(0, ir.UMin(ir.ShiftRightArithmetic(cbuf.dynamic_offset, shift),
ir.Imm32(DESCRIPTOR_SIZE - 1)));
const IR::U32 shift{ir.Imm32(DESCRIPTOR_SIZE_SHIFT)};
inst->SetArg(0, ir.UMin(ir.ShiftRightLogical(cbuf.dynamic_offset, shift),
ir.Imm32(DESCRIPTOR_SIZE - 1)));
} else {
inst->SetArg(0, IR::Value{});
}
if (!host_info.support_snorm_render_buffer && inst->GetOpcode() == IR::Opcode::ImageFetch &&
flags.type == TextureType::Buffer) {
const auto pixel_format = ReadTexturePixelFormat(env, cbuf);
const auto pixel_format = ReadTexturePixelFormatCached(env, cbuf);
if (IsPixelFormatSNorm(pixel_format)) {
PatchTexelFetch(*texture_inst.block, *texture_inst.inst, pixel_format);
}

View file

@ -102,23 +102,10 @@ bool DmaPusher::Step() {
ProcessCommands(headers);
};
const Settings::DmaAccuracy accuracy = Settings::values.dma_accuracy.GetValue();
const bool use_gpu_accuracy = accuracy == Settings::DmaAccuracy::Default;
const bool use_safe = Settings::IsDMALevelDefault() ? Settings::IsGPULevelHigh() : Settings::IsDMALevelSafe();
// reduces eye bleeding but also macros are dumb so idk
#define CHECK_LEVEL(level) use_gpu_accuracy ? Settings::IsGPULevel##level() : accuracy == Settings::DmaAccuracy::level;
const bool force_safe = CHECK_LEVEL(Extreme)
const bool unsafe_compute = CHECK_LEVEL(High)
#undef CHECK_LEVEL
if (force_safe) {
if (use_safe) {
safe_process();
} else if (unsafe_compute) {
if (dma_state.method >= MacroRegistersStart) {
unsafe_process();
} else {
safe_process();
}
} else {
unsafe_process();
}

View file

@ -49,6 +49,9 @@ namespace Vulkan {
}
[[nodiscard]] VkMemoryPropertyFlags MemoryUsagePreferredVmaFlags(MemoryUsage usage) {
if (usage == MemoryUsage::Download) {
return VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
}
return usage != MemoryUsage::DeviceLocal ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
: VkMemoryPropertyFlagBits{};
}

View file

@ -1,6 +1,6 @@
#!/bin/bash -e
# SPDX-FileCopyrightText: 2025 Eden Emulator Project
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2025 crueter
@ -8,4 +8,4 @@
LIBS=$(find . externals src/qt_common src/dynarmic -maxdepth 2 -name cpmfile.json -exec jq -j 'keys_unsorted | join(" ")' {} \; -printf " ")
tools/cpm-fetch.sh $LIBS
tools/cpm-fetch.sh "$LIBS"

View file

@ -1,6 +1,6 @@
#!/bin/bash -e
# SPDX-FileCopyrightText: 2025 Eden Emulator Project
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2025 crueter
@ -8,7 +8,7 @@
[ -z "$CPM_SOURCE_CACHE" ] && CPM_SOURCE_CACHE=$PWD/.cache/cpm
mkdir -p $CPM_SOURCE_CACHE
mkdir -p "$CPM_SOURCE_CACHE"
ROOTDIR="$PWD"
@ -25,7 +25,7 @@ download_package() {
curl "$DOWNLOAD" -sS -L -o "$OUTFILE"
ACTUAL_HASH=$(${HASH_ALGO}sum "$OUTFILE" | cut -d" " -f1)
ACTUAL_HASH=$("${HASH_ALGO}"sum "$OUTFILE" | cut -d" " -f1)
[ "$ACTUAL_HASH" != "$HASH" ] && echo "$FILENAME did not match expected hash; expected $HASH but got $ACTUAL_HASH" && exit 1
mkdir -p "$OUTDIR"
@ -46,10 +46,10 @@ download_package() {
# basically if only one real item exists at the top we just move everything from there
# since github and some vendors hate me
DIRS=$(find -maxdepth 1 -type d -o -type f)
DIRS=$(find . -maxdepth 1 -type d -o -type f)
# thanks gnu
if [ $(wc -l <<< "$DIRS") -eq 2 ]; then
if [ "$(wc -l <<< "$DIRS")" -eq 2 ]; then
SUBDIR=$(find . -maxdepth 1 -type d -not -name ".")
mv "$SUBDIR"/* .
mv "$SUBDIR"/.* . 2>/dev/null || true
@ -59,7 +59,7 @@ download_package() {
if grep -e "patches" <<< "$JSON" > /dev/null; then
PATCHES=$(jq -r '.patches | join(" ")' <<< "$JSON")
for patch in $PATCHES; do
patch --binary -p1 < "$ROOTDIR"/.patch/$package/$patch
patch --binary -p1 < "$ROOTDIR"/.patch/"$package"/"$patch"
done
fi
@ -102,7 +102,7 @@ ci_package() {
done
}
for package in $@
for package in "$@"
do
# prepare for cancer
# TODO(crueter): Fetch json once?
@ -145,12 +145,11 @@ do
fi
TAG=$(jq -r ".tag" <<< "$JSON")
TAG=$(sed "s/%VERSION%/$VERSION_REPLACE/" <<< $TAG)
TAG="${TAG//%VERSION%/$VERSION_REPLACE}"
ARTIFACT=$(jq -r ".artifact" <<< "$JSON")
ARTIFACT=$(sed "s/%VERSION%/$VERSION_REPLACE/" <<< $ARTIFACT)
ARTIFACT=$(sed "s/%TAG%/$TAG/" <<< $ARTIFACT)
ARTIFACT="${ARTIFACT//%VERSION%/$VERSION_REPLACE}"
ARTIFACT="${ARTIFACT//%TAG%/$TAG}"
if [ "$URL" != "null" ]; then
DOWNLOAD="$URL"
@ -219,4 +218,4 @@ do
download_package
done
rm -rf $TMP
rm -rf "$TMP"

View file

@ -1,4 +1,7 @@
#!/bin/sh
SUM=`wget -q https://github.com/$1/archive/$2.zip -O - | sha512sum`
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
SUM=$(wget -q https://github.com/"$1"/archive/"$2".zip -O - | sha512sum)
echo "$SUM" | cut -d " " -f1

View file

@ -1,8 +0,0 @@
#!/bin/bash -ex
# SPDX-FileCopyrightText: 2024 yuzu Emulator Project
# SPDX-License-Identifier: MIT
git submodule sync
git submodule foreach --recursive git reset --hard
git submodule update --init --recursive

View file

@ -1,4 +1,7 @@
#!/bin/sh
SUM=`wget -q $1 -O - | sha512sum`
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
SUM=$(wget -q "$1" -O - | sha512sum)
echo "$SUM" | cut -d " " -f1