From 343c620250a7091d2e31771b71ee19f35565bf75 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Tue, 13 May 2025 09:15:45 -0400 Subject: [PATCH 1/9] Update CMake files to download dependencies / binaries from self-hosted git repository --- CMakeLists.txt | 4 ++-- CMakeModules/DownloadExternals.cmake | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 72b03ec2e8..9773cfe5f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,7 +141,7 @@ if (YUZU_USE_BUNDLED_VCPKG) set(VCPKG_DOWNLOADS_PATH ${PROJECT_SOURCE_DIR}/externals/vcpkg/downloads) set(NASM_VERSION "2.16.01") set(NASM_DESTINATION_PATH ${VCPKG_DOWNLOADS_PATH}/nasm-${NASM_VERSION}-win64.zip) - set(NASM_DOWNLOAD_URL "https://github.com/eden-emulator/ext-windows-bin/raw/master/nasm/nasm-${NASM_VERSION}-win64.zip") + set(NASM_DOWNLOAD_URL "https://git.eden-emu.dev/eden-emu/ext-windows-bin/raw/master/nasm/nasm-${NASM_VERSION}-win64.zip") if (NOT EXISTS ${NASM_DESTINATION_PATH}) file(DOWNLOAD ${NASM_DOWNLOAD_URL} ${NASM_DESTINATION_PATH} SHOW_PROGRESS STATUS NASM_STATUS) @@ -525,7 +525,7 @@ if (NOT CLANG_FORMAT) message(STATUS "Clang format not found! Downloading...") set(CLANG_FORMAT "${PROJECT_BINARY_DIR}/externals/clang-format${CLANG_FORMAT_POSTFIX}.exe") file(DOWNLOAD - https://github.com/eden-emulator/ext-windows-bin/raw/master/clang-format${CLANG_FORMAT_POSTFIX}.exe + https://git.eden-emu.dev/eden-emu/ext-windows-bin/raw/master/clang-format${CLANG_FORMAT_POSTFIX}.exe "${CLANG_FORMAT}" SHOW_PROGRESS STATUS DOWNLOAD_SUCCESS) if (NOT DOWNLOAD_SUCCESS EQUAL 0) diff --git a/CMakeModules/DownloadExternals.cmake b/CMakeModules/DownloadExternals.cmake index 3fe15a16c4..b5c945eec5 100644 --- a/CMakeModules/DownloadExternals.cmake +++ b/CMakeModules/DownloadExternals.cmake @@ -8,17 +8,17 @@ set(CURRENT_MODULE_DIR ${CMAKE_CURRENT_LIST_DIR}) function(download_bundled_external remote_path lib_name prefix_var) -set(package_base_url "https://github.com/eden-emulator/") +set(package_base_url "https://git.eden-emu.dev/eden-emu/") set(package_repo "no_platform") set(package_extension "no_platform") if (WIN32) set(package_repo "ext-windows-bin/raw/master/") set(package_extension ".7z") elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - set(package_repo "ext-linux-bin/raw/main/") + set(package_repo "ext-linux-bin/raw/master/") set(package_extension ".tar.xz") elseif (ANDROID) - set(package_repo "ext-android-bin/raw/main/") + set(package_repo "ext-android-bin/raw/master/") set(package_extension ".tar.xz") else() message(FATAL_ERROR "No package available for this platform") From e14a42b6ba18c36ceb9ed14bbe6cc1e7dadfd0c7 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Tue, 13 May 2025 09:20:59 -0400 Subject: [PATCH 2/9] Update SDL to 2.32.6 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9773cfe5f5..58188fc659 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -370,7 +370,7 @@ if (ENABLE_SDL2) if (YUZU_USE_BUNDLED_SDL2) # Detect toolchain and platform if ((MSVC_VERSION GREATER_EQUAL 1920) AND ARCHITECTURE_x86_64) - set(SDL2_VER "SDL2-2.28.2") + set(SDL2_VER "SDL2-2.32.6") else() message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.") endif() From daab352512bf6ba902807299d65a5f1979ba0d56 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Tue, 13 May 2025 09:22:42 -0400 Subject: [PATCH 3/9] Update FFmpeg to 7.0.3 --- externals/ffmpeg/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt index 543585d4f2..8804aa6ad3 100644 --- a/externals/ffmpeg/CMakeLists.txt +++ b/externals/ffmpeg/CMakeLists.txt @@ -254,7 +254,7 @@ elseif(ANDROID) set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE) elseif(WIN32) # Use yuzu FFmpeg binaries - set(FFmpeg_EXT_NAME "ffmpeg-6.0") + set(FFmpeg_EXT_NAME "ffmpeg-7.0.3") set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}") download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "") set(FFmpeg_FOUND YES) From 8254a0e0de36b9c0dac53be4f4c97e51d6e8d23b Mon Sep 17 00:00:00 2001 From: MaranBr Date: Tue, 13 May 2025 14:44:29 -0400 Subject: [PATCH 4/9] Update Qt to 6.8.3 and fixes dark mode being forced automatically even when light theme is set in app settings --- CMakeLists.txt | 2 +- CMakeModules/CopyYuzuQt6Deps.cmake | 26 +++++++++++++++++--------- CMakeModules/DownloadExternals.cmake | 13 ++++++------- src/yuzu/CMakeLists.txt | 6 +++--- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58188fc659..40a9b9ee18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -399,7 +399,7 @@ add_subdirectory(externals) if (ENABLE_QT) if (NOT USE_SYSTEM_QT) - download_qt(6.7.3) + download_qt(6.8.3) endif() find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia Concurrent) diff --git a/CMakeModules/CopyYuzuQt6Deps.cmake b/CMakeModules/CopyYuzuQt6Deps.cmake index c6a5fa2db2..39f88cbc19 100644 --- a/CMakeModules/CopyYuzuQt6Deps.cmake +++ b/CMakeModules/CopyYuzuQt6Deps.cmake @@ -16,7 +16,7 @@ function(copy_yuzu_Qt6_deps target_dir) set(PLATFORMS ${DLL_DEST}plugins/platforms/) set(STYLES ${DLL_DEST}plugins/styles/) set(IMAGEFORMATS ${DLL_DEST}plugins/imageformats/) - + set(RESOURCES ${DLL_DEST}resources/) if (MSVC) windows_copy_files(${target_dir} ${Qt6_DLL_DIR} ${DLL_DEST} Qt6Core$<$:d>.* @@ -31,20 +31,31 @@ function(copy_yuzu_Qt6_deps target_dir) endif() if (YUZU_USE_QT_WEB_ENGINE) windows_copy_files(${target_dir} ${Qt6_DLL_DIR} ${DLL_DEST} + Qt6OpenGL$<$:d>.* + Qt6Positioning$<$:d>.* + Qt6PrintSupport$<$:d>.* + Qt6Qml$<$:d>.* + Qt6QmlMeta$<$:d>.* + Qt6QmlModels$<$:d>.* + Qt6QmlWorkerScript$<$:d>.* + Qt6Quick$<$:d>.* + Qt6QuickWidgets$<$:d>.* + Qt6WebChannel$<$:d>.* Qt6WebEngineCore$<$:d>.* Qt6WebEngineWidgets$<$:d>.* - QtWebEngineProcess$<$:d>.* + QtWebEngineProcess$<$:d>.* ) - windows_copy_files(${target_dir} ${Qt6_RESOURCES_DIR} ${DLL_DEST} + windows_copy_files(${target_dir} ${Qt6_RESOURCES_DIR} ${RESOURCES} icudtl.dat qtwebengine_devtools_resources.pak qtwebengine_resources.pak qtwebengine_resources_100p.pak qtwebengine_resources_200p.pak + v8_context_snapshot.bin ) endif() windows_copy_files(yuzu ${Qt6_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$:d>.*) - windows_copy_files(yuzu ${Qt6_STYLES_DIR} ${STYLES} qwindowsvistastyle$<$:d>.*) + windows_copy_files(yuzu ${Qt6_STYLES_DIR} ${STYLES} qmodernwindowsstyle$<$:d>.*) windows_copy_files(yuzu ${Qt6_IMAGEFORMATS_DIR} ${IMAGEFORMATS} qjpeg$<$:d>.* qgif$<$:d>.* @@ -52,9 +63,6 @@ function(copy_yuzu_Qt6_deps target_dir) else() # Update for non-MSVC platforms if needed endif() - - # Create an empty qt.conf file - add_custom_command(TARGET yuzu POST_BUILD - COMMAND ${CMAKE_COMMAND} -E touch ${DLL_DEST}qt.conf - ) + # Fixes dark mode being forced automatically even when light theme is set in app settings. + file(WRITE "${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}/qt.conf" "[Platforms]\nWindowsArguments = darkmode=0") endfunction(copy_yuzu_Qt6_deps) diff --git a/CMakeModules/DownloadExternals.cmake b/CMakeModules/DownloadExternals.cmake index b5c945eec5..f48c844f08 100644 --- a/CMakeModules/DownloadExternals.cmake +++ b/CMakeModules/DownloadExternals.cmake @@ -68,18 +68,18 @@ function(determine_qt_parameters target host_out type_out arch_out arch_path_out set(arch_path "mingw_64") elseif (MSVC) if ("arm64" IN_LIST ARCHITECTURE) - set(arch_path "msvc2019_arm64") + set(arch_path "msvc2022_arm64") elseif ("x86_64" IN_LIST ARCHITECTURE) - set(arch_path "msvc2019_64") + set(arch_path "msvc2022_64") else() message(FATAL_ERROR "Unsupported bundled Qt architecture. Enable USE_SYSTEM_QT and provide your own.") endif() set(arch "win64_${arch_path}") if (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64") - set(host_arch_path "msvc2019_64") + set(host_arch_path "msvc2022_64") elseif (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "ARM64") - set(host_arch_path "msvc2019_64") + set(host_arch_path "msvc2022_arm64") endif() set(host_arch "win64_${host_arch_path}") else() @@ -133,13 +133,12 @@ function(download_qt_configuration prefix_out target host type arch arch_path ba set(install_args ${install_args} install-tool --outputdir ${base_path} ${host} desktop ${target}) else() set(prefix "${base_path}/${target}/${arch_path}") - set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} - -m qtmultimedia --archives qttranslations qttools qtsvg qtbase) + set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} -m qt3d qt5compat qtactiveqt qtcharts qtconnectivity qtdatavis3d qtgraphs qtgrpc qthttpserver qtimageformats qtlanguageserver qtlocation qtlottie qtmultimedia qtnetworkauth qtpdf qtpositioning qtquick3d qtquick3dphysics qtquickeffectmaker qtquicktimeline qtremoteobjects qtscxml qtsensors qtserialbus qtserialport qtshadertools qtspeech qtvirtualkeyboard qtwebchannel qtwebengine qtwebsockets qtwebview) endif() if (NOT EXISTS "${prefix}") message(STATUS "Downloading Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path}") - set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.1.18") + set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.2.1") if (WIN32) set(aqt_path "${base_path}/aqt.exe") if (NOT EXISTS "${aqt_path}") diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 9425ee73f6..83ca3307fc 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -450,12 +450,12 @@ if(UNIX AND NOT APPLE) install(TARGETS yuzu) endif() -if (WIN32 AND QT_VERSION VERSION_GREATER_EQUAL 6) +if (WIN32 AND USE_SYSTEM_QT AND QT_VERSION VERSION_GREATER_EQUAL 6) set(YUZU_EXE_DIR "$") - add_custom_command(TARGET yuzu POST_BUILD COMMAND ${WINDEPLOYQT_EXECUTABLE} "${YUZU_EXE_DIR}/yuzu.exe" --dir "${YUZU_EXE_DIR}" --libdir "${YUZU_EXE_DIR}" --plugindir "${YUZU_EXE_DIR}/plugins" --no-compiler-runtime --no-opengl-sw --no-system-d3d-compiler --no-translations --verbose 0) + add_custom_command(TARGET yuzu POST_BUILD COMMAND ${WINDEPLOYQT_EXECUTABLE} "${YUZU_EXE_DIR}/eden.exe" --dir "${YUZU_EXE_DIR}" --libdir "${YUZU_EXE_DIR}" --plugindir "${YUZU_EXE_DIR}/plugins" --no-compiler-runtime --no-opengl-sw --no-system-d3d-compiler --no-translations --verbose 0) endif() -if (YUZU_USE_BUNDLED_QT) +if (NOT USE_SYSTEM_QT) include(CopyYuzuQt6Deps) copy_yuzu_Qt6_deps(yuzu) endif() From 9d7075254d9ce70f75eed5b9709504cf0d3cc0bc Mon Sep 17 00:00:00 2001 From: Bix Date: Wed, 14 May 2025 17:35:38 +0000 Subject: [PATCH 5/9] Added Samsung Gaming hub support (#107) Added Samsung Gaming hub to the APP manifest. Signed-off-by: Bix Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/107 --- src/android/app/src/main/AndroidManifest.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/android/app/src/main/AndroidManifest.xml b/src/android/app/src/main/AndroidManifest.xml index 6ad1d1c1bf..51b1d1bc58 100644 --- a/src/android/app/src/main/AndroidManifest.xml +++ b/src/android/app/src/main/AndroidManifest.xml @@ -31,9 +31,14 @@ SPDX-License-Identifier: GPL-3.0-or-later android:dataExtractionRules="@xml/data_extraction_rules_api_31" android:enableOnBackInvokedCallback="true"> - + + + Date: Sat, 17 May 2025 20:22:25 +0000 Subject: [PATCH 6/9] fixes vulkan issues and android settings (#105) - removes provoking vertex, vertex input, dynamic state if not supported - moves dynamic state to be a 0-3 slider and vertex input its own checkbox - the rich presence was disabled on linux. - there were duplicate settings in "edens veil"? - weird behavior of the vertex input checkbox on per game setting - adds xenoblade 2 to the d24 conversion control function - adds the flush logs by line setting to android. - adds the memory layout setting to android - Adds the option to show building shaders on the android overlay. Signed-off-by: Aleksandr Popovich Co-authored-by: swurl Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/105 Co-authored-by: Aleksandr Popovich Co-committed-by: Aleksandr Popovich --- .ci/linux/build.sh | 1 - .../java/org/yuzu/yuzu_emu/NativeLibrary.kt | 5 + .../features/settings/model/BooleanSetting.kt | 8 +- .../features/settings/model/IntSetting.kt | 1 + .../settings/model/view/SettingsItem.kt | 31 ++- .../settings/ui/SettingsFragmentPresenter.kt | 18 +- .../yuzu_emu/fragments/EmulationFragment.kt | 23 +- .../app/src/main/jni/android_settings.h | 176 ++++++------ src/android/app/src/main/jni/native.cpp | 17 ++ src/android/app/src/main/jni/native.h | 4 +- .../app/src/main/res/values-ar/strings.xml | 4 +- .../app/src/main/res/values-ckb/strings.xml | 4 +- .../app/src/main/res/values-cs/strings.xml | 4 +- .../app/src/main/res/values-de/strings.xml | 4 +- .../app/src/main/res/values-es/strings.xml | 4 +- .../app/src/main/res/values-fa/strings.xml | 4 +- .../app/src/main/res/values-fr/strings.xml | 4 +- .../app/src/main/res/values-he/strings.xml | 4 +- .../app/src/main/res/values-hu/strings.xml | 4 +- .../app/src/main/res/values-id/strings.xml | 4 +- .../app/src/main/res/values-it/strings.xml | 4 +- .../app/src/main/res/values-ja/strings.xml | 4 +- .../app/src/main/res/values-ko/strings.xml | 4 +- .../app/src/main/res/values-nb/strings.xml | 4 +- .../app/src/main/res/values-pl/strings.xml | 4 +- .../src/main/res/values-pt-rBR/strings.xml | 4 +- .../src/main/res/values-pt-rPT/strings.xml | 4 +- .../app/src/main/res/values-ru/strings.xml | 4 +- .../app/src/main/res/values-uk/strings.xml | 4 +- .../app/src/main/res/values-vi/strings.xml | 4 +- .../src/main/res/values-zh-rCN/strings.xml | 4 +- .../src/main/res/values-zh-rTW/strings.xml | 4 +- .../app/src/main/res/values/arrays.xml | 12 + .../app/src/main/res/values/strings.xml | 22 +- src/common/settings.h | 7 +- src/core/hle/kernel/k_memory_layout.h | 2 +- .../renderer_vulkan/vk_graphics_pipeline.cpp | 6 +- .../renderer_vulkan/vk_pipeline_cache.cpp | 28 +- .../renderer_vulkan/vk_rasterizer.cpp | 61 +++-- .../renderer_vulkan/vk_rasterizer.h | 4 + .../vulkan_common/vulkan_device.cpp | 254 ++++++++++-------- src/video_core/vulkan_common/vulkan_device.h | 82 +++--- .../configure_graphics_extensions.cpp | 17 +- src/yuzu/configuration/shared_translation.cpp | 83 +++--- src/yuzu/configuration/shared_widget.cpp | 6 +- src/yuzu/configuration/shared_widget.h | 2 +- 46 files changed, 555 insertions(+), 403 deletions(-) diff --git a/.ci/linux/build.sh b/.ci/linux/build.sh index c020cc7edd..f030e9b748 100755 --- a/.ci/linux/build.sh +++ b/.ci/linux/build.sh @@ -60,7 +60,6 @@ cmake .. -G Ninja \ -DYUZU_USE_QT_MULTIMEDIA=OFF \ -DYUZU_USE_QT_WEB_ENGINE=OFF \ -DENABLE_QT_TRANSLATION=ON \ - -DUSE_DISCORD_PRESENCE=OFF \ -DYUZU_USE_FASTER_LD=OFF \ -DYUZU_ENABLE_LTO=ON \ -DCMAKE_LINKER=/usr/bin/mold \ diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt index 1848ca9ef9..0be943eb86 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt @@ -166,6 +166,11 @@ object NativeLibrary { */ external fun getPerfStats(): DoubleArray + /** + * Returns the number of shaders being built + */ + external fun getShadersBuilding(): Int + /** * Returns the current CPU backend. */ diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 2601387b76..3c8ce3504d 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -20,7 +20,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { RENDERER_FAST_GPU("use_fast_gpu_time"), RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"), RENDERER_DEBUG("debug"), - RENDERER_DYNA_STATE3("dyna_state3"), + RENDERER_VERTEX_INPUT("vertex_input"), RENDERER_PROVOKING_VERTEX("provoking_vertex"), RENDERER_DESCRIPTOR_INDEXING("descriptor_indexing"), PICTURE_IN_PICTURE("picture_in_picture"), @@ -41,12 +41,14 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { SHOW_APP_RAM_USAGE("show_app_ram_usage"), SHOW_SYSTEM_RAM_USAGE("show_system_ram_usage"), SHOW_BAT_TEMPERATURE("show_bat_temperature"), + SHOW_SHADERS_BUILDING("show_shaders_building"), OVERLAY_BACKGROUND("overlay_background"), - USE_LRU_CACHE("use_lru_cache"),; + DEBUG_FLUSH_BY_LINE("flush_lines"), + USE_LRU_CACHE("use_lru_cache"); + external fun isFrameSkippingEnabled(): Boolean external fun isFrameInterpolationEnabled(): Boolean - override fun getBoolean(needsGlobal: Boolean): Boolean = NativeConfig.getBoolean(key, needsGlobal) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt index 035a33a762..3e1c43ca89 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt @@ -33,6 +33,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting { LOCK_DRAWER("lock_drawer"), VERTICAL_ALIGNMENT("vertical_alignment"), PERF_OVERLAY_POSITION("perf_overlay_position"), + MEMORY_LAYOUT("memory_layout_mode"), FSR_SHARPENING_SLIDER("fsr_sharpening_slider"); override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index a373bd816c..49e2a19474 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -136,14 +136,14 @@ abstract class SettingsItem( titleId = R.string.dyna_state, descriptionId = R.string.dyna_state_description, min = 0, - max = 2, + max = 3, ) ) put( SwitchSetting( - BooleanSetting.RENDERER_DYNA_STATE3, - titleId = R.string.dyna_state3, - descriptionId = R.string.dyna_state3_description + BooleanSetting.RENDERER_VERTEX_INPUT, + titleId = R.string.vertex_input, + descriptionId = R.string.vertex_input_description ) ) put( @@ -193,6 +193,13 @@ abstract class SettingsItem( descriptionId = R.string.picture_in_picture_description ) ) + put( + SwitchSetting( + BooleanSetting.DEBUG_FLUSH_BY_LINE, + titleId = R.string.flush_by_line, + descriptionId = R.string.flush_by_line_description + ) + ) val dockedModeSetting = object : AbstractBooleanSetting { override val key = BooleanSetting.USE_DOCKED_MODE.key @@ -238,6 +245,15 @@ abstract class SettingsItem( descriptionId = R.string.use_docked_mode_description ) ) + put( + SingleChoiceSetting( + IntSetting.MEMORY_LAYOUT, + titleId = R.string.memory_layout, + descriptionId = R.string.memory_layout_description, + choicesId = R.array.memoryNames, + valuesId = R.array.memoryValues + ) + ) put( SwitchSetting( BooleanSetting.CORE_SYNC_CORE_SPEED, @@ -397,6 +413,13 @@ abstract class SettingsItem( descriptionId = R.string.show_bat_temperature_description ) ) + put( + SwitchSetting( + BooleanSetting.SHOW_SHADERS_BUILDING, + R.string.show_shaders_building, + descriptionId = R.string.show_shaders_building_description + ) + ) put( SingleChoiceSetting( IntSetting.RENDERER_VSYNC, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index aa7cae083b..0d426f67f5 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -241,17 +241,6 @@ class SettingsFragmentPresenter( ) ) addEdenVeilSettings(sl) - - add(BooleanSetting.FRAME_INTERPOLATION.key) - add(BooleanSetting.FRAME_SKIPPING.key) - add(BooleanSetting.CORE_SYNC_CORE_SPEED.key) - add(IntSetting.RENDERER_SHADER_BACKEND.key) - add(IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT.key) - add(IntSetting.RENDERER_NVDEC_EMULATION.key) - add(IntSetting.RENDERER_ASTC_DECODE_METHOD.key) - add(IntSetting.RENDERER_ASTC_RECOMPRESSION.key) - add(IntSetting.RENDERER_VRAM_USAGE_MODE.key) - add(BooleanSetting.USE_LRU_CACHE.key) } } @@ -261,6 +250,7 @@ class SettingsFragmentPresenter( add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key) add(ShortSetting.RENDERER_SPEED_LIMIT.key) add(BooleanSetting.USE_DOCKED_MODE.key) + add(IntSetting.MEMORY_LAYOUT.key) add(IntSetting.REGION_INDEX.key) add(IntSetting.LANGUAGE_INDEX.key) add(BooleanSetting.USE_CUSTOM_RTC.key) @@ -301,6 +291,7 @@ class SettingsFragmentPresenter( add(BooleanSetting.SHOW_APP_RAM_USAGE.key) add(BooleanSetting.SHOW_SYSTEM_RAM_USAGE.key) add(BooleanSetting.SHOW_BAT_TEMPERATURE.key) + add(BooleanSetting.SHOW_SHADERS_BUILDING.key) } } @@ -466,7 +457,7 @@ class SettingsFragmentPresenter( add(ByteSetting.RENDERER_DYNA_STATE.key) - add(BooleanSetting.RENDERER_DYNA_STATE3.key) + add(BooleanSetting.RENDERER_VERTEX_INPUT.key) add(BooleanSetting.RENDERER_PROVOKING_VERTEX.key) add(BooleanSetting.RENDERER_DESCRIPTOR_INDEXING.key) @@ -1143,6 +1134,9 @@ class SettingsFragmentPresenter( add(BooleanSetting.USE_AUTO_STUB.key) add(BooleanSetting.CPU_DEBUG_MODE.key) add(SettingsItem.FASTMEM_COMBINED) + + add(HeaderSetting(R.string.log)) + add(BooleanSetting.DEBUG_FLUSH_BY_LINE.key) } } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt index ddf3cb1fe1..8fc473410a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt @@ -64,6 +64,7 @@ import org.yuzu.yuzu_emu.features.settings.model.IntSetting import org.yuzu.yuzu_emu.features.settings.model.Settings import org.yuzu.yuzu_emu.features.settings.model.Settings.EmulationOrientation import org.yuzu.yuzu_emu.features.settings.model.Settings.EmulationVerticalAlignment +import org.yuzu.yuzu_emu.features.settings.model.ShortSetting import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile import org.yuzu.yuzu_emu.model.DriverViewModel import org.yuzu.yuzu_emu.model.EmulationViewModel @@ -399,7 +400,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { emulationState.updateSurface() // Setup overlays - updateshowStatsOvelray() + updateShowStatsOverlay() // Re update binding when the specs values get initialized properly binding.inGameMenu.getHeaderView(0).apply { @@ -532,7 +533,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { } } @SuppressLint("DefaultLocale") - private fun updateshowStatsOvelray() { + private fun updateShowStatsOverlay() { val showOverlay = BooleanSetting.SHOW_PERFORMANCE_OVERLAY.getBoolean() binding.showStatsOverlayText.apply { setTextColor( @@ -587,10 +588,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { if (BooleanSetting.SHOW_SPEED.getBoolean(NativeConfig.isPerGameConfigLoaded())) { if (sb.isNotEmpty()) sb.append(" | ") + // TODO(alekpop): this is broken on android only. it uses the clock timer but it should not. sb.append( String.format( - "Speed: %d%%", - (perfStats[SPEED] * 100.0 + 0.5).toInt() + "Speed: %d%% / %d%%", + (perfStats[SPEED] * 100.0 + 0.5).toInt(), + ShortSetting.RENDERER_SPEED_LIMIT.getShort(NativeConfig.isPerGameConfigLoaded()) ) ) } @@ -619,6 +622,16 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { sb.append(String.format("%.1f°C/%.1f°F", batteryTemp, tempF)) } + val shadersBuilding = NativeLibrary.getShadersBuilding() + + if (BooleanSetting.SHOW_SHADERS_BUILDING.getBoolean(NativeConfig.isPerGameConfigLoaded()) && shadersBuilding != 0) { + if (sb.isNotEmpty()) sb.append(" | ") + + val prefix = getString(R.string.shaders_prefix) + val suffix = getString(R.string.shaders_suffix) + sb.append(String.format("$prefix %d $suffix", shadersBuilding)) + } + if (BooleanSetting.OVERLAY_BACKGROUND.getBoolean(NativeConfig.isPerGameConfigLoaded())) { binding.showStatsOverlayText.setBackgroundResource(R.color.yuzu_transparent_black) } else { @@ -849,7 +862,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { R.id.menu_show_stats_overlay -> { it.isChecked = !it.isChecked BooleanSetting.SHOW_PERFORMANCE_OVERLAY.setBoolean(it.isChecked) - updateshowStatsOvelray() + updateShowStatsOverlay() true } R.id.menu_edit_overlay -> { diff --git a/src/android/app/src/main/jni/android_settings.h b/src/android/app/src/main/jni/android_settings.h index ff569d1981..9a71822c6a 100644 --- a/src/android/app/src/main/jni/android_settings.h +++ b/src/android/app/src/main/jni/android_settings.h @@ -9,90 +9,116 @@ namespace AndroidSettings { -struct GameDir { - std::string path; - bool deep_scan = false; -}; + struct GameDir { + std::string path; + bool deep_scan = false; + }; -struct OverlayControlData { - std::string id; - bool enabled; - std::pair landscape_position; - std::pair portrait_position; - std::pair foldable_position; -}; + struct OverlayControlData { + std::string id; + bool enabled; + std::pair landscape_position; + std::pair portrait_position; + std::pair foldable_position; + }; -struct Values { - Settings::Linkage linkage; + struct Values { + Settings::Linkage linkage; - // Path settings - std::vector game_dirs; + // Path settings + std::vector game_dirs; - // Android - Settings::Setting picture_in_picture{linkage, false, "picture_in_picture", - Settings::Category::Android}; - Settings::Setting screen_layout{linkage, - 5, - "screen_layout", - Settings::Category::Android, - Settings::Specialization::Default, - true, - true}; - Settings::Setting vertical_alignment{linkage, - 0, - "vertical_alignment", - Settings::Category::Android, - Settings::Specialization::Default, - true, - true}; + // Android + Settings::Setting picture_in_picture{linkage, false, "picture_in_picture", + Settings::Category::Android}; + Settings::Setting screen_layout{linkage, + 5, + "screen_layout", + Settings::Category::Android, + Settings::Specialization::Default, + true, + true}; + Settings::Setting vertical_alignment{linkage, + 0, + "vertical_alignment", + Settings::Category::Android, + Settings::Specialization::Default, + true, + true}; - Settings::SwitchableSetting driver_path{linkage, "", "driver_path", - Settings::Category::GpuDriver}; + Settings::SwitchableSetting driver_path{linkage, "", "driver_path", + Settings::Category::GpuDriver}; - // LRU Cache - Settings::SwitchableSetting use_lru_cache{linkage, true, "use_lru_cache", - Settings::Category::System}; + // LRU Cache + Settings::SwitchableSetting use_lru_cache{linkage, true, "use_lru_cache", + Settings::Category::System}; - Settings::Setting theme{linkage, 0, "theme", Settings::Category::Android}; - Settings::Setting theme_mode{linkage, -1, "theme_mode", Settings::Category::Android}; - Settings::Setting black_backgrounds{linkage, false, "black_backgrounds", - Settings::Category::Android}; + Settings::Setting theme{linkage, 0, "theme", Settings::Category::Android}; + Settings::Setting theme_mode{linkage, -1, "theme_mode", Settings::Category::Android}; + Settings::Setting black_backgrounds{linkage, false, "black_backgrounds", + Settings::Category::Android}; - // Input/performance overlay settings - std::vector overlay_control_data; - Settings::Setting overlay_scale{linkage, 50, "control_scale", Settings::Category::Overlay}; - Settings::Setting overlay_opacity{linkage, 100, "control_opacity", - Settings::Category::Overlay}; - - Settings::Setting joystick_rel_center{linkage, true, "joystick_rel_center", - Settings::Category::Overlay}; - Settings::Setting dpad_slide{linkage, true, "dpad_slide", Settings::Category::Overlay}; - Settings::Setting haptic_feedback{linkage, true, "haptic_feedback", - Settings::Category::Overlay}; - Settings::Setting show_performance_overlay{linkage, true, "show_performance_overlay", - Settings::Category::Overlay, Settings::Specialization::Paired, true , true}; - Settings::Setting overlay_background{linkage, false, "overlay_background", - Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay}; - Settings::Setting perf_overlay_position{linkage, 0, "perf_overlay_position", - Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay}; - Settings::Setting show_fps{linkage, true, "show_fps", - Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay}; - Settings::Setting show_frame_time{linkage, false, "show_frame_time", - Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay}; - Settings::Setting show_speed{linkage, true, "show_speed", - Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay}; - Settings::Setting show_app_ram_usage{linkage, false, "show_app_ram_usage", - Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay}; - Settings::Setting show_system_ram_usage{linkage, false, "show_system_ram_usage", - Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay}; - Settings::Setting show_bat_temperature{linkage, false, "show_bat_temperature", - Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay}; - Settings::Setting show_input_overlay{linkage, true, "show_input_overlay", + // Input/performance overlay settings + std::vector overlay_control_data; + Settings::Setting overlay_scale{linkage, 50, "control_scale", + Settings::Category::Overlay}; + Settings::Setting overlay_opacity{linkage, 100, "control_opacity", Settings::Category::Overlay}; - Settings::Setting touchscreen{linkage, true, "touchscreen", Settings::Category::Overlay}; - Settings::Setting lock_drawer{linkage, false, "lock_drawer", Settings::Category::Overlay}; -}; -extern Values values; + Settings::Setting joystick_rel_center{linkage, true, "joystick_rel_center", + Settings::Category::Overlay}; + Settings::Setting dpad_slide{linkage, true, "dpad_slide", + Settings::Category::Overlay}; + Settings::Setting haptic_feedback{linkage, true, "haptic_feedback", + Settings::Category::Overlay}; + Settings::Setting show_performance_overlay{linkage, true, "show_performance_overlay", + Settings::Category::Overlay, + Settings::Specialization::Paired, true, + true}; + Settings::Setting overlay_background{linkage, false, "overlay_background", + Settings::Category::Overlay, + Settings::Specialization::Default, true, true, + &show_performance_overlay}; + Settings::Setting perf_overlay_position{linkage, 0, "perf_overlay_position", + Settings::Category::Overlay, + Settings::Specialization::Default, true, true, + &show_performance_overlay}; + Settings::Setting show_fps{linkage, true, "show_fps", + Settings::Category::Overlay, + Settings::Specialization::Default, true, true, + &show_performance_overlay}; + Settings::Setting show_frame_time{linkage, false, "show_frame_time", + Settings::Category::Overlay, + Settings::Specialization::Default, true, true, + &show_performance_overlay}; + Settings::Setting show_speed{linkage, true, "show_speed", + Settings::Category::Overlay, + Settings::Specialization::Default, true, true, + &show_performance_overlay}; + Settings::Setting show_app_ram_usage{linkage, false, "show_app_ram_usage", + Settings::Category::Overlay, + Settings::Specialization::Default, true, true, + &show_performance_overlay}; + Settings::Setting show_system_ram_usage{linkage, false, "show_system_ram_usage", + Settings::Category::Overlay, + Settings::Specialization::Default, true, true, + &show_performance_overlay}; + Settings::Setting show_bat_temperature{linkage, false, "show_bat_temperature", + Settings::Category::Overlay, + Settings::Specialization::Default, true, true, + &show_performance_overlay}; + Settings::Setting show_shaders_building{linkage, true, "show_shaders_building", + Settings::Category::Overlay, + Settings::Specialization::Default, true, true, + &show_performance_overlay}; + Settings::Setting show_input_overlay{linkage, true, "show_input_overlay", + Settings::Category::Overlay}; + Settings::Setting touchscreen{linkage, true, "touchscreen", + Settings::Category::Overlay}; + Settings::Setting lock_drawer{linkage, false, "lock_drawer", + Settings::Category::Overlay}; + }; + + extern Values values; } // namespace AndroidSettings diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 6dac1ef84e..962fae126c 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -67,6 +67,7 @@ #include "video_core/renderer_vulkan/renderer_vulkan.h" #include "video_core/vulkan_common/vulkan_instance.h" #include "video_core/vulkan_common/vulkan_surface.h" +#include "video_core/shader_notify.h" #define jconst [[maybe_unused]] const auto #define jauto [[maybe_unused]] auto @@ -158,6 +159,12 @@ const Core::PerfStatsResults& EmulationSession::PerfStats() { return m_perf_stats; } +int EmulationSession::ShadersBuilding() { + auto& shader_notify = m_system.GPU().ShaderNotify(); + m_shaders_building = shader_notify.ShadersBuilding(); + return m_shaders_building; +} + void EmulationSession::SurfaceChanged() { if (!IsRunning()) { return; @@ -610,6 +617,16 @@ jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPerfStats(JNIEnv* env, jcl return j_stats; } +jint Java_org_yuzu_yuzu_1emu_NativeLibrary_getShadersBuilding(JNIEnv* env, jclass clazz) { + jint j_shaders = 0; + + if (EmulationSession::GetInstance().IsRunning()) { + j_shaders = EmulationSession::GetInstance().ShadersBuilding(); + } + + return j_shaders; +} + jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuBackend(JNIEnv* env, jclass clazz) { if (Settings::IsNceEnabled()) { return Common::Android::ToJString(env, "NCE"); diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h index 6a4551ada2..4cc838ee5a 100644 --- a/src/android/app/src/main/jni/native.h +++ b/src/android/app/src/main/jni/native.h @@ -44,6 +44,7 @@ public: void ShutdownEmulation(); const Core::PerfStatsResults& PerfStats(); + int ShadersBuilding(); void ConfigureFilesystemProvider(const std::string& filepath); void InitializeSystem(bool reload); void SetAppletId(int applet_id); @@ -72,6 +73,7 @@ private: InputCommon::InputSubsystem m_input_subsystem; Common::DetachedTasks m_detached_tasks; Core::PerfStatsResults m_perf_stats{}; + int m_shaders_building{0}; std::shared_ptr m_vfs; Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized}; std::atomic m_is_running = false; @@ -89,4 +91,4 @@ private: // Program index for next boot std::atomic m_next_program_index = -1; -}; +}; \ No newline at end of file diff --git a/src/android/app/src/main/res/values-ar/strings.xml b/src/android/app/src/main/res/values-ar/strings.xml index 53c0be9039..6ffcc1ff9e 100644 --- a/src/android/app/src/main/res/values-ar/strings.xml +++ b/src/android/app/src/main/res/values-ar/strings.xml @@ -49,8 +49,8 @@ تمكين أو تعطيل ذاكرة التخزين المؤقت الأقل استخدامًا (LRU)، مما يزيد الأداء عن طريق توفير استخدام وحدة المعالجة المركزية. بعض الألعاب بها مشاكل معها، خاصة TotK 1.2.1، لذا قم بتعطيلها إذا لم يتم تشغيل اللعبة أو تعطلت بشكل عشوائي. الحالة الديناميكية الممتدة يُمكّن ميزات فولكان لتحسين الأداء، التقديم، وتوفير الموارد أثناء إنشاء خطوط المعالجة مع الحفاظ على استهلاك أقل لوحدة المعالجة المركزية/وحدة معالجة الرسومات. قد تزيد هذه الامتدادات من درجة حرارة الجهاز، وقد لا تتفاعل وحدات معالجة الرسومات القديمة من سلسلة A6XX بشكل صحيح. اضبط على 0 لاستخدام تنسيقات Yuzu المحاكاة. - EDS3 + VertexInputDynamicState - يحسن الأداء على الأجهزة الأحدث. مدعوم فقط على وحدات معالجة الرسومات التي تدعم فولكان 1.3+. + VertexInputDynamicState + يحسن الأداء على الأجهزة الأحدث. مدعوم فقط على وحدات معالجة الرسومات التي تدعم فولكان 1.3+. مزامنة سرعة النواة مزامنة سرعة النواة مع النسبة القصوى للسرعة لتحسين الأداء دون تغيير السرعة الفعلية للعبة. استخدام الستاب التلقائي diff --git a/src/android/app/src/main/res/values-ckb/strings.xml b/src/android/app/src/main/res/values-ckb/strings.xml index a96132bfbb..00b282081d 100644 --- a/src/android/app/src/main/res/values-ckb/strings.xml +++ b/src/android/app/src/main/res/values-ckb/strings.xml @@ -50,8 +50,8 @@ چالاک یان ناچالاککردنی کاشەی LRU (کەمترین بەکارهێنراوی دوایی)، کارایی زیاد دەکات بە هەڵگرتنی بەکارهێنانی CPU. هەندێک یاری کێشەییان هەیە لەگەڵیدا، بەتایبەتی TotK 1.2.1، بۆیە ئەگەر یاریەکە نەکەوتەوە یان بە هەڕەمەکی داخرا، ناچالاکی بکە. الحالة الديناميكية الممتدة يُمكّن ميزات فولكان لتحسين الأداء، التقديم، وتوفير الموارد أثناء إنشاء خطوط المعالجة مع الحفاظ على استهلاك أقل لوحدة المعالجة المركزية/وحدة معالجة الرسومات. قد تزيد هذه الامتدادات من درجة حرارة الجهاز، وقد لا تتفاعل وحدات معالجة الرسومات القديمة من سلسلة A6XX بشكل صحيح. اضبط على 0 لاستخدام تنسيقات Yuzu المحاكاة. - EDS3 + VertexInputDynamicState - يحسن الأداء على الأجهزة الأحدث. مدعوم فقط على وحدات معالجة الرسومات التي تدعم فولكان 1.3+. + VertexInputDynamicState + يحسن الأداء على الأجهزة الأحدث. مدعوم فقط على وحدات معالجة الرسومات التي تدعم فولكان 1.3+. مزامنة سرعة النواة خێرایی تیکەکانی ناوک ڕێکبخە لەگەڵ ڕێژەی خێرایی بەرزترین بۆ باشترکردنی کارایی بەبێ گۆڕینی خێرایی ڕاستەقینەی یارییەکە. استخدام الستاب التلقائي diff --git a/src/android/app/src/main/res/values-cs/strings.xml b/src/android/app/src/main/res/values-cs/strings.xml index 76ef57a906..95fcc9f75c 100644 --- a/src/android/app/src/main/res/values-cs/strings.xml +++ b/src/android/app/src/main/res/values-cs/strings.xml @@ -49,8 +49,8 @@ Povolte nebo zakažte mezipaměť LRU (Least Recently Used), což zvýší výkon snížením zatížení CPU. Některé hry s ní mají problémy, zejména TotK 1.2.1, proto ji deaktivujte, pokud hra nespustí nebo náhodně padá. Rozšířený dynamický stav Umožňuje funkce Vulkan pro lepší výkon, vykreslování a úsporu zdrojů při vytváření grafických pipeline při zachování nižšího využití CPU/GPU. Tato rozšíření mohou zvýšit teplotu zařízení a starší GPU řady A6XX nemusí reagovat správně. Nastavte na 0 pro použití emulovaných formátů Yuzu. - EDS3 + VertexInputDynamicState - Zlepšuje výkon na novějších zařízeních. Podporováno pouze na GPU s Vulkan 1.3+. + VertexInputDynamicState + Zlepšuje výkon na novějších zařízeních. Podporováno pouze na GPU s Vulkan 1.3+. Synchronizovat rychlost jádra Synchronizuje rychlost jádra s maximálním procentem rychlosti, aby se zlepšil výkon bez změny skutečné rychlosti hry. Použít automatický stub diff --git a/src/android/app/src/main/res/values-de/strings.xml b/src/android/app/src/main/res/values-de/strings.xml index 805db9adcc..d444c5ca88 100644 --- a/src/android/app/src/main/res/values-de/strings.xml +++ b/src/android/app/src/main/res/values-de/strings.xml @@ -50,8 +50,8 @@ Aktivieren oder deaktivieren Sie den LRU-Cache (Least Recently Used), um die Leistung durch Reduzierung der CPU-Auslastung zu verbessern. Einige Spiele haben Probleme damit, insbesondere TotK 1.2.1, deaktivieren Sie ihn also, wenn das Spiel nicht startet oder zufällig abstürzt. Erweiterter dynamischer Status Aktiviert Vulkan-Funktionen zur Verbesserung der Leistung, des Renderings und zur Ressourceneinsparung bei der Pipeline-Erstellung, während die CPU/GPU-Auslastung niedrig bleibt. Diese Erweiterungen können die Gerätetemperatur erhöhen, und ältere GPUs der A6XX-Serie reagieren möglicherweise nicht korrekt. Auf 0 setzen, um emulierte Yuzu-Formate zu verwenden. - EDS3 + VertexInputDynamicState - Verbessert die Leistung auf neueren Geräten. Wird nur von GPUs mit Vulkan 1.3+ unterstützt. + VertexInputDynamicState + Verbessert die Leistung auf neueren Geräten. Wird nur von GPUs mit Vulkan 1.3+ unterstützt. Kern-Geschwindigkeit synchronisieren Synchronisiert die Taktrate des Kerns mit der maximalen Geschwindigkeit, um die Leistung zu verbessern, ohne die tatsächliche Spielgeschwindigkeit zu verändern. Auto-Stub verwenden diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml index 5137b04d18..fb819a2401 100644 --- a/src/android/app/src/main/res/values-es/strings.xml +++ b/src/android/app/src/main/res/values-es/strings.xml @@ -50,8 +50,8 @@ Activa o desactiva la caché LRU (menos usados recientemente), aumentando el rendimiento al ahorrar uso de CPU. Algunos juegos tienen problemas con ella, especialmente TotK 1.2.1, así que desactívala si el juego no arranca o se cierra aleatoriamente. Estado dinámico extendido Habilita funciones Vulkan para mejorar rendimiento, renderizado y ahorrar recursos en creación de pipelines manteniendo bajo uso de CPU/GPU. Estas extensiones pueden aumentar la temperatura del dispositivo y GPUs antiguas de serie A6XX podrían no responder correctamente. Establecer en 0 para usar formatos emulados de Yuzu. - EDS3 + VertexInputDynamicState - Mejora el rendimiento en dispositivos nuevos. Solo compatible con GPUs Vulkan 1.3+. + VertexInputDynamicState + Mejora el rendimiento en dispositivos nuevos. Solo compatible con GPUs Vulkan 1.3+. Sincronizar velocidad del núcleo Sincroniza la velocidad del núcleo con el porcentaje máximo de velocidad para mejorar el rendimiento sin alterar la velocidad real del juego. Usar Auto Stub diff --git a/src/android/app/src/main/res/values-fa/strings.xml b/src/android/app/src/main/res/values-fa/strings.xml index 9513e16bc0..c39f102d77 100644 --- a/src/android/app/src/main/res/values-fa/strings.xml +++ b/src/android/app/src/main/res/values-fa/strings.xml @@ -50,8 +50,8 @@ فعال یا غیرفعال کردن کش LRU (کمترین اخیراً استفاده شده)، که با کاهش استفاده از CPU عملکرد را افزایش می‌دهد. برخی بازی‌ها با آن مشکل دارند، به ویژه TotK 1.2.1، بنابراین اگر بازی اجرا نشد یا به صورت تصادفی کرش کرد، آن را غیرفعال کنید. حالت پویای گسترده قابلیت‌های ولکان را برای بهبود عملکرد، رندرینگ و صرفه‌جویی در منابع هنگام ایجاد خط لوله فعال می‌کند در حالی که مصرف CPU/GPU پایین حفظ می‌شود. این افزونه‌ها ممکن است دمای دستگاه را افزایش دهند و کارت‌های گرافیک سری قدیمی A6XX ممکن است واکنش مناسبی نشان ندهند. برای استفاده از فرمت‌های شبیه‌سازی شده یوزو روی 0 تنظیم کنید - EDS3 + حالت پویای ورودی رأس - عملکرد را در دستگاه‌های جدیدتر بهبود می‌بخشد. فقط در کارت‌های گرافیک با پشتیبانی از ولکان 1.3+ قابل استفاده است + حالت پویای ورودی رأس + عملکرد را در دستگاه‌های جدیدتر بهبود می‌بخشد. فقط در کارت‌های گرافیک با پشتیبانی از ولکان 1.3+ قابل استفاده است همگام‌سازی سرعت هسته همگام‌سازی سرعت هسته با حداکثر درصد سرعت برای بهبود عملکرد بدون تغییر سرعت واقعی بازی. استفاده از استاب خودکار diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml index 7eeaebc7b7..07b9b92e8d 100644 --- a/src/android/app/src/main/res/values-fr/strings.xml +++ b/src/android/app/src/main/res/values-fr/strings.xml @@ -50,8 +50,8 @@ Activez ou désactivez le cache LRU (Least Recently Used), ce qui améliore les performances en réduisant l\'utilisation du CPU. Certains jeux ont des problèmes avec, notamment TotK 1.2.1, désactivez-le donc si le jeu ne démarre pas ou plante aléatoirement. État dynamique étendu Active les fonctionnalités Vulkan pour améliorer les performances, le rendu et économiser les ressources lors de la création de pipelines tout en maintenant une faible utilisation CPU/GPU. Ces extensions peuvent augmenter la température de l`appareil, et les GPU plus anciens de la série A6XX peuvent ne pas réagir correctement. Réglez sur 0 pour utiliser les formats émulés de Yuzu. - EDS3 + VertexInputDynamicState - Améliore les performances sur les appareils récents. Pris en charge uniquement par les GPU Vulkan 1.3+. + VertexInputDynamicState + Améliore les performances sur les appareils récents. Pris en charge uniquement par les GPU Vulkan 1.3+. Synchroniser la vitesse du cœur Synchronise la vitesse du cœur avec le pourcentage de vitesse maximal pour améliorer les performances sans modifier la vitesse réelle du jeu. Utiliser le stub automatique diff --git a/src/android/app/src/main/res/values-he/strings.xml b/src/android/app/src/main/res/values-he/strings.xml index 7437db4f9f..3cd91dea59 100644 --- a/src/android/app/src/main/res/values-he/strings.xml +++ b/src/android/app/src/main/res/values-he/strings.xml @@ -50,8 +50,8 @@ הפעל או השבת את מטמון LRU (Least Recently Used), המשפר ביצועים על ידי חיסכון בשימוש במעבד. חלק מהמשחקים נתקלים בבעיות עם זה, במיוחד TotK 1.2.1, אז השבת אם המשחק לא נטען או קורס אקראית. מצב דינמי מורחב מאפשר תכונות Vulkan לשיפור ביצועים, רינדור וחיסכון במשאבים תוך שמירה על שימוש נמוך ב-CPU/GPU. הרחבות אלו עשויות להעלות את טמפ` המכשיר, וכרטיסי מסך מסדרת A6XX הישנים יותר עשויים לא להגיב כראוי. הגדר ל-0 כדי להשתמש בפורמטים המדומים של Yuzu. - EDS3 + VertexInputDynamicState - משפר ביצועים במכשירים חדשים יותר. נתמך רק בכרטיסי מסך עם Vulkan 1.3+. + VertexInputDynamicState + משפר ביצועים במכשירים חדשים יותר. נתמך רק בכרטיסי מסך עם Vulkan 1.3+. סנכרון מהירות ליבה סנכרן את מהירות הליבה לאחוז המהירות המרבי כדי לשפר ביצועים מבלי לשנות את מהירות המשחק בפועל. שימוש ב-Auto Stub diff --git a/src/android/app/src/main/res/values-hu/strings.xml b/src/android/app/src/main/res/values-hu/strings.xml index 9fb6f6321d..902d6ed647 100644 --- a/src/android/app/src/main/res/values-hu/strings.xml +++ b/src/android/app/src/main/res/values-hu/strings.xml @@ -50,8 +50,8 @@ Engedélyezze vagy tiltsa le az LRU gyorsítótárat (Least Recently Used), amely a CPU használatának csökkentésével növeli a teljesítményt. Néhány játékkal problémák adódhatnak, különösen a TotK 1.2.1 esetében, ezért tiltsa le, ha a játék nem indul el vagy véletlenszerűen összeomlik. Kiterjesztett Dinamikus Állapot Engedélyezi a Vulkan funkciókat a teljesítmény, a renderelés javításához és erőforrások megtakarításához a pipeline létrehozásánál, miközben alacsony CPU/GPU használatot tart fenn. Ezek a kiterjesztések növelhetik az eszköz hőmérsékletét, és a régebbi A6XX sorozatú GPU-k nem feltétlenül reagálnak megfelelően. Állítsa 0-ra a Yuzu által emulált formátumok használatához. - EDS3 + VertexInputDynamicState - Javítja a teljesítményt újabb eszközökön. Csak Vulkan 1.3+ GPU-kon támogatott. + VertexInputDynamicState + Javítja a teljesítményt újabb eszközökön. Csak Vulkan 1.3+ GPU-kon támogatott. Magsebesség szinkronizálása A mag sebességének szinkronizálása a maximális sebesség százalékával a teljesítmény javítása érdekében a játék tényleges sebességének megváltoztatása nélkül. Automatikus Stub használata diff --git a/src/android/app/src/main/res/values-id/strings.xml b/src/android/app/src/main/res/values-id/strings.xml index 4c8a969e5d..7741089115 100644 --- a/src/android/app/src/main/res/values-id/strings.xml +++ b/src/android/app/src/main/res/values-id/strings.xml @@ -50,8 +50,8 @@ Aktifkan atau nonaktifkan cache LRU (Least Recently Used), meningkatkan performa dengan menghemat penggunaan CPU. Beberapa game memiliki masalah dengannya, terutama TotK 1.2.1, jadi nonaktifkan jika game tidak mau boot atau sering crash. Status Dinamis Ekstensi Mengaktifkan fitur Vulkan untuk meningkatkan performa, rendering, dan menghemat sumber daya saat pembuatan pipeline sambil mempertahankan penggunaan CPU/GPU yang rendah. Ekstensi ini dapat meningkatkan suhu perangkat, dan GPU seri A6XX lama mungkin tidak merespons dengan benar. Setel ke 0 untuk menggunakan format emulasi Yuzu. - EDS3 + VertexInputDynamicState - Meningkatkan performa di perangkat baru. Hanya didukung di GPU Vulkan 1.3+. + VertexInputDynamicState + Meningkatkan performa di perangkat baru. Hanya didukung di GPU Vulkan 1.3+. Sinkronisasi Kecepatan Inti Sinkronkan kecepatan inti dengan persentase kecepatan maksimum untuk meningkatkan performa tanpa mengubah kecepatan sebenarnya dari permainan. Gunakan Auto Stub diff --git a/src/android/app/src/main/res/values-it/strings.xml b/src/android/app/src/main/res/values-it/strings.xml index 69a55c7a06..654b27a812 100644 --- a/src/android/app/src/main/res/values-it/strings.xml +++ b/src/android/app/src/main/res/values-it/strings.xml @@ -50,8 +50,8 @@ Abilita o disabilita la cache LRU (Least Recently Used), aumentando le prestazioni risparmiando l\'utilizzo della CPU. Alcuni giochi hanno problemi con essa, in particolare TotK 1.2.1, quindi disabilitala se il gioco non si avvia o si blocca casualmente. Stato dinamico esteso Abilita funzionalità Vulkan per migliorare prestazioni, rendering e risparmiare risorse durante la creazione della pipeline mantenendo un basso utilizzo di CPU/GPU. Queste estensioni possono aumentare la temperatura del dispositivo e le GPU più vecchie della serie A6XX potrebbero non rispondere correttamente. Imposta su 0 per usare i formati emulati da Yuzu. - EDS3 + VertexInputDynamicState - Migliora le prestazioni sui dispositivi più recenti. Supportato solo su GPU Vulkan 1.3+. + VertexInputDynamicState + Migliora le prestazioni sui dispositivi più recenti. Supportato solo su GPU Vulkan 1.3+. Sincronizza velocità core Sincronizza la velocità del core con la percentuale massima di velocità per migliorare le prestazioni senza alterare la velocità effettiva del gioco. Usa Auto Stub diff --git a/src/android/app/src/main/res/values-ja/strings.xml b/src/android/app/src/main/res/values-ja/strings.xml index 8314382285..e2d2985a66 100644 --- a/src/android/app/src/main/res/values-ja/strings.xml +++ b/src/android/app/src/main/res/values-ja/strings.xml @@ -50,8 +50,8 @@ LRUキャッシュ(最近最も使われていない)を有効または無効にし、CPU使用率を節約してパフォーマンスを向上させます。一部のゲーム(特にTotK 1.2.1)で問題が発生する可能性があるため、ゲームが起動しないかランダムにクラッシュする場合は無効にしてください。 拡張ダイナミックステート Vulkan機能を有効にしてパフォーマンスとレンダリングを向上させ、パイプライン作成時のリソースを節約しながらCPU/GPU使用率を低く保ちます。これらの拡張機能はデバイスの温度を上昇させる可能性があり、古いA6XXシリーズのGPUでは正しく反応しない場合があります。Yuzuのエミュレート形式を使用するには0に設定します。 - EDS3 + 頂点入力動的状態 - 新しいデバイスでパフォーマンスを向上させます。Vulkan 1.3+ GPUでのみサポートされています。 + 頂点入力動的状態 + 新しいデバイスでパフォーマンスを向上させます。Vulkan 1.3+ GPUでのみサポートされています。 コア速度の同期 コアの速度を最大速度パーセンテージに同期させ、ゲームの実際の速度を変えずにパフォーマンスを向上させます。 自動スタブを使用 diff --git a/src/android/app/src/main/res/values-ko/strings.xml b/src/android/app/src/main/res/values-ko/strings.xml index ede1e59d92..5dbb6d883e 100644 --- a/src/android/app/src/main/res/values-ko/strings.xml +++ b/src/android/app/src/main/res/values-ko/strings.xml @@ -50,8 +50,8 @@ LRU 캐시(최근 사용되지 않은 항목)를 활성화 또는 비활성화하여 CPU 사용량을 절약하고 성능을 향상시킵니다. 일부 게임(특히 TotK 1.2.1)에서 문제가 발생할 수 있으므로 게임이 부팅되지 않거나 무작위로 충돌하는 경우 비활성화하세요. 확장 동적 상태 Vulkan 기능을 활성화하여 파이프라인 생성 시 성능, 렌더링을 개선하고 리소스를 절약하면서 CPU/GPU 사용량을 낮게 유지합니다. 이러한 확장 기능은 장치 온도를 높일 수 있으며, 이전 A6XX 라인의 GPU는 제대로 반응하지 않을 수 있습니다. Yuzu 에뮬레이션 형식을 사용하려면 0으로 설정하세요. - EDS3 + 정점 입력 동적 상태 - 최신 기기에서 성능을 향상시킵니다. Vulkan 1.3+ GPU에서만 지원됩니다. + 정점 입력 동적 상태 + 최신 기기에서 성능을 향상시킵니다. Vulkan 1.3+ GPU에서만 지원됩니다. 코어 속도 동기화 코어 틱 속도를 최대 속도 백분율과 동기화하여 게임의 실제 속도를 변경하지 않고 성능을 향상시킵니다. 자동 스텁 사용 diff --git a/src/android/app/src/main/res/values-nb/strings.xml b/src/android/app/src/main/res/values-nb/strings.xml index 22792fb302..1a5b5ccefc 100644 --- a/src/android/app/src/main/res/values-nb/strings.xml +++ b/src/android/app/src/main/res/values-nb/strings.xml @@ -50,8 +50,8 @@ Aktiver eller deaktiver LRU-mellomlager (Least Recently Used), som forbedrer ytelsen ved å spare CPU-bruk. Noen spill har problemer med dette, spesielt TotK 1.2.1, så deaktiver hvis spillet ikke starter eller krasjer tilfeldig. Utvidet dynamisk tilstand Aktiverer Vulkan-funksjoner for å forbedre ytelse, rendering og spare ressurser ved pipeline-opprettelse samtidig som CPU/GPU-bruken holdes lav. Disse utvidelsene kan øke enhetstemperaturen, og eldre A6XX-serien GPU-er kan reagere unormalt. Sett til 0 for å bruke Yuzus emulerte formater. - EDS3 + VertexInputDynamicState - Forbedrer ytelsen på nyere enheter. Støttes kun på Vulkan 1.3+ GPU-er. + VertexInputDynamicState + Forbedrer ytelsen på nyere enheter. Støttes kun på Vulkan 1.3+ GPU-er. Synkroniser kjernespeed Synkroniser kjernens hastighet med maksimal hastighetsprosent for å forbedre ytelsen uten å endre spillets faktiske hastighet. Bruk Auto Stub diff --git a/src/android/app/src/main/res/values-pl/strings.xml b/src/android/app/src/main/res/values-pl/strings.xml index 55702b21ce..04a71eb8f1 100644 --- a/src/android/app/src/main/res/values-pl/strings.xml +++ b/src/android/app/src/main/res/values-pl/strings.xml @@ -50,8 +50,8 @@ Włącz lub wyłącz pamięć podręczną LRU (najrzadziej używane), zwiększając wydajność poprzez oszczędzanie użycia procesora. Niektóre gry mają z nią problemy, szczególnie TotK 1.2.1, więc wyłącz, jeśli gra się nie uruchamia lub losowo się zawiesza. Rozszerzony stan dynamiczny Włącza funkcje Vulkan w celu poprawy wydajności, renderowania i oszczędzania zasobów podczas tworzenia potoku, utrzymując niskie użycie CPU/GPU. Te rozszerzenia mogą zwiększać temperaturę urządzenia, a starsze GPU z serii A6XX mogą nie reagować prawidłowo. Ustaw na 0, aby używać formatów emulowanych przez Yuzu. - EDS3 + VertexInputDynamicState - Poprawia wydajność na nowszych urządzeniach. Obsługiwane tylko przez GPU Vulkan 1.3+. + VertexInputDynamicState + Poprawia wydajność na nowszych urządzeniach. Obsługiwane tylko przez GPU Vulkan 1.3+. Synchronizuj prędkość rdzenia Synchronizuje prędkość rdzenia z maksymalnym procentem prędkości, aby poprawić wydajność bez zmiany rzeczywistej prędkości gry. Użyj Auto Stub diff --git a/src/android/app/src/main/res/values-pt-rBR/strings.xml b/src/android/app/src/main/res/values-pt-rBR/strings.xml index 8ea90ceb61..d5eb1f6e7d 100644 --- a/src/android/app/src/main/res/values-pt-rBR/strings.xml +++ b/src/android/app/src/main/res/values-pt-rBR/strings.xml @@ -50,8 +50,8 @@ Ative ou desative o cache LRU (Least Recently Used), aumentando o desempenho ao economizar uso da CPU. Alguns jogos têm problemas com ele, especialmente TotK 1.2.1, então desative se o jogo não iniciar ou travar aleatoriamente. Estado Dinâmico Estendido Ativa recursos Vulkan para melhorar desempenho, renderização e economizar recursos na criação de pipelines mantendo baixo uso de CPU/GPU. Essas extensões podem aumentar a temperatura do dispositivo e GPUs mais antigas da linha A6XX podem não responder corretamente. Defina como 0 para usar formatos emulados do Yuzu. - EDS3 + VertexInputDynamicState - Melhora desempenho em dispositivos mais novos. Suportado apenas em GPUs Vulkan 1.3+. + VertexInputDynamicState + Melhora desempenho em dispositivos mais novos. Suportado apenas em GPUs Vulkan 1.3+. Sincronizar velocidade do núcleo Sincroniza a velocidade do núcleo com a porcentagem máxima de velocidade para melhorar o desempenho sem alterar a velocidade real do jogo. Usar Auto Stub diff --git a/src/android/app/src/main/res/values-pt-rPT/strings.xml b/src/android/app/src/main/res/values-pt-rPT/strings.xml index 2006f4201a..0f4cb60e18 100644 --- a/src/android/app/src/main/res/values-pt-rPT/strings.xml +++ b/src/android/app/src/main/res/values-pt-rPT/strings.xml @@ -50,8 +50,8 @@ Ative ou desative a cache LRU (Least Recently Used), aumentando o desempenho ao poupar utilização da CPU. Alguns jogos têm problemas com ela, especialmente TotK 1.2.1, por isso desative se o jogo não arrancar ou falhar aleatoriamente. Estado Dinâmico Estendido Ativa funcionalidades Vulkan para melhorar desempenho, renderização e poupar recursos na criação de pipelines mantendo baixo uso de CPU/GPU. Estas extensões podem aumentar a temperatura do dispositivo e GPUs mais antigas da linha A6XX podem não responder corretamente. Defina como 0 para usar formatos emulados do Yuzu. - EDS3 + VertexInputDynamicState - Melhora o desempenho em dispositivos mais recentes. Suportado apenas em GPUs Vulkan 1.3+. + VertexInputDynamicState + Melhora o desempenho em dispositivos mais recentes. Suportado apenas em GPUs Vulkan 1.3+. Sincronizar velocidade do núcleo Sincroniza a velocidade do núcleo com a percentagem máxima de velocidade para melhorar o desempenho sem alterar a velocidade real do jogo. Usar Auto Stub diff --git a/src/android/app/src/main/res/values-ru/strings.xml b/src/android/app/src/main/res/values-ru/strings.xml index b16dce419c..243494ba5d 100644 --- a/src/android/app/src/main/res/values-ru/strings.xml +++ b/src/android/app/src/main/res/values-ru/strings.xml @@ -50,8 +50,8 @@ Включите или отключите кэш LRU (наименее недавно использованный), что повышает производительность за счет экономии использования ЦП. Некоторые игры имеют проблемы с ним, особенно TotK 1.2.1, поэтому отключите, если игра не запускается или случайно вылетает. Расширенное динамическое состояние Включает функции Vulkan для улучшения производительности, рендеринга и экономии ресурсов при создании конвейеров, сохраняя низкое использование CPU/GPU. Эти расширения могут повысить температуру устройства, а старые GPU серии A6XX могут работать некорректно. Установите 0 для использования эмулируемых форматов Yuzu. - EDS3 + Динамическое состояние ввода вершин - Улучшает производительность на новых устройствах. Поддерживается только GPU с Vulkan 1.3+. + Динамическое состояние ввода вершин + Улучшает производительность на новых устройствах. Поддерживается только GPU с Vulkan 1.3+. Синхронизация скорости ядра Синхронизирует скорость ядра с максимальным процентом скорости для улучшения производительности без изменения фактической скорости игры. Использовать Auto Stub diff --git a/src/android/app/src/main/res/values-uk/strings.xml b/src/android/app/src/main/res/values-uk/strings.xml index 369f116308..6fd938bcc4 100644 --- a/src/android/app/src/main/res/values-uk/strings.xml +++ b/src/android/app/src/main/res/values-uk/strings.xml @@ -50,8 +50,8 @@ Увімкніть або вимкніть кеш LRU (найменш нещодавно використаний), що підвищує продуктивність за рахунок економії використання CPU. Деякі ігри мають проблеми з ним, особливо TotK 1.2.1, тому вимкніть, якщо гра не запускається або випадково вилітає. Розширений динамічний стан Активує функції Vulkan для покращення продуктивності, рендерингу та економії ресурсів під час створення конвеєрів, зберігаючи низьке використання CPU/GPU. Ці розширення можуть підвищити температуру пристрою, а старі GPU серії A6XX можуть реагувати некоректно. Встановіть 0 для використання емульованих форматів Yuzu. - EDS3 + Динамічний стан вводу вершин - Покращує продуктивність на нових пристроях. Підтримується лише GPU з Vulkan 1.3+. + Динамічний стан вводу вершин + Покращує продуктивність на нових пристроях. Підтримується лише GPU з Vulkan 1.3+. Синхронізувати швидкість ядра Синхронізує швидкість ядра з максимальним відсотком швидкості для покращення продуктивності без зміни реальної швидкості гри. Використовувати Auto Stub diff --git a/src/android/app/src/main/res/values-vi/strings.xml b/src/android/app/src/main/res/values-vi/strings.xml index 475b379b64..083af5f53f 100644 --- a/src/android/app/src/main/res/values-vi/strings.xml +++ b/src/android/app/src/main/res/values-vi/strings.xml @@ -50,8 +50,8 @@ Bật hoặc tắt bộ nhớ đệm LRU (ít được sử dụng gần đây nhất), tăng hiệu suất bằng cách tiết kiệm sử dụng CPU. Một số trò chơi có vấn đề với nó, đặc biệt là TotK 1.2.1, vì vậy hãy tắt nếu trò chơi không khởi động hoặc bị treo ngẫu nhiên. Trạng thái động mở rộng Kích hoạt các tính năng Vulkan để cải thiện hiệu suất, kết xuất và tiết kiệm tài nguyên khi tạo pipeline trong khi vẫn duy trì mức sử dụng CPU/GPU thấp. Các tiện ích mở rộng này có thể làm tăng nhiệt độ thiết bị và GPU dòng A6XX cũ hơn có thể không phản ứng đúng cách. Đặt thành 0 để sử dụng định dạng mô phỏng của Yuzu. - EDS3 + Trạng thái động đầu vào đỉnh - Cải thiện hiệu suất trên các thiết bị mới hơn. Chỉ được hỗ trợ trên GPU Vulkan 1.3+. + Trạng thái động đầu vào đỉnh + Cải thiện hiệu suất trên các thiết bị mới hơn. Chỉ được hỗ trợ trên GPU Vulkan 1.3+. Đồng bộ tốc độ lõi Đồng bộ tốc độ lõi với tỷ lệ phần trăm tốc độ tối đa để cải thiện hiệu suất mà không làm thay đổi tốc độ thực tế của trò chơi. Sử dụng Auto Stub diff --git a/src/android/app/src/main/res/values-zh-rCN/strings.xml b/src/android/app/src/main/res/values-zh-rCN/strings.xml index a57b0def0c..007f6b9a56 100644 --- a/src/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/android/app/src/main/res/values-zh-rCN/strings.xml @@ -50,8 +50,8 @@ 启用或禁用LRU(最近最少使用)缓存,通过节省CPU使用来提高性能。某些游戏(尤其是TotK 1.2.1)可能存在问题,如果游戏无法启动或随机崩溃,请禁用它。 扩展动态状态 启用Vulkan功能以在保持低CPU/GPU使用率的同时提高性能、渲染效果并节省管道创建资源。这些扩展可能会提高设备温度,较旧的A6XX系列GPU可能无法正确响应。设置为0可使用Yuzu模拟格式。 - EDS3 + 顶点输入动态状态 - 提高新设备上的性能。仅支持Vulkan 1.3+ GPU。 + 顶点输入动态状态 + 提高新设备上的性能。仅支持Vulkan 1.3+ GPU。 同步核心速度 将核心速度与最大速度百分比同步,在不改变游戏实际速度的情况下提高性能。 使用自动存根 diff --git a/src/android/app/src/main/res/values-zh-rTW/strings.xml b/src/android/app/src/main/res/values-zh-rTW/strings.xml index 80a3a89c56..d7d311e810 100644 --- a/src/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/android/app/src/main/res/values-zh-rTW/strings.xml @@ -50,8 +50,8 @@ 啟用或停用LRU(最近最少使用)快取,通過節省CPU使用來提高效能。某些遊戲(尤其是TotK 1.2.1)可能存在問題,如果遊戲無法啟動或隨機崩潰,請停用它。 擴展動態狀態 啟用Vulkan功能以在保持低CPU/GPU使用率的同時提高效能、渲染效果並節省管線建立資源。這些擴充可能會提高裝置溫度,較舊的A6XX系列GPU可能無法正確響應。設為0可使用Yuzu模擬格式。 - EDS3 + 頂點輸入動態狀態 - 提高新裝置上的效能。僅支援Vulkan 1.3+ GPU。 + 頂點輸入動態狀態 + 提高新裝置上的效能。僅支援Vulkan 1.3+ GPU。 同步核心速度 將核心速度與最大速度百分比同步,在不改變遊戲實際速度的情況下提高效能。 使用自動存根 diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index cb108dc548..eeac14d6f4 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -21,6 +21,18 @@ 1 + + @string/memory_4gb + @string/memory_6gb + @string/memory_8gb + + + + 0 + 1 + 2 + + @string/language_brazilian_portuguese @string/language_british_english diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index cb9930d0a3..45cfb1c32d 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -12,8 +12,10 @@ (Enhanced) (Skipping) + Building + Shader(s) System: - ShoW Performance Stats Overlay + Show Performance Stats Overlay Customization Visibility Overlay @@ -31,6 +33,8 @@ Display the amount of RAM used by the system Show Battery Temperature Display current Battery temperature in Celsius and Fahrenheit + Show Shaders Building + Display current number of shaders being built Overlay Position Choose where the performance stats overlay is displayed on the screen Top Left @@ -48,9 +52,9 @@ Enhanced Frame Pacing Ensures smooth and consistent frame delivery by synchronizing the timing between frames, reducing stuttering and uneven animation. Ideal for games that experience frame timing instability or micro-stutters during gameplay. Extended Dynamic State - Enables Vulkan features to improve performance, rendering, and save resources on pipeline creation while maintaining lower CPU/GPU usage. These extensions may increase device temperature, and GPUs belonging to the older A6XX line may not react properly. Set to 0 to use Legacy emulated formats. - EDS3 + VertexInputDynamicState - Improves performance on newer devices. Only supported on Vulkan 1.3+ GPUs. + Enables Vulkan features to improve performance, rendering, and save resources on pipeline creation while maintaining lower CPU/GPU usage. These extensions may increase device temperature, and GPUs belonging to the older A6XX line may not react properly. Set to 0 to use Legacy emulated formats. Setting 3 will only work on new devices. + VertexInputDynamicState + Improves performance on newer devices. Only supported on Vulkan 1.3+ GPUs. Synchronize Core Speed Synchronize the core tick speed to the maximum speed percentage to improve performance without altering the game\'s actual speed. Use Auto Stub @@ -361,12 +365,16 @@ Specifies the percentage to limit emulation speed. 100% is the normal speed. Values higher or lower will increase or decrease the speed limit. CPU backend CPU accuracy + Flush debug logs by line + Flushes debugging logs on each line written, making debugging easier in cases of crashing or freezing. %1$s%2$s Device name Docked Mode Increases resolution, decreasing performance. Handheld Mode is used when disabled, lowering resolution and increasing performance. + Memory Layout + Change the emulated memory layout. This setting will not increase performance, but may help with games utilizing high resolutions via mods. Do not use on phones with 8GB of RAM or less. Emulated region Emulated language Select RTC date @@ -411,6 +419,7 @@ Graphics debugging Sets the graphics API to a slow debugging mode. Fastmem + Logging Output engine @@ -680,6 +689,11 @@ Korea Taiwan + + 4GB (Recommended) + 6GB (Unsafe) + 8GB (Unsafe) + 日本語 English diff --git a/src/common/settings.h b/src/common/settings.h index 6b4532c961..c7d34e6f2f 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -452,12 +452,15 @@ struct Values { 2, #endif 0, - 2, + 3, "dyna_state", Category::RendererExtensions, Specialization::Scalar}; - SwitchableSetting dyna_state3{linkage, true, "dyna_state3", Category::RendererExtensions}; + SwitchableSetting vertex_input{linkage, + false, + "vertex_input", + Category::RendererExtensions}; SwitchableSetting provoking_vertex{linkage, true, "provoking_vertex", Category::RendererExtensions}; SwitchableSetting descriptor_indexing{linkage, true, "descriptor_indexing", Category::RendererExtensions}; diff --git a/src/core/hle/kernel/k_memory_layout.h b/src/core/hle/kernel/k_memory_layout.h index d7adb31699..7ca5a5b41e 100644 --- a/src/core/hle/kernel/k_memory_layout.h +++ b/src/core/hle/kernel/k_memory_layout.h @@ -25,7 +25,7 @@ constexpr std::size_t GetMaximumOverheadSize(std::size_t size) { } constexpr std::size_t MainMemorySize = 4_GiB; -constexpr std::size_t MainMemorySizeMax = 8_GiB; +constexpr std::size_t MainMemorySizeMax = 12_GiB; constexpr std::size_t ReservedEarlyDramSize = 384_KiB; constexpr std::size_t DramPhysicalAddress = 0x80000000; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 4b4331d2f4..c2ed3a5719 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -803,6 +803,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE, VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_LINE_STIPPLE, }; + if (key.state.dynamic_vertex_input) { + dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT); + } if (key.state.extended_dynamic_state) { static constexpr std::array extended{ VK_DYNAMIC_STATE_CULL_MODE_EXT, @@ -815,9 +818,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT, VK_DYNAMIC_STATE_STENCIL_OP_EXT, }; - if (key.state.dynamic_vertex_input) { - dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT); - } dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end()); if (key.state.extended_dynamic_state_2) { static constexpr std::array extended2{ diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 27efc02e69..82d68e59f4 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -128,7 +128,8 @@ Shader::AttributeType CastAttributeType(const FixedPipelineState::VertexAttribut return Shader::AttributeType::Float; } -Shader::AttributeType AttributeType(const FixedPipelineState& state, size_t index) { +Shader::AttributeType AttributeType(const FixedPipelineState& state, size_t index) +{ switch (state.DynamicAttributeType(index)) { case 0: return Shader::AttributeType::Disabled; @@ -179,7 +180,8 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span program info.generic_input_types[index] = AttributeType(key.state, index); } } else { - std::ranges::transform(key.state.attributes, info.generic_input_types.begin(), + std::ranges::transform(key.state.attributes, + info.generic_input_types.begin(), &CastAttributeType); } break; @@ -403,17 +405,23 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, } const u8 dynamic_state = Settings::values.dyna_state.GetValue(); - const bool dynamic_state3 = dynamic_state == 2 && Settings::values.dyna_state3.GetValue(); + + const bool vertex_input = Settings::values.vertex_input.GetValue(); LOG_INFO(Render_Vulkan, "DynamicState value is set to {}", (u32) dynamic_state); - LOG_INFO(Render_Vulkan, "DynamicState3 value is set to {}", dynamic_state3); + dynamic_features = DynamicFeatures{ - .has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported() && dynamic_state > 0, - .has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported() && dynamic_state > 1, - .has_extended_dynamic_state_2_extra = device.IsExtExtendedDynamicState2ExtrasSupported() && dynamic_state > 1, - .has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported() && dynamic_state3, - .has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported() && dynamic_state3, - .has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(),// && dynamic_state3, + .has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported() + && dynamic_state > 0, + .has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported() + && dynamic_state > 1, + .has_extended_dynamic_state_2_extra = device.IsExtExtendedDynamicState2ExtrasSupported() + && dynamic_state > 1, + .has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported() + && dynamic_state > 2, + .has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported() + && dynamic_state > 2, + .has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported() && vertex_input, }; LOG_INFO(Render_Vulkan, "DynamicState1: {}", dynamic_features.has_extended_dynamic_state); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index d0cff37f61..62c057bfb4 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -952,28 +952,28 @@ void RasterizerVulkan::UpdateDynamicStates() { UpdateDepthBiasEnable(regs); } if (device.IsExtExtendedDynamicState3EnablesSupported()) { - using namespace Tegra::Engines; - - if (device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_OPEN_SOURCE - || device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_PROPRIETARY) { - struct In { - const Maxwell3D::Regs::VertexAttribute::Type d; - In(Maxwell3D::Regs::VertexAttribute::Type n) : d(n) {} - bool operator()(Maxwell3D::Regs::VertexAttribute n) const { - return n.type == d; - } - }; - - auto has_float = std::any_of( - regs.vertex_attrib_format.begin(), regs.vertex_attrib_format.end(), - In(Maxwell3D::Regs::VertexAttribute::Type::Float)); - - if (regs.logic_op.enable) - regs.logic_op.enable = static_cast(!has_float); - - UpdateLogicOpEnable(regs); - } else - UpdateLogicOpEnable(regs); + using namespace Tegra::Engines; + + if (device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_OPEN_SOURCE + || device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_PROPRIETARY) { + struct In { + const Maxwell3D::Regs::VertexAttribute::Type d; + In(Maxwell3D::Regs::VertexAttribute::Type n) : d(n) {} + bool operator()(Maxwell3D::Regs::VertexAttribute n) const { + return n.type == d; + } + }; + + auto has_float = std::any_of( + regs.vertex_attrib_format.begin(), regs.vertex_attrib_format.end(), + In(Maxwell3D::Regs::VertexAttribute::Type::Float)); + + if (regs.logic_op.enable) + regs.logic_op.enable = static_cast(!has_float); + + UpdateLogicOpEnable(regs); + } else + UpdateLogicOpEnable(regs); UpdateDepthClampEnable(regs); } } @@ -1103,12 +1103,21 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) { regs.zeta.format == Tegra::DepthFormat::X8Z24_UNORM || regs.zeta.format == Tegra::DepthFormat::S8Z24_UNORM || regs.zeta.format == Tegra::DepthFormat::V8Z24_UNORM; - if (is_d24 && !device.SupportsD24DepthBuffer() && program_id == 0x1006A800016E000ULL) { - // Only activate this in Super Smash Brothers Ultimate + + size_t length = sizeof(NEEDS_D24) / sizeof(u64); + bool needs_convert = false; + for (size_t i = 0; i < length; ++i) { + if (NEEDS_D24[i] == program_id) { + needs_convert = true; + break; + } + } + + if (is_d24 && !device.SupportsD24DepthBuffer() && needs_convert) { // the base formulas can be obtained from here: // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias - const double rescale_factor = - static_cast(1ULL << (32 - 24)) / (static_cast(0x1.ep+127)); + const double rescale_factor = static_cast(1ULL << (32 - 24)) + / (static_cast(0x1.ep+127)); units = static_cast(static_cast(units) * rescale_factor); } scheduler.Record([constant = units, clamp = regs.depth_bias_clamp, diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 0617b37f05..33bc6cd8e4 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -144,6 +144,10 @@ private: static constexpr size_t MAX_IMAGE_VIEWS = MAX_TEXTURES + MAX_IMAGES; static constexpr VkDeviceSize DEFAULT_BUFFER_SIZE = 4 * sizeof(float); + static constexpr u64 NEEDS_D24[] = { + 0x1006A800016E000ULL, // SSBU + 0x0100E95004038000ULL, // XC2 + }; template void PrepareDraw(bool is_indexed, Func&&); diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index f0b3ed4e6b..9607487a50 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -459,6 +459,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR first_next = &diagnostics_nv; } + // TODO(alekpop): impl is incomplete, needs the settings to be assigned. VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptor_indexing{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT, .pNext = use_diagnostics_nv ? static_cast(&diagnostics_nv) : static_cast(&features2), @@ -491,17 +492,20 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR CollectPhysicalMemoryInfo(); CollectToolingInfo(); + // TODO(alekpop): many things here are still applying and need to be changed to match the real behaviors. + if (is_qualcomm || is_turnip) { LOG_WARNING(Render_Vulkan, "Qualcomm and Turnip drivers have broken VK_EXT_custom_border_color"); - //RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, - //VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + RemoveExtensionFeature(extensions.custom_border_color, + features.custom_border_color, + VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); } if (is_qualcomm) { LOG_WARNING(Render_Vulkan, "Qualcomm drivers have a slow VK_KHR_push_descriptor implementation"); - //RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); #if defined(ANDROID) && defined(ARCHITECTURE_arm64) // Patch the driver to enable BCn textures. @@ -535,7 +539,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } else if (arch <= NvidiaArchitecture::Arch_Volta) { if (nv_major_version < 527) { LOG_WARNING(Render_Vulkan, "Volta and older have broken VK_KHR_push_descriptor"); - //RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); } } if (nv_major_version >= 510) { @@ -543,15 +547,16 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR cant_blit_msaa = true; } } + if (extensions.extended_dynamic_state && is_radv) { // Mask driver version variant const u32 version = (properties.properties.driverVersion << 3) >> 3; if (version < VK_MAKE_API_VERSION(0, 21, 2, 0)) { LOG_WARNING(Render_Vulkan, "RADV versions older than 21.2 have broken VK_EXT_extended_dynamic_state"); - //RemoveExtensionFeature(extensions.extended_dynamic_state, - //features.extended_dynamic_state, - //VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.extended_dynamic_state, + features.extended_dynamic_state, + VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); } } if (extensions.extended_dynamic_state2 && is_radv) { @@ -560,9 +565,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_WARNING( Render_Vulkan, "RADV versions older than 22.3.1 have broken VK_EXT_extended_dynamic_state2"); - // RemoveExtensionFeature(extensions.extended_dynamic_state2, - // features.extended_dynamic_state2, - // VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + RemoveExtensionFeature(extensions.extended_dynamic_state2, + features.extended_dynamic_state2, + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); } } if (extensions.extended_dynamic_state2 && is_qualcomm) { @@ -572,53 +577,54 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR // Qualcomm Adreno 7xx drivers do not properly support extended_dynamic_state2. LOG_WARNING(Render_Vulkan, "Qualcomm Adreno 7xx drivers have broken VK_EXT_extended_dynamic_state2"); - //RemoveExtensionFeature(extensions.extended_dynamic_state2, - //features.extended_dynamic_state2, - //VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + RemoveExtensionFeature(extensions.extended_dynamic_state2, + features.extended_dynamic_state2, + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); } } if (extensions.extended_dynamic_state3 && is_radv) { LOG_WARNING(Render_Vulkan, "RADV has broken extendedDynamicState3ColorBlendEquation"); - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = true; - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = true; - dynamic_state3_blending = true; + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; + dynamic_state3_blending = false; const u32 version = (properties.properties.driverVersion << 3) >> 3; if (version < VK_MAKE_API_VERSION(0, 23, 1, 0)) { LOG_WARNING(Render_Vulkan, "RADV versions older than 23.1.0 have broken depth clamp dynamic state"); - features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = true; - dynamic_state3_enables = true; + features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = false; + dynamic_state3_enables = false; } } if (extensions.extended_dynamic_state3 && (is_amd_driver || driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) { // AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation LOG_WARNING(Render_Vulkan, "AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation"); - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = true; - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = true; - dynamic_state3_blending = true; + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; + dynamic_state3_blending = false; } if (extensions.vertex_input_dynamic_state && is_radv) { - // TODO(ameerj): Blacklist only offending driver versions - // TODO(ameerj): Confirm if RDNA1 is affected + // TODO(alekpop): Blacklist only offending driver versions + // NOTE(alekpop): It still affects the latest RADV. + // TODO(alekpop): Confirm if RDNA1 is affected const bool is_rdna2 = supported_extensions.contains(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); if (is_rdna2) { LOG_WARNING(Render_Vulkan, "RADV has broken VK_EXT_vertex_input_dynamic_state on RDNA2 hardware"); - // RemoveExtensionFeature(extensions.vertex_input_dynamic_state, - // features.vertex_input_dynamic_state, - // VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + features.vertex_input_dynamic_state, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } } if (extensions.vertex_input_dynamic_state && is_qualcomm) { // Qualcomm drivers do not properly support vertex_input_dynamic_state. LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken VK_EXT_vertex_input_dynamic_state"); - //RemoveExtensionFeature(extensions.vertex_input_dynamic_state, - // features.vertex_input_dynamic_state, - // VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + features.vertex_input_dynamic_state, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } sets_per_pool = 64; @@ -652,9 +658,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const u32 version = (properties.properties.driverVersion << 3) >> 3; if (version < VK_MAKE_API_VERSION(27, 20, 100, 0)) { LOG_WARNING(Render_Vulkan, "Intel has broken VK_EXT_vertex_input_dynamic_state"); - //RemoveExtensionFeature(extensions.vertex_input_dynamic_state, - //features.vertex_input_dynamic_state, - //VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + features.vertex_input_dynamic_state, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } } if (features.shader_float16_int8.shaderFloat16 && is_intel_windows) { @@ -681,14 +687,14 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR // mesa/mesa/-/commit/ff91c5ca42bc80aa411cb3fd8f550aa6fdd16bdc LOG_WARNING(Render_Vulkan, "ANV drivers 22.3.0 to 23.1.0 have broken VK_KHR_push_descriptor"); - //RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); } } else if (extensions.push_descriptor && is_nvidia) { const auto arch = GetNvidiaArch(); if (arch <= NvidiaArchitecture::Arch_Pascal) { LOG_WARNING(Render_Vulkan, "Pascal and older architectures have broken VK_KHR_push_descriptor"); - //RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); } } @@ -722,33 +728,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR dynamic_state3_enables = true; } - if (Settings::values.dyna_state.GetValue() == 0) { - must_emulate_scaled_formats = true; - LOG_INFO(Render_Vulkan, "Dynamic state is disabled (dyna_state = 0), forcing scaled format emulation ON"); - - // Disable dynamic state 1-3 and all extensions - RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, - VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); - - RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, - VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); - - RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, - VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); - - RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, - VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); - - RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, - VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); - dynamic_state3_blending = false; - dynamic_state3_enables = false; - - LOG_INFO(Render_Vulkan, "All dynamic state extensions and features have been disabled"); - } else { - must_emulate_scaled_formats = false; - LOG_INFO(Render_Vulkan, "Dynamic state is enabled (dyna_state = 1-3), disabling scaled format emulation"); - } + must_emulate_scaled_formats = !Settings::values.dyna_state.GetValue(); + LOG_INFO(Render_Vulkan, "Scaled format emulation: {}", must_emulate_scaled_formats); logical = vk::Device::Create(physical, queue_cis, ExtensionListForVulkan(loaded_extensions), first_next, dld); @@ -1206,85 +1187,120 @@ void Device::RemoveUnsuitableExtensions() { RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_control, features.depth_clip_control, VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME); - /* */ // VK_EXT_extended_dynamic_state - extensions.extended_dynamic_state = features.extended_dynamic_state.extendedDynamicState; - RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state, - features.extended_dynamic_state, - VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + int dynamic_state = Settings::values.dyna_state.GetValue(); + + // VK_EXT_extended_dynamic_state + if (dynamic_state < 1) { + extensions.extended_dynamic_state = features.extended_dynamic_state.extendedDynamicState; + RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state, + features.extended_dynamic_state, + VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + } else { + RemoveExtensionFeature(extensions.extended_dynamic_state, + features.extended_dynamic_state, + VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + } // VK_EXT_extended_dynamic_state2 - extensions.extended_dynamic_state2 = features.extended_dynamic_state2.extendedDynamicState2; - RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state2, - features.extended_dynamic_state2, - VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + if (dynamic_state < 2) { + extensions.extended_dynamic_state2 = features.extended_dynamic_state2.extendedDynamicState2; + RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state2, + features.extended_dynamic_state2, + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + } else { + RemoveExtensionFeature(extensions.extended_dynamic_state2, + features.extended_dynamic_state2, + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + } // VK_EXT_extended_dynamic_state3 - dynamic_state3_blending = - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable && - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation && - features.extended_dynamic_state3.extendedDynamicState3ColorWriteMask; - dynamic_state3_enables = - features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable && - features.extended_dynamic_state3.extendedDynamicState3LogicOpEnable; - - extensions.extended_dynamic_state3 = dynamic_state3_blending || dynamic_state3_enables; - dynamic_state3_blending = dynamic_state3_blending && extensions.extended_dynamic_state3; - dynamic_state3_enables = dynamic_state3_enables && extensions.extended_dynamic_state3; - RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state3, - features.extended_dynamic_state3, - VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); + if (dynamic_state < 3) { + dynamic_state3_blending + = features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable + && features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation + && features.extended_dynamic_state3.extendedDynamicState3ColorWriteMask; + dynamic_state3_enables + = features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable + && features.extended_dynamic_state3.extendedDynamicState3LogicOpEnable; + extensions.extended_dynamic_state3 = dynamic_state3_blending || dynamic_state3_enables; + dynamic_state3_blending = dynamic_state3_blending && extensions.extended_dynamic_state3; + dynamic_state3_enables = dynamic_state3_enables && extensions.extended_dynamic_state3; + RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state3, + features.extended_dynamic_state3, + VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); + } else { + RemoveExtensionFeature(extensions.extended_dynamic_state3, + features.extended_dynamic_state3, + VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); + } // VK_EXT_provoking_vertex - extensions.provoking_vertex = - features.provoking_vertex.provokingVertexLast && - features.provoking_vertex.transformFeedbackPreservesProvokingVertex; - // RemoveExtensionFeatureIfUnsuitable(extensions.provoking_vertex, features.provoking_vertex, - // VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); + if (Settings::values.provoking_vertex.GetValue()) { + extensions.provoking_vertex = features.provoking_vertex.provokingVertexLast + && features.provoking_vertex + .transformFeedbackPreservesProvokingVertex; + RemoveExtensionFeatureIfUnsuitable(extensions.provoking_vertex, + features.provoking_vertex, + VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); + } else { + RemoveExtensionFeature(extensions.provoking_vertex, + features.provoking_vertex, + VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); + } // VK_KHR_shader_atomic_int64 - extensions.shader_atomic_int64 = features.shader_atomic_int64.shaderBufferInt64Atomics && - features.shader_atomic_int64.shaderSharedInt64Atomics; - RemoveExtensionFeatureIfUnsuitable(extensions.shader_atomic_int64, features.shader_atomic_int64, + extensions.shader_atomic_int64 = features.shader_atomic_int64.shaderBufferInt64Atomics + && features.shader_atomic_int64.shaderSharedInt64Atomics; + RemoveExtensionFeatureIfUnsuitable(extensions.shader_atomic_int64, + features.shader_atomic_int64, VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME); // VK_EXT_shader_demote_to_helper_invocation - extensions.shader_demote_to_helper_invocation = - features.shader_demote_to_helper_invocation.shaderDemoteToHelperInvocation; + extensions.shader_demote_to_helper_invocation = features.shader_demote_to_helper_invocation + .shaderDemoteToHelperInvocation; RemoveExtensionFeatureIfUnsuitable(extensions.shader_demote_to_helper_invocation, features.shader_demote_to_helper_invocation, VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME); // VK_EXT_subgroup_size_control - extensions.subgroup_size_control = - features.subgroup_size_control.subgroupSizeControl && - properties.subgroup_size_control.minSubgroupSize <= GuestWarpSize && - properties.subgroup_size_control.maxSubgroupSize >= GuestWarpSize; + extensions.subgroup_size_control = features.subgroup_size_control.subgroupSizeControl + && properties.subgroup_size_control.minSubgroupSize + <= GuestWarpSize + && properties.subgroup_size_control.maxSubgroupSize + >= GuestWarpSize; RemoveExtensionFeatureIfUnsuitable(extensions.subgroup_size_control, features.subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); // VK_EXT_transform_feedback - extensions.transform_feedback = - features.transform_feedback.transformFeedback && - features.transform_feedback.geometryStreams && - properties.transform_feedback.maxTransformFeedbackStreams >= 4 && - properties.transform_feedback.maxTransformFeedbackBuffers > 0 && - properties.transform_feedback.transformFeedbackQueries && - properties.transform_feedback.transformFeedbackDraw; - RemoveExtensionFeatureIfUnsuitable(extensions.transform_feedback, features.transform_feedback, + extensions.transform_feedback = features.transform_feedback.transformFeedback + && features.transform_feedback.geometryStreams + && properties.transform_feedback.maxTransformFeedbackStreams + >= 4 + && properties.transform_feedback.maxTransformFeedbackBuffers > 0 + && properties.transform_feedback.transformFeedbackQueries + && properties.transform_feedback.transformFeedbackDraw; + RemoveExtensionFeatureIfUnsuitable(extensions.transform_feedback, + features.transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME); // VK_EXT_vertex_input_dynamic_state - extensions.vertex_input_dynamic_state = - features.vertex_input_dynamic_state.vertexInputDynamicState; - //RemoveExtensionFeatureIfUnsuitable(extensions.vertex_input_dynamic_state, - //features.vertex_input_dynamic_state, - //VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + if (Settings::values.vertex_input.GetValue()) { + extensions.vertex_input_dynamic_state = features.vertex_input_dynamic_state + .vertexInputDynamicState; + RemoveExtensionFeatureIfUnsuitable(extensions.vertex_input_dynamic_state, + features.vertex_input_dynamic_state, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + } else { + RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + features.vertex_input_dynamic_state, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + } // VK_KHR_pipeline_executable_properties if (Settings::values.renderer_shader_feedback.GetValue()) { - extensions.pipeline_executable_properties = - features.pipeline_executable_properties.pipelineExecutableInfo; + extensions.pipeline_executable_properties = features.pipeline_executable_properties + .pipelineExecutableInfo; RemoveExtensionFeatureIfUnsuitable(extensions.pipeline_executable_properties, features.pipeline_executable_properties, VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME); @@ -1295,12 +1311,12 @@ void Device::RemoveUnsuitableExtensions() { } // VK_KHR_workgroup_memory_explicit_layout - extensions.workgroup_memory_explicit_layout = - features.features.shaderInt16 && - features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayout && - features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayout8BitAccess && - features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayout16BitAccess && - features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayoutScalarBlockLayout; + extensions.workgroup_memory_explicit_layout + = features.features.shaderInt16 + && features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayout + && features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayout8BitAccess + && features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayout16BitAccess + && features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayoutScalarBlockLayout; RemoveExtensionFeatureIfUnsuitable(extensions.workgroup_memory_explicit_layout, features.workgroup_memory_explicit_layout, VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME); diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index ddc9451a7e..01d0eb52f7 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -39,27 +39,35 @@ VK_DEFINE_HANDLE(VmaAllocator) FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control) // Define all features which may be used by the implementation and require an extension here. -#define FOR_EACH_VK_FEATURE_EXT(FEATURE) \ - FEATURE(EXT, CustomBorderColor, CUSTOM_BORDER_COLOR, custom_border_color) \ - FEATURE(EXT, DepthBiasControl, DEPTH_BIAS_CONTROL, depth_bias_control) \ - FEATURE(EXT, DepthClipControl, DEPTH_CLIP_CONTROL, depth_clip_control) \ - FEATURE(EXT, ExtendedDynamicState, EXTENDED_DYNAMIC_STATE, extended_dynamic_state) \ - FEATURE(EXT, ExtendedDynamicState2, EXTENDED_DYNAMIC_STATE_2, extended_dynamic_state2) \ - FEATURE(EXT, ExtendedDynamicState3, EXTENDED_DYNAMIC_STATE_3, extended_dynamic_state3) \ - FEATURE(EXT, 4444Formats, 4444_FORMATS, format_a4b4g4r4) \ - FEATURE(EXT, IndexTypeUint8, INDEX_TYPE_UINT8, index_type_uint8) \ - FEATURE(EXT, LineRasterization, LINE_RASTERIZATION, line_rasterization) \ - FEATURE(EXT, PrimitiveTopologyListRestart, PRIMITIVE_TOPOLOGY_LIST_RESTART, \ - primitive_topology_list_restart) \ - FEATURE(EXT, ProvokingVertex, PROVOKING_VERTEX, provoking_vertex) \ - FEATURE(EXT, Robustness2, ROBUSTNESS_2, robustness2) \ - FEATURE(EXT, TransformFeedback, TRANSFORM_FEEDBACK, transform_feedback) \ - FEATURE(EXT, VertexInputDynamicState, VERTEX_INPUT_DYNAMIC_STATE, vertex_input_dynamic_state) \ - FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \ - pipeline_executable_properties) \ - FEATURE(KHR, WorkgroupMemoryExplicitLayout, WORKGROUP_MEMORY_EXPLICIT_LAYOUT, \ +#define FOR_EACH_VK_FEATURE_EXT(FEATURE) \ + FEATURE(EXT, CustomBorderColor, CUSTOM_BORDER_COLOR, custom_border_color) \ + FEATURE(EXT, DepthBiasControl, DEPTH_BIAS_CONTROL, depth_bias_control) \ + FEATURE(EXT, DepthClipControl, DEPTH_CLIP_CONTROL, depth_clip_control) \ + FEATURE(EXT, ExtendedDynamicState, EXTENDED_DYNAMIC_STATE, extended_dynamic_state) \ + FEATURE(EXT, ExtendedDynamicState2, EXTENDED_DYNAMIC_STATE_2, extended_dynamic_state2) \ + FEATURE(EXT, ExtendedDynamicState3, EXTENDED_DYNAMIC_STATE_3, extended_dynamic_state3) \ + FEATURE(EXT, 4444Formats, 4444_FORMATS, format_a4b4g4r4) \ + FEATURE(EXT, IndexTypeUint8, INDEX_TYPE_UINT8, index_type_uint8) \ + FEATURE(EXT, LineRasterization, LINE_RASTERIZATION, line_rasterization) \ + FEATURE(EXT, \ + PrimitiveTopologyListRestart, \ + PRIMITIVE_TOPOLOGY_LIST_RESTART, \ + primitive_topology_list_restart) \ + FEATURE(EXT, ProvokingVertex, PROVOKING_VERTEX, provoking_vertex) \ + FEATURE(EXT, Robustness2, ROBUSTNESS_2, robustness2) \ + FEATURE(EXT, TransformFeedback, TRANSFORM_FEEDBACK, transform_feedback) \ + FEATURE(EXT, VertexInputDynamicState, VERTEX_INPUT_DYNAMIC_STATE, vertex_input_dynamic_state) \ + FEATURE(KHR, \ + PipelineExecutableProperties, \ + PIPELINE_EXECUTABLE_PROPERTIES, \ + pipeline_executable_properties) \ + FEATURE(KHR, \ + WorkgroupMemoryExplicitLayout, \ + WORKGROUP_MEMORY_EXPLICIT_LAYOUT, \ workgroup_memory_explicit_layout) +// TODO(alekpop): descriptor index is incomplete and needs fix. + // Define miscellaneous extensions which may be used by the implementation here. #define FOR_EACH_VK_EXTENSION(EXTENSION) \ EXTENSION(EXT, CONDITIONAL_RENDERING, conditional_rendering) \ @@ -149,24 +157,24 @@ VK_DEFINE_HANDLE(VmaAllocator) FEATURE_NAME(variable_pointer, variablePointersStorageBuffer) // Define features where the absence of the feature may result in a degraded experience. -#define FOR_EACH_VK_RECOMMENDED_FEATURE(FEATURE_NAME) \ - FEATURE_NAME(custom_border_color, customBorderColors) \ - FEATURE_NAME(depth_bias_control, depthBiasControl) \ - FEATURE_NAME(depth_bias_control, leastRepresentableValueForceUnormRepresentation) \ - FEATURE_NAME(depth_bias_control, depthBiasExact) \ - FEATURE_NAME(extended_dynamic_state, extendedDynamicState) \ - FEATURE_NAME(format_a4b4g4r4, formatA4B4G4R4) \ - FEATURE_NAME(index_type_uint8, indexTypeUint8) \ - FEATURE_NAME(primitive_topology_list_restart, primitiveTopologyListRestart) \ - FEATURE_NAME(provoking_vertex, provokingVertexLast) \ - FEATURE_NAME(robustness2, nullDescriptor) \ - FEATURE_NAME(robustness2, robustBufferAccess2) \ - FEATURE_NAME(robustness2, robustImageAccess2) \ - FEATURE_NAME(shader_float16_int8, shaderFloat16) \ - FEATURE_NAME(shader_float16_int8, shaderInt8) \ - FEATURE_NAME(timeline_semaphore, timelineSemaphore) \ - FEATURE_NAME(transform_feedback, transformFeedback) \ - FEATURE_NAME(uniform_buffer_standard_layout, uniformBufferStandardLayout) \ +#define FOR_EACH_VK_RECOMMENDED_FEATURE(FEATURE_NAME) \ + FEATURE_NAME(custom_border_color, customBorderColors) \ + FEATURE_NAME(depth_bias_control, depthBiasControl) \ + FEATURE_NAME(depth_bias_control, leastRepresentableValueForceUnormRepresentation) \ + FEATURE_NAME(depth_bias_control, depthBiasExact) \ + FEATURE_NAME(extended_dynamic_state, extendedDynamicState) \ + FEATURE_NAME(format_a4b4g4r4, formatA4B4G4R4) \ + FEATURE_NAME(index_type_uint8, indexTypeUint8) \ + FEATURE_NAME(primitive_topology_list_restart, primitiveTopologyListRestart) \ + FEATURE_NAME(provoking_vertex, provokingVertexLast) \ + FEATURE_NAME(robustness2, nullDescriptor) \ + FEATURE_NAME(robustness2, robustBufferAccess2) \ + FEATURE_NAME(robustness2, robustImageAccess2) \ + FEATURE_NAME(shader_float16_int8, shaderFloat16) \ + FEATURE_NAME(shader_float16_int8, shaderInt8) \ + FEATURE_NAME(timeline_semaphore, timelineSemaphore) \ + FEATURE_NAME(transform_feedback, transformFeedback) \ + FEATURE_NAME(uniform_buffer_standard_layout, uniformBufferStandardLayout) \ FEATURE_NAME(vertex_input_dynamic_state, vertexInputDynamicState) namespace Vulkan { diff --git a/src/yuzu/configuration/configure_graphics_extensions.cpp b/src/yuzu/configuration/configure_graphics_extensions.cpp index 51c7a6cdea..6ac7948288 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.cpp +++ b/src/yuzu/configuration/configure_graphics_extensions.cpp @@ -30,12 +30,11 @@ ConfigureGraphicsExtensions::~ConfigureGraphicsExtensions() = default; void ConfigureGraphicsExtensions::SetConfiguration() {} -void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& builder) { +void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& builder) +{ auto& layout = *ui->populate_target->layout(); std::map hold{}; // A map will sort the data for us - QSlider *dyna_state = nullptr; - QCheckBox *dyna_state3 = nullptr; for (auto setting : Settings::values.linkage.by_category[Settings::Category::RendererExtensions]) { ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs); @@ -53,22 +52,14 @@ void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& buil if (setting->Id() == Settings::values.dyna_state.Id()) { widget->slider->setTickInterval(1); widget->slider->setTickPosition(QSlider::TicksAbove); - dyna_state = widget->slider; - } else if (setting->Id() == Settings::values.dyna_state3.Id()) { - dyna_state3 = widget->checkbox; + } else if (setting->Id() == Settings::values.vertex_input.Id()) { + // widget->checkbox->setDisabled(true); } } for (const auto& [id, widget] : hold) { layout.addWidget(widget); } - - connect(dyna_state, &QSlider::sliderMoved, this, [dyna_state3](int value) { - dyna_state3->setEnabled(value == 2); - if (value < 2) { - dyna_state3->setChecked(false); - } - }); } void ConfigureGraphicsExtensions::ApplyConfiguration() { diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index 02bb9a322f..ead67a46d0 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -27,31 +27,30 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { // A setting can be ignored by giving it a blank name // Applets - INSERT(Settings, cabinet_applet_mode, tr("Amiibo editor"), QStringLiteral()); - INSERT(Settings, controller_applet_mode, tr("Controller configuration"), QStringLiteral()); - INSERT(Settings, data_erase_applet_mode, tr("Data erase"), QStringLiteral()); - INSERT(Settings, error_applet_mode, tr("Error"), QStringLiteral()); - INSERT(Settings, net_connect_applet_mode, tr("Net connect"), QStringLiteral()); - INSERT(Settings, player_select_applet_mode, tr("Player select"), QStringLiteral()); - INSERT(Settings, swkbd_applet_mode, tr("Software keyboard"), QStringLiteral()); - INSERT(Settings, mii_edit_applet_mode, tr("Mii Edit"), QStringLiteral()); - INSERT(Settings, web_applet_mode, tr("Online web"), QStringLiteral()); - INSERT(Settings, shop_applet_mode, tr("Shop"), QStringLiteral()); - INSERT(Settings, photo_viewer_applet_mode, tr("Photo viewer"), QStringLiteral()); - INSERT(Settings, offline_web_applet_mode, tr("Offline web"), QStringLiteral()); - INSERT(Settings, login_share_applet_mode, tr("Login share"), QStringLiteral()); - INSERT(Settings, wifi_web_auth_applet_mode, tr("Wifi web auth"), QStringLiteral()); - INSERT(Settings, my_page_applet_mode, tr("My page"), QStringLiteral()); + INSERT(Settings, cabinet_applet_mode, tr("Amiibo editor"), QString()); + INSERT(Settings, controller_applet_mode, tr("Controller configuration"), QString()); + INSERT(Settings, data_erase_applet_mode, tr("Data erase"), QString()); + INSERT(Settings, error_applet_mode, tr("Error"), QString()); + INSERT(Settings, net_connect_applet_mode, tr("Net connect"), QString()); + INSERT(Settings, player_select_applet_mode, tr("Player select"), QString()); + INSERT(Settings, swkbd_applet_mode, tr("Software keyboard"), QString()); + INSERT(Settings, mii_edit_applet_mode, tr("Mii Edit"), QString()); + INSERT(Settings, web_applet_mode, tr("Online web"), QString()); + INSERT(Settings, shop_applet_mode, tr("Shop"), QString()); + INSERT(Settings, photo_viewer_applet_mode, tr("Photo viewer"), QString()); + INSERT(Settings, offline_web_applet_mode, tr("Offline web"), QString()); + INSERT(Settings, login_share_applet_mode, tr("Login share"), QString()); + INSERT(Settings, wifi_web_auth_applet_mode, tr("Wifi web auth"), QString()); + INSERT(Settings, my_page_applet_mode, tr("My page"), QString()); // Audio - INSERT(Settings, sink_id, tr("Output Engine:"), QStringLiteral()); - INSERT(Settings, audio_output_device_id, tr("Output Device:"), QStringLiteral()); - INSERT(Settings, audio_input_device_id, tr("Input Device:"), QStringLiteral()); - INSERT(Settings, audio_muted, tr("Mute audio"), QStringLiteral()); - INSERT(Settings, volume, tr("Volume:"), QStringLiteral()); - INSERT(Settings, dump_audio_commands, QStringLiteral(), QStringLiteral()); - INSERT(UISettings, mute_when_in_background, tr("Mute audio when in background"), - QStringLiteral()); + INSERT(Settings, sink_id, tr("Output Engine:"), QString()); + INSERT(Settings, audio_output_device_id, tr("Output Device:"), QString()); + INSERT(Settings, audio_input_device_id, tr("Input Device:"), QString()); + INSERT(Settings, audio_muted, tr("Mute audio"), QString()); + INSERT(Settings, volume, tr("Volume:"), QString()); + INSERT(Settings, dump_audio_commands, QString(), QString()); + INSERT(UISettings, mute_when_in_background, tr("Mute audio when in background"), QString()); // Core INSERT( @@ -65,7 +64,7 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { "to let big texture mods fit in emulated RAM.\nEnabling it will increase memory " "use. It is not recommended to enable unless a specific game with a texture mod needs " "it.")); - INSERT(Settings, use_speed_limit, QStringLiteral(), QStringLiteral()); + INSERT(Settings, use_speed_limit, QString(), QString()); INSERT(Settings, speed_limit, tr("Limit Speed Percent"), tr("Controls the game's maximum rendering speed, but it’s up to each game if it runs " "faster or not.\n200% for a 30 FPS game is 60 FPS, and for a " @@ -80,7 +79,7 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { INSERT(Settings, cpu_accuracy, tr("Accuracy:"), tr("This setting controls the accuracy of the emulated CPU.\nDon't change this unless " "you know what you are doing.")); - INSERT(Settings, cpu_backend, tr("Backend:"), QStringLiteral()); + INSERT(Settings, cpu_backend, tr("Backend:"), QString()); // Cpu Debug @@ -127,7 +126,7 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { tr("Forces the game to render at a different resolution.\nHigher resolutions require " "much more VRAM and bandwidth.\n" "Options lower than 1X can cause rendering issues.")); - INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QStringLiteral()); + INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QString()); INSERT(Settings, fsr_sharpening_slider, tr("FSR Sharpness:"), tr("Determines how sharpened the image will look while using FSR’s dynamic contrast.")); INSERT(Settings, anti_aliasing, tr("Anti-Aliasing Method:"), @@ -184,9 +183,9 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { "a slow down.\nMailbox can have lower latency than FIFO and does not tear but may drop " "frames.\nImmediate (no synchronization) just presents whatever is available and can " "exhibit tearing.")); - INSERT(Settings, bg_red, QStringLiteral(), QStringLiteral()); - INSERT(Settings, bg_green, QStringLiteral(), QStringLiteral()); - INSERT(Settings, bg_blue, QStringLiteral(), QStringLiteral()); + INSERT(Settings, bg_red, QString(), QString()); + INSERT(Settings, bg_green, QString(), QString()); + INSERT(Settings, bg_blue, QString(), QString()); // Renderer (Advanced Graphics) INSERT(Settings, async_presentation, tr("Enable asynchronous presentation (Vulkan only)"), @@ -235,17 +234,23 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { tr("Enables the VkExtendedDynamicState* extensions.\nHigher dynamic states will generally improve " "performance, but may cause issues on certain games or devices.")); - INSERT(Settings, dyna_state3, tr("EDS3 + Vertex Input"), - tr("Enables the VkExtendedDynamicState3 and VkVertexInputDynamicState extensions.\n" - "Only Vulkan 1.3+ devices support these extensions, and will generally see improved performance.")); + INSERT(Settings, + vertex_input, + tr("VertexInputDynamicState"), + tr("Enables the VkVertexInputDynamicState extension.\n" + "Only Vulkan 1.3+ devices support this extension, and will generally see improved " + "performance.")); INSERT(Settings, provoking_vertex, tr("Provoking Vertex"), tr("Improves lighting and vertex handling in certain games.\n" "Only Vulkan 1.0+ devices support this extension.")); - INSERT(Settings, descriptor_indexing, tr("Descriptor Indexing"), + INSERT(Settings, + descriptor_indexing, + tr("Descriptor Indexing"), tr("Improves texture & buffer handling and the Maxwell translation layer.\n" - "Some Vulkan 1.1+ and all 1.2+ devices support this extension.")); + "Some Vulkan 1.1+ and all 1.2+ devices support this extension.\n" + "This extension is incomplete. Use with caution.")); // Renderer (Debug) @@ -253,12 +258,12 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { INSERT(Settings, rng_seed, tr("RNG Seed"), tr("Controls the seed of the random number generator.\nMainly used for speedrunning " "purposes.")); - INSERT(Settings, rng_seed_enabled, QStringLiteral(), QStringLiteral()); + INSERT(Settings, rng_seed_enabled, QString(), QString()); INSERT(Settings, device_name, tr("Device Name"), tr("The name of the emulated Switch.")); INSERT(Settings, custom_rtc, tr("Custom RTC Date:"), tr("This option allows to change the emulated clock of the Switch.\n" "Can be used to manipulate time in games.")); - INSERT(Settings, custom_rtc_enabled, QStringLiteral(), QStringLiteral()); + INSERT(Settings, custom_rtc_enabled, QString(), QString()); INSERT(Settings, custom_rtc_offset, QStringLiteral(" "), QStringLiteral("The number of seconds from the current unix time")); INSERT(Settings, language_index, tr("Language:"), @@ -266,12 +271,12 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { INSERT(Settings, region_index, tr("Region:"), tr("The region of the emulated Switch.")); INSERT(Settings, time_zone_index, tr("Time Zone:"), tr("The time zone of the emulated Switch.")); - INSERT(Settings, sound_index, tr("Sound Output Mode:"), QStringLiteral()); + INSERT(Settings, sound_index, tr("Sound Output Mode:"), QString()); INSERT(Settings, use_docked_mode, tr("Console Mode:"), tr("Selects if the console is emulated in Docked or Handheld mode.\nGames will change " "their resolution, details and supported controllers and depending on this setting.\n" "Setting to Handheld can help improve performance for low end systems.")); - INSERT(Settings, current_user, QStringLiteral(), QStringLiteral()); + INSERT(Settings, current_user, QString(), QString()); // Controls @@ -303,7 +308,7 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { "attempts to open the controller applet, it is immediately closed.")); // Linux - INSERT(Settings, enable_gamemode, tr("Enable Gamemode"), QStringLiteral()); + INSERT(Settings, enable_gamemode, tr("Enable Gamemode"), QString()); // Ui Debugging diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp index 688f2ec9b6..c27a4644e9 100644 --- a/src/yuzu/configuration/shared_widget.cpp +++ b/src/yuzu/configuration/shared_widget.cpp @@ -71,7 +71,7 @@ QPushButton* Widget::CreateRestoreGlobalButton(bool using_global, QWidget* paren QStyle* style = parent->style(); QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_LineEditClearButton)); - QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(), parent); + QPushButton* restore_button = new QPushButton(*icon, QString(), parent); restore_button->setObjectName(QStringLiteral("RestoreButton%1").arg(restore_button_count)); restore_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -731,10 +731,10 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati return std::pair{translations.at(id).first, translations.at(id).second}; } LOG_WARNING(Frontend, "Translation table lacks entry for \"{}\"", setting_label); - return std::pair{QString::fromStdString(setting_label), QStringLiteral()}; + return std::pair{QString::fromStdString(setting_label), QString()}; }(); - if (label == QStringLiteral()) { + if (label == QString()) { LOG_DEBUG(Frontend, "Translation table has empty entry for \"{}\", skipping...", setting.GetLabel()); return; diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h index 226284cf36..5c67d83542 100644 --- a/src/yuzu/configuration/shared_widget.h +++ b/src/yuzu/configuration/shared_widget.h @@ -46,7 +46,7 @@ enum class RequestType { constexpr float default_multiplier{1.f}; constexpr float default_float_multiplier{100.f}; -static const QString default_suffix = QStringLiteral(); +static const QString default_suffix = QString(); class Widget : public QWidget { Q_OBJECT From ce5d5d2aff50f9ce8159d609824eb2391bed9ef2 Mon Sep 17 00:00:00 2001 From: MrPurple666 Date: Sun, 18 May 2025 17:45:32 +0000 Subject: [PATCH 7/9] THIS NEEDS TO BE CHECKED BEFORE MERGE: RAII fix, initial MSAA, some fixes for memory misallocation (#116) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • MSAA Fixes: Fixes upload/download for MSAA textures using temporary non-MSAA images. Ensures compatibility with color formats and adds fallbacks for depth/stencil. • Memory fix misallocation: Adds checks for null/zero-length operations in memory management and improves cleanup to avoid crashes (Related to crash issues due to misallocation, RP5 and 865) • Vulkan Initialization (RAII): this almost rewrites the way vulkan initializes to avoid crashes, using a correct order now (thanks @crueter for the initial fix) •Please check before merging: - Test MSAA workflows (especially color/depth transitions and low memory cases). - Verify memory operations (e.g., unmapping zero-length regions). - Check Vulkan object lifetimes and platform-specific behavior. - Check others plataforms beyond android Why is everything in one PR? Otherwise, this is all a big fix, by checking the points above we can create a branch for each one and check them by themselves. I'm not standing still while I'm away, I'm just out of time for now. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/116 Co-authored-by: MrPurple666 Co-committed-by: MrPurple666 --- src/common/free_region_manager.h | 15 + src/common/host_memory.cpp | 31 +- .../renderer_vulkan/renderer_vulkan.cpp | 48 +-- .../renderer_vulkan/renderer_vulkan.h | 27 +- .../renderer_vulkan/vk_texture_cache.cpp | 310 +++++++++++++----- .../renderer_vulkan/vk_texture_cache.h | 3 +- 6 files changed, 314 insertions(+), 120 deletions(-) diff --git a/src/common/free_region_manager.h b/src/common/free_region_manager.h index 2e590d6094..2ff629b359 100644 --- a/src/common/free_region_manager.h +++ b/src/common/free_region_manager.h @@ -12,12 +12,22 @@ class FreeRegionManager { public: explicit FreeRegionManager() = default; ~FreeRegionManager() = default; + + // Clear all free regions + void Clear() { + std::scoped_lock lk(m_mutex); + m_free_regions.clear(); + } void SetAddressSpace(void* start, size_t size) { this->FreeBlock(start, size); } std::pair FreeBlock(void* block_ptr, size_t size) { + if (block_ptr == nullptr || size == 0) { + return {nullptr, 0}; + } + std::scoped_lock lk(m_mutex); // Check to see if we are adjacent to any regions. @@ -41,6 +51,11 @@ public: } void AllocateBlock(void* block_ptr, size_t size) { + // Skip if pointer is null or size is zero + if (block_ptr == nullptr || size == 0) { + return; + } + std::scoped_lock lk(m_mutex); auto address = reinterpret_cast(block_ptr); diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index e0b5a6a67c..d06522ec2c 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -491,6 +491,12 @@ public: // Intersect the range with our address space. AdjustMap(&virtual_offset, &length); + // Skip if length is zero after adjustment + if (length == 0) { + LOG_DEBUG(HW_Memory, "Skipping zero-length mapping at virtual_offset={}", virtual_offset); + return; + } + // We are removing a placeholder. free_manager.AllocateBlock(virtual_base + virtual_offset, length); @@ -520,13 +526,21 @@ public: // Intersect the range with our address space. AdjustMap(&virtual_offset, &length); + // Skip if length is zero after adjustment + if (length == 0) { + return; + } + // Merge with any adjacent placeholder mappings. auto [merged_pointer, merged_size] = free_manager.FreeBlock(virtual_base + virtual_offset, length); - void* ret = mmap(merged_pointer, merged_size, PROT_NONE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); - ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); + // Only attempt to mmap if we have a valid pointer and size + if (merged_pointer != nullptr && merged_size > 0) { + void* ret = mmap(merged_pointer, merged_size, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); + } } void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute) { @@ -576,19 +590,26 @@ public: private: /// Release all resources in the object void Release() { + // Make sure we release resources in the correct order + // First clear the free region manager to avoid any dangling references + free_manager.Clear(); + if (virtual_map_base != MAP_FAILED) { int ret = munmap(virtual_map_base, virtual_size); ASSERT_MSG(ret == 0, "munmap failed: {}", strerror(errno)); + virtual_map_base = reinterpret_cast(MAP_FAILED); } if (backing_base != MAP_FAILED) { int ret = munmap(backing_base, backing_size); ASSERT_MSG(ret == 0, "munmap failed: {}", strerror(errno)); + backing_base = reinterpret_cast(MAP_FAILED); } if (fd != -1) { int ret = close(fd); ASSERT_MSG(ret == 0, "close failed: {}", strerror(errno)); + fd = -1; } } @@ -686,8 +707,10 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length, ASSERT(virtual_offset + length <= virtual_size); ASSERT(host_offset + length <= backing_size); if (length == 0 || !virtual_base || !impl) { + LOG_ERROR(HW_Memory, "Invalid mapping operation: virtual_base or impl is null"); return; } + LOG_INFO(HW_Memory, "Mapping memory: virtual_offset={}, host_offset={}, length={}", virtual_offset, host_offset, length); impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms); } @@ -696,8 +719,10 @@ void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap) ASSERT(length % PageAlignment == 0); ASSERT(virtual_offset + length <= virtual_size); if (length == 0 || !virtual_base || !impl) { + LOG_ERROR(HW_Memory, "Invalid unmapping operation: virtual_base or impl is null"); return; } + LOG_INFO(HW_Memory, "Unmapping memory: virtual_offset={}, length={}", virtual_offset, length); impl->Unmap(virtual_offset + virtual_base_offset, length); } diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 30f5ff7a75..f5b73d63ef 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -110,27 +110,16 @@ try , device_memory(device_memory_) , gpu(gpu_) , library(OpenLibrary(context.get())) - , - // Create raw Vulkan instance first - instance(CreateInstance(*library, - dld, - VK_API_VERSION_1_1, - render_window.GetWindowInfo().type, - Settings::values.renderer_debug.GetValue())) - , - // Now create RAII wrappers for the resources in the correct order - managed_instance(MakeManagedInstance(instance, dld)) - , - // Create debug messenger if debug is enabled - debug_messenger(Settings::values.renderer_debug ? CreateDebugUtilsCallback(instance) - : vk::DebugUtilsMessenger{}) - , managed_debug_messenger(Settings::values.renderer_debug - ? MakeManagedDebugUtilsMessenger(debug_messenger, instance, dld) - : ManagedDebugUtilsMessenger{}) - , - // Create surface - surface(CreateSurface(instance, render_window.GetWindowInfo())) - , managed_surface(MakeManagedSurface(surface, instance, dld)) + , dld() + // Initialize resources in the same order as they are declared in the header + , instance(CreateInstance(*library, + dld, + VK_API_VERSION_1_1, + render_window.GetWindowInfo().type, + Settings::values.renderer_debug.GetValue())) + , debug_messenger(Settings::values.renderer_debug ? CreateDebugUtilsCallback(instance) + : vk::DebugUtilsMessenger{}) + , surface(CreateSurface(instance, render_window.GetWindowInfo())) , device(CreateDevice(instance, dld, *surface)) , memory_allocator(device) , state_tracker() @@ -172,22 +161,19 @@ try scheduler, PresentFiltersForAppletCapture) , rasterizer(render_window, gpu, device_memory, device, memory_allocator, state_tracker, scheduler) - , applet_frame() { + , turbo_mode() + , applet_frame() + , managed_instance(MakeManagedInstance(instance, dld)) + , managed_debug_messenger(Settings::values.renderer_debug + ? MakeManagedDebugUtilsMessenger(debug_messenger, instance, dld) + : ManagedDebugUtilsMessenger{}) + , managed_surface(MakeManagedSurface(surface, instance, dld)) { if (Settings::values.renderer_force_max_clock.GetValue() && device.ShouldBoostClocks()) { turbo_mode.emplace(instance, dld); scheduler.RegisterOnSubmit([this] { turbo_mode->QueueSubmitted(); }); } -#ifndef ANDROID - // Release ownership from the old instance and surface - instance.release(); - surface.release(); - if (Settings::values.renderer_debug) { - debug_messenger.release(); - } -#endif - Report(); } catch (const vk::Exception& exception) { LOG_ERROR(Render_Vulkan, "Vulkan initialization failed with error: {}", exception.what()); diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index c1e6d5db7f..ec4215253f 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -76,32 +76,37 @@ private: std::shared_ptr library; vk::InstanceDispatch dld; - // Keep original handles for compatibility with existing code + // Order of member variables determines destruction order (reverse of declaration) + // Critical Vulkan resources should be declared in proper dependency order + + // Base Vulkan instance, debugging, and surface vk::Instance instance; - // RAII wrapper for instance - ManagedInstance managed_instance; - vk::DebugUtilsMessenger debug_messenger; - // RAII wrapper for debug messenger - ManagedDebugUtilsMessenger managed_debug_messenger; - vk::SurfaceKHR surface; - // RAII wrapper for surface - ManagedSurface managed_surface; - + + // Device and core resources Device device; MemoryAllocator memory_allocator; StateTracker state_tracker; Scheduler scheduler; Swapchain swapchain; PresentManager present_manager; + + // Rendering components BlitScreen blit_swapchain; BlitScreen blit_capture; BlitScreen blit_applet; RasterizerVulkan rasterizer; - std::optional turbo_mode; + // Optional components + std::optional turbo_mode; Frame applet_frame; + + // RAII wrappers - must be destroyed before their raw handles + // so they are declared after to be destroyed first + ManagedInstance managed_instance; + ManagedDebugUtilsMessenger managed_debug_messenger; + ManagedSurface managed_surface; }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 0b98d71b97..ebd8b65760 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1523,22 +1523,76 @@ Image::Image(const VideoCommon::NullImageParams& params) : VideoCommon::ImageBas Image::~Image() = default; void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, - std::span copies) { + std::span copies) { // TODO: Move this to another API const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); if (is_rescaled) { ScaleDown(true); } - scheduler->RequestOutsideRenderPassOperationContext(); - auto vk_copies = TransformBufferImageCopies(copies, offset, aspect_mask); - const VkBuffer src_buffer = buffer; - const VkImage vk_image = *original_image; - const VkImageAspectFlags vk_aspect_mask = aspect_mask; - const bool is_initialized = std::exchange(initialized, true); - scheduler->Record([src_buffer, vk_image, vk_aspect_mask, is_initialized, - vk_copies](vk::CommandBuffer cmdbuf) { - CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, is_initialized, vk_copies); - }); + + // Handle MSAA upload if necessary + if (info.num_samples > 1 && runtime->CanUploadMSAA()) { + // Only use MSAA copy pass for color formats + // Depth/stencil formats need special handling + if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) { + // Create a temporary non-MSAA image to upload the data first + ImageInfo temp_info = info; + temp_info.num_samples = 1; + + // Create image with same usage flags as the target image to avoid validation errors + VkImageCreateInfo image_ci = MakeImageCreateInfo(runtime->device, temp_info); + image_ci.usage = original_image.UsageFlags(); + vk::Image temp_image = runtime->memory_allocator.CreateImage(image_ci); + + // Upload to the temporary non-MSAA image + scheduler->RequestOutsideRenderPassOperationContext(); + auto vk_copies = TransformBufferImageCopies(copies, offset, aspect_mask); + const VkBuffer src_buffer = buffer; + const VkImage temp_vk_image = *temp_image; + const VkImageAspectFlags vk_aspect_mask = aspect_mask; + scheduler->Record([src_buffer, temp_vk_image, vk_aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { + CopyBufferToImage(cmdbuf, src_buffer, temp_vk_image, vk_aspect_mask, false, vk_copies); + }); + + // Now use MSAACopyPass to convert from non-MSAA to MSAA + std::vector image_copies; + for (const auto& copy : copies) { + VideoCommon::ImageCopy image_copy; + image_copy.src_offset = {0, 0, 0}; // Use zero offset for source + image_copy.dst_offset = copy.image_offset; + image_copy.src_subresource = copy.image_subresource; + image_copy.dst_subresource = copy.image_subresource; + image_copy.extent = copy.image_extent; + image_copies.push_back(image_copy); + } + + // Create a wrapper Image for the temporary image + Image temp_wrapper(*runtime, temp_info, 0, 0); + temp_wrapper.original_image = std::move(temp_image); + temp_wrapper.current_image = &Image::original_image; + temp_wrapper.aspect_mask = aspect_mask; + temp_wrapper.initialized = true; + + // Use MSAACopyPass to convert from non-MSAA to MSAA + runtime->msaa_copy_pass->CopyImage(*this, temp_wrapper, image_copies, false); + std::exchange(initialized, true); + return; + } + // For depth/stencil formats, fall back to regular upload + } else { + // Regular non-MSAA upload + scheduler->RequestOutsideRenderPassOperationContext(); + auto vk_copies = TransformBufferImageCopies(copies, offset, aspect_mask); + const VkBuffer src_buffer = buffer; + const VkImage vk_image = *original_image; + const VkImageAspectFlags vk_aspect_mask = aspect_mask; + const bool is_initialized = std::exchange(initialized, true); + scheduler->Record([src_buffer, vk_image, vk_aspect_mask, is_initialized, + vk_copies](vk::CommandBuffer cmdbuf) { + CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, is_initialized, vk_copies); + }); + } + if (is_rescaled) { ScaleUp(); } @@ -1560,75 +1614,185 @@ void Image::DownloadMemory(VkBuffer buffer, size_t offset, } void Image::DownloadMemory(std::span buffers_span, std::span offsets_span, - std::span copies) { + std::span copies) { const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); if (is_rescaled) { ScaleDown(); } - boost::container::small_vector buffers_vector{}; - boost::container::small_vector, 8> - vk_copies; - for (size_t index = 0; index < buffers_span.size(); index++) { - buffers_vector.emplace_back(buffers_span[index]); - vk_copies.emplace_back( - TransformBufferImageCopies(copies, offsets_span[index], aspect_mask)); - } - scheduler->RequestOutsideRenderPassOperationContext(); - scheduler->Record([buffers = std::move(buffers_vector), image = *original_image, - aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { - const VkImageMemoryBarrier read_barrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, - .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, - .oldLayout = VK_IMAGE_LAYOUT_GENERAL, - .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = image, - .subresourceRange{ - .aspectMask = aspect_mask_, - .baseMipLevel = 0, - .levelCount = VK_REMAINING_MIP_LEVELS, - .baseArrayLayer = 0, - .layerCount = VK_REMAINING_ARRAY_LAYERS, - }, - }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, read_barrier); - for (size_t index = 0; index < buffers.size(); index++) { - cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffers[index], - vk_copies[index]); + // Handle MSAA download if necessary + if (info.num_samples > 1 && runtime->msaa_copy_pass) { + // Only use MSAA copy pass for color formats + // Depth/stencil formats need special handling + if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) { + // Create a temporary non-MSAA image to download the data + ImageInfo temp_info = info; + temp_info.num_samples = 1; + + // Create image with same usage flags as the target image to avoid validation errors + VkImageCreateInfo image_ci = MakeImageCreateInfo(runtime->device, temp_info); + image_ci.usage = original_image.UsageFlags(); + vk::Image temp_image = runtime->memory_allocator.CreateImage(image_ci); + + // Create a wrapper Image for the temporary image + Image temp_wrapper(*runtime, temp_info, 0, 0); + temp_wrapper.original_image = std::move(temp_image); + temp_wrapper.current_image = &Image::original_image; + temp_wrapper.aspect_mask = aspect_mask; + temp_wrapper.initialized = true; + + // Convert from MSAA to non-MSAA using MSAACopyPass + std::vector image_copies; + for (const auto& copy : copies) { + VideoCommon::ImageCopy image_copy; + image_copy.src_offset = copy.image_offset; + image_copy.dst_offset = copy.image_offset; + image_copy.src_subresource = copy.image_subresource; + image_copy.dst_subresource = copy.image_subresource; + image_copy.extent = copy.image_extent; + image_copies.push_back(image_copy); + } + + // Use MSAACopyPass to convert from MSAA to non-MSAA + runtime->msaa_copy_pass->CopyImage(temp_wrapper, *this, image_copies, true); + + // Now download from the non-MSAA image + boost::container::small_vector buffers_vector{}; + boost::container::small_vector, 8> + vk_copies; + for (size_t index = 0; index < buffers_span.size(); index++) { + buffers_vector.emplace_back(buffers_span[index]); + vk_copies.emplace_back( + TransformBufferImageCopies(copies, offsets_span[index], aspect_mask)); + } + + scheduler->RequestOutsideRenderPassOperationContext(); + scheduler->Record([buffers = std::move(buffers_vector), image = *temp_wrapper.original_image, + aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { + const VkImageMemoryBarrier read_barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_GENERAL, + .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = image, + .subresourceRange{ + .aspectMask = aspect_mask_, + .baseMipLevel = 0, + .levelCount = VK_REMAINING_MIP_LEVELS, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }, + }; + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, read_barrier); + + for (size_t index = 0; index < buffers.size(); index++) { + cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffers[index], + vk_copies[index]); + } + + const VkMemoryBarrier memory_write_barrier{ + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, + .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, + }; + const VkImageMemoryBarrier image_write_barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = 0, + .dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = image, + .subresourceRange{ + .aspectMask = aspect_mask_, + .baseMipLevel = 0, + .levelCount = VK_REMAINING_MIP_LEVELS, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }, + }; + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + 0, memory_write_barrier, nullptr, image_write_barrier); + }); + return; } + // For depth/stencil formats, fall back to regular download + } else { + // Regular non-MSAA download + boost::container::small_vector buffers_vector{}; + boost::container::small_vector, 8> + vk_copies; + for (size_t index = 0; index < buffers_span.size(); index++) { + buffers_vector.emplace_back(buffers_span[index]); + vk_copies.emplace_back( + TransformBufferImageCopies(copies, offsets_span[index], aspect_mask)); + } + scheduler->RequestOutsideRenderPassOperationContext(); + scheduler->Record([buffers = std::move(buffers_vector), image = *original_image, + aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) { + const VkImageMemoryBarrier read_barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_GENERAL, + .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = image, + .subresourceRange{ + .aspectMask = aspect_mask_, + .baseMipLevel = 0, + .levelCount = VK_REMAINING_MIP_LEVELS, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }, + }; + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, read_barrier); + + for (size_t index = 0; index < buffers.size(); index++) { + cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffers[index], + vk_copies[index]); + } + + const VkMemoryBarrier memory_write_barrier{ + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, + .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, + }; + const VkImageMemoryBarrier image_write_barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = 0, + .dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = image, + .subresourceRange{ + .aspectMask = aspect_mask_, + .baseMipLevel = 0, + .levelCount = VK_REMAINING_MIP_LEVELS, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }, + }; + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + 0, memory_write_barrier, nullptr, image_write_barrier); + }); + } - const VkMemoryBarrier memory_write_barrier{ - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, - .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, - }; - const VkImageMemoryBarrier image_write_barrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = image, - .subresourceRange{ - .aspectMask = aspect_mask_, - .baseMipLevel = 0, - .levelCount = VK_REMAINING_MIP_LEVELS, - .baseArrayLayer = 0, - .layerCount = VK_REMAINING_ARRAY_LAYERS, - }, - }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - 0, memory_write_barrier, nullptr, image_write_barrier); - }); if (is_rescaled) { ScaleUp(true); } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 18d20b2db5..cd11cc8fc7 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -82,8 +82,7 @@ public: } bool CanUploadMSAA() const noexcept { - // TODO: Implement buffer to MSAA uploads - return false; + return msaa_copy_pass.operator bool(); } void AccelerateImageUpload(Image&, const StagingBufferRef&, From cda9f32b165ba0c4035a14a4602f3a39cb247565 Mon Sep 17 00:00:00 2001 From: Aleksandr Popovich Date: Sun, 18 May 2025 17:47:54 +0000 Subject: [PATCH 8/9] added qlaunch shortcut and command line option. (#112) Signed-off-by: Aleksandr Popovich Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/112 Co-authored-by: Aleksandr Popovich Co-committed-by: Aleksandr Popovich --- src/yuzu/main.cpp | 181 +++++++++++++++++++++++++++++++++++++++++++--- src/yuzu/main.h | 4 + src/yuzu/main.ui | 27 +++++++ 3 files changed, 200 insertions(+), 12 deletions(-) diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 497c519f74..450d340580 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -481,6 +481,8 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) } QString game_path; + bool should_launch_qlaunch = false; + bool should_launch_setup = false; bool has_gamepath = false; bool is_fullscreen = false; @@ -549,6 +551,11 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) game_path = args[++i]; has_gamepath = true; } + + if (args[i] == QStringLiteral("-qlaunch")) + should_launch_qlaunch = true; + if (args[i] == QStringLiteral("-setup")) + should_launch_setup = true; } // Override fullscreen setting if gamepath or argument is provided @@ -556,8 +563,16 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) ui->action_Fullscreen->setChecked(is_fullscreen); } - if (!game_path.isEmpty()) { - BootGame(game_path, ApplicationAppletParameters()); + if (should_launch_setup) { + OnInitialSetup(); + } else { + if (!game_path.isEmpty()) { + BootGame(game_path, ApplicationAppletParameters()); + } else { + if (should_launch_qlaunch) { + OnHomeMenu(); + } + } } } @@ -1582,6 +1597,9 @@ void GMainWindow::ConnectMenuEvents() { connect_menu(ui->action_Load_Mii_Edit, &GMainWindow::OnMiiEdit); connect_menu(ui->action_Open_Controller_Menu, &GMainWindow::OnOpenControllerMenu); connect_menu(ui->action_Load_Home_Menu, &GMainWindow::OnHomeMenu); + connect_menu(ui->action_Open_Setup, &GMainWindow::OnInitialSetup); + connect_menu(ui->action_Desktop, &GMainWindow::OnCreateHomeMenuDesktopShortcut); + connect_menu(ui->action_Application_Menu, &GMainWindow::OnCreateHomeMenuApplicationMenuShortcut); connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot); // TAS @@ -1826,18 +1844,18 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa switch (role) { - case QMessageBox::RejectRole: - return false; + case QMessageBox::RejectRole: + return false; - case QMessageBox::AcceptRole: - default: - if (dontShowAgain->isChecked()) { - currentIgnored << QString::number(params.program_id); + case QMessageBox::AcceptRole: + default: + if (dontShowAgain->isChecked()) { + currentIgnored << QString::number(params.program_id); - settings.setValue("ignoredBadUpdates", currentIgnored); - settings.sync(); - } - break; + settings.setValue("ignoredBadUpdates", currentIgnored); + settings.sync(); + } + break; } } } @@ -4546,6 +4564,145 @@ void GMainWindow::OnHomeMenu() { BootGame(filename, LibraryAppletParameters(QLaunchId, Service::AM::AppletId::QLaunch)); } +void GMainWindow::OnInitialSetup() +{ + constexpr u64 Starter = static_cast(Service::AM::AppletProgramId::Starter); + auto bis_system = system->GetFileSystemController().GetSystemNANDContents(); + if (!bis_system) { + QMessageBox::warning(this, tr("No firmware available"), + tr("Please install the firmware to use Starter.")); + return; + } + + auto qlaunch_nca = bis_system->GetEntry(Starter, FileSys::ContentRecordType::Program); + if (!qlaunch_nca) { + QMessageBox::warning(this, tr("Starter Applet"), + tr("Starter is not available. Please reinstall firmware.")); + return; + } + + system->GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::Starter); + + const auto filename = QString::fromStdString((qlaunch_nca->GetFullPath())); + UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); + BootGame(filename, LibraryAppletParameters(Starter, Service::AM::AppletId::Starter)); +} + +void GMainWindow::OnCreateHomeMenuDesktopShortcut() +{ + OnCreateHomeMenuShortcut(GameListShortcutTarget::Desktop); +} + +void GMainWindow::OnCreateHomeMenuApplicationMenuShortcut() +{ + OnCreateHomeMenuShortcut(GameListShortcutTarget::Applications); +} + +void GMainWindow::OnCreateHomeMenuShortcut(GameListShortcutTarget target) +{ + // Get path to yuzu executable + const QStringList args = QApplication::arguments(); + std::filesystem::path yuzu_command = args[0].toStdString(); + // If relative path, make it an absolute path + if (yuzu_command.c_str()[0] == '.') { + yuzu_command = Common::FS::GetCurrentDir() / yuzu_command; + } + // Shortcut path + std::filesystem::path shortcut_path{}; + if (target == GameListShortcutTarget::Desktop) { + shortcut_path = + QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).toStdString(); + } else if (target == GameListShortcutTarget::Applications) { + shortcut_path = + QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation).toStdString(); + } + + if (!std::filesystem::exists(shortcut_path)) { + GMainWindow::CreateShortcutMessagesGUI( + this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR, + QString::fromStdString(shortcut_path.generic_string())); + LOG_ERROR(Frontend, "Invalid shortcut target {}", shortcut_path.generic_string()); + return; + } + + constexpr u64 QLaunchId = static_cast(Service::AM::AppletProgramId::QLaunch); + auto bis_system = system->GetFileSystemController().GetSystemNANDContents(); + if (!bis_system) { + QMessageBox::warning(this, tr("No firmware available"), + tr("Please install the firmware to use the home menu.")); + return; + } + + auto qlaunch_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program); + if (!qlaunch_nca) { + QMessageBox::warning(this, tr("Home Menu Applet"), + tr("Home Menu is not available. Please reinstall firmware.")); + return; + } + + const std::string game_title = "QLaunch"; + const QString qt_game_title = tr("QLaunch"); + + auto qlaunch_applet_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program); + const auto game_path = QString::fromStdString((qlaunch_applet_nca->GetFullPath())); + + const FileSys::PatchManager pm{static_cast(Service::AM::AppletProgramId::QLaunch), system->GetFileSystemController(), + system->GetContentProvider()}; + const auto control = pm.GetControlMetadata(); + const auto loader = + Loader::GetLoader(*system, vfs->OpenFile(game_path.toStdString(), FileSys::OpenMode::Read)); + + // Get icon from game file + std::vector icon_image_file{}; + if (control.second != nullptr) { + icon_image_file = control.second->ReadAllBytes(); + } else if (loader->ReadIcon(icon_image_file) != Loader::ResultStatus::Success) { + LOG_WARNING(Frontend, "Could not read icon from {:s}", game_path.toStdString()); + } + QImage icon_data = + QImage::fromData(icon_image_file.data(), static_cast(icon_image_file.size())); + std::filesystem::path out_icon_path; + if (GMainWindow::MakeShortcutIcoPath(QLaunchId, game_title, out_icon_path)) { + if (!SaveIconToFile(out_icon_path, icon_data)) { + LOG_ERROR(Frontend, "Could not write icon to file"); + } + } + +#if defined(__linux__) + // Special case for AppImages + // Warn once if we are making a shortcut to a volatile AppImage + const std::string appimage_ending = + std::string(Common::g_scm_rev).substr(0, 9).append(".AppImage"); + if (yuzu_command.string().ends_with(appimage_ending) && + !UISettings::values.shortcut_already_warned) { + if (GMainWindow::CreateShortcutMessagesGUI( + this, GMainWindow::CREATE_SHORTCUT_MSGBOX_APPVOLATILE_WARNING, qt_game_title)) { + return; + } + UISettings::values.shortcut_already_warned = true; + } +#endif // __linux__ + + // Create shortcut + std::string arguments = "-qlaunch"; + if (GMainWindow::CreateShortcutMessagesGUI( + this, GMainWindow::CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES, qt_game_title)) { + arguments = "-f " + arguments; + } + const std::string comment = fmt::format("Start {:s} with the eden Emulator", game_title); + const std::string categories = "Game;Emulator;Qt;"; + const std::string keywords = "Switch;Nintendo;"; + + if (GMainWindow::CreateShortcutLink(shortcut_path, comment, out_icon_path, yuzu_command, + arguments, categories, keywords, game_title)) { + GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_SUCCESS, + qt_game_title); + return; + } + GMainWindow::CreateShortcutMessagesGUI(this, GMainWindow::CREATE_SHORTCUT_MSGBOX_ERROR, + qt_game_title); +} + void GMainWindow::OnCaptureScreenshot() { if (emu_thread == nullptr || !emu_thread->IsRunning()) { return; diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 5afec3d199..099bee52fb 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -401,6 +401,10 @@ private slots: void OnMiiEdit(); void OnOpenControllerMenu(); void OnHomeMenu(); + void OnInitialSetup(); + void OnCreateHomeMenuDesktopShortcut(); + void OnCreateHomeMenuApplicationMenuShortcut(); + void OnCreateHomeMenuShortcut(GameListShortcutTarget target); void OnCaptureScreenshot(); void OnCheckFirmwareDecryption(); void OnLanguageChanged(const QString& locale); diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index fbecd9eee3..6b19d1f8f5 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui @@ -165,6 +165,13 @@ + + + &Create Home Menu Shortcut + + + + @@ -174,6 +181,8 @@ + + @@ -490,6 +499,24 @@ &Discord + + + Open &Setup + + + QAction::MenuRole::TextHeuristicRole + + + + + &Desktop + + + + + &Application Menu + + From a776f5bc3b04490fc1c6cfff15e2862e092beea5 Mon Sep 17 00:00:00 2001 From: swurl Date: Sun, 18 May 2025 17:49:11 +0000 Subject: [PATCH 9/9] update dynarmic (#110) Signed-off-by: swurl Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/110 Co-authored-by: swurl Co-committed-by: swurl --- externals/dynarmic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/dynarmic b/externals/dynarmic index ae9962226e..ec9349f20e 160000 --- a/externals/dynarmic +++ b/externals/dynarmic @@ -1 +1 @@ -Subproject commit ae9962226e65e2b6d5f85141de4d31fa958f669a +Subproject commit ec9349f20ea7d3cc34af9a678e76aedda4410f5a