mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-03 11:13:54 +00:00
Compare commits
83 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e46c19391d | |||
| 3d453e6236 | |||
| 9392ccf124 | |||
| 16b9b5aa0c | |||
| 2df4744b53 | |||
| faf82ccdd7 | |||
| 8f18e82931 | |||
| 7102ff8ecb | |||
| 385b844e2a | |||
| 518f571fcf | |||
| e0d4318042 | |||
| 06ac01adb0 | |||
| a6d49872a1 | |||
| b0b4817162 | |||
| 9f776cfca7 | |||
| 5b1613087c | |||
| b22a796f4b | |||
| 04cfc60756 | |||
| 6a3ff818e0 | |||
| 22b51d0c61 | |||
| 78ce48e4ca | |||
| 9510516e68 | |||
| 33ae95f4ae | |||
| 1cd118eccc | |||
| 4bf30b41a6 | |||
| 6390edb76d | |||
| f0ba93d75f | |||
| 68ff82679f | |||
| 543d4dfc8e | |||
| e3be392b8a | |||
| b754fcc49c | |||
| a4c37b5117 | |||
| 8206c7abac | |||
| faacc62b10 | |||
| b0a01ca629 | |||
| 945d5c373b | |||
| cb04b133ea | |||
| ff3de66bab | |||
| 3ce788b09c | |||
| 2a1b9278b9 | |||
| 842b5e0b3a | |||
| 2f83399798 | |||
| 2e52ca5753 | |||
| 69cd5ee0d1 | |||
| 1f0605c35d | |||
| b9c28ef6a1 | |||
| 809a61f600 | |||
| c7b24bad1a | |||
| 4244a6418d | |||
| 26044e18e1 | |||
| 04d08f0cf1 | |||
| 2bf037c7bb | |||
| f6668ef01b | |||
| 20a775ed08 | |||
| 3379556d89 | |||
| 8e687924b8 | |||
| d3e8c5e977 | |||
| 95e67e6533 | |||
| bdd1785b04 | |||
| f9e5ac191e | |||
| f3a674c064 | |||
| 4aa35bc835 | |||
| 894f2544a0 | |||
| ceffda663c | |||
| 27e7fa10d9 | |||
| d3bd4f42cf | |||
| 5a8fb951dd | |||
| 27942142cf | |||
| db647f9a40 | |||
| 35aeb0cf55 | |||
| 3423d3c6a5 | |||
| 607bc18ad4 | |||
| 2000fdfb7b | |||
| dc95cd09ee | |||
| e7a931d06b | |||
| 8648c27cbb | |||
| def76946f0 | |||
| 13d39f39aa | |||
| 7731b5bc86 | |||
| c4ab2f6b9e | |||
| dd12266c26 | |||
| a3d32a18b8 | |||
| c0ffc900cd |
@@ -1,9 +1,9 @@
|
|||||||
name: tx-pull
|
name: tx-pull
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# tuesday, saturday at 2pm
|
# monday at 4pm
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 14 * * 2,6'
|
- cron: '0 16 * * 1'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: File a bug report
|
|||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: Tech support does not belong here. You should only file an issue here if you think you have experienced an actual bug with yuzu.
|
value: Tech support does not belong here. You should only file an issue here if you think you have experienced an actual bug with Eden.
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
attributes:
|
attributes:
|
||||||
label: Is there an existing issue for this?
|
label: Is there an existing issue for this?
|
||||||
@@ -43,7 +43,7 @@ body:
|
|||||||
id: log
|
id: log
|
||||||
attributes:
|
attributes:
|
||||||
label: Log File
|
label: Log File
|
||||||
description: A log file will help our developers to better diagnose and fix the issue. Instructions can be found [here](https://yuzu-emu.org/help/reference/log-files).
|
description: A log file will help our developers to better diagnose and fix the issue. Instructions can be found [here](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/HowToAccessLogs.md).
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ labels: "request"
|
|||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: Tech support does not belong here. You should only file an issue here if you are requesting a feature you believe would make yuzu better.
|
value: Tech support does not belong here. You should only file an issue here if you are requesting a feature you believe would make Eden better.
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
attributes:
|
attributes:
|
||||||
label: Is there an existing issue for this?
|
label: Is there an existing issue for this?
|
||||||
@@ -23,6 +23,6 @@ body:
|
|||||||
id: why-feature
|
id: why-feature
|
||||||
attributes:
|
attributes:
|
||||||
label: Why would this feature be useful?
|
label: Why would this feature be useful?
|
||||||
description: A brief description of why this feature would make yuzu better.
|
description: A brief description of why this feature would make Eden better.
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
+35
-17
@@ -28,23 +28,23 @@ if (NOT DEFINED ARCHITECTURE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Needed for FFmpeg w/ VAAPI and DRM
|
# Needed for FFmpeg w/ VAAPI and DRM
|
||||||
if (PLATFORM_OPENBSD)
|
if (OPENBSD)
|
||||||
# OpenBSD 7.8 broke libcxx when upgrading, so we must define the PSTL backend manually
|
# OpenBSD 7.8 broke libcxx when upgrading, so we must define the PSTL backend manually
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R6/include -D_LIBCPP_PSTL_BACKEND_SERIAL=1")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R6/include -D_LIBCPP_PSTL_BACKEND_SERIAL=1")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R6/include -D_LIBCPP_PSTL_BACKEND_SERIAL=1")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R6/include -D_LIBCPP_PSTL_BACKEND_SERIAL=1")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/X11R6/lib")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/X11R6/lib")
|
||||||
elseif (PLATFORM_NETBSD)
|
elseif (NETBSD)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include -I${CMAKE_SYSROOT}/usr/pkg/include/c++/v1")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include -I${CMAKE_SYSROOT}/usr/pkg/include/c++/v1")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include -I${CMAKE_SYSROOT}/usr/pkg/include/c++/v1")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include -I${CMAKE_SYSROOT}/usr/pkg/include/c++/v1")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/X11R7/lib")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/X11R7/lib")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# NetBSD: Fun for the whole family!
|
# NetBSD: Fun for the whole family!
|
||||||
if (PLATFORM_NETBSD)
|
if (NETBSD)
|
||||||
set(ENV{PKG_CONFIG_PATH} "${PKG_CONFIG_PATH}:${CMAKE_SYSROOT}/usr/pkg/lib/ffmpeg7/pkgconfig")
|
set(ENV{PKG_CONFIG_PATH} "${PKG_CONFIG_PATH}:${CMAKE_SYSROOT}/usr/pkg/lib/ffmpeg7/pkgconfig")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
cmake_dependent_option(YUZU_STATIC_ROOM "Build a static room executable only (CI only)" OFF "PLATFORM_LINUX" OFF)
|
cmake_dependent_option(YUZU_STATIC_ROOM "Build a static room executable only (CI only)" OFF "LINUX" OFF)
|
||||||
if (YUZU_STATIC_ROOM)
|
if (YUZU_STATIC_ROOM)
|
||||||
set(YUZU_ROOM ON)
|
set(YUZU_ROOM ON)
|
||||||
set(YUZU_ROOM_STANDALONE ON)
|
set(YUZU_ROOM_STANDALONE ON)
|
||||||
@@ -79,6 +79,10 @@ set(YUZU_QT_MIRROR "" CACHE STRING "What mirror to use for downloading the bundl
|
|||||||
cmake_dependent_option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF)
|
cmake_dependent_option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF)
|
||||||
|
|
||||||
option(ENABLE_DEBUG_TOOLS "Enable debugging tools (maxwell disassembler, SPIRV translator, etc)" OFF)
|
option(ENABLE_DEBUG_TOOLS "Enable debugging tools (maxwell disassembler, SPIRV translator, etc)" OFF)
|
||||||
|
option(ENABLE_WERROR "Enable -Werror diagnostics" ON)
|
||||||
|
|
||||||
|
# Lossless Scaling frame generation. Only Android.
|
||||||
|
cmake_dependent_option(ENABLE_LSFG "Enable Lossless Scaling frame generation" ON "ANDROID" OFF)
|
||||||
|
|
||||||
# non-linux bundled qt are static
|
# non-linux bundled qt are static
|
||||||
if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX))
|
if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX))
|
||||||
@@ -157,6 +161,19 @@ if (CXX_CLANG_CL)
|
|||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-reserved-identifier>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-reserved-identifier>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-deprecated-declarations>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-deprecated-declarations>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-cast-function-type-mismatch>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-cast-function-type-mismatch>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c99-extensions>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++17-compat>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++11-compat-reserved-user-defined-literal>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++11-compat-deprecated-writable-strings>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++11-compat-pedantic>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++11-compat>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++0x-compat>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++98-c++11-compat-binary-literal>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++98-compat-pedantic>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++98-compat>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c99-compat>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c98-compat>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c99-extensions>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:/EHsc>)
|
$<$<COMPILE_LANGUAGE:C,CXX>:/EHsc>)
|
||||||
# REQUIRED CPU features IN Windows-amd64
|
# REQUIRED CPU features IN Windows-amd64
|
||||||
if (ARCHITECTURE_x86_64)
|
if (ARCHITECTURE_x86_64)
|
||||||
@@ -210,7 +227,7 @@ endif()
|
|||||||
|
|
||||||
# ffmpeg
|
# ffmpeg
|
||||||
option(YUZU_USE_BUNDLED_FFMPEG "Download bundled FFmpeg" ${EXT_DEFAULT})
|
option(YUZU_USE_BUNDLED_FFMPEG "Download bundled FFmpeg" ${EXT_DEFAULT})
|
||||||
cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from external source" "${PLATFORM_SUN}" "NOT WIN32 AND NOT ANDROID" OFF)
|
cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from external source" "${SOLARIS}" "NOT WIN32 AND NOT ANDROID" OFF)
|
||||||
|
|
||||||
# sirit
|
# sirit
|
||||||
set(BUNDLED_SIRIT_DEFAULT OFF)
|
set(BUNDLED_SIRIT_DEFAULT OFF)
|
||||||
@@ -221,7 +238,7 @@ endif()
|
|||||||
option(YUZU_USE_BUNDLED_SIRIT "Download bundled sirit" ${BUNDLED_SIRIT_DEFAULT})
|
option(YUZU_USE_BUNDLED_SIRIT "Download bundled sirit" ${BUNDLED_SIRIT_DEFAULT})
|
||||||
|
|
||||||
# FreeBSD 15+ has libusb, versions below should disable it
|
# FreeBSD 15+ has libusb, versions below should disable it
|
||||||
cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "WIN32 OR PLATFORM_LINUX OR PLATFORM_FREEBSD OR APPLE" OFF)
|
cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "WIN32 OR LINUX OR FREEBSD OR APPLE" OFF)
|
||||||
|
|
||||||
cmake_dependent_option(ENABLE_OPENGL "Enable OpenGL" ON "NOT (WIN32 AND ARCHITECTURE_arm64) AND NOT APPLE" OFF)
|
cmake_dependent_option(ENABLE_OPENGL "Enable OpenGL" ON "NOT (WIN32 AND ARCHITECTURE_arm64) AND NOT APPLE" OFF)
|
||||||
mark_as_advanced(FORCE ENABLE_OPENGL)
|
mark_as_advanced(FORCE ENABLE_OPENGL)
|
||||||
@@ -235,7 +252,7 @@ option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}")
|
|||||||
|
|
||||||
# Install udev rules on Linux (mainly for gyros)
|
# Install udev rules on Linux (mainly for gyros)
|
||||||
# Only acts on joysticks and nothing else.
|
# Only acts on joysticks and nothing else.
|
||||||
cmake_dependent_option(YUZU_INSTALL_UDEV_RULES "Install udev rules for gyro access" OFF "PLATFORM_LINUX" OFF)
|
cmake_dependent_option(YUZU_INSTALL_UDEV_RULES "Install udev rules for gyro access" OFF "LINUX" OFF)
|
||||||
|
|
||||||
option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON)
|
option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON)
|
||||||
|
|
||||||
@@ -248,7 +265,7 @@ cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable"
|
|||||||
|
|
||||||
cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "NOT ANDROID" OFF)
|
cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "NOT ANDROID" OFF)
|
||||||
|
|
||||||
cmake_dependent_option(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR PLATFORM_LINUX" OFF)
|
cmake_dependent_option(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR LINUX" OFF)
|
||||||
|
|
||||||
option(YUZU_DOWNLOAD_TIME_ZONE_DATA "Always download time zone binaries" ON)
|
option(YUZU_DOWNLOAD_TIME_ZONE_DATA "Always download time zone binaries" ON)
|
||||||
set(YUZU_TZDB_PATH "" CACHE STRING "Path to a pre-downloaded timezone database")
|
set(YUZU_TZDB_PATH "" CACHE STRING "Path to a pre-downloaded timezone database")
|
||||||
@@ -258,7 +275,7 @@ cmake_dependent_option(YUZU_USE_BUNDLED_MOLTENVK "Download bundled MoltenVK lib"
|
|||||||
option(YUZU_DISABLE_LLVM "Disable LLVM (useful for CI)" OFF)
|
option(YUZU_DISABLE_LLVM "Disable LLVM (useful for CI)" OFF)
|
||||||
|
|
||||||
set(DEFAULT_YUZU_USE_BUNDLED_OPENSSL OFF)
|
set(DEFAULT_YUZU_USE_BUNDLED_OPENSSL OFF)
|
||||||
if (EXT_DEFAULT OR PLATFORM_SUN OR PLATFORM_OPENBSD)
|
if (EXT_DEFAULT OR SOLARIS OR OPENBSD)
|
||||||
set(DEFAULT_YUZU_USE_BUNDLED_OPENSSL ON)
|
set(DEFAULT_YUZU_USE_BUNDLED_OPENSSL ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -281,7 +298,7 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/hooks/pre-commit AND NOT EXISTS ${PROJECT_SOURCE
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX))
|
if (ARCHITECTURE_arm64 AND (ANDROID OR LINUX))
|
||||||
set(HAS_NCE 1)
|
set(HAS_NCE 1)
|
||||||
add_compile_definitions(HAS_NCE=1)
|
add_compile_definitions(HAS_NCE=1)
|
||||||
endif()
|
endif()
|
||||||
@@ -290,7 +307,7 @@ if (YUZU_ROOM)
|
|||||||
add_compile_definitions(YUZU_ROOM)
|
add_compile_definitions(YUZU_ROOM)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (UNIX AND NOT (PLATFORM_LINUX OR WIN32))
|
if (UNIX AND NOT (LINUX OR WIN32))
|
||||||
if(CXX_APPLE OR CXX_CLANG)
|
if(CXX_APPLE OR CXX_CLANG)
|
||||||
# libc++ has stop_token and jthread as experimental
|
# libc++ has stop_token and jthread as experimental
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexperimental-library")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexperimental-library")
|
||||||
@@ -325,11 +342,12 @@ if (CXX_GCC OR CXX_CLANG)
|
|||||||
endif()
|
endif()
|
||||||
elseif(ARCHITECTURE_arm64)
|
elseif(ARCHITECTURE_arm64)
|
||||||
# See https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html
|
# See https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html
|
||||||
set(YUZU_BUILD_PRESET "custom" CACHE STRING "Build preset to use. One of: custom, generic, armv9, native")
|
set(YUZU_BUILD_PRESET "custom" CACHE STRING "Build preset to use. One of: custom, generic, optimized, armv9, native")
|
||||||
set(mtune generic)
|
set(mtune generic)
|
||||||
|
|
||||||
if (${YUZU_BUILD_PRESET} STREQUAL "generic")
|
if (${YUZU_BUILD_PRESET} STREQUAL "generic")
|
||||||
set(march armv8-a)
|
set(march armv8-a)
|
||||||
|
elseif (${YUZU_BUILD_PRESET} STREQUAL "optimized")
|
||||||
|
set(march armv8.2-a+lse+rcpc)
|
||||||
elseif (${YUZU_BUILD_PRESET} STREQUAL "armv9")
|
elseif (${YUZU_BUILD_PRESET} STREQUAL "armv9")
|
||||||
set(march armv9-a)
|
set(march armv9-a)
|
||||||
endif()
|
endif()
|
||||||
@@ -404,7 +422,7 @@ if (Boost_ADDED)
|
|||||||
|
|
||||||
if (NOT MSVC OR CXX_CLANG)
|
if (NOT MSVC OR CXX_CLANG)
|
||||||
# boost sucks
|
# boost sucks
|
||||||
if (PLATFORM_SUN)
|
if (SOLARIS)
|
||||||
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-pthreads>)
|
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-pthreads>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -508,9 +526,9 @@ elseif (WIN32)
|
|||||||
# PSAPI is the Process Status API
|
# PSAPI is the Process Status API
|
||||||
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version crypt32 rpcrt4 gdi32 wldap32 mswsock)
|
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version crypt32 rpcrt4 gdi32 wldap32 mswsock)
|
||||||
endif()
|
endif()
|
||||||
elseif (PLATFORM_MANAGARM)
|
elseif (MANAGARM)
|
||||||
set(PLATFORM_LIBRARIES iconv intl)
|
set(PLATFORM_LIBRARIES iconv intl)
|
||||||
elseif (PLATFORM_HAIKU)
|
elseif (HAIKUOS)
|
||||||
# Haiku is so special :)
|
# Haiku is so special :)
|
||||||
set(PLATFORM_LIBRARIES bsd /boot/system/lib/libnetwork.so)
|
set(PLATFORM_LIBRARIES bsd /boot/system/lib/libnetwork.so)
|
||||||
elseif (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU|SunOS)$")
|
elseif (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU|SunOS)$")
|
||||||
@@ -604,7 +622,7 @@ if (ENABLE_QT)
|
|||||||
|
|
||||||
# Best practice is to ask for all components at once, so they are from the same version
|
# Best practice is to ask for all components at once, so they are from the same version
|
||||||
set(YUZU_QT_COMPONENTS Core Widgets Charts Concurrent Gui)
|
set(YUZU_QT_COMPONENTS Core Widgets Charts Concurrent Gui)
|
||||||
if (PLATFORM_LINUX OR PLATFORM_FREEBSD)
|
if (LINUX OR FREEBSD)
|
||||||
list(APPEND YUZU_QT_COMPONENTS DBus)
|
list(APPEND YUZU_QT_COMPONENTS DBus)
|
||||||
# yes Qt, we get it
|
# yes Qt, we get it
|
||||||
set(QT_NO_PRIVATE_MODULE_WARNING ON)
|
set(QT_NO_PRIVATE_MODULE_WARNING ON)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ find_package_handle_standard_args(Opus
|
|||||||
VERSION_VAR OPUS_VERSION
|
VERSION_VAR OPUS_VERSION
|
||||||
)
|
)
|
||||||
|
|
||||||
if (PLATFORM_MSYS)
|
if (MSYS2)
|
||||||
FixMsysPath(PkgConfig::OPUS)
|
FixMsysPath(PkgConfig::OPUS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ find_package_handle_standard_args(enet
|
|||||||
VERSION_VAR ENET_VERSION
|
VERSION_VAR ENET_VERSION
|
||||||
)
|
)
|
||||||
|
|
||||||
if (PLATFORM_MSYS)
|
if (MSYS2)
|
||||||
FixMsysPath(PkgConfig::ENET)
|
FixMsysPath(PkgConfig::ENET)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ find_package_handle_standard_args(libusb
|
|||||||
VERSION_VAR LIBUSB_VERSION
|
VERSION_VAR LIBUSB_VERSION
|
||||||
)
|
)
|
||||||
|
|
||||||
if (PLATFORM_MSYS)
|
if (MSYS2)
|
||||||
FixMsysPath(PkgConfig::LIBUSB)
|
FixMsysPath(PkgConfig::LIBUSB)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ else()
|
|||||||
find_package(PkgConfig QUIET)
|
find_package(PkgConfig QUIET)
|
||||||
pkg_search_module(LZ4 QUIET IMPORTED_TARGET liblz4)
|
pkg_search_module(LZ4 QUIET IMPORTED_TARGET liblz4)
|
||||||
|
|
||||||
if (PLATFORM_MSYS)
|
if (MSYS2)
|
||||||
FixMsysPath(PkgConfig::LZ4)
|
FixMsysPath(PkgConfig::LZ4)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -22,9 +22,13 @@ Eden is free, open-source, copyleft software, licensed under the terms of the [G
|
|||||||
|
|
||||||
- No LLM or AI usage, *period*, for patches, pull requests, issues, comments, debugging, brainstorming, etc.
|
- No LLM or AI usage, *period*, for patches, pull requests, issues, comments, debugging, brainstorming, etc.
|
||||||
- For details on why, see the [detailed AI policy](docs/policies/AI.md).
|
- For details on why, see the [detailed AI policy](docs/policies/AI.md).
|
||||||
|
- Usage of any form of profanity or otherwise unsavory language is generally discouraged.
|
||||||
|
- This is primarily because it rarely helps to actually understand what's going on.
|
||||||
|
- Remember that your comments should be focused and actually address what's happening. With very few exceptions, expletives are actively detrimental at best.
|
||||||
- New code must follow the same general style as the surrounding codebase. Exceptions may be granted in certain cases.
|
- New code must follow the same general style as the surrounding codebase. Exceptions may be granted in certain cases.
|
||||||
- Maintainers reserve the right to change your patches and pull requests at will. We will try to avoid this.
|
- Maintainers reserve the right to change your patches and pull requests at will. We will try to avoid this.
|
||||||
- You should respect all decisions made by the [code owners](docs/CODEOWNERS) in your particular subsystem. If you feel they are overstepping or are incorrect, don't be afraid to stand your ground!
|
- You should generally respect all decisions made by the [code owners](docs/CODEOWNERS) in your particular subsystem.
|
||||||
|
- However, if you feel they are overstepping or are incorrect, don't be afraid to stand your ground! Maintainers are not always correct.
|
||||||
- While we do *not* adhere to the terms of a formal code of conduct, you will generally be expected to respect other developers, contributors, and community members.
|
- While we do *not* adhere to the terms of a formal code of conduct, you will generally be expected to respect other developers, contributors, and community members.
|
||||||
- You **must** have basic knowledge of [Git](https://git-scm.com/learn). Knowing how to manage your branches and follow proper fork policies is a necessity.
|
- You **must** have basic knowledge of [Git](https://git-scm.com/learn). Knowing how to manage your branches and follow proper fork policies is a necessity.
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ These options control dependencies.
|
|||||||
- `YUZU_INSTALL_UDEV_RULES` (OFF) Install udev rules to enable hidraw access
|
- `YUZU_INSTALL_UDEV_RULES` (OFF) Install udev rules to enable hidraw access
|
||||||
- Needed for gyroscopes
|
- Needed for gyroscopes
|
||||||
- Only available on Linux
|
- Only available on Linux
|
||||||
|
- `ENABLE_DEBUG_TOOLS` (OFF) Enables debugging and development tools, see [tools](../tools/README.md).
|
||||||
|
- `ENABLE_WERROR` (ON) Enables warnings as errors (-Werror).
|
||||||
|
|
||||||
### Flavors
|
### Flavors
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ Everyone has their own way of viewing good/bad C++ practices, my general outline
|
|||||||
- The reason is because the project has `-fno-rtti` disabled by default, due to the costs of dynamic polymorphism.
|
- The reason is because the project has `-fno-rtti` disabled by default, due to the costs of dynamic polymorphism.
|
||||||
- Always copy-on-value for objects with `sizeof(void *) >= sizeof(T) * 2`, i.e objects sized as 2 pointers or less, for bigger objects you can use ref/pointer as usual.
|
- Always copy-on-value for objects with `sizeof(void *) >= sizeof(T) * 2`, i.e objects sized as 2 pointers or less, for bigger objects you can use ref/pointer as usual.
|
||||||
- Try using move semantics instead of references, whenever possible.
|
- Try using move semantics instead of references, whenever possible.
|
||||||
- Remember function parameters are extremelly cheap as fuck, don't be afraid to place upto 8 parameters on a given function.
|
- Function parameters are cheap. Don't be afraid to use as many as needed (API usability permitting).
|
||||||
- Don't save a reference in structures of a parent object, i.e:
|
- Don't save a reference in structures of a parent object, i.e:
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
|
|||||||
Vendored
+1
-1
@@ -164,7 +164,7 @@ if (NOT ANDROID)
|
|||||||
AddJsonPackage(sdl3)
|
AddJsonPackage(sdl3)
|
||||||
else()
|
else()
|
||||||
message(STATUS "Using bundled SDL3")
|
message(STATUS "Using bundled SDL3")
|
||||||
if (PLATFORM_FREEBSD)
|
if (FREEBSD)
|
||||||
set(BUILD_SHARED_LIBS ON)
|
set(BUILD_SHARED_LIBS ON)
|
||||||
endif()
|
endif()
|
||||||
AddJsonPackage(sdl3-ci)
|
AddJsonPackage(sdl3-ci)
|
||||||
|
|||||||
+23
-80
@@ -1,45 +1,46 @@
|
|||||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
# SPDX-FileCopyrightText: Copyright 2026 crueter
|
||||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
|
||||||
## DetectPlatform ##
|
## DetectPlatform ##
|
||||||
|
|
||||||
# This is a small helper that sets PLATFORM_<platform> variables for various
|
# This is a small helper that sets platform variables for various
|
||||||
# operating systems and distributions. Note that Apple, Windows, Android, etc.
|
# operating systems and distributions. Note that Apple, Windows, Android, etc.
|
||||||
# are not covered, as CMake already does that for us.
|
# are not covered, as CMake already does that for us.
|
||||||
|
|
||||||
# It also sets CXX_<compiler> for the C++ compiler.
|
# It also sets CXX_<compiler> for the C++ compiler.
|
||||||
|
|
||||||
# Furthermore, some platforms have really silly requirements/quirks, so this
|
|
||||||
# also does a few of those.
|
|
||||||
|
|
||||||
# This module contains contributions from the Eden Emulator Project,
|
# This module contains contributions from the Eden Emulator Project,
|
||||||
# notably from crueter and Lizzie.
|
# notably from crueter and Lizzie.
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
|
if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
|
||||||
set(PLATFORM_SUN ON)
|
set(SOLARIS ON)
|
||||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenOrbis")
|
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenOrbis")
|
||||||
set(PLATFORM_PS4 ON)
|
set(OPENORBIS ON)
|
||||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "managarm")
|
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "managarm")
|
||||||
set(PLATFORM_MANAGARM ON)
|
set(MANAGARM ON)
|
||||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
|
||||||
set(PLATFORM_FREEBSD ON)
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
|
|
||||||
set(PLATFORM_OPENBSD ON)
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "NetBSD")
|
|
||||||
set(PLATFORM_NETBSD ON)
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "DragonFly")
|
|
||||||
set(PLATFORM_DRAGONFLYBSD ON)
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Haiku")
|
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Haiku")
|
||||||
set(PLATFORM_HAIKU ON)
|
set(HAIKUOS ON)
|
||||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
endif()
|
||||||
set(PLATFORM_LINUX ON)
|
|
||||||
|
# BSD
|
||||||
|
if (DEFINED BSD)
|
||||||
|
if ("${BSD}" STREQUAL "DragonFlyBSD")
|
||||||
|
set(DRAGONFLYBSD ON)
|
||||||
|
elseif ("${BSD}" STREQUAL "FreeBSD")
|
||||||
|
set(FREEBSD ON)
|
||||||
|
elseif ("${BSD}" STREQUAL "OpenBSD")
|
||||||
|
set(OPENBSD ON)
|
||||||
|
elseif ("${BSD}" STREQUAL "NetBSD")
|
||||||
|
set(NETBSD ON)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# dumb heuristic to detect msys2
|
# dumb heuristic to detect msys2
|
||||||
if (CMAKE_COMMAND MATCHES "msys64")
|
if (CMAKE_COMMAND MATCHES "msys64")
|
||||||
set(PLATFORM_MSYS ON)
|
set(MSYS2 ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# compiler checks
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
set(CXX_CLANG ON)
|
set(CXX_CLANG ON)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
@@ -47,8 +48,6 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|||||||
endif()
|
endif()
|
||||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
set(CXX_GCC ON)
|
set(CXX_GCC ON)
|
||||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|
||||||
set(CXX_CL ON)
|
|
||||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
|
||||||
set(CXX_ICC ON)
|
set(CXX_ICC ON)
|
||||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||||
@@ -61,37 +60,13 @@ if(MINGW AND CXX_CLANG)
|
|||||||
set(CMAKE_SYSTEM_VERSION 10.0.0)
|
set(CMAKE_SYSTEM_VERSION 10.0.0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# NB: this does not account for SPARC
|
|
||||||
if (PLATFORM_SUN)
|
|
||||||
# Terrific OpenIndiana pkg shenanigans
|
|
||||||
list(APPEND CMAKE_PREFIX_PATH
|
|
||||||
"${CMAKE_SYSROOT}/usr/lib/qt/6.6/lib/amd64/cmake")
|
|
||||||
list(APPEND CMAKE_MODULE_PATH
|
|
||||||
"${CMAKE_SYSROOT}/usr/lib/qt/6.6/lib/amd64/cmake")
|
|
||||||
|
|
||||||
# Amazing - absolutely incredible
|
|
||||||
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SYSROOT}/usr/lib/amd64/cmake")
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SYSROOT}/usr/lib/amd64/cmake")
|
|
||||||
|
|
||||||
# For some mighty reason, doing a normal release build sometimes
|
|
||||||
# may not trigger the proper -O3 switch to materialize
|
|
||||||
if (CMAKE_BUILD_TYPE MATCHES "Release")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
|
|
||||||
endif()
|
|
||||||
if (CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# MSYS2 utilities
|
# MSYS2 utilities
|
||||||
|
|
||||||
# Sometimes, PkgConfig modules will incorrectly reference / when CMake
|
# Sometimes, PkgConfig modules will incorrectly reference / when CMake
|
||||||
# wants you to reference it as C:/msys64/. This function corrects that.
|
# wants you to reference it as C:/msys64/. This function corrects that.
|
||||||
# Example in a Find module:
|
# Example in a Find module:
|
||||||
#[[
|
#[[
|
||||||
if (PLATFORM_MSYS)
|
if (MSYS2)
|
||||||
FixMsysPath(PkgConfig::OPUS)
|
FixMsysPath(PkgConfig::OPUS)
|
||||||
endif()
|
endif()
|
||||||
]]
|
]]
|
||||||
@@ -116,41 +91,9 @@ function(FixMsysPath target)
|
|||||||
INTERFACE_INCLUDE_DIRECTORIES ${include_dir})
|
INTERFACE_INCLUDE_DIRECTORIES ${include_dir})
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# MSYSTEM handling + program_path
|
# Saves linking time
|
||||||
if (PLATFORM_MSYS)
|
|
||||||
# really, really dumb heuristic to detect what environment we are in
|
|
||||||
macro(system var)
|
|
||||||
if (CMAKE_COMMAND MATCHES ${var})
|
|
||||||
set(MSYSTEM ${var})
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
system(mingw64)
|
|
||||||
system(clang64)
|
|
||||||
system(clangarm64)
|
|
||||||
system(ucrt64)
|
|
||||||
|
|
||||||
if (NOT DEFINED MSYSTEM)
|
|
||||||
set(MSYSTEM msys2)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# We generally want to prioritize environment-specific binaries if possible
|
|
||||||
# some, like autoconf, are not present on environments besides msys2 though
|
|
||||||
set(CMAKE_PROGRAM_PATH C:/msys64/${MSYSTEM}/bin C:/msys64/usr/bin)
|
|
||||||
set(ENV{PKG_CONFIG_PATH} C:/msys64/${MSYSTEM}/lib/pkgconfig)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# This saves a truly ridiculous amount of time during linking
|
|
||||||
# In my tests, without this, Eden takes 2 mins, with this, it takes 3-5 seconds
|
|
||||||
# or on GitHub Actions, 10 minutes -> 3 seconds
|
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
set(MINGW_FLAGS "-Wl,--strip-all -Wl,--gc-sections")
|
set(MINGW_FLAGS "-Wl,--strip-all -Wl,--gc-sections")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE
|
set(CMAKE_EXE_LINKER_FLAGS_RELEASE
|
||||||
"${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${MINGW_FLAGS}")
|
"${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${MINGW_FLAGS}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# awesome
|
|
||||||
if (PLATFORM_FREEBSD OR PLATFORM_DRAGONFLYBSD)
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS
|
|
||||||
"${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/local/lib")
|
|
||||||
endif()
|
|
||||||
|
|||||||
Vendored
+5
-5
@@ -56,7 +56,7 @@ if (NOT YUZU_USE_BUNDLED_FFMPEG)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (PLATFORM_PS4 OR PLATFORM_MANAGARM)
|
if (OPENORBIS OR MANAGARM)
|
||||||
# Doesn't support VA-API, don't go thru the embarrassment of trying to enable it
|
# Doesn't support VA-API, don't go thru the embarrassment of trying to enable it
|
||||||
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi)
|
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi)
|
||||||
elseif (ANDROID)
|
elseif (ANDROID)
|
||||||
@@ -75,7 +75,7 @@ elseif (UNIX AND NOT DEFINED FFmpeg_IS_CROSS_COMPILING AND NOT ANDROID)
|
|||||||
if(X11_FOUND)
|
if(X11_FOUND)
|
||||||
if (NOT APPLE)
|
if (NOT APPLE)
|
||||||
# In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so
|
# In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so
|
||||||
if(PLATFORM_SUN)
|
if(SOLARIS)
|
||||||
list(APPEND FFmpeg_HWACCEL_LIBRARIES
|
list(APPEND FFmpeg_HWACCEL_LIBRARIES
|
||||||
X11
|
X11
|
||||||
"${CMAKE_SYSROOT}/usr/lib/xorg/amd64/libdrm.so")
|
"${CMAKE_SYSROOT}/usr/lib/xorg/amd64/libdrm.so")
|
||||||
@@ -158,7 +158,7 @@ elseif (UNIX AND NOT DEFINED FFmpeg_IS_CROSS_COMPILING AND NOT ANDROID)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (PLATFORM_PS4)
|
if (OPENORBIS)
|
||||||
list(APPEND FFmpeg_CROSS_COMPILE_LIBS
|
list(APPEND FFmpeg_CROSS_COMPILE_LIBS
|
||||||
-lkernel
|
-lkernel
|
||||||
-lSceUserService
|
-lSceUserService
|
||||||
@@ -172,7 +172,7 @@ if (PLATFORM_PS4)
|
|||||||
--extra-cxxflags=${CMAKE_SYSROOT}/usr/include
|
--extra-cxxflags=${CMAKE_SYSROOT}/usr/include
|
||||||
--extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}"
|
--extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}"
|
||||||
)
|
)
|
||||||
elseif (PLATFORM_MANAGARM)
|
elseif (MANAGARM)
|
||||||
# Required for proper stuff
|
# Required for proper stuff
|
||||||
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
|
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
|
||||||
--disable-pthreads
|
--disable-pthreads
|
||||||
@@ -299,7 +299,7 @@ else()
|
|||||||
set(FFmpeg_BUILD_LIBRARIES ${FFmpeg_LIBRARIES})
|
set(FFmpeg_BUILD_LIBRARIES ${FFmpeg_LIBRARIES})
|
||||||
|
|
||||||
# BSD make or Solaris make don't support ffmpeg make-j8
|
# BSD make or Solaris make don't support ffmpeg make-j8
|
||||||
if (PLATFORM_LINUX OR ANDROID OR APPLE OR WIN32 OR PLATFORM_FREEBSD)
|
if (LINUX OR ANDROID OR APPLE OR WIN32 OR FREEBSD)
|
||||||
set(FFmpeg_MAKE_ARGS -j${SYSTEM_THREADS})
|
set(FFmpeg_MAKE_ARGS -j${SYSTEM_THREADS})
|
||||||
else()
|
else()
|
||||||
set(FFmpeg_MAKE_ARGS "")
|
set(FFmpeg_MAKE_ARGS "")
|
||||||
|
|||||||
Vendored
+1
-1
@@ -11,7 +11,7 @@ if (NOT libusb_ADDED)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# TODO: *BSD fails to compile--may need different configs/symbols
|
# TODO: *BSD fails to compile--may need different configs/symbols
|
||||||
if (MINGW OR PLATFORM_LINUX OR APPLE)
|
if (MINGW OR LINUX OR APPLE)
|
||||||
set(LIBUSB_FOUND ON CACHE BOOL "libusb is present" FORCE)
|
set(LIBUSB_FOUND ON CACHE BOOL "libusb is present" FORCE)
|
||||||
set(LIBUSB_VERSION "1.0.24" CACHE STRING "libusb version string" FORCE)
|
set(LIBUSB_VERSION "1.0.24" CACHE STRING "libusb version string" FORCE)
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-2
@@ -1177,7 +1177,7 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef STBI_NO_TGA
|
#ifndef STBI_NO_TGA
|
||||||
// test tga last because it's a crappy test!
|
// test tga last because it's a bad test!
|
||||||
if (stbi__tga_test(s))
|
if (stbi__tga_test(s))
|
||||||
return stbi__tga_load(s,x,y,comp,req_comp, ri);
|
return stbi__tga_load(s,x,y,comp,req_comp, ri);
|
||||||
#endif
|
#endif
|
||||||
@@ -7662,7 +7662,7 @@ static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp)
|
|||||||
if (stbi__hdr_info(s, x, y, comp)) return 1;
|
if (stbi__hdr_info(s, x, y, comp)) return 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// test tga last because it's a crappy test!
|
// test tga last because it's a bad test!
|
||||||
#ifndef STBI_NO_TGA
|
#ifndef STBI_NO_TGA
|
||||||
if (stbi__tga_info(s, x, y, comp))
|
if (stbi__tga_info(s, x, y, comp))
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
+21
-9
@@ -155,12 +155,24 @@ else()
|
|||||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>)
|
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (ENABLE_WERROR)
|
||||||
|
add_compile_options(
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=all>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=extra>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=missing-declarations>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=shadow>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=unused>)
|
||||||
|
else()
|
||||||
|
add_compile_options(
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wall>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wextra>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wmissing-declarations>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wshadow>
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wunused>
|
||||||
|
# Some compilers could particularly misbehave :)
|
||||||
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-error-all>)
|
||||||
|
endif()
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=all>
|
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=extra>
|
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=missing-declarations>
|
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=shadow>
|
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=unused>
|
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-attributes>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-attributes>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-invalid-offsetof>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-invalid-offsetof>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-unused-parameter>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-unused-parameter>
|
||||||
@@ -169,9 +181,9 @@ else()
|
|||||||
if (CXX_CLANG OR CXX_ICC OR CXX_APPLE) # Clang, AppleClang, or Intel C++
|
if (CXX_CLANG OR CXX_ICC OR CXX_APPLE) # Clang, AppleClang, or Intel C++
|
||||||
if (NOT MSVC)
|
if (NOT MSVC)
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=shadow-uncaptured-local>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wshadow-uncaptured-local>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=implicit-fallthrough>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wimplicit-fallthrough>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=type-limits>)
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wtype-limits>)
|
||||||
endif()
|
endif()
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-braced-scalar-init>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-braced-scalar-init>
|
||||||
@@ -181,7 +193,7 @@ else()
|
|||||||
|
|
||||||
if (ARCHITECTURE_x86_64)
|
if (ARCHITECTURE_x86_64)
|
||||||
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-mcx16>)
|
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-mcx16>)
|
||||||
if (PLATFORM_LINUX OR PLATFORM_FREEBSD)
|
if (LINUX OR FREEBSD)
|
||||||
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-mtls-dialect=gnu2>)
|
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-mtls-dialect=gnu2>)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -539,6 +539,40 @@ object NativeLibrary {
|
|||||||
*/
|
*/
|
||||||
external fun installKeys(path: String, ext: String): Int
|
external fun installKeys(path: String, ext: String): Int
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Whether this GPU can run the Lossless Scaling frame generation shaders,
|
||||||
|
* which are built against the Vulkan memory model.
|
||||||
|
*/
|
||||||
|
external fun supportsFrameGeneration(): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Path the user-supplied Lossless Scaling library is expected at.
|
||||||
|
*/
|
||||||
|
external fun getLosslessDllPath(): String
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the installed Lossless Scaling library and checks that every shader the
|
||||||
|
* frame generation chain needs is present.
|
||||||
|
*
|
||||||
|
* @return The result code, matching the losslessDllResults array.
|
||||||
|
*/
|
||||||
|
external fun validateLosslessDll(): Int
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates the frame generation shaders out of the installed Lossless Scaling library
|
||||||
|
* and writes them to the SPIR-V cache. Slow, so call it off the main thread.
|
||||||
|
*
|
||||||
|
* @return The result code, matching the losslessDllResults array.
|
||||||
|
*/
|
||||||
|
external fun prepareLosslessDll(): Int
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the installed Lossless Scaling library.
|
||||||
|
*
|
||||||
|
* @return Whether the library is gone after the call.
|
||||||
|
*/
|
||||||
|
external fun removeLosslessDll(): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the PatchManager for any addons that are available
|
* Checks the PatchManager for any addons that are available
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -559,6 +559,15 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||||||
private fun enableFullscreenImmersive() {
|
private fun enableFullscreenImmersive() {
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
window.decorView.systemUiVisibility =
|
||||||
|
View.SYSTEM_UI_FLAG_FULLSCREEN or
|
||||||
|
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
|
||||||
|
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
|
|
||||||
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
|
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
|
||||||
controller.hide(WindowInsetsCompat.Type.systemBars())
|
controller.hide(WindowInsetsCompat.Type.systemBars())
|
||||||
controller.systemBarsBehavior =
|
controller.systemBarsBehavior =
|
||||||
|
|||||||
+4
-2
@@ -18,7 +18,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
|||||||
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
|
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
|
||||||
FIX_BLOOM_EFFECTS("fix_bloom_effects"),
|
FIX_BLOOM_EFFECTS("fix_bloom_effects"),
|
||||||
EMULATE_BGR565("emulate_bgr565"),
|
EMULATE_BGR565("emulate_bgr565"),
|
||||||
RESCALE_HACK("rescale_hack"),
|
|
||||||
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
|
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
|
||||||
USE_DOCKED_MODE("use_docked_mode"),
|
USE_DOCKED_MODE("use_docked_mode"),
|
||||||
USE_AUTO_STUB("use_auto_stub"),
|
USE_AUTO_STUB("use_auto_stub"),
|
||||||
@@ -27,7 +26,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
|||||||
RENDERER_ASYNCHRONOUS_GPU_EMULATION("use_asynchronous_gpu_emulation"),
|
RENDERER_ASYNCHRONOUS_GPU_EMULATION("use_asynchronous_gpu_emulation"),
|
||||||
RENDERER_ASYNC_PRESENTATION("async_presentation"),
|
RENDERER_ASYNC_PRESENTATION("async_presentation"),
|
||||||
RENDERER_ASYNCHRONOUS_SHADERS("use_asynchronous_shaders"),
|
RENDERER_ASYNCHRONOUS_SHADERS("use_asynchronous_shaders"),
|
||||||
RENDERER_UNIFIED_MEMORY("use_unified_memory"),
|
|
||||||
RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"),
|
RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"),
|
||||||
ENABLE_BUFFER_HISTORY("enable_buffer_history"),
|
ENABLE_BUFFER_HISTORY("enable_buffer_history"),
|
||||||
USE_OPTIMIZED_VERTEX_BUFFERS("use_optimized_vertex_buffers"),
|
USE_OPTIMIZED_VERTEX_BUFFERS("use_optimized_vertex_buffers"),
|
||||||
@@ -38,6 +36,10 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
|||||||
RENDERER_PATCH_OLD_QCOM_DRIVERS("patch_old_qcom_drivers"),
|
RENDERER_PATCH_OLD_QCOM_DRIVERS("patch_old_qcom_drivers"),
|
||||||
RENDERER_VERTEX_INPUT_DYNAMIC_STATE("vertex_input_dynamic_state"),
|
RENDERER_VERTEX_INPUT_DYNAMIC_STATE("vertex_input_dynamic_state"),
|
||||||
RENDERER_SAMPLE_SHADING("sample_shading"),
|
RENDERER_SAMPLE_SHADING("sample_shading"),
|
||||||
|
RENDERER_FRAME_GEN("frame_gen"),
|
||||||
|
RENDERER_FRAME_GEN_FP16("frame_gen_fp16"),
|
||||||
|
RENDERER_FRAME_GEN_FLOW_SCALE_AUTO("frame_gen_flow_scale_auto"),
|
||||||
|
RENDERER_FRAME_GEN_DUMP_FLOW("frame_gen_dump_flow"),
|
||||||
GPU_UNSWIZZLE_ENABLED("gpu_unswizzle_enabled"),
|
GPU_UNSWIZZLE_ENABLED("gpu_unswizzle_enabled"),
|
||||||
PICTURE_IN_PICTURE("picture_in_picture"),
|
PICTURE_IN_PICTURE("picture_in_picture"),
|
||||||
USE_CUSTOM_RTC("custom_rtc_enabled"),
|
USE_CUSTOM_RTC("custom_rtc_enabled"),
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
|
|||||||
RENDERER_ASTC_DECODE_METHOD("accelerate_astc"),
|
RENDERER_ASTC_DECODE_METHOD("accelerate_astc"),
|
||||||
RENDERER_ACCURACY("gpu_accuracy"),
|
RENDERER_ACCURACY("gpu_accuracy"),
|
||||||
RENDERER_RESOLUTION("resolution_setup"),
|
RENDERER_RESOLUTION("resolution_setup"),
|
||||||
|
RENDERER_FRAME_GEN_MULTIPLIER("frame_gen_multiplier"),
|
||||||
|
RENDERER_FRAME_GEN_TARGET_RATE("frame_gen_target_rate"),
|
||||||
|
RENDERER_FRAME_GEN_QUEUE_TARGET("frame_gen_queue_target"),
|
||||||
|
RENDERER_FRAME_GEN_FLOW_SCALE("frame_gen_flow_scale"),
|
||||||
RENDERER_VSYNC("use_vsync"),
|
RENDERER_VSYNC("use_vsync"),
|
||||||
RENDERER_SCALING_FILTER("scaling_filter"),
|
RENDERER_SCALING_FILTER("scaling_filter"),
|
||||||
RENDERER_ANTI_ALIASING("anti_aliasing"),
|
RENDERER_ANTI_ALIASING("anti_aliasing"),
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ object Settings {
|
|||||||
SECTION_ROOT(R.string.advanced_settings),
|
SECTION_ROOT(R.string.advanced_settings),
|
||||||
SECTION_SYSTEM(R.string.preferences_system),
|
SECTION_SYSTEM(R.string.preferences_system),
|
||||||
SECTION_RENDERER(R.string.preferences_graphics),
|
SECTION_RENDERER(R.string.preferences_graphics),
|
||||||
|
SECTION_FRAME_GEN(R.string.frame_gen),
|
||||||
SECTION_PERFORMANCE_STATS(R.string.stats_overlay_options),
|
SECTION_PERFORMANCE_STATS(R.string.stats_overlay_options),
|
||||||
SECTION_INPUT_OVERLAY(R.string.input_overlay_options),
|
SECTION_INPUT_OVERLAY(R.string.input_overlay_options),
|
||||||
SECTION_SOC_OVERLAY(R.string.soc_overlay_options),
|
SECTION_SOC_OVERLAY(R.string.soc_overlay_options),
|
||||||
|
|||||||
+104
-14
@@ -21,6 +21,7 @@ import org.yuzu.yuzu_emu.features.settings.model.LongSetting
|
|||||||
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
|
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
||||||
import org.yuzu.yuzu_emu.network.NetDataValidators
|
import org.yuzu.yuzu_emu.network.NetDataValidators
|
||||||
|
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
||||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,6 +66,19 @@ abstract class SettingsItem(
|
|||||||
return NativeLibrary.isFirmwareAvailable()
|
return NativeLibrary.isFirmwareAvailable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (setting.key in frameGenKeys &&
|
||||||
|
!(LosslessScalingHelper.isInstalled() && LosslessScalingHelper.isSupportedByGpu())
|
||||||
|
) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// A frame rate target moves the multiplier on its own
|
||||||
|
if (setting.key == IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.key &&
|
||||||
|
frameGenTargetRate != 0
|
||||||
|
) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Can't edit settings that aren't saveable in per-game config even if they are switchable
|
// Can't edit settings that aren't saveable in per-game config even if they are switchable
|
||||||
if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) {
|
if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) {
|
||||||
return false
|
return false
|
||||||
@@ -88,7 +102,31 @@ abstract class SettingsItem(
|
|||||||
val clearable: Boolean
|
val clearable: Boolean
|
||||||
get() = !setting.global && NativeConfig.isPerGameConfigLoaded()
|
get() = !setting.global && NativeConfig.isPerGameConfigLoaded()
|
||||||
|
|
||||||
|
private val frameGenTargetRate: Int
|
||||||
|
get() {
|
||||||
|
val key = IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key
|
||||||
|
val needsGlobal = if (NativeLibrary.isRunning() &&
|
||||||
|
!NativeConfig.isPerGameConfigLoaded()
|
||||||
|
) {
|
||||||
|
!NativeConfig.usingGlobal(key)
|
||||||
|
} else {
|
||||||
|
NativeConfig.usingGlobal(key)
|
||||||
|
}
|
||||||
|
return IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.getInt(needsGlobal)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private val frameGenKeys = setOf(
|
||||||
|
BooleanSetting.RENDERER_FRAME_GEN.key,
|
||||||
|
IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.key,
|
||||||
|
IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key,
|
||||||
|
IntSetting.RENDERER_FRAME_GEN_QUEUE_TARGET.key,
|
||||||
|
BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.key,
|
||||||
|
IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE.key,
|
||||||
|
BooleanSetting.RENDERER_FRAME_GEN_FP16.key,
|
||||||
|
BooleanSetting.RENDERER_FRAME_GEN_DUMP_FLOW.key
|
||||||
|
)
|
||||||
|
|
||||||
const val TYPE_HEADER = 0
|
const val TYPE_HEADER = 0
|
||||||
const val TYPE_SWITCH = 1
|
const val TYPE_SWITCH = 1
|
||||||
const val TYPE_SINGLE_CHOICE = 2
|
const val TYPE_SINGLE_CHOICE = 2
|
||||||
@@ -586,6 +624,7 @@ abstract class SettingsItem(
|
|||||||
IntSetting.FSR_SHARPENING_SLIDER,
|
IntSetting.FSR_SHARPENING_SLIDER,
|
||||||
titleId = R.string.fsr_sharpness,
|
titleId = R.string.fsr_sharpness,
|
||||||
descriptionId = R.string.fsr_sharpness_description,
|
descriptionId = R.string.fsr_sharpness_description,
|
||||||
|
max = 200,
|
||||||
units = "%"
|
units = "%"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -607,6 +646,71 @@ abstract class SettingsItem(
|
|||||||
valuesId = R.array.rendererAntiAliasingValues
|
valuesId = R.array.rendererAntiAliasingValues
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
put(
|
||||||
|
SwitchSetting(
|
||||||
|
BooleanSetting.RENDERER_FRAME_GEN,
|
||||||
|
titleId = R.string.frame_gen,
|
||||||
|
descriptionId = R.string.frame_gen_description
|
||||||
|
)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
SingleChoiceSetting(
|
||||||
|
IntSetting.RENDERER_FRAME_GEN_MULTIPLIER,
|
||||||
|
titleId = R.string.frame_gen_multiplier,
|
||||||
|
descriptionId = R.string.frame_gen_multiplier_description,
|
||||||
|
choicesId = R.array.frameGenMultiplierNames,
|
||||||
|
valuesId = R.array.frameGenMultiplierValues
|
||||||
|
)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
SingleChoiceSetting(
|
||||||
|
IntSetting.RENDERER_FRAME_GEN_TARGET_RATE,
|
||||||
|
titleId = R.string.frame_gen_target_rate,
|
||||||
|
descriptionId = R.string.frame_gen_target_rate_description,
|
||||||
|
choicesId = R.array.frameGenTargetRateNames,
|
||||||
|
valuesId = R.array.frameGenTargetRateValues
|
||||||
|
)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
SingleChoiceSetting(
|
||||||
|
IntSetting.RENDERER_FRAME_GEN_QUEUE_TARGET,
|
||||||
|
titleId = R.string.frame_gen_queue_target,
|
||||||
|
descriptionId = R.string.frame_gen_queue_target_description,
|
||||||
|
choicesId = R.array.frameGenQueueTargetNames,
|
||||||
|
valuesId = R.array.frameGenQueueTargetValues
|
||||||
|
)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
SwitchSetting(
|
||||||
|
BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO,
|
||||||
|
titleId = R.string.frame_gen_flow_scale_auto,
|
||||||
|
descriptionId = R.string.frame_gen_flow_scale_auto_description
|
||||||
|
)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
SliderSetting(
|
||||||
|
IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE,
|
||||||
|
titleId = R.string.frame_gen_flow_scale,
|
||||||
|
descriptionId = R.string.frame_gen_flow_scale_description,
|
||||||
|
min = 25,
|
||||||
|
max = 100,
|
||||||
|
units = "%"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
SwitchSetting(
|
||||||
|
BooleanSetting.RENDERER_FRAME_GEN_FP16,
|
||||||
|
titleId = R.string.frame_gen_fp16,
|
||||||
|
descriptionId = R.string.frame_gen_fp16_description
|
||||||
|
)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
SwitchSetting(
|
||||||
|
BooleanSetting.RENDERER_FRAME_GEN_DUMP_FLOW,
|
||||||
|
titleId = R.string.frame_gen_dump_flow,
|
||||||
|
descriptionId = R.string.frame_gen_dump_flow_description
|
||||||
|
)
|
||||||
|
)
|
||||||
put(
|
put(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
IntSetting.RENDERER_SCREEN_LAYOUT,
|
IntSetting.RENDERER_SCREEN_LAYOUT,
|
||||||
@@ -685,13 +789,6 @@ abstract class SettingsItem(
|
|||||||
descriptionId = R.string.renderer_asynchronous_shaders_description
|
descriptionId = R.string.renderer_asynchronous_shaders_description
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
put(
|
|
||||||
SwitchSetting(
|
|
||||||
BooleanSetting.RENDERER_UNIFIED_MEMORY,
|
|
||||||
titleId = R.string.renderer_unified_memory,
|
|
||||||
descriptionId = R.string.renderer_unified_memory_description
|
|
||||||
)
|
|
||||||
)
|
|
||||||
put(
|
put(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
IntSetting.FAST_GPU_TIME,
|
IntSetting.FAST_GPU_TIME,
|
||||||
@@ -780,13 +877,6 @@ abstract class SettingsItem(
|
|||||||
descriptionId = R.string.fix_bloom_effects_description
|
descriptionId = R.string.fix_bloom_effects_description
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
put(
|
|
||||||
SwitchSetting(
|
|
||||||
BooleanSetting.RESCALE_HACK,
|
|
||||||
titleId = R.string.rescale_hack,
|
|
||||||
descriptionId = R.string.rescale_hack_description
|
|
||||||
)
|
|
||||||
)
|
|
||||||
put(
|
put(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
BooleanSetting.EMULATE_BGR565,
|
BooleanSetting.EMULATE_BGR565,
|
||||||
|
|||||||
+3
-1
@@ -382,7 +382,9 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
|
|||||||
}
|
}
|
||||||
scSetting.setSelectedValue(value)
|
scSetting.setSelectedValue(value)
|
||||||
|
|
||||||
if (scSetting.setting.key == IntSetting.RENDERER_SCALING_FILTER.key) {
|
if (scSetting.setting.key == IntSetting.RENDERER_SCALING_FILTER.key ||
|
||||||
|
scSetting.setting.key == IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key
|
||||||
|
) {
|
||||||
settingsViewModel.setShouldReloadSettingsList(true)
|
settingsViewModel.setShouldReloadSettingsList(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+38
-2
@@ -27,6 +27,7 @@ import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
|
|||||||
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.*
|
import org.yuzu.yuzu_emu.features.settings.model.view.*
|
||||||
import org.yuzu.yuzu_emu.utils.InputHandler
|
import org.yuzu.yuzu_emu.utils.InputHandler
|
||||||
|
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
||||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
||||||
import org.yuzu.yuzu_emu.utils.FullscreenHelper
|
import org.yuzu.yuzu_emu.utils.FullscreenHelper
|
||||||
@@ -76,6 +77,41 @@ class SettingsFragmentPresenter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addFrameGenSettings(sl: ArrayList<SettingsItem>) {
|
||||||
|
sl.apply {
|
||||||
|
if (!LosslessScalingHelper.isSupportedByGpu()) {
|
||||||
|
add(
|
||||||
|
RunnableSetting(
|
||||||
|
titleId = R.string.frame_gen_unsupported,
|
||||||
|
descriptionId = R.string.frame_gen_unsupported_description,
|
||||||
|
isRunnable = false
|
||||||
|
) {}
|
||||||
|
)
|
||||||
|
} else if (!LosslessScalingHelper.isInstalled()) {
|
||||||
|
add(
|
||||||
|
RunnableSetting(
|
||||||
|
titleId = R.string.lossless_scaling_missing,
|
||||||
|
descriptionId = R.string.lossless_scaling_missing_description,
|
||||||
|
isRunnable = false
|
||||||
|
) {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
add(BooleanSetting.RENDERER_FRAME_GEN.key)
|
||||||
|
add(IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key)
|
||||||
|
add(IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.key)
|
||||||
|
add(IntSetting.RENDERER_FRAME_GEN_QUEUE_TARGET.key)
|
||||||
|
add(BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.key)
|
||||||
|
if (!BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.getBoolean(
|
||||||
|
getNeedsGlobalForKey(BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.key)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
add(IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE.key)
|
||||||
|
}
|
||||||
|
add(BooleanSetting.RENDERER_FRAME_GEN_FP16.key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun isSharpnessScalingFilterSelected(): Boolean {
|
private fun isSharpnessScalingFilterSelected(): Boolean {
|
||||||
val needsGlobal = getNeedsGlobalForKey(IntSetting.RENDERER_SCALING_FILTER.key)
|
val needsGlobal = getNeedsGlobalForKey(IntSetting.RENDERER_SCALING_FILTER.key)
|
||||||
val selectedFilter = IntSetting.RENDERER_SCALING_FILTER.getInt(needsGlobal)
|
val selectedFilter = IntSetting.RENDERER_SCALING_FILTER.getInt(needsGlobal)
|
||||||
@@ -120,6 +156,7 @@ class SettingsFragmentPresenter(
|
|||||||
MenuTag.SECTION_ROOT -> addConfigSettings(sl)
|
MenuTag.SECTION_ROOT -> addConfigSettings(sl)
|
||||||
MenuTag.SECTION_SYSTEM -> addSystemSettings(sl)
|
MenuTag.SECTION_SYSTEM -> addSystemSettings(sl)
|
||||||
MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl)
|
MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl)
|
||||||
|
MenuTag.SECTION_FRAME_GEN -> addFrameGenSettings(sl)
|
||||||
MenuTag.SECTION_PERFORMANCE_STATS -> addPerformanceOverlaySettings(sl)
|
MenuTag.SECTION_PERFORMANCE_STATS -> addPerformanceOverlaySettings(sl)
|
||||||
MenuTag.SECTION_SOC_OVERLAY -> addSocOverlaySettings(sl)
|
MenuTag.SECTION_SOC_OVERLAY -> addSocOverlaySettings(sl)
|
||||||
MenuTag.SECTION_INPUT_OVERLAY -> addInputOverlaySettings(sl)
|
MenuTag.SECTION_INPUT_OVERLAY -> addInputOverlaySettings(sl)
|
||||||
@@ -302,9 +339,7 @@ class SettingsFragmentPresenter(
|
|||||||
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
|
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
|
||||||
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
|
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
|
||||||
add(BooleanSetting.EMULATE_BGR565.key)
|
add(BooleanSetting.EMULATE_BGR565.key)
|
||||||
add(BooleanSetting.RESCALE_HACK.key)
|
|
||||||
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
|
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
|
||||||
add(BooleanSetting.RENDERER_UNIFIED_MEMORY.key)
|
|
||||||
add(IntSetting.ANDROID_PIPELINE_WORKERS.key)
|
add(IntSetting.ANDROID_PIPELINE_WORKERS.key)
|
||||||
add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key)
|
add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key)
|
||||||
add(BooleanSetting.RENDERER_ASYNC_PRESENTATION.key)
|
add(BooleanSetting.RENDERER_ASYNC_PRESENTATION.key)
|
||||||
@@ -1297,6 +1332,7 @@ class SettingsFragmentPresenter(
|
|||||||
add(BooleanSetting.DUMP_GUEST_SHADERS.key)
|
add(BooleanSetting.DUMP_GUEST_SHADERS.key)
|
||||||
add(BooleanSetting.GPU_LOG_SHADER_DUMPS.key)
|
add(BooleanSetting.GPU_LOG_SHADER_DUMPS.key)
|
||||||
add(BooleanSetting.DUMP_MACROS.key)
|
add(BooleanSetting.DUMP_MACROS.key)
|
||||||
|
add(BooleanSetting.RENDERER_FRAME_GEN_DUMP_FLOW.key)
|
||||||
add(BooleanSetting.GPU_LOG_MEMORY_TRACKING.key)
|
add(BooleanSetting.GPU_LOG_MEMORY_TRACKING.key)
|
||||||
add(BooleanSetting.GPU_LOG_DRIVER_DEBUG.key)
|
add(BooleanSetting.GPU_LOG_DRIVER_DEBUG.key)
|
||||||
add(IntSetting.GPU_LOG_RING_BUFFER_SIZE.key)
|
add(IntSetting.GPU_LOG_RING_BUFFER_SIZE.key)
|
||||||
|
|||||||
+2
@@ -29,6 +29,7 @@ enum class SettingsSubscreen {
|
|||||||
DRIVER_MANAGER,
|
DRIVER_MANAGER,
|
||||||
DRIVER_FETCHER,
|
DRIVER_FETCHER,
|
||||||
FREEDRENO_SETTINGS,
|
FREEDRENO_SETTINGS,
|
||||||
|
LOSSLESS_MANAGER,
|
||||||
APPLET_LAUNCHER,
|
APPLET_LAUNCHER,
|
||||||
INSTALLABLE,
|
INSTALLABLE,
|
||||||
GAME_FOLDERS,
|
GAME_FOLDERS,
|
||||||
@@ -126,6 +127,7 @@ class SettingsSubscreenActivity : AppCompatActivity() {
|
|||||||
SettingsSubscreen.DRIVER_MANAGER -> R.id.driverManagerFragment
|
SettingsSubscreen.DRIVER_MANAGER -> R.id.driverManagerFragment
|
||||||
SettingsSubscreen.DRIVER_FETCHER -> R.id.driverFetcherFragment
|
SettingsSubscreen.DRIVER_FETCHER -> R.id.driverFetcherFragment
|
||||||
SettingsSubscreen.FREEDRENO_SETTINGS -> R.id.freedrenoSettingsFragment
|
SettingsSubscreen.FREEDRENO_SETTINGS -> R.id.freedrenoSettingsFragment
|
||||||
|
SettingsSubscreen.LOSSLESS_MANAGER -> R.id.losslessManagerFragment
|
||||||
SettingsSubscreen.APPLET_LAUNCHER -> R.id.appletLauncherFragment
|
SettingsSubscreen.APPLET_LAUNCHER -> R.id.appletLauncherFragment
|
||||||
SettingsSubscreen.INSTALLABLE -> R.id.installableFragment
|
SettingsSubscreen.INSTALLABLE -> R.id.installableFragment
|
||||||
SettingsSubscreen.GAME_FOLDERS -> R.id.gameFoldersFragment
|
SettingsSubscreen.GAME_FOLDERS -> R.id.gameFoldersFragment
|
||||||
|
|||||||
@@ -1182,7 +1182,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
container,
|
container,
|
||||||
IntSetting.FSR_SHARPENING_SLIDER,
|
IntSetting.FSR_SHARPENING_SLIDER,
|
||||||
minValue = 0,
|
minValue = 0,
|
||||||
maxValue = 100,
|
maxValue = 200,
|
||||||
units = "%"
|
units = "%"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -369,6 +369,21 @@ class GamePropertiesFragment : Fragment() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(
|
||||||
|
SubmenuProperty(
|
||||||
|
R.string.frame_gen,
|
||||||
|
R.string.frame_gen_per_game_description,
|
||||||
|
R.drawable.ic_duck,
|
||||||
|
action = {
|
||||||
|
val action = HomeNavigationDirections.actionGlobalSettingsActivity(
|
||||||
|
args.game,
|
||||||
|
Settings.MenuTag.SECTION_FRAME_GEN
|
||||||
|
)
|
||||||
|
binding.root.findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if (GpuDriverHelper.isAdrenoGpu()) {
|
if (GpuDriverHelper.isAdrenoGpu()) {
|
||||||
add(
|
add(
|
||||||
SubmenuProperty(
|
SubmenuProperty(
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import org.yuzu.yuzu_emu.ui.main.MainActivity
|
|||||||
import org.yuzu.yuzu_emu.utils.FileUtil
|
import org.yuzu.yuzu_emu.utils.FileUtil
|
||||||
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
||||||
import org.yuzu.yuzu_emu.utils.Log
|
import org.yuzu.yuzu_emu.utils.Log
|
||||||
|
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
||||||
import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins
|
import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins
|
||||||
|
|
||||||
class HomeSettingsFragment : Fragment() {
|
class HomeSettingsFragment : Fragment() {
|
||||||
@@ -170,6 +171,24 @@ class HomeSettingsFragment : Fragment() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(
|
||||||
|
HomeSetting(
|
||||||
|
R.string.lossless_scaling,
|
||||||
|
R.string.lossless_scaling_description,
|
||||||
|
R.drawable.ic_duck,
|
||||||
|
{
|
||||||
|
val action = HomeNavigationDirections.actionGlobalSettingsSubscreenActivity(
|
||||||
|
SettingsSubscreen.LOSSLESS_MANAGER,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
binding.root.findNavController().navigate(action)
|
||||||
|
},
|
||||||
|
{ true },
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
LosslessScalingHelper.statusText
|
||||||
|
)
|
||||||
|
)
|
||||||
add(
|
add(
|
||||||
HomeSetting(
|
HomeSetting(
|
||||||
R.string.multiplayer,
|
R.string.multiplayer,
|
||||||
@@ -337,6 +356,7 @@ class HomeSettingsFragment : Fragment() {
|
|||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
driverViewModel.updateDriverNameForGame(null)
|
driverViewModel.updateDriverNameForGame(null)
|
||||||
|
LosslessScalingHelper.refreshStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
|||||||
@@ -0,0 +1,174 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.fragments
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
import org.yuzu.yuzu_emu.adapters.HomeSettingAdapter
|
||||||
|
import org.yuzu.yuzu_emu.databinding.FragmentLosslessManagerBinding
|
||||||
|
import org.yuzu.yuzu_emu.features.fetcher.SpacingItemDecoration
|
||||||
|
import org.yuzu.yuzu_emu.model.HomeSetting
|
||||||
|
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
||||||
|
import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins
|
||||||
|
import org.yuzu.yuzu_emu.utils.collect
|
||||||
|
|
||||||
|
class LosslessManagerFragment : Fragment() {
|
||||||
|
private var _binding: FragmentLosslessManagerBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||||
|
returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||||
|
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||||
|
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
_binding = FragmentLosslessManagerBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
binding.toolbarLossless.setNavigationOnClickListener {
|
||||||
|
requireActivity().onBackPressedDispatcher.onBackPressed()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.losslessOptionsList.apply {
|
||||||
|
layoutManager =
|
||||||
|
GridLayoutManager(requireContext(), resources.getInteger(R.integer.grid_columns))
|
||||||
|
addItemDecoration(
|
||||||
|
SpacingItemDecoration(resources.getDimensionPixelSize(R.dimen.spacing_small))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
LosslessScalingHelper.statusText.collect(viewLifecycleOwner) { refreshOptions() }
|
||||||
|
|
||||||
|
setInsets()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshOptions() {
|
||||||
|
binding.losslessOptionsList.adapter = HomeSettingAdapter(
|
||||||
|
requireActivity() as AppCompatActivity,
|
||||||
|
viewLifecycleOwner,
|
||||||
|
buildOptions()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildOptions(): List<HomeSetting> {
|
||||||
|
val installed = LosslessScalingHelper.isInstalled()
|
||||||
|
return listOf(
|
||||||
|
HomeSetting(
|
||||||
|
if (installed) R.string.lossless_scaling_replace else R.string.lossless_scaling_install,
|
||||||
|
if (installed) {
|
||||||
|
R.string.lossless_scaling_replace_description
|
||||||
|
} else {
|
||||||
|
R.string.lossless_scaling_install_description
|
||||||
|
},
|
||||||
|
R.drawable.ic_install,
|
||||||
|
{ dllPickerLauncher.launch(arrayOf("*/*")) },
|
||||||
|
{ !NativeLibrary.isRunning() },
|
||||||
|
R.string.lossless_scaling_locked,
|
||||||
|
R.string.lossless_scaling_locked_description,
|
||||||
|
LosslessScalingHelper.statusText
|
||||||
|
),
|
||||||
|
HomeSetting(
|
||||||
|
R.string.lossless_scaling_remove,
|
||||||
|
R.string.lossless_scaling_remove_description,
|
||||||
|
R.drawable.ic_delete,
|
||||||
|
{ confirmRemoval() },
|
||||||
|
{ installed && !NativeLibrary.isRunning() },
|
||||||
|
if (installed) {
|
||||||
|
R.string.lossless_scaling_locked
|
||||||
|
} else {
|
||||||
|
R.string.lossless_scaling_remove_unavailable
|
||||||
|
},
|
||||||
|
if (installed) {
|
||||||
|
R.string.lossless_scaling_locked_description
|
||||||
|
} else {
|
||||||
|
R.string.lossless_scaling_remove_unavailable_description
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun confirmRemoval() {
|
||||||
|
MessageDialogFragment.newInstance(
|
||||||
|
requireActivity(),
|
||||||
|
titleId = R.string.lossless_scaling_remove,
|
||||||
|
descriptionId = R.string.lossless_scaling_remove_confirmation,
|
||||||
|
positiveButtonTitleId = R.string.lossless_scaling_remove,
|
||||||
|
positiveAction = { LosslessScalingHelper.remove() },
|
||||||
|
showNegativeButton = true,
|
||||||
|
negativeAction = {}
|
||||||
|
).show(parentFragmentManager, MessageDialogFragment.TAG)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val dllPickerLauncher =
|
||||||
|
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||||
|
if (result == null) {
|
||||||
|
return@registerForActivityResult
|
||||||
|
}
|
||||||
|
|
||||||
|
val resultStrings = resources.getStringArray(R.array.losslessDllResults)
|
||||||
|
ProgressDialogFragment.newInstance(
|
||||||
|
requireActivity(),
|
||||||
|
R.string.lossless_scaling_installing,
|
||||||
|
false
|
||||||
|
) { _, _ ->
|
||||||
|
val installResult = LosslessScalingHelper.install(result)
|
||||||
|
if (installResult == LosslessScalingHelper.RESULT_OK) {
|
||||||
|
getString(R.string.lossless_scaling_install_success)
|
||||||
|
} else {
|
||||||
|
MessageDialogFragment.newInstance(
|
||||||
|
titleId = R.string.lossless_scaling_install_failed,
|
||||||
|
descriptionString = resultStrings[installResult]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.show(parentFragmentManager, ProgressDialogFragment.TAG)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setInsets() =
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, windowInsets ->
|
||||||
|
val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout())
|
||||||
|
|
||||||
|
binding.appbarLossless.updateMargins(
|
||||||
|
left = barInsets.left + cutoutInsets.left,
|
||||||
|
right = barInsets.right + cutoutInsets.right
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.scrollViewLossless.updatePadding(bottom = barInsets.bottom)
|
||||||
|
|
||||||
|
binding.losslessOptionsList.updatePadding(
|
||||||
|
left = barInsets.left + cutoutInsets.left,
|
||||||
|
right = barInsets.right + cutoutInsets.right
|
||||||
|
)
|
||||||
|
|
||||||
|
windowInsets
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.fragments
|
package org.yuzu.yuzu_emu.fragments
|
||||||
@@ -42,6 +42,7 @@ import org.yuzu.yuzu_emu.model.SetupPage
|
|||||||
import org.yuzu.yuzu_emu.model.PageState
|
import org.yuzu.yuzu_emu.model.PageState
|
||||||
import org.yuzu.yuzu_emu.ui.main.MainActivity
|
import org.yuzu.yuzu_emu.ui.main.MainActivity
|
||||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
||||||
|
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
||||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
import org.yuzu.yuzu_emu.utils.ViewUtils
|
import org.yuzu.yuzu_emu.utils.ViewUtils
|
||||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
||||||
@@ -202,6 +203,24 @@ class SetupFragment : Fragment() {
|
|||||||
R.string.install_firmware_warning_help,
|
R.string.install_firmware_warning_help,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
add(
|
||||||
|
PageButton(
|
||||||
|
R.drawable.ic_duck,
|
||||||
|
R.string.lossless_scaling,
|
||||||
|
R.string.lossless_scaling_setup_description,
|
||||||
|
{
|
||||||
|
pageButtonCallback = it
|
||||||
|
getLosslessDll.launch(arrayOf("*/*"))
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (LosslessScalingHelper.isInstalled()) {
|
||||||
|
ButtonState.BUTTON_ACTION_COMPLETE
|
||||||
|
} else {
|
||||||
|
ButtonState.BUTTON_ACTION_INCOMPLETE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
add(
|
add(
|
||||||
PageButton(
|
PageButton(
|
||||||
R.drawable.ic_controller,
|
R.drawable.ic_controller,
|
||||||
@@ -446,6 +465,32 @@ class SetupFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val getLosslessDll =
|
||||||
|
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||||
|
if (result == null) {
|
||||||
|
return@registerForActivityResult
|
||||||
|
}
|
||||||
|
|
||||||
|
val resultStrings = resources.getStringArray(R.array.losslessDllResults)
|
||||||
|
ProgressDialogFragment.newInstance(
|
||||||
|
requireActivity(),
|
||||||
|
R.string.lossless_scaling_installing,
|
||||||
|
false
|
||||||
|
) { _, _ ->
|
||||||
|
val installResult = LosslessScalingHelper.install(result)
|
||||||
|
if (installResult == LosslessScalingHelper.RESULT_OK) {
|
||||||
|
getString(R.string.lossless_scaling_install_success)
|
||||||
|
} else {
|
||||||
|
MessageDialogFragment.newInstance(
|
||||||
|
titleId = R.string.lossless_scaling_install_failed,
|
||||||
|
descriptionString = resultStrings[installResult]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.apply {
|
||||||
|
onDialogComplete = { checkForButtonState.invoke() }
|
||||||
|
}.show(parentFragmentManager, ProgressDialogFragment.TAG)
|
||||||
|
}
|
||||||
|
|
||||||
val getGamesDirectory =
|
val getGamesDirectory =
|
||||||
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { result ->
|
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { result ->
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
|||||||
+13
-1
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.fragments
|
package org.yuzu.yuzu_emu.fragments
|
||||||
@@ -72,6 +72,18 @@ class SystemInfoDialogFragment : DialogFragment() {
|
|||||||
|
|
||||||
val vulkanDriver = NativeLibrary.getVulkanDriverVersion()
|
val vulkanDriver = NativeLibrary.getVulkanDriverVersion()
|
||||||
appendLine("${getString(R.string.vulkan_driver_version)}: $vulkanDriver")
|
appendLine("${getString(R.string.vulkan_driver_version)}: $vulkanDriver")
|
||||||
|
|
||||||
|
val frameGen = NativeLibrary.supportsFrameGeneration()
|
||||||
|
appendLine(
|
||||||
|
"${getString(R.string.frame_generation_support)}: " +
|
||||||
|
getString(
|
||||||
|
if (frameGen) {
|
||||||
|
R.string.frame_generation_supported
|
||||||
|
} else {
|
||||||
|
R.string.frame_generation_unsupported
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
appendLine("${getString(R.string.error_getting_emulator_info)}: ${e.message}")
|
appendLine("${getString(R.string.error_getting_emulator_info)}: ${e.message}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.utils
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
object LosslessScalingHelper {
|
||||||
|
const val RESULT_OK = 0
|
||||||
|
const val RESULT_NOT_INSTALLED = 1
|
||||||
|
|
||||||
|
private val _statusText = MutableStateFlow("")
|
||||||
|
val statusText: StateFlow<String> = _statusText.asStateFlow()
|
||||||
|
|
||||||
|
private var installed: Boolean? = null
|
||||||
|
private var gpuSupported: Boolean? = null
|
||||||
|
|
||||||
|
fun isInstalled(): Boolean = installed ?: refreshStatus()
|
||||||
|
|
||||||
|
fun isSupportedByGpu(): Boolean {
|
||||||
|
val cached = gpuSupported
|
||||||
|
if (cached != null) {
|
||||||
|
return cached
|
||||||
|
}
|
||||||
|
val result = NativeLibrary.supportsFrameGeneration()
|
||||||
|
gpuSupported = result
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun refreshStatus(): Boolean {
|
||||||
|
val result = NativeLibrary.validateLosslessDll() == RESULT_OK
|
||||||
|
installed = result
|
||||||
|
|
||||||
|
val context = YuzuApplication.appContext
|
||||||
|
_statusText.value = if (result) {
|
||||||
|
context.getString(R.string.lossless_scaling_installed)
|
||||||
|
} else {
|
||||||
|
context.getString(R.string.lossless_scaling_not_installed)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun install(source: Uri): Int {
|
||||||
|
val destination = File(NativeLibrary.getLosslessDllPath())
|
||||||
|
destination.parentFile?.mkdirs()
|
||||||
|
|
||||||
|
val copied = FileUtil.copyUriToInternalStorage(
|
||||||
|
source,
|
||||||
|
destination.parent!!,
|
||||||
|
destination.name
|
||||||
|
)
|
||||||
|
if (copied == null) {
|
||||||
|
refreshStatus()
|
||||||
|
return RESULT_NOT_INSTALLED
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = NativeLibrary.prepareLosslessDll()
|
||||||
|
if (result != RESULT_OK) {
|
||||||
|
NativeLibrary.removeLosslessDll()
|
||||||
|
}
|
||||||
|
refreshStatus()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove(): Boolean {
|
||||||
|
val removed = NativeLibrary.removeLosslessDll()
|
||||||
|
refreshStatus()
|
||||||
|
return removed
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,8 +33,9 @@ void AndroidConfig::SaveAllValues() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AndroidConfig::ReadAndroidValues() {
|
void AndroidConfig::ReadAndroidValues() {
|
||||||
|
Settings::values.rescale_hack.SetValue(false);
|
||||||
|
ReadAndroidUIValues();
|
||||||
if (global) {
|
if (global) {
|
||||||
ReadAndroidUIValues();
|
|
||||||
ReadUIValues();
|
ReadUIValues();
|
||||||
BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage));
|
BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage));
|
||||||
Settings::values.ext_content_from_game_dirs = ReadBooleanSetting(
|
Settings::values.ext_content_from_game_dirs = ReadBooleanSetting(
|
||||||
@@ -223,8 +224,8 @@ void AndroidConfig::ReadAndroidControlValues() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AndroidConfig::SaveAndroidValues() {
|
void AndroidConfig::SaveAndroidValues() {
|
||||||
|
SaveAndroidUIValues();
|
||||||
if (global) {
|
if (global) {
|
||||||
SaveAndroidUIValues();
|
|
||||||
SaveUIValues();
|
SaveUIValues();
|
||||||
SaveOverlayValues();
|
SaveOverlayValues();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ namespace AndroidSettings {
|
|||||||
&show_performance_overlay};
|
&show_performance_overlay};
|
||||||
|
|
||||||
|
|
||||||
Settings::Setting<s32> pipeline_worker_count{linkage, 4, "pipeline_worker_count",
|
Settings::SwitchableSetting<s32> pipeline_worker_count{linkage, 2, "pipeline_worker_count",
|
||||||
Settings::Category::Android,
|
Settings::Category::Android,
|
||||||
Settings::Specialization::Default,
|
Settings::Specialization::Default,
|
||||||
true,
|
true,
|
||||||
|
|||||||
@@ -124,9 +124,18 @@ float EmuWindow_Android::GetFrameTimeVerifiedHint() const {
|
|||||||
return QuantizeFrameRateHint(verified_rate);
|
return QuantizeFrameRateHint(verified_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float EmuWindow_Android::GetPresentedFrameMultiplier() {
|
||||||
|
if (!Settings::values.frame_gen.GetValue()) {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
return static_cast<float>(std::clamp<u32>(Settings::values.frame_gen_multiplier.GetValue(), 2, 4));
|
||||||
|
}
|
||||||
|
|
||||||
float EmuWindow_Android::GetFrameRateHint() const {
|
float EmuWindow_Android::GetFrameRateHint() const {
|
||||||
const float observed_rate = std::clamp(m_smoothed_present_rate, 0.0f, 240.0f);
|
const float presented_multiplier = GetPresentedFrameMultiplier();
|
||||||
const float frame_time_verified_hint = GetFrameTimeVerifiedHint();
|
const float observed_rate =
|
||||||
|
std::clamp(m_smoothed_present_rate * presented_multiplier, 0.0f, 240.0f);
|
||||||
|
const float frame_time_verified_hint = GetFrameTimeVerifiedHint() * presented_multiplier;
|
||||||
|
|
||||||
if (m_last_frame_rate_hint > 0.0f && observed_rate > 0.0f) {
|
if (m_last_frame_rate_hint > 0.0f && observed_rate > 0.0f) {
|
||||||
const float tolerance = std::max(m_last_frame_rate_hint * 0.12f, 4.0f);
|
const float tolerance = std::max(m_last_frame_rate_hint * 0.12f, 4.0f);
|
||||||
@@ -150,9 +159,9 @@ float EmuWindow_Android::GetFrameRateHint() const {
|
|||||||
return frame_time_verified_hint;
|
return frame_time_verified_hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr float NominalFrameRate = 60.0f;
|
const float nominal_rate = 60.0f * presented_multiplier;
|
||||||
if (!Settings::values.use_speed_limit.GetValue()) {
|
if (!Settings::values.use_speed_limit.GetValue()) {
|
||||||
return NominalFrameRate;
|
return QuantizeFrameRateHint(nominal_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u16 speed_limit = Settings::SpeedLimit();
|
const u16 speed_limit = Settings::SpeedLimit();
|
||||||
@@ -161,7 +170,7 @@ float EmuWindow_Android::GetFrameRateHint() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const float speed_limited_rate =
|
const float speed_limited_rate =
|
||||||
NominalFrameRate * (static_cast<float>(std::min<u16>(speed_limit, 100)) / 100.0f);
|
nominal_rate * (static_cast<float>(std::min<u16>(speed_limit, 100)) / 100.0f);
|
||||||
return QuantizeFrameRateHint(speed_limited_rate);
|
return QuantizeFrameRateHint(speed_limited_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ private:
|
|||||||
void UpdateObservedFrameRate();
|
void UpdateObservedFrameRate();
|
||||||
[[nodiscard]] float GetFrameRateHint() const;
|
[[nodiscard]] float GetFrameRateHint() const;
|
||||||
[[nodiscard]] float GetFrameTimeVerifiedHint() const;
|
[[nodiscard]] float GetFrameTimeVerifiedHint() const;
|
||||||
|
[[nodiscard]] static float GetPresentedFrameMultiplier();
|
||||||
[[nodiscard]] static float QuantizeFrameRateHint(float frame_rate);
|
[[nodiscard]] static float QuantizeFrameRateHint(float frame_rate);
|
||||||
|
|
||||||
float m_window_width{};
|
float m_window_width{};
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ extern "C" {
|
|||||||
#include "common/android/android_common.h"
|
#include "common/android/android_common.h"
|
||||||
#include "common/android/id_cache.h"
|
#include "common/android/id_cache.h"
|
||||||
#include "common/dynamic_library.h"
|
#include "common/dynamic_library.h"
|
||||||
|
#include "common/fs/fs_util.h"
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
@@ -90,6 +91,7 @@ extern "C" {
|
|||||||
#include "hid_core/hid_types.h"
|
#include "hid_core/hid_types.h"
|
||||||
#include "input_common/drivers/virtual_amiibo.h"
|
#include "input_common/drivers/virtual_amiibo.h"
|
||||||
#include "jni/native.h"
|
#include "jni/native.h"
|
||||||
|
#include "video_core/frame_gen/lossless_dll.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
||||||
#include "video_core/capture.h"
|
#include "video_core/capture.h"
|
||||||
@@ -998,7 +1000,7 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuSummary(JNIEnv* env, jobject
|
|||||||
FILE* f = std::fopen(CPUINFO_PATH, "r");
|
FILE* f = std::fopen(CPUINFO_PATH, "r");
|
||||||
if (!f) return Common::Android::ToJString(env, result);
|
if (!f) return Common::Android::ToJString(env, result);
|
||||||
|
|
||||||
char buf[512];
|
char buf[4096];
|
||||||
|
|
||||||
if (f) {
|
if (f) {
|
||||||
std::set<std::string> feature_set;
|
std::set<std::string> feature_set;
|
||||||
@@ -1029,7 +1031,13 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuSummary(JNIEnv* env, jobject
|
|||||||
bool has_dotprod = feature_set.count("asimddp") || feature_set.count("dotprod");
|
bool has_dotprod = feature_set.count("asimddp") || feature_set.count("dotprod");
|
||||||
bool has_i8mm = feature_set.count("i8mm");
|
bool has_i8mm = feature_set.count("i8mm");
|
||||||
bool has_bf16 = feature_set.count("bf16");
|
bool has_bf16 = feature_set.count("bf16");
|
||||||
|
bool has_fp16 = feature_set.count("fphp") || feature_set.count("asimdhp");
|
||||||
bool has_atomics = feature_set.count("atomics") || feature_set.count("lse");
|
bool has_atomics = feature_set.count("atomics") || feature_set.count("lse");
|
||||||
|
bool has_lse2 = feature_set.count("uscat");
|
||||||
|
bool has_rcpc = feature_set.count("lrcpc");
|
||||||
|
bool has_rcpc2 = feature_set.count("ilrcpc");
|
||||||
|
bool has_flagm = feature_set.count("flagm");
|
||||||
|
bool has_flagm2 = feature_set.count("flagm2");
|
||||||
|
|
||||||
std::string features;
|
std::string features;
|
||||||
if (has_neon || has_fp) {
|
if (has_neon || has_fp) {
|
||||||
@@ -1037,6 +1045,7 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuSummary(JNIEnv* env, jobject
|
|||||||
if (has_dotprod) features += "+DP";
|
if (has_dotprod) features += "+DP";
|
||||||
if (has_i8mm) features += "+I8MM";
|
if (has_i8mm) features += "+I8MM";
|
||||||
if (has_bf16) features += "+BF16";
|
if (has_bf16) features += "+BF16";
|
||||||
|
if (has_fp16) features += "+FP16";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_sve) {
|
if (has_sve) {
|
||||||
@@ -1053,6 +1062,19 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuSummary(JNIEnv* env, jobject
|
|||||||
if (has_atomics) {
|
if (has_atomics) {
|
||||||
if (!features.empty()) features += " | ";
|
if (!features.empty()) features += " | ";
|
||||||
features += "LSE";
|
features += "LSE";
|
||||||
|
if (has_lse2) features += "2";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_rcpc) {
|
||||||
|
if (!features.empty()) features += " | ";
|
||||||
|
features += "RCpc";
|
||||||
|
if (has_rcpc2) features += "2";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_flagm) {
|
||||||
|
if (!features.empty()) features += " | ";
|
||||||
|
features += "FlagM";
|
||||||
|
if (has_flagm2) features += "2";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!features.empty()) {
|
if (!features.empty()) {
|
||||||
@@ -1090,6 +1112,34 @@ VkPhysicalDeviceProperties GetVulkanDeviceProperties() {
|
|||||||
const Vulkan::vk::PhysicalDevice physical_device(physical_devices[0], dld);
|
const Vulkan::vk::PhysicalDevice physical_device(physical_devices[0], dld);
|
||||||
return physical_device.GetProperties();
|
return physical_device.GetProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetVulkanMemoryModelSupport() {
|
||||||
|
Common::DynamicLibrary library;
|
||||||
|
if (!library.Open("libvulkan.so")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vulkan::vk::InstanceDispatch dld;
|
||||||
|
const auto instance = Vulkan::CreateInstance(library, dld, VK_API_VERSION_1_1);
|
||||||
|
const auto physical_devices = instance.EnumeratePhysicalDevices();
|
||||||
|
if (physical_devices.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vulkan::vk::PhysicalDevice physical_device(physical_devices[0], dld);
|
||||||
|
|
||||||
|
VkPhysicalDeviceVulkanMemoryModelFeatures memory_model{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES,
|
||||||
|
.pNext = nullptr,
|
||||||
|
};
|
||||||
|
VkPhysicalDeviceFeatures2 features{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
|
||||||
|
.pNext = &memory_model,
|
||||||
|
};
|
||||||
|
physical_device.GetFeatures2(features);
|
||||||
|
|
||||||
|
return memory_model.vulkanMemoryModel == VK_TRUE;
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getVulkanDriverVersion(JNIEnv* env, jobject jobj) {
|
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getVulkanDriverVersion(JNIEnv* env, jobject jobj) {
|
||||||
@@ -1165,6 +1215,14 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getVulkanApiVersion(JNIEnv* env, j
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_supportsFrameGeneration(JNIEnv* env, jobject jobj) {
|
||||||
|
try {
|
||||||
|
return static_cast<jboolean>(GetVulkanMemoryModelSupport());
|
||||||
|
} catch (...) {
|
||||||
|
return static_cast<jboolean>(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getGpuModel(JNIEnv* env, jobject jobj) {
|
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getGpuModel(JNIEnv* env, jobject jobj) {
|
||||||
const auto props = GetVulkanDeviceProperties();
|
const auto props = GetVulkanDeviceProperties();
|
||||||
if (props.deviceID == 0) {
|
if (props.deviceID == 0) {
|
||||||
@@ -1390,6 +1448,39 @@ jint Java_org_yuzu_yuzu_1emu_NativeLibrary_installKeys(JNIEnv* env, jclass clazz
|
|||||||
return static_cast<int>(FirmwareManager::InstallKeys(path, ext));
|
return static_cast<int>(FirmwareManager::InstallKeys(path, ext));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getLosslessDllPath(JNIEnv* env, jclass clazz) {
|
||||||
|
#ifdef HAS_LSFG
|
||||||
|
const auto path = VideoCore::FrameGen::GetLosslessDllPath();
|
||||||
|
return Common::Android::ToJString(env, Common::FS::PathToUTF8String(path));
|
||||||
|
#else
|
||||||
|
return Common::Android::ToJString(env, "");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_validateLosslessDll(JNIEnv* env, jclass clazz) {
|
||||||
|
#ifdef HAS_LSFG
|
||||||
|
return static_cast<jint>(VideoCore::FrameGen::GetInstalledLosslessStatus());
|
||||||
|
#else
|
||||||
|
return static_cast<jint>(VideoCore::FrameGen::LosslessStatus::NotInstalled);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_prepareLosslessDll(JNIEnv* env, jclass clazz) {
|
||||||
|
#ifdef HAS_LSFG
|
||||||
|
return static_cast<jint>(VideoCore::FrameGen::BuildShaderCache());
|
||||||
|
#else
|
||||||
|
return static_cast<jint>(VideoCore::FrameGen::LosslessStatus::NotInstalled);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_removeLosslessDll(JNIEnv* env, jclass clazz) {
|
||||||
|
#ifdef HAS_LSFG
|
||||||
|
return static_cast<jboolean>(VideoCore::FrameGen::RemoveInstalledLosslessDll());
|
||||||
|
#else
|
||||||
|
return static_cast<jboolean>(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj,
|
jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj,
|
||||||
jstring jpath,
|
jstring jpath,
|
||||||
jstring jprogramId) {
|
jstring jprogramId) {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M11,10.6a8,5.2 0 1,0 0,10.4a8,5.2 0 1,0 0,-10.4z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M4.6,12.6L0.8,10.2L3.2,15.5z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M15.3,3.5a4,4 0 1,0 0,8a4,4 0 1,0 0,-8zM16.6,4.9a1,1 0 1,0 0,2a1,1 0 1,0 0,-2z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M18.6,6.5L23.2,7.8L18.6,9.3z" />
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar_lossless"
|
||||||
|
style="@style/Widget.Eden.TransparentTopAppBarLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar_lossless"
|
||||||
|
style="@style/Widget.Eden.TransparentTopToolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:touchscreenBlocksFocus="false"
|
||||||
|
app:navigationIcon="@drawable/ic_back"
|
||||||
|
app:title="@string/lossless_scaling" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/scroll_view_lossless"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
|
android:fadeScrollbars="false"
|
||||||
|
android:scrollbars="vertical"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/appbar_lossless">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="16dp"
|
||||||
|
android:paddingTop="16dp">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/lossless_options_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:nestedScrollingEnabled="false" />
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -47,6 +47,12 @@
|
|||||||
android:defaultValue="@null" />
|
android:defaultValue="@null" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/losslessManagerFragment"
|
||||||
|
android:name="org.yuzu.yuzu_emu.fragments.LosslessManagerFragment"
|
||||||
|
android:label="@string/lossless_scaling"
|
||||||
|
tools:layout="@layout/fragment_lossless_manager" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/appletLauncherFragment"
|
android:id="@+id/appletLauncherFragment"
|
||||||
android:name="org.yuzu.yuzu_emu.fragments.AppletLauncherFragment"
|
android:name="org.yuzu.yuzu_emu.fragments.AppletLauncherFragment"
|
||||||
|
|||||||
@@ -514,8 +514,6 @@
|
|||||||
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno A6XX - A7XX/ Turnip)، ويزيل التوهج في Burnout. تحذير: قد يسبب تشوهات رسومية في ألعاب أخرى.</string>
|
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno A6XX - A7XX/ Turnip)، ويزيل التوهج في Burnout. تحذير: قد يسبب تشوهات رسومية في ألعاب أخرى.</string>
|
||||||
<string name="emulate_bgr565">محاكاة BGR565</string>
|
<string name="emulate_bgr565">محاكاة BGR565</string>
|
||||||
<string name="emulate_bgr565_description">يُصلح مشاكل انعكاس الألوان في الألعاب أو ظهور تشوهات غريبة أو ظلال غريبة.</string>
|
<string name="emulate_bgr565_description">يُصلح مشاكل انعكاس الألوان في الألعاب أو ظهور تشوهات غريبة أو ظلال غريبة.</string>
|
||||||
<string name="rescale_hack">تفعيل ميزة إعادة التحجيم القديمة</string>
|
|
||||||
<string name="rescale_hack_description">يُمكّن هذا الخيار من التعامل مع عملية إعادة تحجيم الألعاب بطريقة تقليدية باستخدام مسار إعادة التحجيم السريع</string>
|
|
||||||
<string name="renderer_asynchronous_shaders">استخدم تظليل غير متزامن</string>
|
<string name="renderer_asynchronous_shaders">استخدم تظليل غير متزامن</string>
|
||||||
<string name="renderer_asynchronous_shaders_description">يقوم بتجميع التظليل بشكل غير متزامن. قد يقلل ذلك من التقطعات ولكنه قد يؤدي أيضًا إلى حدوث أخطاء.</string>
|
<string name="renderer_asynchronous_shaders_description">يقوم بتجميع التظليل بشكل غير متزامن. قد يقلل ذلك من التقطعات ولكنه قد يؤدي أيضًا إلى حدوث أخطاء.</string>
|
||||||
<string name="gpu_unswizzle_settings">إعدادات إلغاء ترتيب بيانات وحدة معالجة الرسومات</string>
|
<string name="gpu_unswizzle_settings">إعدادات إلغاء ترتيب بيانات وحدة معالجة الرسومات</string>
|
||||||
@@ -1088,7 +1086,6 @@
|
|||||||
<string name="theme_mode_light">فاتح</string>
|
<string name="theme_mode_light">فاتح</string>
|
||||||
<string name="theme_mode_dark">داكن</string>
|
<string name="theme_mode_dark">داكن</string>
|
||||||
|
|
||||||
<string name="multiplier_none">لا شيء</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">خلفيات سوداء</string>
|
<string name="use_black_backgrounds">خلفيات سوداء</string>
|
||||||
|
|||||||
@@ -1004,7 +1004,6 @@ Wirklich fortfahren?</string>
|
|||||||
<string name="theme_mode_light">Hell</string>
|
<string name="theme_mode_light">Hell</string>
|
||||||
<string name="theme_mode_dark">Dunkel</string>
|
<string name="theme_mode_dark">Dunkel</string>
|
||||||
|
|
||||||
<string name="multiplier_none">Keine</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Schwarze Hintergründe</string>
|
<string name="use_black_backgrounds">Schwarze Hintergründe</string>
|
||||||
|
|||||||
@@ -506,8 +506,6 @@
|
|||||||
<string name="fix_bloom_effects_description">Reduce el efecto de resplandor en LA/EOW (Adreno A6XX - A7XX/ Turnip), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos.</string>
|
<string name="fix_bloom_effects_description">Reduce el efecto de resplandor en LA/EOW (Adreno A6XX - A7XX/ Turnip), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos.</string>
|
||||||
<string name="emulate_bgr565">Emular BGR565</string>
|
<string name="emulate_bgr565">Emular BGR565</string>
|
||||||
<string name="emulate_bgr565_description">Soluciona problemas con colores invertidos en juegos, artefactos o sombras extrañas.</string>
|
<string name="emulate_bgr565_description">Soluciona problemas con colores invertidos en juegos, artefactos o sombras extrañas.</string>
|
||||||
<string name="rescale_hack">Activar la pasada de reescalado heredada</string>
|
|
||||||
<string name="rescale_hack_description">Permite el manejo de versiones anteriores para el paso de configuración de reescalado para juegos mediante el uso de una ruta de reescalado rápida.</string>
|
|
||||||
<string name="renderer_asynchronous_shaders">Usar sombreadores asíncronos</string>
|
<string name="renderer_asynchronous_shaders">Usar sombreadores asíncronos</string>
|
||||||
<string name="renderer_asynchronous_shaders_description">Compila los sombreadores de forma asíncrona. Esto puede reducir los tirones, pero también puede introducir errores gráficos.</string>
|
<string name="renderer_asynchronous_shaders_description">Compila los sombreadores de forma asíncrona. Esto puede reducir los tirones, pero también puede introducir errores gráficos.</string>
|
||||||
<string name="gpu_unswizzle_settings">Ajustes de desentrelazado de la GPU</string>
|
<string name="gpu_unswizzle_settings">Ajustes de desentrelazado de la GPU</string>
|
||||||
@@ -1080,7 +1078,6 @@
|
|||||||
<string name="theme_mode_light">Claro</string>
|
<string name="theme_mode_light">Claro</string>
|
||||||
<string name="theme_mode_dark">Oscuro</string>
|
<string name="theme_mode_dark">Oscuro</string>
|
||||||
|
|
||||||
<string name="multiplier_none">Nada</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Fondos oscuros</string>
|
<string name="use_black_backgrounds">Fondos oscuros</string>
|
||||||
|
|||||||
@@ -808,9 +808,6 @@
|
|||||||
<string name="multiplier_x4">x4</string>
|
<string name="multiplier_x4">x4</string>
|
||||||
<string name="multiplier_x8">x8</string>
|
<string name="multiplier_x8">x8</string>
|
||||||
<string name="multiplier_x16">x16</string>
|
<string name="multiplier_x16">x16</string>
|
||||||
<string name="multiplier_x32">x32</string>
|
|
||||||
<string name="multiplier_x64">x64</string>
|
|
||||||
<string name="multiplier_none">None</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">پسزمینه مشکی</string>
|
<string name="use_black_backgrounds">پسزمینه مشکی</string>
|
||||||
|
|||||||
@@ -1016,7 +1016,6 @@
|
|||||||
<string name="theme_mode_light">Lumineux</string>
|
<string name="theme_mode_light">Lumineux</string>
|
||||||
<string name="theme_mode_dark">Sombre</string>
|
<string name="theme_mode_dark">Sombre</string>
|
||||||
|
|
||||||
<string name="multiplier_none">Aucun</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Arrière-plan noir</string>
|
<string name="use_black_backgrounds">Arrière-plan noir</string>
|
||||||
|
|||||||
@@ -948,7 +948,6 @@
|
|||||||
<string name="theme_mode_light">Jasny</string>
|
<string name="theme_mode_light">Jasny</string>
|
||||||
<string name="theme_mode_dark">Ciemny</string>
|
<string name="theme_mode_dark">Ciemny</string>
|
||||||
|
|
||||||
<string name="multiplier_none">Brak</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Czarne tła</string>
|
<string name="use_black_backgrounds">Czarne tła</string>
|
||||||
|
|||||||
@@ -897,7 +897,6 @@
|
|||||||
<string name="theme_mode_light">Claro</string>
|
<string name="theme_mode_light">Claro</string>
|
||||||
<string name="theme_mode_dark">Escuro</string>
|
<string name="theme_mode_dark">Escuro</string>
|
||||||
|
|
||||||
<string name="multiplier_none">Nenhum</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Planos de fundo pretos</string>
|
<string name="use_black_backgrounds">Planos de fundo pretos</string>
|
||||||
|
|||||||
@@ -510,8 +510,6 @@
|
|||||||
<string name="fix_bloom_effects_description">Частично убирает размытие в LA/EOW (Adreno A6XX - A7XX/ Turnip), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх.</string>
|
<string name="fix_bloom_effects_description">Частично убирает размытие в LA/EOW (Adreno A6XX - A7XX/ Turnip), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх.</string>
|
||||||
<string name="emulate_bgr565">Эмулировать BGR565</string>
|
<string name="emulate_bgr565">Эмулировать BGR565</string>
|
||||||
<string name="emulate_bgr565_description">Исправляет проблемы с инвертированными цветами в играх, а также со странными артефактами или некорректными тенями.</string>
|
<string name="emulate_bgr565_description">Исправляет проблемы с инвертированными цветами в играх, а также со странными артефактами или некорректными тенями.</string>
|
||||||
<string name="rescale_hack">Включить старый метод изменения разрешения</string>
|
|
||||||
<string name="rescale_hack_description">Включает старый метод обработки этапа перенастройки масштабирования для игр за счёт использования быстрого алгоритма перемасштабирования.</string>
|
|
||||||
<string name="renderer_asynchronous_shaders">Использовать асинхронные шейдеры</string>
|
<string name="renderer_asynchronous_shaders">Использовать асинхронные шейдеры</string>
|
||||||
<string name="renderer_asynchronous_shaders_description">Компилирует шейдеры асинхронно. Это может уменьшить подтормаживания, но также может вызвать графические артефакты.</string>
|
<string name="renderer_asynchronous_shaders_description">Компилирует шейдеры асинхронно. Это может уменьшить подтормаживания, но также может вызвать графические артефакты.</string>
|
||||||
<string name="gpu_unswizzle_settings">Настройки распаковки текстур (Unswizzle)</string>
|
<string name="gpu_unswizzle_settings">Настройки распаковки текстур (Unswizzle)</string>
|
||||||
@@ -1084,7 +1082,6 @@
|
|||||||
<string name="theme_mode_light">Светлая</string>
|
<string name="theme_mode_light">Светлая</string>
|
||||||
<string name="theme_mode_dark">Темная</string>
|
<string name="theme_mode_dark">Темная</string>
|
||||||
|
|
||||||
<string name="multiplier_none">Отключено</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Чёрный фон</string>
|
<string name="use_black_backgrounds">Чёрный фон</string>
|
||||||
|
|||||||
@@ -505,8 +505,6 @@
|
|||||||
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno A6XX–A7XX / Turnip), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
|
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno A6XX–A7XX / Turnip), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
|
||||||
<string name="emulate_bgr565">Емулювати BGR565</string>
|
<string name="emulate_bgr565">Емулювати BGR565</string>
|
||||||
<string name="emulate_bgr565_description">Виправляє проблеми з інвертованими кольорами в іграх або дивними артефактами чи тінями.</string>
|
<string name="emulate_bgr565_description">Виправляє проблеми з інвертованими кольорами в іграх або дивними артефактами чи тінями.</string>
|
||||||
<string name="rescale_hack">Увімкнути застаріле масштабування</string>
|
|
||||||
<string name="rescale_hack_description">Вмикає застарілу обробку масштабування для ігор, використовуючи швидкий шлях масштабування</string>
|
|
||||||
<string name="renderer_asynchronous_shaders">Асинхронні шейдери</string>
|
<string name="renderer_asynchronous_shaders">Асинхронні шейдери</string>
|
||||||
<string name="renderer_asynchronous_shaders_description">Компілює шейдери асинхронно. Це може зменшити затримки, але також може спричинити графічні баги.</string>
|
<string name="renderer_asynchronous_shaders_description">Компілює шейдери асинхронно. Це може зменшити затримки, але також може спричинити графічні баги.</string>
|
||||||
<string name="gpu_unswizzle_settings">Налаштування розпакування за допомогою ГП</string>
|
<string name="gpu_unswizzle_settings">Налаштування розпакування за допомогою ГП</string>
|
||||||
@@ -1066,7 +1064,6 @@
|
|||||||
<string name="theme_mode_light">Світла</string>
|
<string name="theme_mode_light">Світла</string>
|
||||||
<string name="theme_mode_dark">Темна</string>
|
<string name="theme_mode_dark">Темна</string>
|
||||||
|
|
||||||
<string name="multiplier_none">Жодного</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Чорний фон</string>
|
<string name="use_black_backgrounds">Чорний фон</string>
|
||||||
|
|||||||
@@ -504,8 +504,6 @@
|
|||||||
<string name="fix_bloom_effects_description">减少《智慧的再现》和《众神的三角力量2》(Adreno A6XX - A7XX/ Turnip)中的 bloom 模糊,并移除《Burnout》中的 bloom 效果。警告:可能会导致在其他游戏中出现图形异常。</string>
|
<string name="fix_bloom_effects_description">减少《智慧的再现》和《众神的三角力量2》(Adreno A6XX - A7XX/ Turnip)中的 bloom 模糊,并移除《Burnout》中的 bloom 效果。警告:可能会导致在其他游戏中出现图形异常。</string>
|
||||||
<string name="emulate_bgr565">模拟 BGR565</string>
|
<string name="emulate_bgr565">模拟 BGR565</string>
|
||||||
<string name="emulate_bgr565_description">修复游戏中的颜色反转或是异常的画面瑕疵或阴影问题</string>
|
<string name="emulate_bgr565_description">修复游戏中的颜色反转或是异常的画面瑕疵或阴影问题</string>
|
||||||
<string name="rescale_hack">启用旧版缩放处理</string>
|
|
||||||
<string name="rescale_hack_description">启用通过使用快速缩放路径,来为游戏提供缩放配置处理的传统处理方式</string>
|
|
||||||
<string name="renderer_asynchronous_shaders">使用异步着色器</string>
|
<string name="renderer_asynchronous_shaders">使用异步着色器</string>
|
||||||
<string name="renderer_asynchronous_shaders_description">以异步方式编译着色器。采用此方式或可减少卡顿,但也可能引入故障点。</string>
|
<string name="renderer_asynchronous_shaders_description">以异步方式编译着色器。采用此方式或可减少卡顿,但也可能引入故障点。</string>
|
||||||
<string name="gpu_unswizzle_settings">GPU Unswizzle 设置</string>
|
<string name="gpu_unswizzle_settings">GPU Unswizzle 设置</string>
|
||||||
@@ -1078,7 +1076,6 @@
|
|||||||
<string name="theme_mode_light">浅色</string>
|
<string name="theme_mode_light">浅色</string>
|
||||||
<string name="theme_mode_dark">深色</string>
|
<string name="theme_mode_dark">深色</string>
|
||||||
|
|
||||||
<string name="multiplier_none">无</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">使用黑色背景</string>
|
<string name="use_black_backgrounds">使用黑色背景</string>
|
||||||
|
|||||||
@@ -926,7 +926,6 @@
|
|||||||
<string name="theme_mode_light">淺色</string>
|
<string name="theme_mode_light">淺色</string>
|
||||||
<string name="theme_mode_dark">深色</string>
|
<string name="theme_mode_dark">深色</string>
|
||||||
|
|
||||||
<string name="multiplier_none">無</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">黑色背景</string>
|
<string name="use_black_backgrounds">黑色背景</string>
|
||||||
|
|||||||
@@ -162,6 +162,48 @@
|
|||||||
<item>@string/resolution_four</item>
|
<item>@string/resolution_four</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="frameGenMultiplierNames">
|
||||||
|
<item>@string/frame_gen_multiplier_2x</item>
|
||||||
|
<item>@string/frame_gen_multiplier_3x</item>
|
||||||
|
<item>@string/frame_gen_multiplier_4x</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<integer-array name="frameGenMultiplierValues">
|
||||||
|
<item>2</item>
|
||||||
|
<item>3</item>
|
||||||
|
<item>4</item>
|
||||||
|
</integer-array>
|
||||||
|
|
||||||
|
<string-array name="frameGenTargetRateNames">
|
||||||
|
<item>@string/frame_gen_target_rate_off</item>
|
||||||
|
<item>@string/frame_gen_target_rate_60</item>
|
||||||
|
<item>@string/frame_gen_target_rate_90</item>
|
||||||
|
<item>@string/frame_gen_target_rate_120</item>
|
||||||
|
<item>@string/frame_gen_target_rate_144</item>
|
||||||
|
<item>@string/frame_gen_target_rate_165</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<integer-array name="frameGenTargetRateValues">
|
||||||
|
<item>0</item>
|
||||||
|
<item>60</item>
|
||||||
|
<item>90</item>
|
||||||
|
<item>120</item>
|
||||||
|
<item>144</item>
|
||||||
|
<item>165</item>
|
||||||
|
</integer-array>
|
||||||
|
|
||||||
|
<string-array name="frameGenQueueTargetNames">
|
||||||
|
<item>@string/frame_gen_queue_target_0</item>
|
||||||
|
<item>@string/frame_gen_queue_target_1</item>
|
||||||
|
<item>@string/frame_gen_queue_target_2</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<integer-array name="frameGenQueueTargetValues">
|
||||||
|
<item>0</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="rendererVSyncNames">
|
<string-array name="rendererVSyncNames">
|
||||||
<item>@string/renderer_vsync_immediate</item>
|
<item>@string/renderer_vsync_immediate</item>
|
||||||
<item>@string/renderer_vsync_mailbox</item>
|
<item>@string/renderer_vsync_mailbox</item>
|
||||||
@@ -471,9 +513,6 @@
|
|||||||
<item>@string/multiplier_x4</item>
|
<item>@string/multiplier_x4</item>
|
||||||
<item>@string/multiplier_x8</item>
|
<item>@string/multiplier_x8</item>
|
||||||
<item>@string/multiplier_x16</item>
|
<item>@string/multiplier_x16</item>
|
||||||
<item>@string/multiplier_x32</item>
|
|
||||||
<item>@string/multiplier_x64</item>
|
|
||||||
<item>@string/multiplier_none</item>
|
|
||||||
</string-array>
|
</string-array>
|
||||||
<integer-array name="anisoValues">
|
<integer-array name="anisoValues">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
@@ -482,9 +521,6 @@
|
|||||||
<item>3</item>
|
<item>3</item>
|
||||||
<item>4</item>
|
<item>4</item>
|
||||||
<item>5</item>
|
<item>5</item>
|
||||||
<item>6</item>
|
|
||||||
<item>7</item>
|
|
||||||
<item>8</item>
|
|
||||||
</integer-array>
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="verticalAlignmentEntries">
|
<string-array name="verticalAlignmentEntries">
|
||||||
@@ -638,6 +674,16 @@
|
|||||||
<item>@string/error_keys_failed_init</item>
|
<item>@string/error_keys_failed_init</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="losslessDllResults">
|
||||||
|
<item>""</item>
|
||||||
|
<item>@string/error_lossless_copy_failed</item>
|
||||||
|
<item>@string/error_lossless_unreadable</item>
|
||||||
|
<item>@string/error_lossless_not_pe</item>
|
||||||
|
<item>@string/error_lossless_missing_shaders</item>
|
||||||
|
<item>@string/error_lossless_translation_failed</item>
|
||||||
|
<item>@string/error_lossless_cache_failed</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<!-- GPU Logging Arrays -->
|
<!-- GPU Logging Arrays -->
|
||||||
<string-array name="gpuLogLevelEntries">
|
<string-array name="gpuLogLevelEntries">
|
||||||
<item>Off</item>
|
<item>Off</item>
|
||||||
|
|||||||
@@ -298,6 +298,67 @@
|
|||||||
<string name="gpu_driver_fetcher">GPU driver fetcher</string>
|
<string name="gpu_driver_fetcher">GPU driver fetcher</string>
|
||||||
<string name="gpu_driver_manager">GPU driver manager</string>
|
<string name="gpu_driver_manager">GPU driver manager</string>
|
||||||
<string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string>
|
<string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string>
|
||||||
|
<string name="frame_gen">Frame generation</string>
|
||||||
|
<string name="frame_gen_per_game_description">Configure frame generation for this game</string>
|
||||||
|
<string name="frame_gen_description">Insert interpolated frames between rendered ones using Lossless Scaling. Forces FIFO presentation while enabled.</string>
|
||||||
|
<string name="frame_gen_multiplier">Frame multiplier</string>
|
||||||
|
<string name="frame_gen_multiplier_description">How many frames to display for each rendered frame. Higher values cost proportionally more GPU time. Asking for more than your display can present will slow emulation down.</string>
|
||||||
|
<string name="frame_gen_multiplier_2x">2x</string>
|
||||||
|
<string name="frame_gen_multiplier_3x">3x</string>
|
||||||
|
<string name="frame_gen_multiplier_4x">4x</string>
|
||||||
|
<string name="frame_gen_target_rate">Target frame rate</string>
|
||||||
|
<string name="frame_gen_target_rate_description">Pick the rate your display can actually show. The multiplier then rises or falls on its own to hold it, and rolls back any step that makes the game itself run slower.</string>
|
||||||
|
<string name="frame_gen_target_rate_off">Use a fixed multiplier</string>
|
||||||
|
<string name="frame_gen_target_rate_60">60 FPS</string>
|
||||||
|
<string name="frame_gen_target_rate_90">90 FPS</string>
|
||||||
|
<string name="frame_gen_target_rate_120">120 FPS</string>
|
||||||
|
<string name="frame_gen_target_rate_144">144 FPS</string>
|
||||||
|
<string name="frame_gen_target_rate_165">165 FPS</string>
|
||||||
|
<string name="frame_gen_queue_target">Frame queue target</string>
|
||||||
|
<string name="frame_gen_queue_target_description">How many finished frames may wait ahead of the display. Larger queues absorb GPU spikes at the cost of input latency.</string>
|
||||||
|
<string name="frame_gen_queue_target_0">Lowest latency (Unbuffered)</string>
|
||||||
|
<string name="frame_gen_queue_target_1">Balanced (1 frame)</string>
|
||||||
|
<string name="frame_gen_queue_target_2">Smoothest (2 frames)</string>
|
||||||
|
<string name="frame_gen_flow_scale_auto">Match motion estimation to the game</string>
|
||||||
|
<string name="frame_gen_flow_scale_auto_description">Estimate motion at the resolution the game actually renders instead of the upscaled output. Costs nothing in accuracy, since upscaling adds no motion detail.</string>
|
||||||
|
<string name="frame_gen_flow_scale">Motion estimation resolution</string>
|
||||||
|
<string name="frame_gen_flow_scale_description">Resolution of the optical flow pass, as a fraction of the output. Lowering it is the cheapest way to reclaim performance.</string>
|
||||||
|
<string name="frame_gen_fp16">Half precision shaders</string>
|
||||||
|
<string name="frame_gen_fp16_description">Use the 16-bit shader variant. Falls back automatically if the driver or the file lacks it.</string>
|
||||||
|
<string name="frame_gen_dump_flow">Dump generated frame</string>
|
||||||
|
<string name="frame_gen_dump_flow_description">Write the optical flow mip levels and the interpolated frame to the lossless/debug folder once, for troubleshooting</string>
|
||||||
|
<string name="frame_gen_unsupported">Frame generation unavailable</string>
|
||||||
|
<string name="frame_gen_unsupported_description">This GPU driver does not support the Vulkan memory model, which the Lossless Scaling shaders require.</string>
|
||||||
|
<string name="lossless_scaling_setup_description">Optional. Provide your own Lossless.dll to enable frame generation later</string>
|
||||||
|
<string name="lossless_scaling_install">Install Lossless.dll</string>
|
||||||
|
<string name="lossless_scaling_install_description">Frame generation needs your own legal copy of Lossless.dll from Lossless Scaling</string>
|
||||||
|
<string name="lossless_scaling_replace_description">Select a different copy of Lossless.dll</string>
|
||||||
|
<string name="frame_generation_support">Frame generation</string>
|
||||||
|
<string name="frame_generation_supported">Supported</string>
|
||||||
|
<string name="frame_generation_unsupported">Unsupported (no Vulkan memory model)</string>
|
||||||
|
<string name="lossless_scaling">Lossless Scaling</string>
|
||||||
|
<string name="lossless_scaling_description">Provide your own copy of Lossless.dll to enable frame generation</string>
|
||||||
|
<string name="lossless_scaling_installed">Installed</string>
|
||||||
|
<string name="lossless_scaling_not_installed">Not installed</string>
|
||||||
|
<string name="lossless_scaling_replace">Replace</string>
|
||||||
|
<string name="lossless_scaling_remove">Remove</string>
|
||||||
|
<string name="lossless_scaling_remove_description">Delete the installed Lossless.dll and its prepared shaders</string>
|
||||||
|
<string name="lossless_scaling_remove_confirmation">Frame generation will stop working until you install Lossless.dll again. Your original file is not affected.</string>
|
||||||
|
<string name="lossless_scaling_missing">Lossless.dll not installed</string>
|
||||||
|
<string name="lossless_scaling_missing_description">Install it from Settings › Lossless Scaling to use frame generation.</string>
|
||||||
|
<string name="lossless_scaling_locked">Close the game first</string>
|
||||||
|
<string name="lossless_scaling_locked_description">Lossless.dll cannot be changed while a game is running.</string>
|
||||||
|
<string name="lossless_scaling_remove_unavailable">Nothing to remove</string>
|
||||||
|
<string name="lossless_scaling_remove_unavailable_description">Lossless.dll is not installed yet.</string>
|
||||||
|
<string name="lossless_scaling_installing">Preparing frame generation shaders…</string>
|
||||||
|
<string name="lossless_scaling_install_success">Lossless.dll installed successfully</string>
|
||||||
|
<string name="lossless_scaling_install_failed">Could not install Lossless.dll</string>
|
||||||
|
<string name="error_lossless_copy_failed">The selected file could not be copied.</string>
|
||||||
|
<string name="error_lossless_unreadable">The selected file could not be read.</string>
|
||||||
|
<string name="error_lossless_not_pe">The selected file is not a Windows library. Select Lossless.dll from your Lossless Scaling installation.</string>
|
||||||
|
<string name="error_lossless_missing_shaders">This copy of Lossless.dll does not contain the frame generation shaders. Update Lossless Scaling and try again.</string>
|
||||||
|
<string name="error_lossless_translation_failed">The frame generation shaders could not be translated. This version of Lossless Scaling is not supported yet.</string>
|
||||||
|
<string name="error_lossless_cache_failed">The translated shaders could not be written to storage. Check that there is free space available.</string>
|
||||||
<string name="advanced_settings">Advanced settings</string>
|
<string name="advanced_settings">Advanced settings</string>
|
||||||
<string name="settings_description">Configure emulator settings</string>
|
<string name="settings_description">Configure emulator settings</string>
|
||||||
<string name="search_recently_played">Recently played</string>
|
<string name="search_recently_played">Recently played</string>
|
||||||
@@ -520,12 +581,8 @@
|
|||||||
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno A6XX - A7XX/ Turnip), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
|
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno A6XX - A7XX/ Turnip), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
|
||||||
<string name="emulate_bgr565">Emulate BGR565</string>
|
<string name="emulate_bgr565">Emulate BGR565</string>
|
||||||
<string name="emulate_bgr565_description">Fixes problems with inverted colors in games or strange artifacts or strange shadows.</string>
|
<string name="emulate_bgr565_description">Fixes problems with inverted colors in games or strange artifacts or strange shadows.</string>
|
||||||
<string name="rescale_hack">Enable Legacy Rescale Pass</string>
|
|
||||||
<string name="rescale_hack_description">Enables a legacy handling for the rescale configuration pass for games by using a quick rescale path</string>
|
|
||||||
<string name="renderer_asynchronous_shaders">Use asynchronous shaders</string>
|
<string name="renderer_asynchronous_shaders">Use asynchronous shaders</string>
|
||||||
<string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches.</string>
|
<string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches.</string>
|
||||||
<string name="renderer_unified_memory">Unified memory access</string>
|
|
||||||
<string name="renderer_unified_memory_description">Allows GPU write buffer readbacks directly into guest memory, skipping the CPU staging copy.</string>
|
|
||||||
<string name="gpu_unswizzle_settings">GPU Unswizzle Settings</string>
|
<string name="gpu_unswizzle_settings">GPU Unswizzle Settings</string>
|
||||||
<string name="gpu_unswizzle_settings_description">Configure GPU-based texture unswizzling parameters or disable it entirely. Adjust these settings to balance performance and texture loading quality.</string>
|
<string name="gpu_unswizzle_settings_description">Configure GPU-based texture unswizzling parameters or disable it entirely. Adjust these settings to balance performance and texture loading quality.</string>
|
||||||
<string name="gpu_unswizzle_enable">Enable GPU Unswizzle</string>
|
<string name="gpu_unswizzle_enable">Enable GPU Unswizzle</string>
|
||||||
@@ -1187,9 +1244,6 @@
|
|||||||
<string name="multiplier_x4" translatable="false">x4</string>
|
<string name="multiplier_x4" translatable="false">x4</string>
|
||||||
<string name="multiplier_x8" translatable="false">x8</string>
|
<string name="multiplier_x8" translatable="false">x8</string>
|
||||||
<string name="multiplier_x16" translatable="false">x16</string>
|
<string name="multiplier_x16" translatable="false">x16</string>
|
||||||
<string name="multiplier_x32" translatable="false">x32</string>
|
|
||||||
<string name="multiplier_x64" translatable="false">x64</string>
|
|
||||||
<string name="multiplier_none">None</string>
|
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Black backgrounds</string>
|
<string name="use_black_backgrounds">Black backgrounds</string>
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ if (MSVC)
|
|||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_compile_options(audio_core PRIVATE
|
target_compile_options(audio_core PRIVATE
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=conversion>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wconversion>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-sign-conversion>)
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-sign-conversion>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ endif()
|
|||||||
if(CXX_CLANG)
|
if(CXX_CLANG)
|
||||||
target_compile_options(common PRIVATE
|
target_compile_options(common PRIVATE
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-fsized-deallocation>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-fsized-deallocation>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=unreachable-code-aggressive>)
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wunreachable-code-aggressive>)
|
||||||
target_compile_definitions(
|
target_compile_definitions(
|
||||||
common
|
common
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#define KEYS_DIR "keys"
|
#define KEYS_DIR "keys"
|
||||||
#define LOAD_DIR "load"
|
#define LOAD_DIR "load"
|
||||||
#define LOG_DIR "log"
|
#define LOG_DIR "log"
|
||||||
|
#define LOSSLESS_DIR "lossless"
|
||||||
#define NAND_DIR "nand"
|
#define NAND_DIR "nand"
|
||||||
#define PLAY_TIME_DIR "play_time"
|
#define PLAY_TIME_DIR "play_time"
|
||||||
#define SCREENSHOTS_DIR "screenshots"
|
#define SCREENSHOTS_DIR "screenshots"
|
||||||
@@ -37,3 +38,5 @@
|
|||||||
|
|
||||||
// yuzu-specific files
|
// yuzu-specific files
|
||||||
#define LOG_FILE "eden_log.txt"
|
#define LOG_FILE "eden_log.txt"
|
||||||
|
#define LOSSLESS_DLL_FILE "Lossless.dll"
|
||||||
|
#define LOSSLESS_CACHE_FILE "lsfg_spirv.cache"
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ public:
|
|||||||
GenerateEdenPath(EdenPath::KeysDir, eden_path / KEYS_DIR);
|
GenerateEdenPath(EdenPath::KeysDir, eden_path / KEYS_DIR);
|
||||||
GenerateEdenPath(EdenPath::LoadDir, eden_path / LOAD_DIR);
|
GenerateEdenPath(EdenPath::LoadDir, eden_path / LOAD_DIR);
|
||||||
GenerateEdenPath(EdenPath::LogDir, eden_path / LOG_DIR);
|
GenerateEdenPath(EdenPath::LogDir, eden_path / LOG_DIR);
|
||||||
|
GenerateEdenPath(EdenPath::LosslessDir, eden_path / LOSSLESS_DIR);
|
||||||
GenerateEdenPath(EdenPath::NANDDir, eden_path / NAND_DIR);
|
GenerateEdenPath(EdenPath::NANDDir, eden_path / NAND_DIR);
|
||||||
GenerateEdenPath(EdenPath::PlayTimeDir, eden_path / PLAY_TIME_DIR);
|
GenerateEdenPath(EdenPath::PlayTimeDir, eden_path / PLAY_TIME_DIR);
|
||||||
GenerateEdenPath(EdenPath::SaveDir, eden_path / NAND_DIR);
|
GenerateEdenPath(EdenPath::SaveDir, eden_path / NAND_DIR);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
@@ -23,6 +23,7 @@ enum class EdenPath {
|
|||||||
KeysDir, // Where key files are stored.
|
KeysDir, // Where key files are stored.
|
||||||
LoadDir, // Where cheat/mod files are stored.
|
LoadDir, // Where cheat/mod files are stored.
|
||||||
LogDir, // Where log files are stored.
|
LogDir, // Where log files are stored.
|
||||||
|
LosslessDir, // Where the user-supplied Lossless Scaling library is stored.
|
||||||
NANDDir, // Where the emulated NAND is stored.
|
NANDDir, // Where the emulated NAND is stored.
|
||||||
PlayTimeDir, // Where play time data is stored.
|
PlayTimeDir, // Where play time data is stored.
|
||||||
SaveDir, // Where save data is stored.
|
SaveDir, // Where save data is stored.
|
||||||
|
|||||||
@@ -31,9 +31,7 @@ s64 GetMaxPermissibleResidentMapCount() {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
HeapTracker::HeapTracker(Common::HostMemory& buffer)
|
HeapTracker::HeapTracker(Common::HostMemory& buffer)
|
||||||
: m_buffer(buffer),
|
: m_buffer(buffer), m_max_resident_map_count(GetMaxPermissibleResidentMapCount()) {}
|
||||||
m_has_hardware_buffer_backing(!buffer.BackingHardwareBuffers().empty()),
|
|
||||||
m_max_resident_map_count(GetMaxPermissibleResidentMapCount()) {}
|
|
||||||
HeapTracker::~HeapTracker() = default;
|
HeapTracker::~HeapTracker() = default;
|
||||||
|
|
||||||
void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length,
|
void HeapTracker::Map(size_t virtual_offset, size_t host_offset, size_t length,
|
||||||
@@ -87,8 +85,7 @@ void HeapTracker::Unmap(size_t virtual_offset, size_t size, bool is_separate_hea
|
|||||||
|
|
||||||
// If resident, erase from resident map.
|
// If resident, erase from resident map.
|
||||||
if (item->is_resident) {
|
if (item->is_resident) {
|
||||||
m_resident_map_count -= this->HostMapCount(item->paddr, item->size);
|
ASSERT(--m_resident_map_count >= 0);
|
||||||
ASSERT(m_resident_map_count >= 0);
|
|
||||||
m_resident_mappings.erase(m_resident_mappings.iterator_to(*item));
|
m_resident_mappings.erase(m_resident_mappings.iterator_to(*item));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,7 +191,7 @@ bool HeapTracker::DeferredMapSeparateHeap(size_t virtual_offset) {
|
|||||||
|
|
||||||
// This map is now resident.
|
// This map is now resident.
|
||||||
it->is_resident = true;
|
it->is_resident = true;
|
||||||
m_resident_map_count += this->HostMapCount(it->paddr, it->size);
|
m_resident_map_count++;
|
||||||
m_resident_mappings.insert(*it);
|
m_resident_mappings.insert(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,17 +213,17 @@ void HeapTracker::RebuildSeparateHeapAddressSpace() {
|
|||||||
// Despite being worse in theory, this has proven to be better in practice than more
|
// Despite being worse in theory, this has proven to be better in practice than more
|
||||||
// regularly dumping a smaller amount, because it significantly reduces average case
|
// regularly dumping a smaller amount, because it significantly reduces average case
|
||||||
// lock contention.
|
// lock contention.
|
||||||
s64 const desired_count = (std::min)(m_resident_map_count, m_max_resident_map_count) / 2;
|
std::size_t const desired_count = (std::min)(m_resident_map_count, m_max_resident_map_count) / 2;
|
||||||
|
std::size_t const evict_count = m_resident_map_count - desired_count;
|
||||||
auto it = m_resident_mappings.begin();
|
auto it = m_resident_mappings.begin();
|
||||||
|
|
||||||
while (m_resident_map_count > desired_count && it != m_resident_mappings.end()) {
|
for (size_t i = 0; i < evict_count && it != m_resident_mappings.end(); i++) {
|
||||||
// Unmark and unmap.
|
// Unmark and unmap.
|
||||||
it->is_resident = false;
|
it->is_resident = false;
|
||||||
m_buffer.Unmap(it->vaddr, it->size, false);
|
m_buffer.Unmap(it->vaddr, it->size, false);
|
||||||
|
|
||||||
// Advance.
|
// Advance.
|
||||||
m_resident_map_count -= this->HostMapCount(it->paddr, it->size);
|
ASSERT(--m_resident_map_count >= 0);
|
||||||
ASSERT(m_resident_map_count >= 0);
|
|
||||||
it = m_resident_mappings.erase(it);
|
it = m_resident_mappings.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,7 +245,6 @@ void HeapTracker::SplitHeapMapLocked(VAddr offset) {
|
|||||||
// Cache the original values.
|
// Cache the original values.
|
||||||
auto* const left = std::addressof(*it);
|
auto* const left = std::addressof(*it);
|
||||||
const size_t orig_size = left->size;
|
const size_t orig_size = left->size;
|
||||||
const s64 orig_host_map_count = this->HostMapCount(left->paddr, orig_size);
|
|
||||||
|
|
||||||
// Adjust the left map.
|
// Adjust the left map.
|
||||||
const size_t left_size = offset - left->vaddr;
|
const size_t left_size = offset - left->vaddr;
|
||||||
@@ -270,20 +266,11 @@ void HeapTracker::SplitHeapMapLocked(VAddr offset) {
|
|||||||
|
|
||||||
// If resident, also insert into resident map.
|
// If resident, also insert into resident map.
|
||||||
if (right->is_resident) {
|
if (right->is_resident) {
|
||||||
m_resident_map_count += this->HostMapCount(left->paddr, left->size) +
|
m_resident_map_count++;
|
||||||
this->HostMapCount(right->paddr, right->size) -
|
|
||||||
orig_host_map_count;
|
|
||||||
m_resident_mappings.insert(*right);
|
m_resident_mappings.insert(*right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 HeapTracker::HostMapCount(PAddr paddr, size_t size) const {
|
|
||||||
if (!m_has_hardware_buffer_backing) {
|
|
||||||
return size != 0 ? 1 : 0;
|
|
||||||
}
|
|
||||||
return static_cast<s64>(m_buffer.BackingMapCount(paddr, size));
|
|
||||||
}
|
|
||||||
|
|
||||||
HeapTracker::AddrTree::iterator HeapTracker::GetNearestHeapMapLocked(VAddr offset) {
|
HeapTracker::AddrTree::iterator HeapTracker::GetNearestHeapMapLocked(VAddr offset) {
|
||||||
const SeparateHeapMap key{
|
const SeparateHeapMap key{
|
||||||
.vaddr = offset,
|
.vaddr = offset,
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -85,13 +82,10 @@ private:
|
|||||||
|
|
||||||
AddrTree::iterator GetNearestHeapMapLocked(VAddr offset);
|
AddrTree::iterator GetNearestHeapMapLocked(VAddr offset);
|
||||||
|
|
||||||
s64 HostMapCount(PAddr paddr, size_t size) const;
|
|
||||||
|
|
||||||
void RebuildSeparateHeapAddressSpace();
|
void RebuildSeparateHeapAddressSpace();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Common::HostMemory& m_buffer;
|
Common::HostMemory& m_buffer;
|
||||||
const bool m_has_hardware_buffer_backing;
|
|
||||||
const s64 m_max_resident_map_count;
|
const s64 m_max_resident_map_count;
|
||||||
|
|
||||||
std::shared_mutex m_rebuild_lock{};
|
std::shared_mutex m_rebuild_lock{};
|
||||||
|
|||||||
+6
-368
@@ -51,45 +51,14 @@
|
|||||||
|
|
||||||
#endif // ^^^ POSIX ^^^
|
#endif // ^^^ POSIX ^^^
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/free_region_manager.h"
|
#include "common/free_region_manager.h"
|
||||||
#include "common/host_memory.h"
|
#include "common/host_memory.h"
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/memory_detect.h"
|
|
||||||
#include "common/settings.h"
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <android/hardware_buffer.h>
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct NativeHandle {
|
|
||||||
int version;
|
|
||||||
int numFds;
|
|
||||||
int numInts;
|
|
||||||
int data[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
using PFN_AHardwareBuffer_getNativeHandle = const NativeHandle* (*)(const AHardwareBuffer*);
|
|
||||||
|
|
||||||
PFN_AHardwareBuffer_getNativeHandle ResolveGetNativeHandle() {
|
|
||||||
void* const lib = dlopen("libnativewindow.so", RTLD_NOW);
|
|
||||||
if (lib == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return reinterpret_cast<PFN_AHardwareBuffer_getNativeHandle>(
|
|
||||||
dlsym(lib, "AHardwareBuffer_getNativeHandle"));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__ANDROID__) && __ANDROID_API__ < 30
|
#if defined(__ANDROID__) && __ANDROID_API__ < 30
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
@@ -106,12 +75,6 @@ namespace Common {
|
|||||||
[[maybe_unused]] constexpr size_t PageAlignment = 0x1000;
|
[[maybe_unused]] constexpr size_t PageAlignment = 0x1000;
|
||||||
[[maybe_unused]] constexpr size_t HugePageSize = 0x200000;
|
[[maybe_unused]] constexpr size_t HugePageSize = 0x200000;
|
||||||
|
|
||||||
static std::atomic<u64> committed_backing_size{};
|
|
||||||
|
|
||||||
u64 GetCommittedBackingSize() noexcept {
|
|
||||||
return committed_backing_size.load(std::memory_order_relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
// Manually imported for MinGW compatibility
|
// Manually imported for MinGW compatibility
|
||||||
@@ -160,7 +123,7 @@ static void GetFuncAddress(Common::DynamicLibrary& dll, const char* name, T& pfn
|
|||||||
|
|
||||||
class HostMemory::Impl {
|
class HostMemory::Impl {
|
||||||
public:
|
public:
|
||||||
explicit Impl(size_t backing_size_, size_t virtual_size_, size_t)
|
explicit Impl(size_t backing_size_, size_t virtual_size_)
|
||||||
: backing_size{backing_size_}
|
: backing_size{backing_size_}
|
||||||
, virtual_size{virtual_size_}
|
, virtual_size{virtual_size_}
|
||||||
, process{GetCurrentProcess()}
|
, process{GetCurrentProcess()}
|
||||||
@@ -266,10 +229,6 @@ public:
|
|||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBackingShared() const noexcept {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t backing_size; ///< Size of the backing memory in bytes
|
const size_t backing_size; ///< Size of the backing memory in bytes
|
||||||
const size_t virtual_size; ///< Size of the virtual address placeholder in bytes
|
const size_t virtual_size; ///< Size of the virtual address placeholder in bytes
|
||||||
|
|
||||||
@@ -542,10 +501,9 @@ static int shm_open_anon(int flags, mode_t mode) {
|
|||||||
|
|
||||||
class HostMemory::Impl {
|
class HostMemory::Impl {
|
||||||
public:
|
public:
|
||||||
explicit Impl(size_t backing_size_, size_t virtual_size_, size_t preferred_offset_)
|
explicit Impl(size_t backing_size_, size_t virtual_size_)
|
||||||
: backing_size{backing_size_}
|
: backing_size{backing_size_}
|
||||||
, virtual_size{virtual_size_}
|
, virtual_size{virtual_size_}
|
||||||
, preferred_offset{preferred_offset_}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool Init() {
|
bool Init() {
|
||||||
@@ -585,15 +543,10 @@ public:
|
|||||||
LOG_WARNING(Common_Memory, "Using private mappings instead of shared ones");
|
LOG_WARNING(Common_Memory, "Using private mappings instead of shared ones");
|
||||||
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
|
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
|
||||||
if (fd > 0) {
|
if (fd > 0) {
|
||||||
|
fd = -1;
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
fd = -1;
|
|
||||||
} else {
|
} else {
|
||||||
#ifdef __ANDROID__
|
|
||||||
if (InitAhbBacking()) {
|
|
||||||
return InitVirtual();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
|
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
|
||||||
}
|
}
|
||||||
if (backing_base == MAP_FAILED) {
|
if (backing_base == MAP_FAILED) {
|
||||||
@@ -601,10 +554,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return InitVirtual();
|
// Virtual memory initialization
|
||||||
}
|
|
||||||
|
|
||||||
bool InitVirtual() {
|
|
||||||
virtual_base = virtual_map_base = static_cast<u8*>(ChooseVirtualBase(virtual_size));
|
virtual_base = virtual_map_base = static_cast<u8*>(ChooseVirtualBase(virtual_size));
|
||||||
if (virtual_base == MAP_FAILED) {
|
if (virtual_base == MAP_FAILED) {
|
||||||
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
|
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
|
||||||
@@ -617,242 +567,6 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
static AHardwareBuffer_Desc MakeBlobDesc(size_t len) {
|
|
||||||
return AHardwareBuffer_Desc{
|
|
||||||
.width = static_cast<u32>(len),
|
|
||||||
.height = 1,
|
|
||||||
.layers = 1,
|
|
||||||
.format = AHARDWAREBUFFER_FORMAT_BLOB,
|
|
||||||
.usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
|
|
||||||
AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
|
|
||||||
AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER,
|
|
||||||
.stride = 0,
|
|
||||||
.rfu0 = 0,
|
|
||||||
.rfu1 = 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ProbeAhbBacking(PFN_AHardwareBuffer_getNativeHandle get_native_handle) {
|
|
||||||
const AHardwareBuffer_Desc desc = MakeBlobDesc(PageAlignment * 2);
|
|
||||||
AHardwareBuffer* buffer{};
|
|
||||||
if (AHardwareBuffer_allocate(&desc, &buffer) != 0 || buffer == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const NativeHandle* const handle = get_native_handle(buffer);
|
|
||||||
if (handle == nullptr || handle->numFds < 1) {
|
|
||||||
AHardwareBuffer_release(buffer);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const int probe_fd = handle->data[0];
|
|
||||||
bool ok = true;
|
|
||||||
const auto try_map = [&](int prot, off_t offset, const char* what) {
|
|
||||||
if (!ok) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void* const ptr = mmap(nullptr, PageAlignment, prot, MAP_SHARED, probe_fd, offset);
|
|
||||||
if (ptr == MAP_FAILED) {
|
|
||||||
ok = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
munmap(ptr, PageAlignment);
|
|
||||||
};
|
|
||||||
try_map(PROT_READ | PROT_WRITE, 0, "shared mappings");
|
|
||||||
try_map(PROT_READ | PROT_WRITE, static_cast<off_t>(PageAlignment), "mappings at an offset");
|
|
||||||
#ifdef ARCHITECTURE_arm64
|
|
||||||
try_map(PROT_READ | PROT_EXEC, 0, "executable mappings");
|
|
||||||
#endif
|
|
||||||
AHardwareBuffer_release(buffer);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ComputeAhbBudget(size_t window_size) const {
|
|
||||||
const u64 total_physical = Common::GetMemInfo().TotalPhysicalMemory;
|
|
||||||
constexpr u64 BaselineFootprint = 6ULL << 30;
|
|
||||||
if (total_physical <= BaselineFootprint) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
const u64 max_map_count = Common::GetMaxMapCount();
|
|
||||||
constexpr u64 ReservedMaps = 24576;
|
|
||||||
if (max_map_count == 0 || max_map_count <= ReservedMaps) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
u64 budget = (total_physical - BaselineFootprint) / 2;
|
|
||||||
constexpr u64 MapSlotsPerWindow = 4096;
|
|
||||||
const u64 affordable_windows = (max_map_count - ReservedMaps) / MapSlotsPerWindow;
|
|
||||||
budget = (std::min)(budget, affordable_windows * window_size);
|
|
||||||
const u64 available = Common::GetAvailablePhysicalMemory();
|
|
||||||
if (available != 0) {
|
|
||||||
budget = (std::min)(budget, available / 2);
|
|
||||||
}
|
|
||||||
budget = (std::min)(budget, static_cast<u64>(backing_size));
|
|
||||||
budget = Common::AlignDown(budget, window_size);
|
|
||||||
constexpr u64 MinimumBudget = 256ULL << 20;
|
|
||||||
if (budget < MinimumBudget) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return static_cast<size_t>(budget);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitAhbBacking() {
|
|
||||||
if (!Settings::values.use_unified_memory.GetValue()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
static const PFN_AHardwareBuffer_getNativeHandle get_native_handle =
|
|
||||||
ResolveGetNativeHandle();
|
|
||||||
if (get_native_handle == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
constexpr size_t window_size = 256ULL << 20;
|
|
||||||
const size_t budget = ComputeAhbBudget(window_size);
|
|
||||||
if (budget == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ProbeAhbBacking(get_native_handle)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const size_t aligned_backing = Common::AlignDown(backing_size, window_size);
|
|
||||||
const size_t max_windows = (std::min)(budget, aligned_backing) / window_size;
|
|
||||||
|
|
||||||
std::vector<AHardwareBuffer*> buffers;
|
|
||||||
std::vector<int> buffer_fds;
|
|
||||||
const auto cleanup = [&] {
|
|
||||||
for (AHardwareBuffer* buffer : buffers) {
|
|
||||||
AHardwareBuffer_release(buffer);
|
|
||||||
}
|
|
||||||
buffers.clear();
|
|
||||||
buffer_fds.clear();
|
|
||||||
};
|
|
||||||
for (size_t i = 0; i < max_windows; ++i) {
|
|
||||||
const AHardwareBuffer_Desc desc = MakeBlobDesc(window_size);
|
|
||||||
AHardwareBuffer* buffer{};
|
|
||||||
if (AHardwareBuffer_allocate(&desc, &buffer) != 0 || buffer == nullptr) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const NativeHandle* const handle = get_native_handle(buffer);
|
|
||||||
if (handle == nullptr || handle->numFds < 1) {
|
|
||||||
AHardwareBuffer_release(buffer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const int buffer_fd = handle->data[0];
|
|
||||||
const off_t buffer_len = lseek(buffer_fd, 0, SEEK_END);
|
|
||||||
if (buffer_len < static_cast<off_t>(window_size)) {
|
|
||||||
AHardwareBuffer_release(buffer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
buffers.push_back(buffer);
|
|
||||||
buffer_fds.push_back(buffer_fd);
|
|
||||||
}
|
|
||||||
const size_t num_windows = buffers.size();
|
|
||||||
if (num_windows == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const size_t region_size = num_windows * window_size;
|
|
||||||
const size_t region_base = Common::AlignDown(
|
|
||||||
(std::min)(preferred_offset, aligned_backing - region_size), window_size);
|
|
||||||
u8* const base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_NONE,
|
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0));
|
|
||||||
if (base == MAP_FAILED) {
|
|
||||||
cleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto map_over_reservation = [&](size_t offset, size_t len, int map_fd,
|
|
||||||
off_t map_offset) {
|
|
||||||
if (len == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (mmap(base + offset, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, map_fd,
|
|
||||||
map_offset) == MAP_FAILED) {
|
|
||||||
munmap(base, backing_size);
|
|
||||||
cleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
if (!map_over_reservation(0, region_base, fd, 0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < num_windows; ++i) {
|
|
||||||
if (!map_over_reservation(region_base + i * window_size, window_size, buffer_fds[i],
|
|
||||||
0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const size_t tail_offset = region_base + region_size;
|
|
||||||
if (!map_over_reservation(tail_offset, backing_size - tail_offset, fd,
|
|
||||||
static_cast<off_t>(tail_offset))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
backing_base = base;
|
|
||||||
ahb_windows = std::move(buffers);
|
|
||||||
ahb_fds = std::move(buffer_fds);
|
|
||||||
ahb_window_size = window_size;
|
|
||||||
ahb_base = region_base;
|
|
||||||
ahb_bytes = region_size;
|
|
||||||
committed_backing_size.store(region_size, std::memory_order_relaxed);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapBackingRange(size_t virtual_offset, size_t host_offset, size_t length, int prot_flags) {
|
|
||||||
while (length > 0) {
|
|
||||||
int map_fd = fd;
|
|
||||||
off_t map_offset = static_cast<off_t>(host_offset);
|
|
||||||
size_t chunk = length;
|
|
||||||
if (host_offset < ahb_base) {
|
|
||||||
chunk = (std::min)(chunk, ahb_base - host_offset);
|
|
||||||
} else if (host_offset < ahb_base + ahb_bytes) {
|
|
||||||
const size_t relative = host_offset - ahb_base;
|
|
||||||
const size_t window = relative / ahb_window_size;
|
|
||||||
const size_t local = relative % ahb_window_size;
|
|
||||||
map_fd = ahb_fds[window];
|
|
||||||
map_offset = static_cast<off_t>(local);
|
|
||||||
chunk = (std::min)(chunk, ahb_window_size - local);
|
|
||||||
}
|
|
||||||
void* const ret = mmap(virtual_base + virtual_offset, chunk, prot_flags,
|
|
||||||
MAP_SHARED | MAP_FIXED, map_fd, map_offset);
|
|
||||||
ASSERT_MSG(ret != MAP_FAILED, "mmap: {}", strerror(errno));
|
|
||||||
virtual_offset += chunk;
|
|
||||||
host_offset += chunk;
|
|
||||||
length -= chunk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t BackingMapCount(size_t host_offset, size_t length) const noexcept {
|
|
||||||
if (length == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (ahb_bytes == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
size_t count = 0;
|
|
||||||
while (length > 0) {
|
|
||||||
size_t chunk = length;
|
|
||||||
if (host_offset < ahb_base) {
|
|
||||||
chunk = (std::min)(chunk, ahb_base - host_offset);
|
|
||||||
} else if (host_offset < ahb_base + ahb_bytes) {
|
|
||||||
const size_t local = (host_offset - ahb_base) % ahb_window_size;
|
|
||||||
chunk = (std::min)(chunk, ahb_window_size - local);
|
|
||||||
}
|
|
||||||
host_offset += chunk;
|
|
||||||
length -= chunk;
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::span<AHardwareBuffer* const> AhbWindows() const noexcept {
|
|
||||||
return ahb_windows;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t AhbWindowSize() const noexcept {
|
|
||||||
return ahb_bytes != 0 ? ahb_window_size : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t AhbBase() const noexcept {
|
|
||||||
return ahb_base;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
~Impl() {
|
~Impl() {
|
||||||
Release();
|
Release();
|
||||||
}
|
}
|
||||||
@@ -873,12 +587,6 @@ public:
|
|||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef ARCHITECTURE_arm64
|
||||||
if (True(perms & MemoryPermission::Execute))
|
if (True(perms & MemoryPermission::Execute))
|
||||||
prot_flags |= PROT_EXEC;
|
prot_flags |= PROT_EXEC;
|
||||||
#endif
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
if (ahb_bytes != 0) {
|
|
||||||
MapBackingRange(virtual_offset, host_offset, length, prot_flags);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
int flags = (fd >= 0 ? MAP_SHARED : MAP_PRIVATE) | MAP_FIXED;
|
int flags = (fd >= 0 ? MAP_SHARED : MAP_PRIVATE) | MAP_FIXED;
|
||||||
void* ret = mmap(virtual_base + virtual_offset, length, prot_flags, flags, fd, host_offset);
|
void* ret = mmap(virtual_base + virtual_offset, length, prot_flags, flags, fd, host_offset);
|
||||||
@@ -924,18 +632,8 @@ public:
|
|||||||
virtual_base = nullptr;
|
virtual_base = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBackingShared() const noexcept {
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
if (ahb_bytes != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return fd >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t backing_size; ///< Size of the backing memory in bytes
|
const size_t backing_size; ///< Size of the backing memory in bytes
|
||||||
const size_t virtual_size; ///< Size of the virtual address placeholder in bytes
|
const size_t virtual_size; ///< Size of the virtual address placeholder in bytes
|
||||||
const size_t preferred_offset;
|
|
||||||
|
|
||||||
u8* backing_base{reinterpret_cast<u8*>(MAP_FAILED)};
|
u8* backing_base{reinterpret_cast<u8*>(MAP_FAILED)};
|
||||||
u8* virtual_base{reinterpret_cast<u8*>(MAP_FAILED)};
|
u8* virtual_base{reinterpret_cast<u8*>(MAP_FAILED)};
|
||||||
@@ -958,18 +656,6 @@ private:
|
|||||||
int ret = close(fd);
|
int ret = close(fd);
|
||||||
ASSERT_MSG(ret == 0, "close failed: {}", strerror(errno));
|
ASSERT_MSG(ret == 0, "close failed: {}", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
for (AHardwareBuffer* buffer : ahb_windows) {
|
|
||||||
AHardwareBuffer_release(buffer);
|
|
||||||
}
|
|
||||||
ahb_windows.clear();
|
|
||||||
ahb_fds.clear();
|
|
||||||
if (ahb_bytes != 0) {
|
|
||||||
committed_backing_size.store(0, std::memory_order_relaxed);
|
|
||||||
ahb_bytes = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdjustMap(size_t* virtual_offset, size_t* length) {
|
void AdjustMap(size_t* virtual_offset, size_t* length) {
|
||||||
@@ -995,19 +681,11 @@ private:
|
|||||||
|
|
||||||
int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create
|
int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create
|
||||||
FreeRegionManager free_manager{};
|
FreeRegionManager free_manager{};
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
std::vector<AHardwareBuffer*> ahb_windows;
|
|
||||||
std::vector<int> ahb_fds;
|
|
||||||
size_t ahb_window_size{};
|
|
||||||
size_t ahb_base{};
|
|
||||||
size_t ahb_bytes{};
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ^^^ POSIX ^^^
|
#endif // ^^^ POSIX ^^^
|
||||||
|
|
||||||
HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_, size_t preferred_offset_)
|
HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_)
|
||||||
: backing_size(backing_size_)
|
: backing_size(backing_size_)
|
||||||
, virtual_size(virtual_size_)
|
, virtual_size(virtual_size_)
|
||||||
{
|
{
|
||||||
@@ -1019,7 +697,7 @@ HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_, size_t prefer
|
|||||||
#else
|
#else
|
||||||
// Try to allocate a fastmem arena.
|
// Try to allocate a fastmem arena.
|
||||||
// The implementation will fail with std::bad_alloc on errors.
|
// The implementation will fail with std::bad_alloc on errors.
|
||||||
impl = std::make_unique<HostMemory::Impl>(AlignUp(backing_size, PageAlignment), AlignUp(virtual_size, PageAlignment) + HugePageSize, preferred_offset_);
|
impl = std::make_unique<HostMemory::Impl>(AlignUp(backing_size, PageAlignment), AlignUp(virtual_size, PageAlignment) + HugePageSize);
|
||||||
if (impl->Init()) {
|
if (impl->Init()) {
|
||||||
backing_base = impl->backing_base;
|
backing_base = impl->backing_base;
|
||||||
virtual_base = impl->virtual_base;
|
virtual_base = impl->virtual_base;
|
||||||
@@ -1089,46 +767,6 @@ void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 f
|
|||||||
std::memset(backing_base + physical_offset, fill_value, length);
|
std::memset(backing_base + physical_offset, fill_value, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::span<AHardwareBuffer* const> HostMemory::BackingHardwareBuffers() const noexcept {
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
return impl ? impl->AhbWindows() : std::span<AHardwareBuffer* const>{};
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t HostMemory::BackingMapCount(size_t host_offset, size_t length) const noexcept {
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
return impl ? impl->BackingMapCount(host_offset, length) : (length != 0 ? 1 : 0);
|
|
||||||
#else
|
|
||||||
return length != 0 ? 1 : 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t HostMemory::BackingHardwareBufferWindowSize() const noexcept {
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
return impl ? impl->AhbWindowSize() : 0;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HostMemory::IsBackingShared() const noexcept {
|
|
||||||
#if defined(__OPENORBIS__) || defined(__managarm__)
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return impl && impl->IsBackingShared();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t HostMemory::BackingHardwareBufferBase() const noexcept {
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
return impl ? impl->AhbBase() : 0;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void HostMemory::EnableDirectMappedAddress() {
|
void HostMemory::EnableDirectMappedAddress() {
|
||||||
#if !(defined(__OPENORBIS__) || defined(__managarm__))
|
#if !(defined(__OPENORBIS__) || defined(__managarm__))
|
||||||
if (impl) {
|
if (impl) {
|
||||||
|
|||||||
@@ -8,17 +8,12 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <span>
|
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/virtual_buffer.h"
|
#include "common/virtual_buffer.h"
|
||||||
|
|
||||||
struct AHardwareBuffer;
|
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
[[nodiscard]] u64 GetCommittedBackingSize() noexcept;
|
|
||||||
|
|
||||||
enum class MemoryPermission : u32 {
|
enum class MemoryPermission : u32 {
|
||||||
Read = 1 << 0,
|
Read = 1 << 0,
|
||||||
Write = 1 << 1,
|
Write = 1 << 1,
|
||||||
@@ -33,7 +28,7 @@ DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission)
|
|||||||
*/
|
*/
|
||||||
class HostMemory {
|
class HostMemory {
|
||||||
public:
|
public:
|
||||||
explicit HostMemory(size_t backing_size_, size_t virtual_size_, size_t preferred_offset_ = 0);
|
explicit HostMemory(size_t backing_size_, size_t virtual_size_);
|
||||||
~HostMemory();
|
~HostMemory();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -67,20 +62,6 @@ public:
|
|||||||
return backing_base;
|
return backing_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] size_t BackingSize() const noexcept {
|
|
||||||
return backing_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] size_t BackingMapCount(size_t host_offset, size_t length) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] std::span<AHardwareBuffer* const> BackingHardwareBuffers() const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] size_t BackingHardwareBufferWindowSize() const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] size_t BackingHardwareBufferBase() const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] bool IsBackingShared() const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] u8* VirtualBasePointer() noexcept {
|
[[nodiscard]] u8* VirtualBasePointer() noexcept {
|
||||||
return virtual_base;
|
return virtual_base;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -20,10 +17,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "common/memory_detect.h"
|
#include "common/memory_detect.h"
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
@@ -76,55 +69,4 @@ const MemoryInfo& GetMemInfo() {
|
|||||||
return mem_info;
|
return mem_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 GetAvailablePhysicalMemory() {
|
|
||||||
#ifdef _WIN32
|
|
||||||
MEMORYSTATUSEX memorystatus;
|
|
||||||
memorystatus.dwLength = sizeof(memorystatus);
|
|
||||||
if (GlobalMemoryStatusEx(&memorystatus)) {
|
|
||||||
return memorystatus.ullAvailPhys;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
#elif defined(__linux__)
|
|
||||||
if (std::FILE* const file = std::fopen("/proc/meminfo", "re")) {
|
|
||||||
char line[256];
|
|
||||||
u64 available = 0;
|
|
||||||
while (std::fgets(line, sizeof(line), file) != nullptr) {
|
|
||||||
if (std::strncmp(line, "MemAvailable:", 13) == 0) {
|
|
||||||
available = std::strtoull(line + 13, nullptr, 10) * 1024ULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::fclose(file);
|
|
||||||
if (available != 0) {
|
|
||||||
return available;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
struct sysinfo info;
|
|
||||||
if (sysinfo(&info) == 0) {
|
|
||||||
const u64 unit = info.mem_unit != 0 ? info.mem_unit : 1ULL;
|
|
||||||
return (static_cast<u64>(info.freeram) + static_cast<u64>(info.bufferram)) * unit;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 GetMaxMapCount() {
|
|
||||||
#ifdef __linux__
|
|
||||||
if (std::FILE* const file = std::fopen("/proc/sys/vm/max_map_count", "re")) {
|
|
||||||
char line[32];
|
|
||||||
u64 count = 0;
|
|
||||||
if (std::fgets(line, sizeof(line), file) != nullptr) {
|
|
||||||
count = std::strtoull(line, nullptr, 10);
|
|
||||||
}
|
|
||||||
std::fclose(file);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -21,8 +18,4 @@ struct MemoryInfo {
|
|||||||
*/
|
*/
|
||||||
[[nodiscard]] const MemoryInfo& GetMemInfo();
|
[[nodiscard]] const MemoryInfo& GetMemInfo();
|
||||||
|
|
||||||
[[nodiscard]] u64 GetAvailablePhysicalMemory();
|
|
||||||
|
|
||||||
[[nodiscard]] u64 GetMaxMapCount();
|
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|||||||
@@ -380,6 +380,28 @@ void UpdateRescalingInfo() {
|
|||||||
TranslateResolutionInfo(setup, info);
|
TranslateResolutionInfo(setup, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 FrameGenMultiplier() {
|
||||||
|
return std::clamp(values.frame_gen_multiplier.GetValue(), MIN_FRAME_GEN_MULTIPLIER,
|
||||||
|
MAX_FRAME_GEN_MULTIPLIER);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FrameGenGenerations() {
|
||||||
|
if (!values.frame_gen.GetValue()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return FrameGenMultiplier() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FrameGenMaxGenerations() {
|
||||||
|
if (!values.frame_gen.GetValue()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (values.frame_gen_target_rate.GetValue() != 0) {
|
||||||
|
return MAX_FRAME_GEN_MULTIPLIER - 1;
|
||||||
|
}
|
||||||
|
return FrameGenMultiplier() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
void RestoreGlobalState(bool is_powered_on) {
|
void RestoreGlobalState(bool is_powered_on) {
|
||||||
// If a game is running, DO NOT restore the global settings state
|
// If a game is running, DO NOT restore the global settings state
|
||||||
if (is_powered_on) {
|
if (is_powered_on) {
|
||||||
|
|||||||
+85
-12
@@ -352,7 +352,7 @@ struct Values {
|
|||||||
true};
|
true};
|
||||||
|
|
||||||
SwitchableSetting<ScalingFilter> scaling_filter{linkage,
|
SwitchableSetting<ScalingFilter> scaling_filter{linkage,
|
||||||
ScalingFilter::Bilinear,
|
ScalingFilter::NearestNeighbor,
|
||||||
"scaling_filter",
|
"scaling_filter",
|
||||||
Category::Renderer,
|
Category::Renderer,
|
||||||
Specialization::Default,
|
Specialization::Default,
|
||||||
@@ -388,6 +388,69 @@ struct Values {
|
|||||||
true,
|
true,
|
||||||
true};
|
true};
|
||||||
|
|
||||||
|
SwitchableSetting<bool> frame_gen{linkage, false, "frame_gen", Category::Renderer,
|
||||||
|
Specialization::Default, true, false};
|
||||||
|
|
||||||
|
SwitchableSetting<u32, true> frame_gen_multiplier{linkage,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
4,
|
||||||
|
"frame_gen_multiplier",
|
||||||
|
Category::Renderer,
|
||||||
|
Specialization::Countable,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
&frame_gen};
|
||||||
|
|
||||||
|
SwitchableSetting<u32, true> frame_gen_target_rate{linkage,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
240,
|
||||||
|
"frame_gen_target_rate",
|
||||||
|
Category::Renderer,
|
||||||
|
Specialization::Countable,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
&frame_gen};
|
||||||
|
|
||||||
|
SwitchableSetting<bool> frame_gen_flow_scale_auto{linkage,
|
||||||
|
true,
|
||||||
|
"frame_gen_flow_scale_auto",
|
||||||
|
Category::Renderer,
|
||||||
|
Specialization::Default,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
&frame_gen};
|
||||||
|
|
||||||
|
SwitchableSetting<u32, true> frame_gen_flow_scale{linkage,
|
||||||
|
75,
|
||||||
|
25,
|
||||||
|
100,
|
||||||
|
"frame_gen_flow_scale",
|
||||||
|
Category::Renderer,
|
||||||
|
Specialization::Countable |
|
||||||
|
Specialization::Percentage,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
&frame_gen};
|
||||||
|
|
||||||
|
SwitchableSetting<u32, true> frame_gen_queue_target{linkage,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
"frame_gen_queue_target",
|
||||||
|
Category::Renderer,
|
||||||
|
Specialization::Countable,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
&frame_gen};
|
||||||
|
|
||||||
|
SwitchableSetting<bool> frame_gen_fp16{linkage, true, "frame_gen_fp16", Category::Renderer,
|
||||||
|
Specialization::Default, true, false, &frame_gen};
|
||||||
|
|
||||||
|
SwitchableSetting<bool> frame_gen_dump_flow{linkage, false, "frame_gen_dump_flow",
|
||||||
|
Category::Renderer};
|
||||||
|
|
||||||
SwitchableSetting<bool> use_asynchronous_gpu_emulation{linkage,
|
SwitchableSetting<bool> use_asynchronous_gpu_emulation{linkage,
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
false,
|
false,
|
||||||
@@ -569,13 +632,8 @@ struct Values {
|
|||||||
SwitchableSetting<bool> emulate_bgr565{linkage, false, "emulate_bgr565",
|
SwitchableSetting<bool> emulate_bgr565{linkage, false, "emulate_bgr565",
|
||||||
Category::RendererHacks};
|
Category::RendererHacks};
|
||||||
|
|
||||||
SwitchableSetting<bool> rescale_hack{linkage,
|
SwitchableSetting<bool> rescale_hack{linkage, false, "rescale_hack",
|
||||||
#ifdef __ANDROID__
|
Category::RendererHacks};
|
||||||
true,
|
|
||||||
#else
|
|
||||||
false,
|
|
||||||
#endif
|
|
||||||
"rescale_hack", Category::RendererHacks};
|
|
||||||
SwitchableSetting<bool> enable_gpu_buffer_readback{linkage,
|
SwitchableSetting<bool> enable_gpu_buffer_readback{linkage,
|
||||||
false,
|
false,
|
||||||
"enable_gpu_buffer_readback",
|
"enable_gpu_buffer_readback",
|
||||||
@@ -587,9 +645,6 @@ struct Values {
|
|||||||
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
|
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
|
||||||
Category::RendererHacks};
|
Category::RendererHacks};
|
||||||
|
|
||||||
SwitchableSetting<bool> use_unified_memory{linkage, false, "use_unified_memory",
|
|
||||||
Category::RendererHacks};
|
|
||||||
|
|
||||||
SwitchableSetting<GpuUnswizzleSize> gpu_unswizzle_texture_size{linkage,
|
SwitchableSetting<GpuUnswizzleSize> gpu_unswizzle_texture_size{linkage,
|
||||||
GpuUnswizzleSize::Large,
|
GpuUnswizzleSize::Large,
|
||||||
"gpu_unswizzle_texture_size",
|
"gpu_unswizzle_texture_size",
|
||||||
@@ -705,7 +760,15 @@ struct Values {
|
|||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
InputSetting<std::array<PlayerInput, 10>> players;
|
InputSetting<std::array<PlayerInput, 10>> players;
|
||||||
|
Setting<bool> disable_wgi_xinput{
|
||||||
|
linkage, false, "disable_wgi_xinput", Category::Controls, Specialization::Default,
|
||||||
|
// Only read/write disable_wgi_xinput on Windows platforms
|
||||||
|
#ifdef _WIN32
|
||||||
|
true
|
||||||
|
#else
|
||||||
|
false
|
||||||
|
#endif
|
||||||
|
};
|
||||||
Setting<bool> enable_raw_input{
|
Setting<bool> enable_raw_input{
|
||||||
linkage, false, "enable_raw_input", Category::Controls, Specialization::Default,
|
linkage, false, "enable_raw_input", Category::Controls, Specialization::Default,
|
||||||
// Only read/write enable_raw_input on Windows platforms
|
// Only read/write enable_raw_input on Windows platforms
|
||||||
@@ -870,10 +933,20 @@ struct Values {
|
|||||||
|
|
||||||
// Per-game overrides
|
// Per-game overrides
|
||||||
bool use_squashed_iterated_blend;
|
bool use_squashed_iterated_blend;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Values values;
|
extern Values values;
|
||||||
|
|
||||||
|
constexpr u32 MIN_FRAME_GEN_MULTIPLIER = 2;
|
||||||
|
constexpr u32 MAX_FRAME_GEN_MULTIPLIER = 4;
|
||||||
|
|
||||||
|
[[nodiscard]] u32 FrameGenMultiplier();
|
||||||
|
|
||||||
|
[[nodiscard]] size_t FrameGenGenerations();
|
||||||
|
|
||||||
|
[[nodiscard]] size_t FrameGenMaxGenerations();
|
||||||
|
|
||||||
bool getDebugKnobAt(u8 i);
|
bool getDebugKnobAt(u8 i);
|
||||||
|
|
||||||
void UpdateGPUAccuracy();
|
void UpdateGPUAccuracy();
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ ENUM(TimeZone, Auto, Default, Cet, Cst6Cdt, Cuba, Eet, Egypt, Eire, Est, Est5Edt
|
|||||||
GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica,
|
GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica,
|
||||||
Japan, Kwajalein, Libya, Met, Mst, Mst7Mdt, Navajo, Nz, NzChat, Poland, Portugal, Prc, Pst8Pdt,
|
Japan, Kwajalein, Libya, Met, Mst, Mst7Mdt, Navajo, Nz, NzChat, Poland, Portugal, Prc, Pst8Pdt,
|
||||||
Roc, Rok, Singapore, Turkey, Uct, Universal, Utc, WSu, Wet, Zulu);
|
Roc, Rok, Singapore, Turkey, Uct, Universal, Utc, WSu, Wet, Zulu);
|
||||||
ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16, X32, X64, None);
|
ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16);
|
||||||
ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous);
|
ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous);
|
||||||
ENUM(AstcRecompression, Uncompressed, Bc1, Bc3);
|
ENUM(AstcRecompression, Uncompressed, Bc1, Bc3);
|
||||||
ENUM(FramePacingMode, Target_Auto, Target_30, Target_60, Target_90, Target_120);
|
ENUM(FramePacingMode, Target_Auto, Target_30, Target_60, Target_90, Target_120);
|
||||||
|
|||||||
@@ -1173,7 +1173,7 @@ add_library(core STATIC
|
|||||||
|
|
||||||
if (ENABLE_WIFI_SCAN)
|
if (ENABLE_WIFI_SCAN)
|
||||||
target_sources(core PRIVATE internal_network/wifi_scanner.cpp)
|
target_sources(core PRIVATE internal_network/wifi_scanner.cpp)
|
||||||
if (PLATFORM_LINUX)
|
if (LINUX)
|
||||||
target_link_libraries(core PRIVATE iw)
|
target_link_libraries(core PRIVATE iw)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
@@ -1199,7 +1199,7 @@ if (MSVC)
|
|||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_compile_options(core PRIVATE
|
target_compile_options(core PRIVATE
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=conversion>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wconversion>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-sign-conversion>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-sign-conversion>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-cast-function-type>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-cast-function-type>
|
||||||
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>)
|
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>)
|
||||||
|
|||||||
+1
-5
@@ -119,7 +119,6 @@ struct System::Impl {
|
|||||||
|
|
||||||
is_multicore = Settings::values.use_multi_core.GetValue();
|
is_multicore = Settings::values.use_multi_core.GetValue();
|
||||||
extended_memory_layout = Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_4Gb;
|
extended_memory_layout = Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_4Gb;
|
||||||
unified_memory = Settings::values.use_unified_memory.GetValue();
|
|
||||||
|
|
||||||
core_timing.SetMulticore(is_multicore);
|
core_timing.SetMulticore(is_multicore);
|
||||||
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
|
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
|
||||||
@@ -147,8 +146,7 @@ struct System::Impl {
|
|||||||
!device_memory.has_value() ||
|
!device_memory.has_value() ||
|
||||||
is_multicore != Settings::values.use_multi_core.GetValue() ||
|
is_multicore != Settings::values.use_multi_core.GetValue() ||
|
||||||
extended_memory_layout != (Settings::values.memory_layout_mode.GetValue() !=
|
extended_memory_layout != (Settings::values.memory_layout_mode.GetValue() !=
|
||||||
Settings::MemoryLayout::Memory_4Gb) ||
|
Settings::MemoryLayout::Memory_4Gb);
|
||||||
unified_memory != Settings::values.use_unified_memory.GetValue();
|
|
||||||
|
|
||||||
if (!must_reinitialize) {
|
if (!must_reinitialize) {
|
||||||
return;
|
return;
|
||||||
@@ -159,7 +157,6 @@ struct System::Impl {
|
|||||||
is_multicore = Settings::values.use_multi_core.GetValue();
|
is_multicore = Settings::values.use_multi_core.GetValue();
|
||||||
extended_memory_layout =
|
extended_memory_layout =
|
||||||
Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_4Gb;
|
Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_4Gb;
|
||||||
unified_memory = Settings::values.use_unified_memory.GetValue();
|
|
||||||
|
|
||||||
Initialize(system);
|
Initialize(system);
|
||||||
}
|
}
|
||||||
@@ -506,7 +503,6 @@ struct System::Impl {
|
|||||||
std::atomic_bool is_powered_on{};
|
std::atomic_bool is_powered_on{};
|
||||||
bool is_multicore : 1 = false;
|
bool is_multicore : 1 = false;
|
||||||
bool extended_memory_layout : 1 = false;
|
bool extended_memory_layout : 1 = false;
|
||||||
bool unified_memory : 1 = false;
|
|
||||||
bool exit_locked : 1 = false;
|
bool exit_locked : 1 = false;
|
||||||
bool exit_requested : 1 = false;
|
bool exit_requested : 1 = false;
|
||||||
bool nvdec_active : 1 = false;
|
bool nvdec_active : 1 = false;
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -15,18 +12,9 @@ constexpr size_t VirtualReserveSize = 1ULL << 38;
|
|||||||
constexpr size_t VirtualReserveSize = 1ULL << 39;
|
constexpr size_t VirtualReserveSize = 1ULL << 39;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace {
|
|
||||||
size_t ApplicationPoolOffset() {
|
|
||||||
using Init = Kernel::Board::Nintendo::Nx::KSystemControl::Init;
|
|
||||||
const size_t dram_size = Init::GetIntendedMemorySize();
|
|
||||||
const size_t application_pool_size = Init::GetApplicationPoolSize();
|
|
||||||
return dram_size > application_pool_size ? dram_size - application_pool_size : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceMemory::DeviceMemory()
|
DeviceMemory::DeviceMemory()
|
||||||
: buffer{Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetIntendedMemorySize(),
|
: buffer{Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetIntendedMemorySize(),
|
||||||
VirtualReserveSize, ApplicationPoolOffset()} {}
|
VirtualReserveSize} {}
|
||||||
|
|
||||||
DeviceMemory::~DeviceMemory() = default;
|
DeviceMemory::~DeviceMemory() = default;
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,6 @@
|
|||||||
#include "common/scratch_buffer.h"
|
#include "common/scratch_buffer.h"
|
||||||
#include "common/virtual_buffer.h"
|
#include "common/virtual_buffer.h"
|
||||||
|
|
||||||
struct AHardwareBuffer;
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
constexpr size_t DEVICE_PAGEBITS = 12ULL;
|
constexpr size_t DEVICE_PAGEBITS = 12ULL;
|
||||||
@@ -97,34 +95,6 @@ public:
|
|||||||
ApplyOpOnPAddr(address, buffer, operation);
|
ApplyOpOnPAddr(address, buffer, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* GetPhysicalBase() noexcept {
|
|
||||||
return reinterpret_cast<u8*>(physical_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
const u8* GetPhysicalBase() const noexcept {
|
|
||||||
return reinterpret_cast<const u8*>(physical_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetPhysicalSize() const noexcept {
|
|
||||||
return physical_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::span<AHardwareBuffer* const> GetBackingHardwareBuffers() const noexcept {
|
|
||||||
return ahb_windows;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetBackingHardwareBufferWindowSize() const noexcept {
|
|
||||||
return ahb_window_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetBackingHardwareBufferBase() const noexcept {
|
|
||||||
return ahb_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsBackingShared() const noexcept {
|
|
||||||
return backing_is_shared;
|
|
||||||
}
|
|
||||||
|
|
||||||
PAddr GetPhysicalRawAddressFromDAddr(DAddr address) const {
|
PAddr GetPhysicalRawAddressFromDAddr(DAddr address) const {
|
||||||
PAddr subbits = PAddr(address & page_mask);
|
PAddr subbits = PAddr(address & page_mask);
|
||||||
auto paddr = tracked_entries[(address >> page_bits)].compressed_physical_ptr;
|
auto paddr = tracked_entries[(address >> page_bits)].compressed_physical_ptr;
|
||||||
@@ -201,11 +171,6 @@ private:
|
|||||||
std::unique_ptr<DeviceMemoryManagerAllocator<Traits>> impl;
|
std::unique_ptr<DeviceMemoryManagerAllocator<Traits>> impl;
|
||||||
|
|
||||||
const uintptr_t physical_base;
|
const uintptr_t physical_base;
|
||||||
const size_t physical_size;
|
|
||||||
const std::span<AHardwareBuffer* const> ahb_windows;
|
|
||||||
const size_t ahb_window_size;
|
|
||||||
const size_t ahb_base;
|
|
||||||
const bool backing_is_shared;
|
|
||||||
DeviceInterface* device_inter;
|
DeviceInterface* device_inter;
|
||||||
|
|
||||||
struct TrackedEntry {
|
struct TrackedEntry {
|
||||||
|
|||||||
@@ -171,11 +171,6 @@ struct DeviceMemoryManagerAllocator {
|
|||||||
template <typename Traits>
|
template <typename Traits>
|
||||||
DeviceMemoryManager<Traits>::DeviceMemoryManager(const DeviceMemory& device_memory_)
|
DeviceMemoryManager<Traits>::DeviceMemoryManager(const DeviceMemory& device_memory_)
|
||||||
: physical_base{uintptr_t(device_memory_.buffer.BackingBasePointer())}
|
: physical_base{uintptr_t(device_memory_.buffer.BackingBasePointer())}
|
||||||
, physical_size{device_memory_.buffer.BackingSize()}
|
|
||||||
, ahb_windows{device_memory_.buffer.BackingHardwareBuffers()}
|
|
||||||
, ahb_window_size{device_memory_.buffer.BackingHardwareBufferWindowSize()}
|
|
||||||
, ahb_base{device_memory_.buffer.BackingHardwareBufferBase()}
|
|
||||||
, backing_is_shared{device_memory_.buffer.IsBackingShared()}
|
|
||||||
, device_inter{nullptr}
|
, device_inter{nullptr}
|
||||||
, compressed_device_addr(1ULL << ((Settings::values.memory_layout_mode.GetValue() == Settings::MemoryLayout::Memory_4Gb ? physical_min_bits : physical_max_bits) - Memory::YUZU_PAGEBITS))
|
, compressed_device_addr(1ULL << ((Settings::values.memory_layout_mode.GetValue() == Settings::MemoryLayout::Memory_4Gb ? physical_min_bits : physical_max_bits) - Memory::YUZU_PAGEBITS))
|
||||||
, tracked_entries(device_as_size >> Memory::YUZU_PAGEBITS)
|
, tracked_entries(device_as_size >> Memory::YUZU_PAGEBITS)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ Result CloseHandle(Core::System& system, Handle handle) {
|
|||||||
|
|
||||||
/// Clears the signaled state of an event or process.
|
/// Clears the signaled state of an event or process.
|
||||||
Result ResetSignal(Core::System& system, Handle handle) {
|
Result ResetSignal(Core::System& system, Handle handle) {
|
||||||
LOG_DEBUG(Kernel_SVC, "called handle {:#08x}", handle);
|
LOG_TRACE(Kernel_SVC, "called handle {:#08x}", handle);
|
||||||
|
|
||||||
// Get the current handle table.
|
// Get the current handle table.
|
||||||
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
@@ -264,7 +265,7 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NvResult nvhost_ctrl_gpu::ZBCSetTable(IoctlZbcSetTable& params) {
|
NvResult nvhost_ctrl_gpu::ZBCSetTable(IoctlZbcSetTable& params) {
|
||||||
if (params.type > supported_types) {
|
if (params.type == 0 || params.type > supported_types) {
|
||||||
LOG_ERROR(Service_NVDRV, "ZBCSetTable: invalid type {:#x}", params.type);
|
LOG_ERROR(Service_NVDRV, "ZBCSetTable: invalid type {:#x}", params.type);
|
||||||
return NvResult::BadParameter;
|
return NvResult::BadParameter;
|
||||||
}
|
}
|
||||||
@@ -279,42 +280,61 @@ NvResult nvhost_ctrl_gpu::ZBCSetTable(IoctlZbcSetTable& params) {
|
|||||||
color_entry.format = params.format;
|
color_entry.format = params.format;
|
||||||
color_entry.ref_cnt = 1u;
|
color_entry.ref_cnt = 1u;
|
||||||
|
|
||||||
auto color_it = std::ranges::find_if(zbc_colors,
|
const auto color_end = zbc_colors.begin() + zbc_used_color_entries;
|
||||||
[&](const ZbcColorEntry& color_in_question) {
|
auto color_it = std::find_if(zbc_colors.begin(), color_end,
|
||||||
return color_entry.format == color_in_question.format &&
|
[&](const ZbcColorEntry& color_in_question) {
|
||||||
color_entry.color_ds == color_in_question.color_ds &&
|
return color_entry.format == color_in_question.format &&
|
||||||
color_entry.color_l2 == color_in_question.color_l2;
|
color_entry.color_ds == color_in_question.color_ds &&
|
||||||
});
|
color_entry.color_l2 == color_in_question.color_l2;
|
||||||
|
});
|
||||||
|
|
||||||
if (color_it != zbc_colors.end()) {
|
if (color_it != color_end) {
|
||||||
++color_it->ref_cnt;
|
++color_it->ref_cnt;
|
||||||
LOG_DEBUG(Service_NVDRV, "ZBCSetTable: reused color entry fmt={:#x}, ref_cnt={:#x}",
|
LOG_DEBUG(Service_NVDRV, "ZBCSetTable: reused color entry fmt={:#x}, ref_cnt={:#x}",
|
||||||
params.format, color_it->ref_cnt);
|
params.format, color_it->ref_cnt);
|
||||||
} else {
|
break;
|
||||||
zbc_colors.push_back(color_entry);
|
|
||||||
LOG_DEBUG(Service_NVDRV, "ZBCSetTable: added color entry fmt={:#x}, index={:#x}",
|
|
||||||
params.format, zbc_colors.size() - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zbc_used_color_entries >= ZBC_TABLE_SIZE) {
|
||||||
|
LOG_WARNING(Service_NVDRV, "ZBCSetTable: color table is full, fmt={:#x}",
|
||||||
|
params.format);
|
||||||
|
return NvResult::InsufficientMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
zbc_colors[zbc_used_color_entries] = color_entry;
|
||||||
|
LOG_DEBUG(Service_NVDRV, "ZBCSetTable: added color entry fmt={:#x}, index={:#x}",
|
||||||
|
params.format, zbc_used_color_entries);
|
||||||
|
++zbc_used_color_entries;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ZBCTypes::depth: {
|
case ZBCTypes::depth: {
|
||||||
ZbcDepthEntry depth_entry{params.depth, params.format, 1u};
|
ZbcDepthEntry depth_entry{params.depth, params.format, 1u};
|
||||||
|
|
||||||
auto depth_it = std::ranges::find_if(zbc_depths,
|
const auto depth_end = zbc_depths.begin() + zbc_used_depth_entries;
|
||||||
[&](const ZbcDepthEntry& depth_entry_in_question) {
|
auto depth_it = std::find_if(zbc_depths.begin(), depth_end,
|
||||||
return depth_entry.format == depth_entry_in_question.format &&
|
[&](const ZbcDepthEntry& depth_entry_in_question) {
|
||||||
depth_entry.depth == depth_entry_in_question.depth;
|
return depth_entry.format == depth_entry_in_question.format &&
|
||||||
});
|
depth_entry.depth == depth_entry_in_question.depth;
|
||||||
|
});
|
||||||
|
|
||||||
if (depth_it != zbc_depths.end()) {
|
if (depth_it != depth_end) {
|
||||||
++depth_it->ref_cnt;
|
++depth_it->ref_cnt;
|
||||||
LOG_DEBUG(Service_NVDRV, "ZBCSetTable: reused depth entry fmt={:#x}, ref_cnt={:#x}",
|
LOG_DEBUG(Service_NVDRV, "ZBCSetTable: reused depth entry fmt={:#x}, ref_cnt={:#x}",
|
||||||
depth_entry.format, depth_it->ref_cnt);
|
depth_entry.format, depth_it->ref_cnt);
|
||||||
} else {
|
break;
|
||||||
zbc_depths.push_back(depth_entry);
|
|
||||||
LOG_DEBUG(Service_NVDRV, "ZBCSetTable: added depth entry fmt={:#x}, index={:#x}",
|
|
||||||
depth_entry.format, zbc_depths.size() - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zbc_used_depth_entries >= ZBC_TABLE_SIZE) {
|
||||||
|
LOG_WARNING(Service_NVDRV, "ZBCSetTable: depth table is full, fmt={:#x}",
|
||||||
|
depth_entry.format);
|
||||||
|
return NvResult::InsufficientMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
zbc_depths[zbc_used_depth_entries] = depth_entry;
|
||||||
|
LOG_DEBUG(Service_NVDRV, "ZBCSetTable: added depth entry fmt={:#x}, index={:#x}",
|
||||||
|
depth_entry.format, zbc_used_depth_entries);
|
||||||
|
++zbc_used_depth_entries;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,10 +349,16 @@ NvResult nvhost_ctrl_gpu::ZBCQueryTable(IoctlZbcQueryTable& params) {
|
|||||||
|
|
||||||
std::scoped_lock lk(zbc_mutex);
|
std::scoped_lock lk(zbc_mutex);
|
||||||
|
|
||||||
|
if (params.type == 0) {
|
||||||
|
params.index_size = ZBC_TABLE_SIZE;
|
||||||
|
return NvResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
switch (static_cast<ZBCTypes>(params.type)) {
|
switch (static_cast<ZBCTypes>(params.type)) {
|
||||||
case ZBCTypes::color: {
|
case ZBCTypes::color: {
|
||||||
if (params.index_size >= zbc_colors.size()) {
|
if (params.index_size >= zbc_used_color_entries) {
|
||||||
LOG_ERROR(Service_NVDRV, "ZBCQueryTable: invalid color index {:#x}", params.index_size);
|
LOG_ERROR(Service_NVDRV, "ZBCQueryTable: invalid color index {:#x}",
|
||||||
|
params.index_size);
|
||||||
return NvResult::BadParameter;
|
return NvResult::BadParameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,12 +368,13 @@ NvResult nvhost_ctrl_gpu::ZBCQueryTable(IoctlZbcQueryTable& params) {
|
|||||||
params.depth = 0;
|
params.depth = 0;
|
||||||
params.ref_cnt = colors.ref_cnt;
|
params.ref_cnt = colors.ref_cnt;
|
||||||
params.format = colors.format;
|
params.format = colors.format;
|
||||||
params.index_size = static_cast<u32>(zbc_colors.size());
|
params.index_size = zbc_used_color_entries;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ZBCTypes::depth: {
|
case ZBCTypes::depth: {
|
||||||
if (params.index_size >= zbc_depths.size()) {
|
if (params.index_size >= zbc_used_depth_entries) {
|
||||||
LOG_ERROR(Service_NVDRV, "ZBCQueryTable: invalid depth index {:#x}", params.index_size);
|
LOG_ERROR(Service_NVDRV, "ZBCQueryTable: invalid depth index {:#x}",
|
||||||
|
params.index_size);
|
||||||
return NvResult::BadParameter;
|
return NvResult::BadParameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +384,8 @@ NvResult nvhost_ctrl_gpu::ZBCQueryTable(IoctlZbcQueryTable& params) {
|
|||||||
params.depth = depth_entry.depth;
|
params.depth = depth_entry.depth;
|
||||||
params.ref_cnt = depth_entry.ref_cnt;
|
params.ref_cnt = depth_entry.ref_cnt;
|
||||||
params.format = depth_entry.format;
|
params.format = depth_entry.format;
|
||||||
params.index_size = static_cast<u32>(zbc_depths.size());
|
params.index_size = zbc_used_depth_entries;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <array>
|
||||||
|
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
@@ -212,10 +212,14 @@ private:
|
|||||||
Kernel::KEvent* unknown_event;
|
Kernel::KEvent* unknown_event;
|
||||||
|
|
||||||
// ZBC Tables
|
// ZBC Tables
|
||||||
|
static constexpr u32 ZBC_TABLE_SIZE = 15u;
|
||||||
|
static constexpr u32 supported_types = 2u;
|
||||||
|
|
||||||
std::mutex zbc_mutex{};
|
std::mutex zbc_mutex{};
|
||||||
std::vector<ZbcColorEntry> zbc_colors{};
|
std::array<ZbcColorEntry, ZBC_TABLE_SIZE> zbc_colors{};
|
||||||
std::vector<ZbcDepthEntry> zbc_depths{};
|
std::array<ZbcDepthEntry, ZBC_TABLE_SIZE> zbc_depths{};
|
||||||
const u32 supported_types = 2u;
|
u32 zbc_used_color_entries{};
|
||||||
|
u32 zbc_used_depth_entries{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::Nvidia::Devices
|
} // namespace Service::Nvidia::Devices
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator
|
||||||
@@ -84,7 +84,7 @@ private:
|
|||||||
RestrictionSettings restriction_settings{};
|
RestrictionSettings restriction_settings{};
|
||||||
std::array<char, 8> pin_code{};
|
std::array<char, 8> pin_code{};
|
||||||
Capability capability{};
|
Capability capability{};
|
||||||
// TODO: this is RAW as fuck
|
// TODO: this is raw
|
||||||
PlayTimerSettings raw_play_timer_settings{};
|
PlayTimerSettings raw_play_timer_settings{};
|
||||||
|
|
||||||
KernelHelpers::ServiceContext service_context;
|
KernelHelpers::ServiceContext service_context;
|
||||||
|
|||||||
@@ -1020,7 +1020,7 @@ Result ISystemSettingsServer::GetBatteryLot(Out<BatteryLot> out_battery_lot) {
|
|||||||
c.lot_number[1] = 'H';
|
c.lot_number[1] = 'H';
|
||||||
c.lot_number[2] = 'A';
|
c.lot_number[2] = 'A';
|
||||||
c.lot_number[3] = 'C';
|
c.lot_number[3] = 'C';
|
||||||
// TODO: I have no fucking idea what the letters mean
|
// TODO: what do the letters mean?
|
||||||
c.lot_number[4] = 'H';
|
c.lot_number[4] = 'H';
|
||||||
c.lot_number[5] = 'Z';
|
c.lot_number[5] = 'Z';
|
||||||
c.lot_number[6] = 'Z';
|
c.lot_number[6] = 'Z';
|
||||||
|
|||||||
@@ -88,25 +88,10 @@ Result IApplicationDisplayService::GetIndirectDisplayTransactionService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IApplicationDisplayService::OpenDisplay(Out<u64> out_display_id, DisplayName display_name) {
|
Result IApplicationDisplayService::OpenDisplay(Out<u64> out_display_id, DisplayName display_name) {
|
||||||
LOG_DEBUG(Service_VI, "called with display_name={}", display_name.data());
|
|
||||||
|
|
||||||
// Ensure the display name is null-terminated
|
// Ensure the display name is null-terminated
|
||||||
display_name[display_name.size() - 1] = '\0';
|
display_name[display_name.size() - 1] = '\0';
|
||||||
|
|
||||||
// According to switchbrew, only "Default", "External", "Edid", "Internal" and "Null" are valid
|
LOG_DEBUG(Service_VI, "called with display_name={}", display_name.data());
|
||||||
const std::array<std::string_view, 5> valid_names = {
|
|
||||||
"Default", "External", "Edid", "Internal", "Null"
|
|
||||||
};
|
|
||||||
|
|
||||||
bool valid_name = false;
|
|
||||||
for (const auto& name : valid_names) {
|
|
||||||
if (name == display_name.data()) {
|
|
||||||
valid_name = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
R_UNLESS(valid_name, ResultOperationFailed);
|
|
||||||
|
|
||||||
R_RETURN(m_container->OpenDisplay(out_display_id, display_name));
|
R_RETURN(m_container->OpenDisplay(out_display_id, display_name));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -531,7 +531,8 @@ int TranslateTypeToNative(Type type) {
|
|||||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(MPLS) \
|
NETWORK_PROTOCOL_TRANSLATE_ELEM(MPLS) \
|
||||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(PFSYNC)
|
NETWORK_PROTOCOL_TRANSLATE_ELEM(PFSYNC)
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
// Other platforms get fucked
|
// Other platforms may not support some niche protocols.
|
||||||
|
// This is usually not an issue
|
||||||
#define NETWORK_PROTOCOL_TRANSLATE_LIST \
|
#define NETWORK_PROTOCOL_TRANSLATE_LIST \
|
||||||
NETWORK_PROTOCOL_TRANSLATE_ELEM(IP) \
|
NETWORK_PROTOCOL_TRANSLATE_ELEM(IP) \
|
||||||
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(HOPOPTS)*/ \
|
/*NETWORK_PROTOCOL_TRANSLATE_ELEM(HOPOPTS)*/ \
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ endif()
|
|||||||
# Dynarmic project options
|
# Dynarmic project options
|
||||||
option(DYNARMIC_ENABLE_CPU_FEATURE_DETECTION "Turning this off causes dynarmic to assume the host CPU doesn't support anything later than SSE3" ON)
|
option(DYNARMIC_ENABLE_CPU_FEATURE_DETECTION "Turning this off causes dynarmic to assume the host CPU doesn't support anything later than SSE3" ON)
|
||||||
|
|
||||||
if (PLATFORM_OPENBSD OR PLATFORM_DRAGONFLY OR PLATFORM_NETBSD)
|
if (OPENBSD OR DRAGONFLY OR NETBSD)
|
||||||
set(REQUIRE_WX ON)
|
set(REQUIRE_WX ON)
|
||||||
else()
|
else()
|
||||||
set(REQUIRE_WX OFF)
|
set(REQUIRE_WX OFF)
|
||||||
|
|||||||
@@ -363,7 +363,7 @@ elseif (APPLE)
|
|||||||
backend/exception_handler_macos_mig.c
|
backend/exception_handler_macos_mig.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
elseif (UNIX AND NOT PLATFORM_HAIKU)
|
elseif (UNIX AND NOT HAIKUOS)
|
||||||
# Haiku lacks <ucontext.h>
|
# Haiku lacks <ucontext.h>
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
target_link_libraries(dynarmic PRIVATE rt)
|
target_link_libraries(dynarmic PRIVATE rt)
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ private:
|
|||||||
BlockOfCode block_of_code;
|
BlockOfCode block_of_code;
|
||||||
A32EmitX64 emitter;
|
A32EmitX64 emitter;
|
||||||
Optimization::PolyfillOptions polyfill_options;
|
Optimization::PolyfillOptions polyfill_options;
|
||||||
// Keep it here, you don't wanna mess with the fuckery that's initializer lists
|
// Keep it here in order to not mess with initializer lists
|
||||||
const A32::UserConfig conf;
|
const A32::UserConfig conf;
|
||||||
Jit* jit_interface;
|
Jit* jit_interface;
|
||||||
|
|
||||||
|
|||||||
@@ -2160,8 +2160,6 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||||||
ROUNDING_MODE_CASE(CASE, 0x3e) \
|
ROUNDING_MODE_CASE(CASE, 0x3e) \
|
||||||
ROUNDING_MODE_CASE(CASE, 0x3f)
|
ROUNDING_MODE_CASE(CASE, 0x3f)
|
||||||
|
|
||||||
// FUCK YOU MSVC, FUCKING DEPTH CANT EVEN HANDLE 8+16+32+64 DEPTH OF A ELSE STATMENT YOU FUCKING STUPID
|
|
||||||
// BURN MSVC BURN IT STUPID COMPILER CAN'T EVEN COMPILE THE MOST BASIC C++
|
|
||||||
ROUNDING_MODE_SWITCH(ToNearest_TieEven)
|
ROUNDING_MODE_SWITCH(ToNearest_TieEven)
|
||||||
ROUNDING_MODE_SWITCH(TowardsPlusInfinity)
|
ROUNDING_MODE_SWITCH(TowardsPlusInfinity)
|
||||||
ROUNDING_MODE_SWITCH(TowardsMinusInfinity)
|
ROUNDING_MODE_SWITCH(TowardsMinusInfinity)
|
||||||
|
|||||||
@@ -787,7 +787,7 @@ static void FoldCountLeadingZeros(IR::Inst& inst, bool is_32_bit) {
|
|||||||
/// Folds division operations based on the following:
|
/// Folds division operations based on the following:
|
||||||
///
|
///
|
||||||
/// 1. x / 0 -> 0 (NOTE: This is an ARM-specific behavior defined in the architecture reference manual)
|
/// 1. x / 0 -> 0 (NOTE: This is an ARM-specific behavior defined in the architecture reference manual)
|
||||||
/// 2a. 0x8000_0000 / 0xFFFF_FFFF -> 0x8000_0000 (NOTE: More ARM bullshit)
|
/// 2a. 0x8000_0000 / 0xFFFF_FFFF -> 0x8000_0000 (NOTE: More ARM errata)
|
||||||
/// 2b. 0x8000_0000_0000_0000 / 0xFFFF_FFFF_FFFF_FFFF -> 0x8000_0000_0000_0000
|
/// 2b. 0x8000_0000_0000_0000 / 0xFFFF_FFFF_FFFF_FFFF -> 0x8000_0000_0000_0000
|
||||||
/// 3. imm_x / imm_y -> result
|
/// 3. imm_x / imm_y -> result
|
||||||
/// 4. x / 1 -> x
|
/// 4. x / 1 -> x
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ if (MSVC)
|
|||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_compile_options(hid_core PRIVATE
|
target_compile_options(hid_core PRIVATE
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=conversion>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wconversion>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-sign-conversion>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-sign-conversion>
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-cast-function-type>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-cast-function-type>
|
||||||
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>)
|
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ if (MSVC)
|
|||||||
/we4800 # Implicit conversion from 'type' to bool. Possible information loss
|
/we4800 # Implicit conversion from 'type' to bool. Possible information loss
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_compile_options(input_common PRIVATE $<$<COMPILE_LANGUAGE:C,CXX>:-Werror=conversion>)
|
target_compile_options(input_common PRIVATE $<$<COMPILE_LANGUAGE:C,CXX>:-Wconversion>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ANDROID)
|
if (ANDROID)
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
@@ -157,8 +160,8 @@ Common::ParamPackage Android::BuildButtonParamPackageForButton(PadIdentifier ide
|
|||||||
|
|
||||||
bool Android::MatchVID(Common::UUID device, const std::vector<std::string>& vids) const {
|
bool Android::MatchVID(Common::UUID device, const std::vector<std::string>& vids) const {
|
||||||
for (size_t i = 0; i < vids.size(); ++i) {
|
for (size_t i = 0; i < vids.size(); ++i) {
|
||||||
auto fucker = device.RawString();
|
auto dev_str = device.RawString();
|
||||||
if (fucker.find(vids[i]) != std::string::npos) {
|
if (dev_str.find(vids[i]) != std::string::npos) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -648,6 +648,13 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
|
|||||||
// Disable raw input. When enabled this setting causes SDL to die when a web applet opens
|
// Disable raw input. When enabled this setting causes SDL to die when a web applet opens
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, Settings::values.enable_raw_input ? "1" : "0");
|
SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, Settings::values.enable_raw_input ? "1" : "0");
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (Settings::values.disable_wgi_xinput) {
|
||||||
|
SDL_SetHintWithPriority(SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT, "0", SDL_HINT_OVERRIDE);
|
||||||
|
SDL_SetHintWithPriority(SDL_HINT_JOYSTICK_WGI, "0", SDL_HINT_OVERRIDE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// SDL3 defaults Steam Controller Bluetooth HIDAPI support to off, which can disable gyro.
|
// SDL3 defaults Steam Controller Bluetooth HIDAPI support to off, which can disable gyro.
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STEAM, "1");
|
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STEAM, "1");
|
||||||
SDL_SetHint(SDL_HINT_GAMECONTROLLER_SENSOR_FUSION, "1");
|
SDL_SetHint(SDL_HINT_GAMECONTROLLER_SENSOR_FUSION, "1");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
|
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
|
||||||
@@ -28,6 +28,6 @@ if (ENABLE_WEB_SERVICE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Solaris uses /lib/amd64/libsocket.so and /lib/amd64/libnsl.so
|
# Solaris uses /lib/amd64/libsocket.so and /lib/amd64/libnsl.so
|
||||||
if (PLATFORM_SUN)
|
if (SOLARIS)
|
||||||
target_link_libraries(network PRIVATE socket nsl)
|
target_link_libraries(network PRIVATE socket nsl)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -227,8 +227,6 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
|
|||||||
tr("Preserves GPU-modified data by reading it back before uploading.\nSome games require this to render certain effects properly."));
|
tr("Preserves GPU-modified data by reading it back before uploading.\nSome games require this to render certain effects properly."));
|
||||||
INSERT(Settings, use_asynchronous_shaders, tr("Enable asynchronous shader compilation"),
|
INSERT(Settings, use_asynchronous_shaders, tr("Enable asynchronous shader compilation"),
|
||||||
tr("May reduce shader stutter."));
|
tr("May reduce shader stutter."));
|
||||||
INSERT(Settings, use_unified_memory, tr("Enable unified memory access"),
|
|
||||||
tr("Lets the GPU write buffer readbacks directly into guest memory."));
|
|
||||||
INSERT(Settings, gpu_clock, tr("GPU Clocks"),
|
INSERT(Settings, gpu_clock, tr("GPU Clocks"),
|
||||||
tr("Makes the game believe GPU work finishes faster than it does, so it stops lowering "
|
tr("Makes the game believe GPU work finishes faster than it does, so it stops lowering "
|
||||||
"resolution and render distance to fit the Switch's clocks."));
|
"resolution and render distance to fit the Switch's clocks."));
|
||||||
@@ -524,9 +522,6 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent) {
|
|||||||
PAIR(AnisotropyMode, X4, tr("4x")),
|
PAIR(AnisotropyMode, X4, tr("4x")),
|
||||||
PAIR(AnisotropyMode, X8, tr("8x")),
|
PAIR(AnisotropyMode, X8, tr("8x")),
|
||||||
PAIR(AnisotropyMode, X16, tr("16x")),
|
PAIR(AnisotropyMode, X16, tr("16x")),
|
||||||
PAIR(AnisotropyMode, X32, tr("32x")),
|
|
||||||
PAIR(AnisotropyMode, X64, tr("64x")),
|
|
||||||
PAIR(AnisotropyMode, None, tr("None")),
|
|
||||||
}});
|
}});
|
||||||
translations->insert(
|
translations->insert(
|
||||||
{Settings::EnumMetadata<Settings::Language>::Index(),
|
{Settings::EnumMetadata<Settings::Language>::Index(),
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ if (MSVC)
|
|||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_compile_options(shader_recompiler PRIVATE
|
target_compile_options(shader_recompiler PRIVATE
|
||||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=conversion>
|
$<$<COMPILE_LANGUAGE:C,CXX>:-Wconversion>
|
||||||
# Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6.
|
# Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6.
|
||||||
# And this in turns limits the size of a std::array.
|
# And this in turns limits the size of a std::array.
|
||||||
$<$<CXX_COMPILER_ID:Clang>:-fbracket-depth=1024>
|
$<$<CXX_COMPILER_ID:Clang>:-fbracket-depth=1024>
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -217,6 +220,22 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
|
|||||||
ctx.AddF32("{}={}{}.{};", inst, input_decorator, ctx.position_name, swizzle);
|
ctx.AddF32("{}={}{}.{};", inst, input_decorator, ctx.position_name, swizzle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IR::Attribute::ClipDistance0:
|
||||||
|
case IR::Attribute::ClipDistance1:
|
||||||
|
case IR::Attribute::ClipDistance2:
|
||||||
|
case IR::Attribute::ClipDistance3:
|
||||||
|
case IR::Attribute::ClipDistance4:
|
||||||
|
case IR::Attribute::ClipDistance5:
|
||||||
|
case IR::Attribute::ClipDistance6:
|
||||||
|
case IR::Attribute::ClipDistance7: {
|
||||||
|
const u32 index{static_cast<u32>(attr) - static_cast<u32>(IR::Attribute::ClipDistance0)};
|
||||||
|
if (IsInputArray(ctx.stage)) {
|
||||||
|
ctx.AddF32("{}=gl_in[{}].gl_ClipDistance[{}];", inst, vertex, index);
|
||||||
|
} else {
|
||||||
|
ctx.AddF32("{}=gl_ClipDistance[{}];", inst, index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case IR::Attribute::PointSpriteS:
|
case IR::Attribute::PointSpriteS:
|
||||||
case IR::Attribute::PointSpriteT:
|
case IR::Attribute::PointSpriteT:
|
||||||
ctx.AddF32("{}=gl_PointCoord.{};", inst, swizzle);
|
ctx.AddF32("{}=gl_PointCoord.{};", inst, swizzle);
|
||||||
|
|||||||
@@ -306,9 +306,12 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
|
|||||||
} else if (program.is_geometry_passthrough && !profile.support_geometry_shader_passthrough) {
|
} else if (program.is_geometry_passthrough && !profile.support_geometry_shader_passthrough) {
|
||||||
LOG_WARNING(Shader_GLSL, "Passthrough geometry program used but not supported");
|
LOG_WARNING(Shader_GLSL, "Passthrough geometry program used but not supported");
|
||||||
}
|
}
|
||||||
header += fmt::format(
|
header += fmt::format("layout({},max_vertices={})out;in gl_PerVertex{{vec4 gl_Position;",
|
||||||
"layout({},max_vertices={})out;in gl_PerVertex{{vec4 gl_Position;}}gl_in[];",
|
OutputPrimitive(program.output_topology), program.output_vertices);
|
||||||
OutputPrimitive(program.output_topology), program.output_vertices);
|
if (program.info.loads.ClipDistances()) {
|
||||||
|
header += "float gl_ClipDistance[];";
|
||||||
|
}
|
||||||
|
header += "}gl_in[];";
|
||||||
break;
|
break;
|
||||||
case Stage::Fragment:
|
case Stage::Fragment:
|
||||||
stage_name = "fs";
|
stage_name = "fs";
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ void SetupDenormControl(const Profile& profile, const IR::Program& program, Emit
|
|||||||
if (info.uses_fp32_denorms_flush && info.uses_fp32_denorms_preserve) {
|
if (info.uses_fp32_denorms_flush && info.uses_fp32_denorms_preserve) {
|
||||||
LOG_DEBUG(Shader_SPIRV, "Fp32 denorm flush and preserve on the same shader");
|
LOG_DEBUG(Shader_SPIRV, "Fp32 denorm flush and preserve on the same shader");
|
||||||
} else if (info.uses_fp32_denorms_flush) {
|
} else if (info.uses_fp32_denorms_flush) {
|
||||||
if (profile.support_fp32_denorm_flush) {
|
if (profile.support_fp32_denorm_flush && !profile.has_broken_fp32_denorm_flush) {
|
||||||
ctx.AddCapability(spv::Capability::DenormFlushToZero);
|
ctx.AddCapability(spv::Capability::DenormFlushToZero);
|
||||||
ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormFlushToZero, 32U);
|
ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormFlushToZero, 32U);
|
||||||
} else {
|
} else {
|
||||||
@@ -381,7 +381,8 @@ void SetupSignedNanCapabilities(const Profile& profile, const IR::Program& progr
|
|||||||
ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve);
|
ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve);
|
||||||
ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 16U);
|
ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 16U);
|
||||||
}
|
}
|
||||||
if (profile.support_fp32_signed_zero_nan_preserve) {
|
if (profile.support_fp32_signed_zero_nan_preserve &&
|
||||||
|
!profile.has_broken_fp32_signed_zero_nan_preserve) {
|
||||||
ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve);
|
ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve);
|
||||||
ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 32U);
|
ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 32U);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -367,6 +367,23 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) {
|
|||||||
return ctx.OpSelect(ctx.F32[1], ctx.OpLoad(ctx.U1, ctx.front_face),
|
return ctx.OpSelect(ctx.F32[1], ctx.OpLoad(ctx.U1, ctx.front_face),
|
||||||
ctx.OpBitcast(ctx.F32[1], ctx.Const((std::numeric_limits<u32>::max)())),
|
ctx.OpBitcast(ctx.F32[1], ctx.Const((std::numeric_limits<u32>::max)())),
|
||||||
ctx.f32_zero_value);
|
ctx.f32_zero_value);
|
||||||
|
case IR::Attribute::ClipDistance0:
|
||||||
|
case IR::Attribute::ClipDistance1:
|
||||||
|
case IR::Attribute::ClipDistance2:
|
||||||
|
case IR::Attribute::ClipDistance3:
|
||||||
|
case IR::Attribute::ClipDistance4:
|
||||||
|
case IR::Attribute::ClipDistance5:
|
||||||
|
case IR::Attribute::ClipDistance6:
|
||||||
|
case IR::Attribute::ClipDistance7: {
|
||||||
|
const u32 base{static_cast<u32>(IR::Attribute::ClipDistance0)};
|
||||||
|
const u32 index{static_cast<u32>(attr) - base};
|
||||||
|
if (!ValidId(ctx.input_clip_distances) || index >= ctx.profile.max_user_clip_distances) {
|
||||||
|
return ctx.Const(1.0f);
|
||||||
|
}
|
||||||
|
const Id pointer{
|
||||||
|
AttrPointer(ctx, ctx.input_f32, vertex, ctx.input_clip_distances, ctx.Const(index))};
|
||||||
|
return ctx.OpLoad(ctx.F32[1], pointer);
|
||||||
|
}
|
||||||
case IR::Attribute::PointSpriteS:
|
case IR::Attribute::PointSpriteS:
|
||||||
return ctx.OpLoad(ctx.F32[1],
|
return ctx.OpLoad(ctx.F32[1],
|
||||||
ctx.OpAccessChain(ctx.input_f32, ctx.point_coord, ctx.u32_zero_value));
|
ctx.OpAccessChain(ctx.input_f32, ctx.point_coord, ctx.u32_zero_value));
|
||||||
|
|||||||
@@ -1522,6 +1522,12 @@ void EmitContext::DefineInputs(const IR::Program& program) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (stage == Stage::Geometry && info.loads.ClipDistances() &&
|
||||||
|
profile.max_user_clip_distances > 0) {
|
||||||
|
const u32 used{(std::min)(profile.max_user_clip_distances, 8u)};
|
||||||
|
const Id type{TypeArray(F32[1], Const(used))};
|
||||||
|
input_clip_distances = DefineInput(*this, type, true, spv::BuiltIn::ClipDistance);
|
||||||
|
}
|
||||||
if (loads[IR::Attribute::InstanceId]) {
|
if (loads[IR::Attribute::InstanceId]) {
|
||||||
if (profile.support_vertex_instance_id) {
|
if (profile.support_vertex_instance_id) {
|
||||||
instance_id = DefineInput(*this, U32[1], true, spv::BuiltIn::InstanceId);
|
instance_id = DefineInput(*this, U32[1], true, spv::BuiltIn::InstanceId);
|
||||||
|
|||||||
@@ -285,6 +285,7 @@ public:
|
|||||||
Id point_coord{};
|
Id point_coord{};
|
||||||
Id tess_coord{};
|
Id tess_coord{};
|
||||||
Id clip_distances{};
|
Id clip_distances{};
|
||||||
|
Id input_clip_distances{};
|
||||||
Id layer{};
|
Id layer{};
|
||||||
Id viewport_index{};
|
Id viewport_index{};
|
||||||
Id viewport_mask{};
|
Id viewport_mask{};
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -50,12 +53,6 @@ constexpr std::array RGBA_LUT{
|
|||||||
R | G | B | A, //
|
R | G | B | A, //
|
||||||
};
|
};
|
||||||
|
|
||||||
void CheckAlignment(IR::Reg reg, size_t alignment) {
|
|
||||||
if (!IR::IsAligned(reg, alignment)) {
|
|
||||||
throw NotImplementedException("Unaligned source register {}", reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
IR::Value Composite(TranslatorVisitor& v, Args... regs) {
|
IR::Value Composite(TranslatorVisitor& v, Args... regs) {
|
||||||
return v.ir.CompositeConstruct(v.F(regs)...);
|
return v.ir.CompositeConstruct(v.F(regs)...);
|
||||||
@@ -86,67 +83,53 @@ IR::Value Sample(TranslatorVisitor& v, u64 insn) {
|
|||||||
info.type.Assign(TextureType::Color2D);
|
info.type.Assign(TextureType::Color2D);
|
||||||
return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_b), zero, {}, info);
|
return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_b), zero, {}, info);
|
||||||
case 3: // 2D.LL
|
case 3: // 2D.LL
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
info.type.Assign(TextureType::Color2D);
|
info.type.Assign(TextureType::Color2D);
|
||||||
return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_a + 1), v.F(reg_b), {},
|
return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_a + 1), v.F(reg_b), {},
|
||||||
info);
|
info);
|
||||||
case 4: // 2D.DC
|
case 4: // 2D.DC
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
info.type.Assign(TextureType::Color2D);
|
info.type.Assign(TextureType::Color2D);
|
||||||
info.is_depth.Assign(1);
|
info.is_depth.Assign(1);
|
||||||
return v.ir.ImageSampleDrefImplicitLod(handle, Composite(v, reg_a, reg_a + 1), v.F(reg_b),
|
return v.ir.ImageSampleDrefImplicitLod(handle, Composite(v, reg_a, reg_a + 1), v.F(reg_b),
|
||||||
{}, {}, {}, info);
|
{}, {}, {}, info);
|
||||||
case 5: // 2D.LL.DC
|
case 5: // 2D.LL.DC
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
CheckAlignment(reg_b, 2);
|
|
||||||
info.type.Assign(TextureType::Color2D);
|
info.type.Assign(TextureType::Color2D);
|
||||||
info.is_depth.Assign(1);
|
info.is_depth.Assign(1);
|
||||||
return v.ir.ImageSampleDrefExplicitLod(handle, Composite(v, reg_a, reg_a + 1),
|
return v.ir.ImageSampleDrefExplicitLod(handle, Composite(v, reg_a, reg_a + 1),
|
||||||
v.F(reg_b + 1), v.F(reg_b), {}, info);
|
v.F(reg_b + 1), v.F(reg_b), {}, info);
|
||||||
case 6: // 2D.LZ.DC
|
case 6: // 2D.LZ.DC
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
info.type.Assign(TextureType::Color2D);
|
info.type.Assign(TextureType::Color2D);
|
||||||
info.is_depth.Assign(1);
|
info.is_depth.Assign(1);
|
||||||
return v.ir.ImageSampleDrefExplicitLod(handle, Composite(v, reg_a, reg_a + 1), v.F(reg_b),
|
return v.ir.ImageSampleDrefExplicitLod(handle, Composite(v, reg_a, reg_a + 1), v.F(reg_b),
|
||||||
zero, {}, info);
|
zero, {}, info);
|
||||||
case 7: // ARRAY_2D
|
case 7: // ARRAY_2D
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
info.type.Assign(TextureType::ColorArray2D);
|
info.type.Assign(TextureType::ColorArray2D);
|
||||||
return v.ir.ImageSampleImplicitLod(
|
return v.ir.ImageSampleImplicitLod(
|
||||||
handle, v.ir.CompositeConstruct(v.F(reg_a + 1), v.F(reg_b), ReadArray(v, v.X(reg_a))),
|
handle, v.ir.CompositeConstruct(v.F(reg_a + 1), v.F(reg_b), ReadArray(v, v.X(reg_a))),
|
||||||
{}, {}, {}, info);
|
{}, {}, {}, info);
|
||||||
case 8: // ARRAY_2D.LZ
|
case 8: // ARRAY_2D.LZ
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
info.type.Assign(TextureType::ColorArray2D);
|
info.type.Assign(TextureType::ColorArray2D);
|
||||||
return v.ir.ImageSampleExplicitLod(
|
return v.ir.ImageSampleExplicitLod(
|
||||||
handle, v.ir.CompositeConstruct(v.F(reg_a + 1), v.F(reg_b), ReadArray(v, v.X(reg_a))),
|
handle, v.ir.CompositeConstruct(v.F(reg_a + 1), v.F(reg_b), ReadArray(v, v.X(reg_a))),
|
||||||
zero, {}, info);
|
zero, {}, info);
|
||||||
case 9: // ARRAY_2D.LZ.DC
|
case 9: // ARRAY_2D.LZ.DC
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
CheckAlignment(reg_b, 2);
|
|
||||||
info.type.Assign(TextureType::ColorArray2D);
|
info.type.Assign(TextureType::ColorArray2D);
|
||||||
info.is_depth.Assign(1);
|
info.is_depth.Assign(1);
|
||||||
return v.ir.ImageSampleDrefExplicitLod(
|
return v.ir.ImageSampleDrefExplicitLod(
|
||||||
handle, v.ir.CompositeConstruct(v.F(reg_a + 1), v.F(reg_b), ReadArray(v, v.X(reg_a))),
|
handle, v.ir.CompositeConstruct(v.F(reg_a + 1), v.F(reg_b), ReadArray(v, v.X(reg_a))),
|
||||||
v.F(reg_b + 1), zero, {}, info);
|
v.F(reg_b + 1), zero, {}, info);
|
||||||
case 10: // 3D
|
case 10: // 3D
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
info.type.Assign(TextureType::Color3D);
|
info.type.Assign(TextureType::Color3D);
|
||||||
return v.ir.ImageSampleImplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b), {}, {},
|
return v.ir.ImageSampleImplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b), {}, {},
|
||||||
{}, info);
|
{}, info);
|
||||||
case 11: // 3D.LZ
|
case 11: // 3D.LZ
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
info.type.Assign(TextureType::Color3D);
|
info.type.Assign(TextureType::Color3D);
|
||||||
return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b), zero, {},
|
return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b), zero, {},
|
||||||
info);
|
info);
|
||||||
case 12: // CUBE
|
case 12: // CUBE
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
info.type.Assign(TextureType::ColorCube);
|
info.type.Assign(TextureType::ColorCube);
|
||||||
return v.ir.ImageSampleImplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b), {}, {},
|
return v.ir.ImageSampleImplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b), {}, {},
|
||||||
{}, info);
|
{}, info);
|
||||||
case 13: // CUBE.LL
|
case 13: // CUBE.LL
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
CheckAlignment(reg_b, 2);
|
|
||||||
info.type.Assign(TextureType::ColorCube);
|
info.type.Assign(TextureType::ColorCube);
|
||||||
return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b),
|
return v.ir.ImageSampleExplicitLod(handle, Composite(v, reg_a, reg_a + 1, reg_b),
|
||||||
v.F(reg_b + 1), {}, info);
|
v.F(reg_b + 1), {}, info);
|
||||||
@@ -187,12 +170,10 @@ IR::Reg RegStoreComponent32(u64 insn, unsigned index) {
|
|||||||
case 0:
|
case 0:
|
||||||
return texs.dest_reg_a;
|
return texs.dest_reg_a;
|
||||||
case 1:
|
case 1:
|
||||||
CheckAlignment(texs.dest_reg_a, 2);
|
|
||||||
return texs.dest_reg_a + 1;
|
return texs.dest_reg_a + 1;
|
||||||
case 2:
|
case 2:
|
||||||
return texs.dest_reg_b;
|
return texs.dest_reg_b;
|
||||||
case 3:
|
case 3:
|
||||||
CheckAlignment(texs.dest_reg_b, 2);
|
|
||||||
return texs.dest_reg_b + 1;
|
return texs.dest_reg_b + 1;
|
||||||
}
|
}
|
||||||
throw LogicError("Invalid store index {}", index);
|
throw LogicError("Invalid store index {}", index);
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -34,12 +37,6 @@ union Encoding {
|
|||||||
BitField<36, 13, u64> cbuf_offset;
|
BitField<36, 13, u64> cbuf_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
void CheckAlignment(IR::Reg reg, size_t alignment) {
|
|
||||||
if (!IR::IsAligned(reg, alignment)) {
|
|
||||||
throw NotImplementedException("Unaligned source register {}", reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg reg) {
|
IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg reg) {
|
||||||
const IR::U32 value{v.X(reg)};
|
const IR::U32 value{v.X(reg)};
|
||||||
return v.ir.CompositeConstruct(v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(6), true),
|
return v.ir.CompositeConstruct(v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(6), true),
|
||||||
@@ -60,18 +57,15 @@ IR::Value Sample(TranslatorVisitor& v, u64 insn) {
|
|||||||
info.is_depth.Assign(tld4s.dc != 0 ? 1 : 0);
|
info.is_depth.Assign(tld4s.dc != 0 ? 1 : 0);
|
||||||
IR::Value coords;
|
IR::Value coords;
|
||||||
if (tld4s.aoffi != 0) {
|
if (tld4s.aoffi != 0) {
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
coords = v.ir.CompositeConstruct(v.F(reg_a), v.F(reg_a + 1));
|
coords = v.ir.CompositeConstruct(v.F(reg_a), v.F(reg_a + 1));
|
||||||
IR::Value offset = MakeOffset(v, reg_b);
|
IR::Value offset = MakeOffset(v, reg_b);
|
||||||
if (tld4s.dc != 0) {
|
if (tld4s.dc != 0) {
|
||||||
CheckAlignment(reg_b, 2);
|
|
||||||
IR::F32 dref = v.F(reg_b + 1);
|
IR::F32 dref = v.F(reg_b + 1);
|
||||||
return v.ir.ImageGatherDref(handle, coords, offset, {}, dref, info);
|
return v.ir.ImageGatherDref(handle, coords, offset, {}, dref, info);
|
||||||
}
|
}
|
||||||
return v.ir.ImageGather(handle, coords, offset, {}, info);
|
return v.ir.ImageGather(handle, coords, offset, {}, info);
|
||||||
}
|
}
|
||||||
if (tld4s.dc != 0) {
|
if (tld4s.dc != 0) {
|
||||||
CheckAlignment(reg_a, 2);
|
|
||||||
coords = v.ir.CompositeConstruct(v.F(reg_a), v.F(reg_a + 1));
|
coords = v.ir.CompositeConstruct(v.F(reg_a), v.F(reg_a + 1));
|
||||||
IR::F32 dref = v.F(reg_b);
|
IR::F32 dref = v.F(reg_b);
|
||||||
return v.ir.ImageGatherDref(handle, coords, {}, {}, dref, info);
|
return v.ir.ImageGatherDref(handle, coords, {}, {}, dref, info);
|
||||||
@@ -86,12 +80,10 @@ IR::Reg RegStoreComponent32(u64 insn, size_t index) {
|
|||||||
case 0:
|
case 0:
|
||||||
return tlds4.dest_reg_a;
|
return tlds4.dest_reg_a;
|
||||||
case 1:
|
case 1:
|
||||||
CheckAlignment(tlds4.dest_reg_a, 2);
|
|
||||||
return tlds4.dest_reg_a + 1;
|
return tlds4.dest_reg_a + 1;
|
||||||
case 2:
|
case 2:
|
||||||
return tlds4.dest_reg_b;
|
return tlds4.dest_reg_b;
|
||||||
case 3:
|
case 3:
|
||||||
CheckAlignment(tlds4.dest_reg_b, 2);
|
|
||||||
return tlds4.dest_reg_b + 1;
|
return tlds4.dest_reg_b + 1;
|
||||||
}
|
}
|
||||||
throw LogicError("Invalid store index {}", index);
|
throw LogicError("Invalid store index {}", index);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user