mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-15 13:16:43 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 368815d0b1 | |||
| 241c1423f7 | |||
| 91058d7383 | |||
| 048d02e5b4 | |||
| 17e2be173c | |||
| bd6dd7ecec | |||
| 72ae613176 | |||
| 26ce96297c | |||
| b3cc8723c1 |
@@ -3,6 +3,8 @@ name: Check Strings
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
check-strings:
|
||||
@@ -10,7 +12,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Find Unused Strings
|
||||
run: ./tools/unused-strings.sh
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
|
||||
index eb4e69e..3155805 100644
|
||||
--- a/external/CMakeLists.txt
|
||||
+++ b/external/CMakeLists.txt
|
||||
@@ -72,7 +72,8 @@ if (SPIRV_TOOLS_USE_MIMALLOC)
|
||||
pop_variable(MI_BUILD_TESTS)
|
||||
endif()
|
||||
|
||||
-if (DEFINED SPIRV-Headers_SOURCE_DIR)
|
||||
+# NetBSD doesn't have SPIRV-Headers readily available on system
|
||||
+if (DEFINED SPIRV-Headers_SOURCE_DIR AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "NetBSD")
|
||||
# This allows flexible position of the SPIRV-Headers repo.
|
||||
set(SPIRV_HEADER_DIR ${SPIRV-Headers_SOURCE_DIR})
|
||||
else()
|
||||
@@ -1,287 +0,0 @@
|
||||
From 67bf3d1381b1faf59e87001d6156ba4e21cada14 Mon Sep 17 00:00:00 2001
|
||||
From: crueter <crueter@eden-emu.dev>
|
||||
Date: Mon, 29 Dec 2025 21:22:36 -0500
|
||||
Subject: [PATCH] [cmake] refactor: shared/static handling
|
||||
|
||||
This significantly redoes the way shared and static libraries are
|
||||
handled. Now, it's controlled by two options: `SPIRV_TOOLS_BUILD_STATIC`
|
||||
and `SPIRV_TOOLS_BUILD_SHARED`.
|
||||
|
||||
The default configuration (no `BUILD_SHARED_LIBS` set, options left at
|
||||
default) is to build shared ONLY if this is the master project, or
|
||||
static ONLY if this is a subproject (e.g. FetchContent, CPM.cmake). Also
|
||||
I should note that static-only (i.e. no shared) is now a supported
|
||||
target, this is done because projects including it as a submodule e.g.
|
||||
on Android or Windows may prefer this.
|
||||
|
||||
Now the shared/static handling:
|
||||
- static ON, shared OFF: Only generates `.a` libraries.
|
||||
- static ON, shared ON: Generates `.a` libraries, but also
|
||||
`libSPIRV-Tools.so`
|
||||
- static OFF, shared ON: Only generates `.so` libraries.
|
||||
|
||||
Notable TODOs:
|
||||
- SPIRV-Tools-shared.pc seems redundant--how should we handle which one
|
||||
to use in the case of distributions that distribute both types (MSYS2
|
||||
for instance)?
|
||||
* *Note: pkgconfig sucks at this and usually just leaves it up to the
|
||||
user, so the optimal solution may indeed be doing absolutely
|
||||
nothing.* CMake is unaffected :)
|
||||
- use namespaces in the CMake config files pleaaaaase
|
||||
|
||||
This is going to change things a good bit for package maintainers, but
|
||||
cest la vie. It's for the greater good, I promise.
|
||||
|
||||
Signed-off-by: crueter <crueter@eden-emu.dev>
|
||||
---
|
||||
CMakeLists.txt | 108 +++++++++++++++++++++++++-----------------
|
||||
source/CMakeLists.txt | 62 ++++++++++++------------
|
||||
2 files changed, 94 insertions(+), 76 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 4d843b4d2f..07201f690f 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -14,6 +14,15 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.22.1)
|
||||
|
||||
+# master project detection--useful for FetchContent/submodule inclusion
|
||||
+set(master_project OFF)
|
||||
+set(subproject ON)
|
||||
+
|
||||
+if (NOT DEFINED PROJECT_NAME)
|
||||
+ set(master_project ON)
|
||||
+ set(subproject OFF)
|
||||
+endif()
|
||||
+
|
||||
project(spirv-tools)
|
||||
|
||||
# Avoid a bug in CMake 3.22.1. By default it will set -std=c++11 for
|
||||
@@ -135,46 +144,49 @@ if (DEFINED SPIRV_TOOLS_EXTRA_DEFINITIONS)
|
||||
add_definitions(${SPIRV_TOOLS_EXTRA_DEFINITIONS})
|
||||
endif()
|
||||
|
||||
-# Library build setting definitions:
|
||||
-#
|
||||
-# * SPIRV_TOOLS_BUILD_STATIC - ON or OFF - Defaults to ON.
|
||||
-# If enabled the following targets will be created:
|
||||
-# ${SPIRV_TOOLS}-static - STATIC library.
|
||||
-# Has full public symbol visibility.
|
||||
-# ${SPIRV_TOOLS}-shared - SHARED library.
|
||||
-# Has default-hidden symbol visibility.
|
||||
-# ${SPIRV_TOOLS} - will alias to one of above, based on BUILD_SHARED_LIBS.
|
||||
-# If disabled the following targets will be created:
|
||||
-# ${SPIRV_TOOLS} - either STATIC or SHARED based on SPIRV_TOOLS_LIBRARY_TYPE.
|
||||
-# Has full public symbol visibility.
|
||||
-# ${SPIRV_TOOLS}-shared - SHARED library.
|
||||
-# Has default-hidden symbol visibility.
|
||||
-#
|
||||
-# * SPIRV_TOOLS_LIBRARY_TYPE - SHARED or STATIC.
|
||||
-# Specifies the library type used for building SPIRV-Tools libraries.
|
||||
-# Defaults to SHARED when BUILD_SHARED_LIBS=1, otherwise STATIC.
|
||||
-#
|
||||
-# * SPIRV_TOOLS_FULL_VISIBILITY - "${SPIRV_TOOLS}-static" or "${SPIRV_TOOLS}"
|
||||
-# Evaluates to the SPIRV_TOOLS target library name that has no hidden symbols.
|
||||
-# This is used by internal targets for accessing symbols that are non-public.
|
||||
-# Note this target provides no API stability guarantees.
|
||||
-#
|
||||
-# Ideally, all of these will go away - see https://github.com/KhronosGroup/SPIRV-Tools/issues/3909.
|
||||
-option(ENABLE_EXCEPTIONS_ON_MSVC "Build SPIRV-TOOLS with c++ exceptions enabled in MSVC" ON)
|
||||
-option(SPIRV_TOOLS_BUILD_STATIC "Build ${SPIRV_TOOLS}-static target. ${SPIRV_TOOLS} will alias to ${SPIRV_TOOLS}-static or ${SPIRV_TOOLS}-shared based on BUILD_SHARED_LIBS" ON)
|
||||
-if(SPIRV_TOOLS_BUILD_STATIC)
|
||||
- set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS}-static)
|
||||
+# If BUILD_SHARED_LIBS is undefined, set it based on whether we are
|
||||
+# the master project or a subproject
|
||||
+if (NOT DEFINED BUILD_SHARED_LIBS)
|
||||
+ set(BUILD_SHARED_LIBS ${master_project})
|
||||
+endif()
|
||||
+
|
||||
+if (BUILD_SHARED_LIBS)
|
||||
+ set(static_default OFF)
|
||||
+else()
|
||||
+ set(static_default ON)
|
||||
+endif()
|
||||
+
|
||||
+option(SPIRV_TOOLS_BUILD_SHARED "Build ${SPIRV_TOOLS} as a shared library"
|
||||
+ ${BUILD_SHARED_LIBS})
|
||||
+option(SPIRV_TOOLS_BUILD_STATIC "Build ${SPIRV_TOOLS} as a static library"
|
||||
+ ${static_default})
|
||||
+
|
||||
+# Avoid conflict between the dll import library and
|
||||
+# the static library (thanks microsoft)
|
||||
+if(CMAKE_STATIC_LIBRARY_PREFIX STREQUAL "" AND
|
||||
+ CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL ".lib")
|
||||
+ set(SPIRV_TOOLS_STATIC_LIBNAME "${SPIRV_TOOLS}-static")
|
||||
+else()
|
||||
+ set(SPIRV_TOOLS_STATIC_LIBNAME "${SPIRV_TOOLS}")
|
||||
+endif()
|
||||
+
|
||||
+if (SPIRV_TOOLS_BUILD_STATIC)
|
||||
+ # If building a static library at all, always build other libraries as static,
|
||||
+ # and link to the static SPIRV-Tools library.
|
||||
set(SPIRV_TOOLS_LIBRARY_TYPE "STATIC")
|
||||
-else(SPIRV_TOOLS_BUILD_STATIC)
|
||||
- set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS})
|
||||
- if (NOT DEFINED SPIRV_TOOLS_LIBRARY_TYPE)
|
||||
- if(BUILD_SHARED_LIBS)
|
||||
- set(SPIRV_TOOLS_LIBRARY_TYPE "SHARED")
|
||||
- else()
|
||||
- set(SPIRV_TOOLS_LIBRARY_TYPE "STATIC")
|
||||
- endif()
|
||||
- endif()
|
||||
-endif(SPIRV_TOOLS_BUILD_STATIC)
|
||||
+ set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS}-static)
|
||||
+elseif (SPIRV_TOOLS_BUILD_SHARED)
|
||||
+ # If only building a shared library, link other libraries to the
|
||||
+ # shared library. Also, other libraries should be shared
|
||||
+ set(SPIRV_TOOLS_LIBRARY_TYPE "SHARED")
|
||||
+ set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS}-shared)
|
||||
+else()
|
||||
+ message(FATAL_ERROR "You must set one of "
|
||||
+ "SPIRV_TOOLS_BUILD_STATIC or SPIRV_TOOLS_BUILD_SHARED!")
|
||||
+endif()
|
||||
+
|
||||
+option(ENABLE_EXCEPTIONS_ON_MSVC
|
||||
+ "Build SPIRV-TOOLS with C++ exceptions enabled in MSVC" ON)
|
||||
|
||||
function(spvtools_default_compile_options TARGET)
|
||||
target_compile_options(${TARGET} PRIVATE ${SPIRV_WARNINGS})
|
||||
@@ -372,7 +384,7 @@ if (NOT "${SPIRV_SKIP_TESTS}")
|
||||
endif()
|
||||
|
||||
set(SPIRV_LIBRARIES "-lSPIRV-Tools-opt -lSPIRV-Tools -lSPIRV-Tools-link")
|
||||
-set(SPIRV_SHARED_LIBRARIES "-lSPIRV-Tools-shared")
|
||||
+set(SPIRV_SHARED_LIBRARIES "-lSPIRV-Tools")
|
||||
|
||||
# Build pkg-config file
|
||||
# Use a first-class target so it's regenerated when relevant files are updated.
|
||||
@@ -388,7 +400,12 @@ add_custom_command(
|
||||
-DSPIRV_LIBRARIES=${SPIRV_LIBRARIES}
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
|
||||
DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
|
||||
-add_custom_command(
|
||||
+
|
||||
+set(pc_files ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc)
|
||||
+
|
||||
+# TODO(crueter): remove?
|
||||
+if (SPIRV_TOOLS_BUILD_SHARED)
|
||||
+ add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
|
||||
@@ -400,9 +417,12 @@ add_custom_command(
|
||||
-DSPIRV_SHARED_LIBRARIES=${SPIRV_SHARED_LIBRARIES}
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
|
||||
DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools-shared.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
|
||||
-add_custom_target(spirv-tools-pkg-config
|
||||
- ALL
|
||||
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc)
|
||||
+ set(pc_files ${pc_files} ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc)
|
||||
+endif()
|
||||
+
|
||||
+add_custom_target(spirv-tools-pkg-config
|
||||
+ ALL
|
||||
+ DEPENDS ${pc_files})
|
||||
|
||||
# Install pkg-config file
|
||||
if (ENABLE_SPIRV_TOOLS_INSTALL)
|
||||
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
|
||||
index bfa1e661bc..fd3712c70c 100644
|
||||
--- a/source/CMakeLists.txt
|
||||
+++ b/source/CMakeLists.txt
|
||||
@@ -337,49 +337,44 @@ function(spirv_tools_default_target_options target)
|
||||
)
|
||||
set_property(TARGET ${target} PROPERTY FOLDER "SPIRV-Tools libraries")
|
||||
spvtools_check_symbol_exports(${target})
|
||||
- add_dependencies(${target} spirv-tools-build-version core_tables extinst_tables)
|
||||
+ add_dependencies(${target}
|
||||
+ spirv-tools-build-version core_tables extinst_tables)
|
||||
endfunction()
|
||||
|
||||
-# Always build ${SPIRV_TOOLS}-shared. This is expected distro packages, and
|
||||
-# unlike the other SPIRV_TOOLS target, defaults to hidden symbol visibility.
|
||||
-add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES})
|
||||
-if (SPIRV_TOOLS_USE_MIMALLOC)
|
||||
- target_link_libraries(${SPIRV_TOOLS}-shared PRIVATE mimalloc-static)
|
||||
+if (SPIRV_TOOLS_BUILD_SHARED)
|
||||
+ add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES})
|
||||
+ if (SPIRV_TOOLS_USE_MIMALLOC)
|
||||
+ target_link_libraries(${SPIRV_TOOLS}-shared PRIVATE mimalloc-static)
|
||||
+ endif()
|
||||
+
|
||||
+ set_target_properties(${SPIRV_TOOLS}-shared PROPERTIES
|
||||
+ OUTPUT_NAME "${SPIRV_TOOLS}")
|
||||
+ spirv_tools_default_target_options(${SPIRV_TOOLS}-shared)
|
||||
+
|
||||
+ target_compile_definitions(${SPIRV_TOOLS}-shared
|
||||
+ PRIVATE SPIRV_TOOLS_IMPLEMENTATION
|
||||
+ PUBLIC SPIRV_TOOLS_SHAREDLIB)
|
||||
+
|
||||
+ list(APPEND SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-shared)
|
||||
endif()
|
||||
-spirv_tools_default_target_options(${SPIRV_TOOLS}-shared)
|
||||
-set_target_properties(${SPIRV_TOOLS}-shared PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||
-target_compile_definitions(${SPIRV_TOOLS}-shared
|
||||
- PRIVATE SPIRV_TOOLS_IMPLEMENTATION
|
||||
- PUBLIC SPIRV_TOOLS_SHAREDLIB
|
||||
-)
|
||||
|
||||
if(SPIRV_TOOLS_BUILD_STATIC)
|
||||
add_library(${SPIRV_TOOLS}-static STATIC ${SPIRV_SOURCES})
|
||||
if (SPIRV_TOOLS_USE_MIMALLOC AND SPIRV_TOOLS_USE_MIMALLOC_IN_STATIC_BUILD)
|
||||
target_link_libraries(${SPIRV_TOOLS}-shared PRIVATE mimalloc-static)
|
||||
endif()
|
||||
+
|
||||
spirv_tools_default_target_options(${SPIRV_TOOLS}-static)
|
||||
- # The static target does not have the '-static' suffix.
|
||||
- set_target_properties(${SPIRV_TOOLS}-static PROPERTIES OUTPUT_NAME "${SPIRV_TOOLS}")
|
||||
-
|
||||
- # Create the "${SPIRV_TOOLS}" target as an alias to either "${SPIRV_TOOLS}-static"
|
||||
- # or "${SPIRV_TOOLS}-shared" depending on the value of BUILD_SHARED_LIBS.
|
||||
- if(BUILD_SHARED_LIBS)
|
||||
- add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-shared)
|
||||
- else()
|
||||
- add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-static)
|
||||
- endif()
|
||||
+ set_target_properties(${SPIRV_TOOLS}-static PROPERTIES
|
||||
+ OUTPUT_NAME "${SPIRV_TOOLS_STATIC_LIBNAME}")
|
||||
|
||||
- set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-static ${SPIRV_TOOLS}-shared)
|
||||
-else()
|
||||
- add_library(${SPIRV_TOOLS} ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_SOURCES})
|
||||
- if (SPIRV_TOOLS_USE_MIMALLOC)
|
||||
- target_link_libraries(${SPIRV_TOOLS} PRIVATE mimalloc-static)
|
||||
- endif()
|
||||
- spirv_tools_default_target_options(${SPIRV_TOOLS})
|
||||
- set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS} ${SPIRV_TOOLS}-shared)
|
||||
+ list(APPEND SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-static)
|
||||
endif()
|
||||
|
||||
+# Create the "SPIRV-Tools" target as an alias to either "SPIRV-Tools-static"
|
||||
+# or "SPIRV-Tools-shared" depending on the value of SPIRV_TOOLS_BUILD_SHARED.
|
||||
+add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS_FULL_VISIBILITY})
|
||||
+
|
||||
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
find_library(LIBRT rt)
|
||||
if(LIBRT)
|
||||
@@ -390,14 +385,17 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
endif()
|
||||
|
||||
if(ENABLE_SPIRV_TOOLS_INSTALL)
|
||||
- if (SPIRV_TOOLS_USE_MIMALLOC AND (NOT SPIRV_TOOLS_BUILD_STATIC OR SPIRV_TOOLS_USE_MIMALLOC_IN_STATIC_BUILD))
|
||||
+ if (SPIRV_TOOLS_USE_MIMALLOC AND
|
||||
+ (NOT SPIRV_TOOLS_BUILD_STATIC OR SPIRV_TOOLS_USE_MIMALLOC_IN_STATIC_BUILD))
|
||||
list(APPEND SPIRV_TOOLS_TARGETS mimalloc-static)
|
||||
endif()
|
||||
install(TARGETS ${SPIRV_TOOLS_TARGETS} EXPORT ${SPIRV_TOOLS}Targets)
|
||||
export(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake)
|
||||
|
||||
spvtools_config_package_dir(${SPIRV_TOOLS} PACKAGE_DIR)
|
||||
- install(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake DESTINATION ${PACKAGE_DIR})
|
||||
+ install(EXPORT ${SPIRV_TOOLS}Targets
|
||||
+ FILE ${SPIRV_TOOLS}Target.cmake
|
||||
+ DESTINATION ${PACKAGE_DIR})
|
||||
|
||||
# Special config file for root library compared to other libs.
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/${SPIRV_TOOLS}Config.cmake
|
||||
@@ -130,7 +130,6 @@ if (YUZU_STATIC_BUILD)
|
||||
|
||||
# these libs do not properly provide static libs/let you do it with cmake
|
||||
set(fmt_FORCE_BUNDLED ON)
|
||||
set(SPIRV-Tools_FORCE_BUNDLED ON)
|
||||
set(SPIRV-Headers_FORCE_BUNDLED ON)
|
||||
set(zstd_FORCE_BUNDLED ON)
|
||||
endif()
|
||||
@@ -523,7 +522,6 @@ if (NOT YUZU_STATIC_ROOM)
|
||||
find_package(VulkanMemoryAllocator)
|
||||
find_package(VulkanUtilityLibraries)
|
||||
find_package(SimpleIni)
|
||||
find_package(SPIRV-Tools)
|
||||
find_package(sirit)
|
||||
find_package(gamemode)
|
||||
find_package(frozen)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(SPIRV-Tools QUIET IMPORTED_TARGET SPIRV-Tools)
|
||||
find_package_handle_standard_args(SPIRV-Tools
|
||||
REQUIRED_VARS SPIRV-Tools_LINK_LIBRARIES
|
||||
VERSION_VAR SPIRV-Tools_VERSION
|
||||
)
|
||||
|
||||
if (PLATFORM_MSYS)
|
||||
FixMsysPath(PkgConfig::SPIRV-Tools)
|
||||
endif()
|
||||
|
||||
if (SPIRV-Tools_FOUND AND NOT TARGET SPIRV-Tools::SPIRV-Tools)
|
||||
if (TARGET SPIRV-Tools)
|
||||
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools)
|
||||
else()
|
||||
add_library(SPIRV-Tools::SPIRV-Tools ALIAS PkgConfig::SPIRV-Tools)
|
||||
endif()
|
||||
endif()
|
||||
@@ -35,17 +35,17 @@ set(GIT_DESC ${BUILD_VERSION})
|
||||
# Generate cpp with Git revision from template
|
||||
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
|
||||
|
||||
# Auto-updater metadata! Must somewhat mirror GitHub API endpoint
|
||||
# Auto-updater metadata! Must somewhat mirror GitHub/Forgejo API endpoint
|
||||
|
||||
set(BUILD_AUTO_UPDATE_API_PATH "/latest/release.json")
|
||||
if (NIGHTLY_BUILD)
|
||||
set(BUILD_AUTO_UPDATE_WEBSITE "https://git.eden-emu.dev")
|
||||
set(BUILD_AUTO_UPDATE_API "git.eden-emu.dev")
|
||||
set(BUILD_AUTO_UPDATE_API_PATH "/api/v1/repos/")
|
||||
set(BUILD_AUTO_UPDATE_API "nightly.eden-emu.dev")
|
||||
set(BUILD_AUTO_UPDATE_REPO "eden-ci/nightly")
|
||||
set(REPO_NAME "Eden Nightly")
|
||||
else()
|
||||
set(BUILD_AUTO_UPDATE_WEBSITE "https://git.eden-emu.dev")
|
||||
set(BUILD_AUTO_UPDATE_API "git.eden-emu.dev")
|
||||
set(BUILD_AUTO_UPDATE_API_PATH "/api/v1/repos/")
|
||||
set(BUILD_AUTO_UPDATE_API "stable.eden-emu.dev")
|
||||
set(BUILD_AUTO_UPDATE_REPO "eden-emu/eden")
|
||||
set(REPO_NAME "Eden")
|
||||
endif()
|
||||
|
||||
Vendored
+36
-36
@@ -239,7 +239,7 @@ Esto vetará su nombre de usuario del foro y su dirección IP.</translation>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/compatdb.ui" line="36"/>
|
||||
<source><html><head/><body><p><span style=" font-size:10pt;">Should you choose to submit a test case to the </span><a href="https://eden-emulator.github.io/game/"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">eden Compatibility List</span></a><span style=" font-size:10pt;">, The following information will be collected and displayed on the site:</span></p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Hardware Information (CPU / GPU / Operating System)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Which version of eden you are running</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The connected eden account</li></ul></body></html></source>
|
||||
<translation><html><head/><body><p><span style=" font-size:10pt;">Si elijes entregar un caso de prueba a la </span><a href="https://eden-emulator.github.io/game/"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">lista de compatibilidad de Eden</span></a><span style=" font-size:10pt;">, Se recopilará y mostrará la siguiente información en el sito:</span></p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Información del hardware (Procesador / Tarjeta gráfica / Sistema operativo)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qué version de Eden estás usando</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">La cuenta de eden que está conectada </li></ul></body></html></translation>
|
||||
<translation><html><head/><body><p><span style=" font-size:10pt;">Si elijes entregar un caso de prueba a la </span><a href="https://eden-emulator.github.io/game/"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">lista de compatibilidad de Eden</span></a><span style=" font-size:10pt;">, Se recopilará y mostrará la siguiente información en el sito:</span></p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Información del hardware (CPU / GPU / Sistema operativo)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qué version de Eden estás usando</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">La cuenta de eden que está conectada </li></ul></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/compatdb.ui" line="77"/>
|
||||
@@ -492,14 +492,14 @@ Esto vetará su nombre de usuario del foro y su dirección IP.</translation>
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="63"/>
|
||||
<source>Multicore CPU Emulation</source>
|
||||
<translation>Emulación del procesador multinúcleo </translation>
|
||||
<translation>Emulación de la CPU multinúcleo </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="64"/>
|
||||
<source>This option increases CPU emulation thread use from 1 to the maximum of 4.
|
||||
This is mainly a debug option and shouldn't be disabled.</source>
|
||||
<translation>Esta opción aumenta el uso de hilos de emulación del procesador de 1 a un máximo de 4.
|
||||
Principalmente es una opción de depuración y no debería desactivarse.</translation>
|
||||
<translation>Esta opción aumenta el uso de hilos de emulación de la CPU de 1 a un máximo de 4.
|
||||
Esta es una opción principalmente de depuración y no debería desactivarse.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="66"/>
|
||||
@@ -556,7 +556,7 @@ Desactivarlo hará que el juego se renderice lo más rápido posible según tu o
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="86"/>
|
||||
<source>Synchronizes CPU core speed with the game's maximum rendering speed to boost FPS without affecting game speed (animations, physics, etc.).
|
||||
Can help reduce stuttering at lower framerates.</source>
|
||||
<translation>Sincroniza la velocidad del núcleo del procesador con la velocidad máxima de renderizado del juego para aumentar los fotogramas por segundo sin afectar la velocidad del juego (animaciones, físicas, etc.).
|
||||
<translation>Sincroniza la velocidad del núcleo de la CPU con la velocidad máxima de renderizado del juego para aumentar los fotogramas por segundo sin afectar la velocidad del juego (animaciones, físicas, etc.).
|
||||
Puede ayudar a reducir los tirones o parpadeos en tasas de fotogramas bajas.</translation>
|
||||
</message>
|
||||
<message>
|
||||
@@ -567,7 +567,7 @@ Puede ayudar a reducir los tirones o parpadeos en tasas de fotogramas bajas.</tr
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="92"/>
|
||||
<source>Change the accuracy of the emulated CPU (for debugging only).</source>
|
||||
<translation>Cambia la precisión del procesador emulado (solo para depuración)</translation>
|
||||
<translation>Cambia la precisión de la CPU emulada (solo para depuración)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="93"/>
|
||||
@@ -578,7 +578,7 @@ Puede ayudar a reducir los tirones o parpadeos en tasas de fotogramas bajas.</tr
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="95"/>
|
||||
<source>CPU Overclock</source>
|
||||
<translation>Overclock del procesador</translation>
|
||||
<translation>Overclock de la CPU</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="96"/>
|
||||
@@ -806,7 +806,7 @@ Esta función es experimental.</translation>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="173"/>
|
||||
<source>Uses an extra CPU thread for rendering.
|
||||
This option should always remain enabled.</source>
|
||||
<translation>Usa un hilo adicional del procesador para el renderizado.
|
||||
<translation>Usa un hilo adicional de la CPU para el renderizado.
|
||||
Esta opción siempre debe permanecer activada.</translation>
|
||||
</message>
|
||||
<message>
|
||||
@@ -836,9 +836,9 @@ GPU: Use the GPU's compute shaders to decode ASTC textures (recommended).
|
||||
CPU Asynchronously: Use the CPU to decode ASTC textures on demand. EliminatesASTC decoding
|
||||
stuttering but may present artifacts.</source>
|
||||
<translation>Esta opción controla cómo deben descodificarse las texturas ASTC.
|
||||
CPU: utiliza el procesador para la descodificación.
|
||||
GPU: utiliza los sombreadores computables de la tarjeta gráfica para descodificar las texturas ASTC (recomendado).
|
||||
CPU asíncrono: usa el procesador para descodificar las texturas ASTC bajo demanda. Elimina los tirones causados por la descodificación ASTC, pero puede generar errores visuales.</translation>
|
||||
CPU: utiliza la CPU para la descodificación.
|
||||
GPU: utiliza los sombreadores computables de la GPU para descodificar las texturas ASTC (recomendado).
|
||||
CPU asíncrona: usa la CPU para descodificar las texturas ASTC bajo demanda. Elimina los tirones causados por la descodificación ASTC, pero puede generar errores visuales.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="184"/>
|
||||
@@ -1354,7 +1354,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="393"/>
|
||||
<source>CPU</source>
|
||||
<translation>Procesador</translation>
|
||||
<translation>CPU</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="394"/>
|
||||
@@ -1364,7 +1364,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="395"/>
|
||||
<source>CPU Asynchronous</source>
|
||||
<translation>Procesador asíncrono</translation>
|
||||
<translation>CPU asíncrona</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="400"/>
|
||||
@@ -1517,7 +1517,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="460"/>
|
||||
<source>CPU Video Decoding</source>
|
||||
<translation>Decodificación de vídeo en el procesador</translation>
|
||||
<translation>Decodificación de vídeo en la CPU</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/qt_common/config/shared_translation.cpp" line="461"/>
|
||||
@@ -2367,7 +2367,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="17"/>
|
||||
<source>CPU</source>
|
||||
<translation>Procesador</translation>
|
||||
<translation>CPU</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="28"/>
|
||||
@@ -2382,12 +2382,12 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="68"/>
|
||||
<source>CPU Backend</source>
|
||||
<translation>Motor del procesador</translation>
|
||||
<translation>Motor de la CPU</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="95"/>
|
||||
<source>Unsafe CPU Optimization Settings</source>
|
||||
<translation>Ajustes de optimización del procesador inseguro</translation>
|
||||
<translation>Ajustes inseguros de la optimización de la CPU</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="101"/>
|
||||
@@ -2405,12 +2405,12 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="17"/>
|
||||
<source>CPU</source>
|
||||
<translation>Procesador</translation>
|
||||
<translation>CPU</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="25"/>
|
||||
<source>Toggle CPU Optimizations</source>
|
||||
<translation>Cambiar las optimizaciones del procesador</translation>
|
||||
<translation>Cambiar las optimizaciones de la CPU</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="31"/>
|
||||
@@ -2606,7 +2606,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="212"/>
|
||||
<source>CPU settings are available only when game is not running.</source>
|
||||
<translation>Los ajustes del procesador solo están disponibles cuando no se esté ejecutando ningún juego.</translation>
|
||||
<translation>Los ajustes de la CPU solo están disponibles cuando no se esté ejecutando ningún juego.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -2644,17 +2644,17 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="209"/>
|
||||
<source>Enable Extended Logging**</source>
|
||||
<translation>Habilitar registro extendido**</translation>
|
||||
<translation>Habilitar el registro extendido**</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="216"/>
|
||||
<source>Show Log in Console</source>
|
||||
<translation>Ver registro en consola</translation>
|
||||
<translation>Ver el registro en la consola</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="223"/>
|
||||
<source>Open Log Location</source>
|
||||
<translation>Abrir ubicación del archivo de registro</translation>
|
||||
<translation>Abrir la ubicación del archivo de registro</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="235"/>
|
||||
@@ -2689,7 +2689,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="282"/>
|
||||
<source>Dump Maxwell Macros</source>
|
||||
<translation>Volcar Macros Maxwell</translation>
|
||||
<translation>Volcar macros Maxwell</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="289"/>
|
||||
@@ -2734,7 +2734,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="338"/>
|
||||
<source>Disable Macro HLE</source>
|
||||
<translation>Desactivar Macro HLE</translation>
|
||||
<translation>Desactivar macro HLE</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="348"/>
|
||||
@@ -2844,7 +2844,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="538"/>
|
||||
<source>Debug Knobs: </source>
|
||||
<translation>perillas de depuración:</translation>
|
||||
<translation>Interruptores de depuración:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="572"/>
|
||||
@@ -2864,7 +2864,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="611"/>
|
||||
<source>Flush log output on each line</source>
|
||||
<translation>Limpia lg salida en cada linea</translation>
|
||||
<translation>Limpia el registro de salida en cada línea</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="618"/>
|
||||
@@ -2879,7 +2879,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="632"/>
|
||||
<source>Censor username in logs</source>
|
||||
<translation>Censura nombre de usario en logs</translation>
|
||||
<translation>Censura del nombre de usuario en los archivos de registro</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug.ui" line="668"/>
|
||||
@@ -2921,7 +2921,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_debug_tab.cpp" line="17"/>
|
||||
<source>CPU</source>
|
||||
<translation>Procesador</translation>
|
||||
<translation>CPU</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -2951,7 +2951,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="71"/>
|
||||
<location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="180"/>
|
||||
<source>CPU</source>
|
||||
<translation>Procesador</translation>
|
||||
<translation>CPU</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="72"/>
|
||||
@@ -2978,7 +2978,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="76"/>
|
||||
<source>GraphicsAdvanced</source>
|
||||
<translation>Gráficosavanzados</translation>
|
||||
<translation>GráficosAvanzados</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="77"/>
|
||||
@@ -3063,7 +3063,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="65"/>
|
||||
<source>Save Data</source>
|
||||
<translation>Datos guardados</translation>
|
||||
<translation>Datos de guardado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="101"/>
|
||||
@@ -3169,7 +3169,7 @@ Cuando un programa intenta abrir el applet del controlador, se cierra inmediatam
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="151"/>
|
||||
<source>Set Custom Path</source>
|
||||
<translation>Configure ruta personalizado</translation>
|
||||
<translation>Configura una ruta personalizado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="152"/>
|
||||
@@ -4812,7 +4812,7 @@ Los valores actuales son %1% y %2% respectivamente.</translation>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="79"/>
|
||||
<source>CPU</source>
|
||||
<translation>Procesador</translation>
|
||||
<translation>CPU</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="80"/>
|
||||
@@ -5814,12 +5814,12 @@ Arrastre los puntos para cambiar de posición, o haga doble clic en las celdas d
|
||||
<message>
|
||||
<location filename="../../src/yuzu/data_dialog.cpp" line="32"/>
|
||||
<source>User NAND</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>NAND del usuario</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/data_dialog.cpp" line="33"/>
|
||||
<source>System NAND</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>NAND del sistema</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/data_dialog.cpp" line="34"/>
|
||||
|
||||
Vendored
+621
-614
File diff suppressed because it is too large
Load Diff
Vendored
+2
-2
@@ -5819,12 +5819,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
|
||||
<message>
|
||||
<location filename="../../src/yuzu/data_dialog.cpp" line="32"/>
|
||||
<source>User NAND</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>NAND користувача</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/data_dialog.cpp" line="33"/>
|
||||
<source>System NAND</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>NAND системи</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../src/yuzu/data_dialog.cpp" line="34"/>
|
||||
|
||||
Vendored
-8
@@ -192,14 +192,6 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# SPIRV Tools
|
||||
AddJsonPackage(spirv-tools)
|
||||
|
||||
if (SPIRV-Tools_ADDED)
|
||||
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools-static)
|
||||
target_link_libraries(SPIRV-Tools-static PRIVATE SPIRV-Tools-opt SPIRV-Tools-link)
|
||||
endif()
|
||||
|
||||
# Catch2
|
||||
if (YUZU_TESTS OR DYNARMIC_TESTS)
|
||||
AddJsonPackage(catch2)
|
||||
|
||||
Vendored
-14
@@ -102,20 +102,6 @@
|
||||
"git_version": "1.3.18",
|
||||
"find_args": "MODULE"
|
||||
},
|
||||
"spirv-tools": {
|
||||
"package": "SPIRV-Tools",
|
||||
"repo": "KhronosGroup/SPIRV-Tools",
|
||||
"sha": "0a7e28689a",
|
||||
"hash": "eadfcceb82f4b414528d99962335e4f806101168474028f3cf7691ac40c37f323decf2a42c525e2d5bfa6f14ff132d6c5cf9b87c151490efad01f5e13ade1520",
|
||||
"git_version": "2025.4",
|
||||
"options": [
|
||||
"SPIRV_SKIP_EXECUTABLES ON"
|
||||
],
|
||||
"patches": [
|
||||
"0001-netbsd-fix.patch",
|
||||
"0002-allow-static-only.patch"
|
||||
]
|
||||
},
|
||||
"spirv-headers": {
|
||||
"package": "SPIRV-Headers",
|
||||
"repo": "KhronosGroup/SPIRV-Headers",
|
||||
|
||||
Vendored
+2
-2
@@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||
@@ -254,7 +254,7 @@ else()
|
||||
OUTPUT
|
||||
${FFmpeg_BUILD_LIBRARIES}
|
||||
COMMAND
|
||||
make ${FFmpeg_MAKE_ARGS}
|
||||
gmake ${FFmpeg_MAKE_ARGS}
|
||||
WORKING_DIRECTORY
|
||||
${FFmpeg_BUILD_DIR}
|
||||
)
|
||||
|
||||
+1
@@ -17,6 +17,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||
USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
|
||||
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
|
||||
FIX_BLOOM_EFFECTS("fix_bloom_effects"),
|
||||
EMULATE_BGR565("emulate_bgr565"),
|
||||
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
|
||||
USE_DOCKED_MODE("use_docked_mode"),
|
||||
USE_AUTO_STUB("use_auto_stub"),
|
||||
|
||||
@@ -24,7 +24,6 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
|
||||
RENDERER_ANTI_ALIASING("anti_aliasing"),
|
||||
RENDERER_SCREEN_LAYOUT("screen_layout"),
|
||||
RENDERER_ASPECT_RATIO("aspect_ratio"),
|
||||
RENDERER_OPTIMIZE_SPIRV_OUTPUT("optimize_spirv_output"),
|
||||
|
||||
RENDERER_DYNA_STATE("dyna_state"),
|
||||
DMA_ACCURACY("dma_accuracy"),
|
||||
|
||||
+7
-9
@@ -643,15 +643,6 @@ abstract class SettingsItem(
|
||||
descriptionId = R.string.renderer_async_presentation_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT,
|
||||
titleId = R.string.renderer_optimize_spirv_output,
|
||||
descriptionId = R.string.renderer_optimize_spirv_output_description,
|
||||
choicesId = R.array.optimizeSpirvOutputEntries,
|
||||
valuesId = R.array.optimizeSpirvOutputValues
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.DMA_ACCURACY,
|
||||
@@ -756,6 +747,13 @@ abstract class SettingsItem(
|
||||
descriptionId = R.string.fix_bloom_effects_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.EMULATE_BGR565,
|
||||
titleId = R.string.emulate_bgr565,
|
||||
descriptionId = R.string.emulate_bgr565_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.CPUOPT_UNSAFE_HOST_MMU,
|
||||
|
||||
+1
-1
@@ -271,7 +271,6 @@ class SettingsFragmentPresenter(
|
||||
add(IntSetting.FSR_SHARPENING_SLIDER.key)
|
||||
}
|
||||
add(IntSetting.RENDERER_ANTI_ALIASING.key)
|
||||
add(IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT.key)
|
||||
|
||||
add(HeaderSetting(R.string.advanced))
|
||||
|
||||
@@ -293,6 +292,7 @@ class SettingsFragmentPresenter(
|
||||
add(IntSetting.FAST_GPU_TIME.key)
|
||||
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
|
||||
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
|
||||
add(BooleanSetting.EMULATE_BGR565.key)
|
||||
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
|
||||
add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key)
|
||||
add(BooleanSetting.RENDERER_ASYNC_PRESENTATION.key)
|
||||
|
||||
@@ -1726,9 +1726,8 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateUrl(
|
||||
jobject obj,
|
||||
jstring version) {
|
||||
const char* version_str = env->GetStringUTFChars(version, nullptr);
|
||||
const std::string url = fmt::format("{}/{}/releases/tag/{}",
|
||||
std::string{Common::g_build_auto_update_website},
|
||||
std::string{Common::g_build_auto_update_repo},
|
||||
const std::string url = fmt::format("{}/{}",
|
||||
std::string{Common::g_build_auto_update_api},
|
||||
version_str);
|
||||
env->ReleaseStringUTFChars(version, version_str);
|
||||
return env->NewStringUTF(url.c_str());
|
||||
@@ -1760,11 +1759,10 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateApkUrl(
|
||||
}
|
||||
|
||||
const std::string apk_filename = fmt::format("Eden-Android-{}-{}.apk", artifact_str, variant);
|
||||
const std::string url = fmt::format("{}/{}/releases/download/{}/{}",
|
||||
std::string{Common::g_build_auto_update_website},
|
||||
std::string{Common::g_build_auto_update_repo},
|
||||
version_str,
|
||||
apk_filename);
|
||||
|
||||
const std::string url = fmt::format("{}/{}/{}",
|
||||
std::string{Common::g_build_auto_update_api},
|
||||
version_str, apk_filename);
|
||||
|
||||
env->ReleaseStringUTFChars(tag, version_str);
|
||||
env->ReleaseStringUTFChars(artifact, artifact_str);
|
||||
|
||||
@@ -463,8 +463,6 @@
|
||||
<string name="fsr_sharpness">حدة FSR</string>
|
||||
<string name="fsr_sharpness_description">يحدد مدى وضوح الصورة عند استخدام التباين الديناميكي لـ FSR</string>
|
||||
<string name="renderer_anti_aliasing">طريقة مضاد التعرج</string>
|
||||
<string name="renderer_optimize_spirv_output">تحسين مخرجات SPIRV</string>
|
||||
<string name="renderer_optimize_spirv_output_description">يعمل على تحسين أداء برامج التظليل المجمعة لتحسين كفاءة وحدة معالجة الرسومات، ولكنه قد يؤدي إلى زيادة وقت التحميل وإبطاء السرعة في البداية.</string>
|
||||
|
||||
|
||||
<string name="advanced">متقدم</string>
|
||||
@@ -495,7 +493,7 @@
|
||||
<string name="enable_buffer_history">تمكين سجل التخزين المؤقت</string>
|
||||
<string name="enable_buffer_history_description">يُتيح هذا الخيار الوصول إلى حالات التخزين المؤقت السابقة. وقد يُحسّن جودة العرض وثبات الأداء في بعض الألعاب.</string>
|
||||
<string name="use_optimized_vertex_buffers">مخازن الرؤوس المُحسّنة</string>
|
||||
<string name="use_optimized_vertex_buffers_description">يُتيح ربطًا مُحسَّنًا لمخازن الرؤوس لتحسين الأداء. يتطلب برامج تشغيل Turnip من Mesa 26.0 أو أحدث. قد يتعطل على برامج التشغيل الأقدم.</string>
|
||||
<string name="use_optimized_vertex_buffers_description">يتيح ربط مخزن الرؤوس المُحسّن لتحسين الأداء. يتطلب برامج تشغيل Turnip/QCOM من إصدار Mesa 26.0 أو أحدث. سيؤدي إلى تعطل النظام عند استخدام برامج تشغيل Turnip الأقدم.</string>
|
||||
|
||||
<string name="hacks">اختراقات</string>
|
||||
|
||||
@@ -504,7 +502,9 @@
|
||||
<string name="skip_cpu_inner_invalidation">تخطي إبطال صلاحية وحدة المعالجة المركزية الداخلية</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقتة من جانب وحدة المعالجة المركزية أثناء تحديثات الذاكرة، مما يقلل من استخدام وحدة المعالجة المركزية ويحسن أداءها. قد يتسبب ذلك في حدوث أعطال أو تعطل في بعض الألعاب.</string>
|
||||
<string name="fix_bloom_effects">إصلاح تأثيرات التوهج</string>
|
||||
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno 700)، ويزيل التوهج في Burnout. تحذير: قد يسبب ظهور خلل رسومي في ألعاب أخرى.</string>
|
||||
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno A6XX - A7XX/ Turnip)، ويزيل التوهج في Burnout. تحذير: قد يسبب تشوهات رسومية في ألعاب أخرى.</string>
|
||||
<string name="emulate_bgr565">محاكاة BGR565</string>
|
||||
<string name="emulate_bgr565_description">يُصلح مشاكل انعكاس الألوان في الألعاب أو ظهور تشوهات غريبة أو ظلال غريبة.</string>
|
||||
<string name="renderer_asynchronous_shaders">استخدم تظليل غير متزامن</string>
|
||||
<string name="renderer_asynchronous_shaders_description">يقوم بتجميع التظليل بشكل غير متزامن. قد يقلل ذلك من التقطعات ولكنه قد يؤدي أيضًا إلى حدوث أخطاء.</string>
|
||||
<string name="gpu_unswizzle_settings">إعدادات إلغاء ترتيب بيانات وحدة معالجة الرسومات</string>
|
||||
|
||||
@@ -332,7 +332,6 @@
|
||||
<string name="fsr_sharpness">تیژی FSR</string>
|
||||
<string name="fsr_sharpness_description">دیاریکردنی تیژی وێنە لە کاتی بەکارهێنانی FSR</string>
|
||||
<string name="renderer_anti_aliasing">شێوازی دژە-خاوڕۆیی</string>
|
||||
<string name="renderer_optimize_spirv_output_description">شێیدەرە کۆمپایلکراوەکان باش دەکات بۆ باشترکردنی کارایی GPU.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">وردیی DMA</string>
|
||||
|
||||
@@ -442,8 +442,6 @@
|
||||
<string name="fsr_sharpness">Ostrost FSR</string>
|
||||
<string name="fsr_sharpness_description">Určuje jak ostře bude obraz vypadat při použití dynamického kontrastu FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Metoda anti-aliasingu</string>
|
||||
<string name="renderer_optimize_spirv_output">Optimalizovat výstup SPIRV</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Optimalizuje kompilované shadery pro zlepšení efektivity GPU, ale mohou se objevit delší nahrávací časy a zpomalení v úvodu.</string>
|
||||
|
||||
|
||||
<string name="advanced">Pokročilé</string>
|
||||
|
||||
@@ -442,8 +442,6 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
|
||||
<string name="fsr_sharpness">FSR-Schärfe</string>
|
||||
<string name="fsr_sharpness_description">Bestimmt die Schärfe bei FSR-Nutzung.</string>
|
||||
<string name="renderer_anti_aliasing">Kantenglättung</string>
|
||||
<string name="renderer_optimize_spirv_output">Optimiere SPIRV-Ausgabe</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Optimiert den kompilierten Shader, um die GPU-Effizienz zu verbessern.</string>
|
||||
|
||||
|
||||
<string name="advanced">Erweitert</string>
|
||||
|
||||
@@ -272,7 +272,7 @@
|
||||
<string name="general_information">Información general</string>
|
||||
<string name="hardware">Hardware</string>
|
||||
<string name="supported_abis">ABIs soportadas</string>
|
||||
<string name="cpu_info">Información del procesador</string>
|
||||
<string name="cpu_info">Información de la CPU</string>
|
||||
<string name="gpu_information">Información de la GPU</string>
|
||||
<string name="vulkan_driver_version">Versión del controlador de Vulkan</string>
|
||||
<string name="error_getting_emulator_info">Error al obtener la información del emulador</string>
|
||||
@@ -416,8 +416,8 @@
|
||||
<string name="turbo_speed_limit_description">Cuando el modo turbo esté activado, la emulación se ejecutará a esta velocidad.</string>
|
||||
<string name="slow_speed_limit">Velocidad lenta</string>
|
||||
<string name="slow_speed_limit_description">Cuando el modo lento esté activado, la emulación se ejecutará a esta velocidad.</string>
|
||||
<string name="cpu_backend">Motor del procesador</string>
|
||||
<string name="cpu_accuracy">Precisión del procesador</string>
|
||||
<string name="cpu_backend">Motor de la CPU</string>
|
||||
<string name="cpu_accuracy">Precisión de la CPU</string>
|
||||
<string name="value_with_units">%1$s%2$s</string>
|
||||
|
||||
<!-- System settings strings -->
|
||||
@@ -433,7 +433,7 @@
|
||||
<string name="set_custom_rtc">Configurar RTC personalizado</string>
|
||||
|
||||
<!-- CPU -->
|
||||
<string name="fast_cpu_time">Overclock del procesador</string>
|
||||
<string name="fast_cpu_time">Overclock de la CPU</string>
|
||||
<string name="fast_cpu_time_description">Fuerza a la CPU emulada a ejecutarser a una velocidad de reloj más alta, lo cual reduce ciertos limitadores de fotogramas por segundo. Usa Boost (1700 MHz) para ejecutar a la velocidad de reloj nativa más alta de la Switch, o Fast (2000 MHz) para ejecutar a una velocidad doble de reloj.</string>
|
||||
<string name="custom_cpu_ticks">Ticks de CPU personalizados</string>
|
||||
<string name="custom_cpu_ticks_description">Establezca un valor personalizado de los ciclos de la CPU. Los valores más altos pueden aumentar el rendimiento, pero también pueden hacer que el juego se congele. Se recomienda un rango de 77–21000.</string>
|
||||
@@ -457,8 +457,6 @@
|
||||
<string name="fsr_sharpness">Nitidez FSR</string>
|
||||
<string name="fsr_sharpness_description">Ajusta la intensidad del filtro de enfoque al usar el contraste dinámico de FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Método de suavizado de bordes</string>
|
||||
<string name="renderer_optimize_spirv_output">Optimizar la salida de SPIRV</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Optimiza los sombreadores compilados para mejorar la eficiencia de la GPU.</string>
|
||||
|
||||
|
||||
<string name="advanced">Avanzado</string>
|
||||
@@ -489,7 +487,7 @@
|
||||
<string name="enable_buffer_history">Activar el historial del búfer</string>
|
||||
<string name="enable_buffer_history_description">Permite el acceso al estado del búfer anterior. Esta opción puede mejorar la calidad de renderizado y la consistencia en el rendimiento de algunos juegos.</string>
|
||||
<string name="use_optimized_vertex_buffers">Búferes de vértices optimizados</string>
|
||||
<string name="use_optimized_vertex_buffers_description">Permite la vinculación optimizada del búfer de vértices para un mejor rendimiento. Requiere controladores de Mesa 26.0+ Turnip. Se producirán fallos en controladores más antiguos.</string>
|
||||
<string name="use_optimized_vertex_buffers_description">Permite la optimización del enlace del búfer de vértices para un mejor rendimiento. Requiere controladores Mesa 26.0+ Turnip/ controladores QCOM. Causará fallos con controladores Turnip más antiguos.</string>
|
||||
|
||||
<string name="hacks">Hacks</string>
|
||||
|
||||
@@ -498,7 +496,9 @@
|
||||
<string name="skip_cpu_inner_invalidation">Omitir invalidación interna de la CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché de la CPU durante las actualizaciones de memoria, lo que reduce el uso de la CPU y mejora su rendimiento. Esto puede causar fallos o bloqueos en algunos juegos.</string>
|
||||
<string name="fix_bloom_effects">Arreglar los efectos de resplandor</string>
|
||||
<string name="fix_bloom_effects_description">Reduce el efecto de resplandor en LA/EOW (Adreno 700), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos.</string>
|
||||
<string name="fix_bloom_effects_description">Reduce el efecto de resplandor en LA/EOW (Adreno A6XX - A7XX/ Turnip), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos.</string>
|
||||
<string name="emulate_bgr565">Emular BGR565</string>
|
||||
<string name="emulate_bgr565_description">Soluciona problemas con colores invertidos en juegos, artefactos o sombras extrañas.</string>
|
||||
<string name="renderer_asynchronous_shaders">Usar sombreadores asíncronos</string>
|
||||
<string name="renderer_asynchronous_shaders_description">Compila los sombreadores de forma asíncrona. Esto puede reducir los tirones, pero también puede introducir errores gráficos.</string>
|
||||
<string name="gpu_unswizzle_settings">Ajustes de desentrelazado de la GPU</string>
|
||||
@@ -536,7 +536,7 @@
|
||||
<string name="warning_resolution">Escalar la resolución a 2x o más puede causar problemas y ralentizar significativamente su dispositivo.</string>
|
||||
|
||||
<!-- Debug settings strings -->
|
||||
<string name="cpu">Procesador</string>
|
||||
<string name="cpu">CPU</string>
|
||||
<string name="use_auto_stub">Usar Auto Stub</string>
|
||||
<string name="use_auto_stub_description">Rellena automáticamente servicios y funciones ausentes. Puede mejorar la compatibilidad pero puede causar cierres inesperados.</string>
|
||||
|
||||
|
||||
@@ -125,8 +125,6 @@
|
||||
<string name="nvdec_emulation_none">هیچکدام</string>
|
||||
|
||||
<!-- Optimize Spir-V output -->
|
||||
<string name="renderer_optimize_spirv_output">بهینهسازی خروجی Spir-V</string>
|
||||
<string name="renderer_optimize_spirv_output_description">شیدر کامپایل شده را برای بهبود کارایی GPU بهینهسازی میکند.</string>
|
||||
<string name="never">هرگز</string>
|
||||
<string name="on_load">در هنگام بارگذاری</string>
|
||||
<string name="always">همیشه</string>
|
||||
|
||||
@@ -455,7 +455,6 @@
|
||||
<string name="fsr_sharpness">Netteté FSR</string>
|
||||
<string name="fsr_sharpness_description">Détermine à quel point l\'image sera affinée lors de l\'utilisation du contraste dynamique FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Méthode d\'anticrénelage</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Optimise le shader compilé pour améliorer l\'efficacité du GPU.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">Précision DMA</string>
|
||||
|
||||
@@ -362,7 +362,6 @@
|
||||
<string name="fsr_sharpness">חדות FSR</string>
|
||||
<string name="fsr_sharpness_description">קובע את מידת החדות בעת שימוש ב-FSR.</string>
|
||||
<string name="renderer_anti_aliasing">שיטת Anti-aliasing</string>
|
||||
<string name="renderer_optimize_spirv_output_description">משפר את השאדר המהודר כדי להגביר את יעילות ה-GPU.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">דיוק DMA</string>
|
||||
|
||||
@@ -351,7 +351,6 @@
|
||||
<string name="fsr_sharpness">FSR élesség</string>
|
||||
<string name="fsr_sharpness_description">Meghatározza, milyen éles lesz a kép az FSR dinamikus kontraszt használata közben.</string>
|
||||
<string name="renderer_anti_aliasing">Élsimítási módszer</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Optimalizálja a lefordított shadert a GPU hatékonyságának javításáért.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">DMA pontosság</string>
|
||||
|
||||
@@ -383,7 +383,6 @@
|
||||
<string name="fsr_sharpness">Ketajaman FSR</string>
|
||||
<string name="fsr_sharpness_description">Menentukan seberapa tajam gambar akan terlihat saat menggunakan kontras dinamis FSR</string>
|
||||
<string name="renderer_anti_aliasing">Metode anti-aliasing</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Mengoptimalkan shader yang dikompilasi untuk meningkatkan efisiensi GPU.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">Akurasi DMA</string>
|
||||
|
||||
@@ -390,7 +390,6 @@
|
||||
<string name="fsr_sharpness">Nitidezza FSR</string>
|
||||
<string name="fsr_sharpness_description">Determina quanto sarà nitida l\'immagine utilizzando il contrasto dinamico di FSR</string>
|
||||
<string name="renderer_anti_aliasing">Metodo di anti-aliasing</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Ottimizza lo shader compilato per migliorare l\'efficienza della GPU.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">Precisione DMA</string>
|
||||
|
||||
@@ -349,7 +349,6 @@
|
||||
<string name="renderer_vsync">垂直同期モード</string>
|
||||
<string name="renderer_scaling_filter">ウィンドウ適応フィルター</string>
|
||||
<string name="renderer_anti_aliasing">アンチエイリアス方式</string>
|
||||
<string name="renderer_optimize_spirv_output_description">コンパイル済みシェーダーを最適化し、GPUの効率を向上させます。</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">DMA精度</string>
|
||||
|
||||
@@ -349,7 +349,6 @@
|
||||
<string name="renderer_vsync">수직동기화 모드</string>
|
||||
<string name="renderer_scaling_filter">윈도우 적응 필터</string>
|
||||
<string name="renderer_anti_aliasing">안티에일리어싱 방법</string>
|
||||
<string name="renderer_optimize_spirv_output_description">컴파일된 셰이더를 최적화하여 GPU 효율성을 향상시킵니다.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">DMA 정확도</string>
|
||||
|
||||
@@ -332,7 +332,6 @@
|
||||
<string name="fsr_sharpness">FSR-skarphet</string>
|
||||
<string name="fsr_sharpness_description">Bestemmer bildekvalitet med FSR</string>
|
||||
<string name="renderer_anti_aliasing">Anti-aliasing-metode</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Optimaliserer den kompilerte shaderen for å forbedre GPU-effektiviteten.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">DMA-nøyaktighet</string>
|
||||
|
||||
@@ -442,8 +442,6 @@
|
||||
<string name="fsr_sharpness">Ostrość FSR</string>
|
||||
<string name="fsr_sharpness_description">Kontroluje ostrość obrazu w FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Metoda wygładzania krawędzi</string>
|
||||
<string name="renderer_optimize_spirv_output">Optymalizuj wyjście SPIRV</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Optymalizuje skompilowany shader w celu poprawy wydajności GPU.</string>
|
||||
|
||||
|
||||
<string name="advanced">Zaawansowane</string>
|
||||
|
||||
@@ -433,7 +433,6 @@
|
||||
<string name="fsr_sharpness">Nitidez do FSR</string>
|
||||
<string name="fsr_sharpness_description">Determina a nitidez da imagem ao utilizar o contraste dinâmico do FSR</string>
|
||||
<string name="renderer_anti_aliasing">Método de Anti-aliasing</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Otimiza o shader compilado para melhorar a eficiência da GPU.</string>
|
||||
|
||||
|
||||
<string name="advanced">Avançado</string>
|
||||
|
||||
@@ -355,7 +355,6 @@
|
||||
<string name="fsr_sharpness">Nitidez do FSR</string>
|
||||
<string name="fsr_sharpness_description">Determina a nitidez da imagem ao usar contraste dinâmico do FSR</string>
|
||||
<string name="renderer_anti_aliasing">Método de Anti-Serrilhado</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Otimiza o shader compilado para melhorar a eficiência da GPU.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">Precisão da DMA</string>
|
||||
|
||||
@@ -459,8 +459,6 @@
|
||||
<string name="fsr_sharpness">Резкость FSR</string>
|
||||
<string name="fsr_sharpness_description">Определяет, насколько чётким будет изображение при использовании динамического контраста FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Метод сглаживания</string>
|
||||
<string name="renderer_optimize_spirv_output">Оптимизация вывода SPIRV</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Оптимизирует скомпилированный шейдер для повышения эффективности ГПУ.</string>
|
||||
|
||||
|
||||
<string name="advanced">Расширенные</string>
|
||||
@@ -491,8 +489,6 @@
|
||||
<string name="enable_buffer_history">Включить историю буфера</string>
|
||||
<string name="enable_buffer_history_description">Позволяет обращаться к предыдущим состояниям буфера. Эта опция может повысить качество рендеринга и стабильность производительности в некоторых играх.</string>
|
||||
<string name="use_optimized_vertex_buffers">Оптимизированные вершинные буферы</string>
|
||||
<string name="use_optimized_vertex_buffers_description">Активирует оптимизированную привязку вершинных буферов для улучшения производительности. Требуются Mesa Turnip драйвера версией не ниже 26.0, на более старых драйверах будут происходить сбои и краши</string>
|
||||
|
||||
<string name="hacks">Хаки</string>
|
||||
|
||||
<string name="fast_gpu_time">Быстрое время ГПУ</string>
|
||||
@@ -500,7 +496,6 @@
|
||||
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
|
||||
<string name="fix_bloom_effects">Исправить эффекты размытия</string>
|
||||
<string name="fix_bloom_effects_description">Частично убирает размытие в LA/EOW (Adreno 700), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх.</string>
|
||||
<string name="renderer_asynchronous_shaders">Использовать асинхронные шейдеры</string>
|
||||
<string name="renderer_asynchronous_shaders_description">Компилирует шейдеры асинхронно. Это может уменьшить подтормаживания, но также может вызвать графические артефакты.</string>
|
||||
<string name="gpu_unswizzle_settings">Настройки распаковки текстур (Unswizzle)</string>
|
||||
|
||||
@@ -354,7 +354,6 @@
|
||||
<string name="fsr_sharpness">ФСР оштрина</string>
|
||||
<string name="fsr_sharpness_description">Одређује колико ће се слика наоштрен трајати док користи \"ФСР\" динамички контраст</string>
|
||||
<string name="renderer_anti_aliasing">Метода против алиасирања</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Оптимизира састављена схадер за побољшање ефикасности ГПУ-а.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">DMA тачност</string>
|
||||
|
||||
@@ -459,8 +459,6 @@
|
||||
<string name="fsr_sharpness">Різкість FSR</string>
|
||||
<string name="fsr_sharpness_description">Визначає різкість зображення при використанні FSR.</string>
|
||||
<string name="renderer_anti_aliasing">Згладжування</string>
|
||||
<string name="renderer_optimize_spirv_output">Оптимізовувати виведення SPIRV</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Оптимізує скомпільований шейдер для покращення ефективності GPU.</string>
|
||||
|
||||
|
||||
<string name="advanced">Додаткові</string>
|
||||
@@ -491,7 +489,7 @@
|
||||
<string name="enable_buffer_history">Увімкнути історію буфера</string>
|
||||
<string name="enable_buffer_history_description">Вмикає доступ до попередніх станів буфера. Цей параметр може покращити якість візуалізації та стабільну продуктивність у деяких іграх.</string>
|
||||
<string name="use_optimized_vertex_buffers">Оптимізовані буфери вершин</string>
|
||||
<string name="use_optimized_vertex_buffers_description">Застосовує оптимізований буфер вершин, щоб покращити продуктивність. Потребує драйверів Mesa 26.0+ Turnip. На старіших драйверах виникатиме збій.</string>
|
||||
<string name="use_optimized_vertex_buffers_description">Застосовує оптимізований буфер вершин, щоб покращити продуктивність. Потребує драйверів Mesa 26.0+ Turnip / QCOM. На старіших драйверах Turnip виникатиме збій.</string>
|
||||
|
||||
<string name="hacks">Обхідні рішення</string>
|
||||
|
||||
@@ -500,7 +498,9 @@
|
||||
<string name="skip_cpu_inner_invalidation">Пропустити внутрішнє інвалідування CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
|
||||
<string name="fix_bloom_effects">Виправити ефекти світіння</string>
|
||||
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno 700), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
|
||||
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno A6XX–A7XX / Turnip), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
|
||||
<string name="emulate_bgr565">Емулювати BGR565</string>
|
||||
<string name="emulate_bgr565_description">Виправляє проблеми з інвертованими кольорами в іграх або дивними артефактами чи тінями.</string>
|
||||
<string name="renderer_asynchronous_shaders">Асинхронні шейдери</string>
|
||||
<string name="renderer_asynchronous_shaders_description">Компілює шейдери асинхронно. Це може зменшити затримки, але також може спричинити графічні баги.</string>
|
||||
<string name="gpu_unswizzle_settings">Налаштування розпакування за допомогою ГП</string>
|
||||
|
||||
@@ -330,7 +330,6 @@
|
||||
<string name="fsr_sharpness">Độ sắc nét FSR</string>
|
||||
<string name="fsr_sharpness_description">Độ sắc nét khi dùng FSR</string>
|
||||
<string name="renderer_anti_aliasing">Phương pháp khử răng cưa</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Tối ưu hóa shader đã biên dịch để cải thiện hiệu suất GPU.</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">Độ chính xác DMA</string>
|
||||
|
||||
@@ -453,8 +453,6 @@
|
||||
<string name="fsr_sharpness">FSR 锐化度</string>
|
||||
<string name="fsr_sharpness_description">指定使用 FSR 时图像的锐化程度</string>
|
||||
<string name="renderer_anti_aliasing">抗锯齿方式</string>
|
||||
<string name="renderer_optimize_spirv_output">优化 SPIRV 输出</string>
|
||||
<string name="renderer_optimize_spirv_output_description">优化编译后的着色器以提高GPU效率。</string>
|
||||
|
||||
|
||||
<string name="advanced">高级</string>
|
||||
@@ -485,8 +483,6 @@
|
||||
<string name="enable_buffer_history">启用缓冲区历史</string>
|
||||
<string name="enable_buffer_history_description">启用对先前缓冲区状态的访问。此选项可在某些游戏中提升渲染质量并保持性能的一致性。</string>
|
||||
<string name="use_optimized_vertex_buffers">优化顶点缓冲区</string>
|
||||
<string name="use_optimized_vertex_buffers_description">启用经过优化的顶点缓冲区绑定以提升性能。需要 Mesa 26.0 及以上版本的 Turnip 驱动程序。在旧版驱动程序上会导致程序崩溃。</string>
|
||||
|
||||
<string name="hacks">Hacks</string>
|
||||
|
||||
<string name="fast_gpu_time">GPU 超频频率</string>
|
||||
@@ -494,7 +490,6 @@
|
||||
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">在内存更新期间跳过某些CPU端缓存无效化,减少CPU使用率并提高其性能。可能会导致某些游戏出现故障或崩溃。</string>
|
||||
<string name="fix_bloom_effects">修复 Bloom 效果</string>
|
||||
<string name="fix_bloom_effects_description">减少《塞尔达传说:智慧的再现》(Adreno 700)中的 bloom 模糊,并移除《Burnout》中的 bloom 效果。警告:可能会导致在其他游戏中出现画面显示问题。</string>
|
||||
<string name="renderer_asynchronous_shaders">使用异步着色器</string>
|
||||
<string name="renderer_asynchronous_shaders_description">异步编译着色器。这可能会减少卡顿,但也可能会导致图形错误。</string>
|
||||
<string name="gpu_unswizzle_settings">GPU 还原设置</string>
|
||||
|
||||
@@ -440,7 +440,6 @@
|
||||
<string name="fsr_sharpness">FSR 銳化度</string>
|
||||
<string name="fsr_sharpness_description">使用 FSR 時圖片的銳化程度</string>
|
||||
<string name="renderer_anti_aliasing">抗鋸齒</string>
|
||||
<string name="renderer_optimize_spirv_output_description">最佳化編譯後的著色器以提高GPU效率。</string>
|
||||
|
||||
|
||||
<string name="dma_accuracy">DMA 準確度</string>
|
||||
|
||||
@@ -469,8 +469,6 @@
|
||||
<string name="fsr_sharpness">FSR sharpness</string>
|
||||
<string name="fsr_sharpness_description">Determines how sharpened the image will look while using FSR\'s dynamic contrast</string>
|
||||
<string name="renderer_anti_aliasing">Anti-aliasing method</string>
|
||||
<string name="renderer_optimize_spirv_output">Optimize SPIRV output</string>
|
||||
<string name="renderer_optimize_spirv_output_description">Optimizes compiled shaders to improve GPU efficiency, but may introduce longer loading times and initial slowdowns.</string>
|
||||
|
||||
|
||||
<string name="advanced">Advanced</string>
|
||||
@@ -501,7 +499,7 @@
|
||||
<string name="enable_buffer_history">Enable buffer history</string>
|
||||
<string name="enable_buffer_history_description">Enables access to previous buffer states. This option may improve rendering quality and performance consistency in some games.</string>
|
||||
<string name="use_optimized_vertex_buffers">Optimized Vertex Buffers</string>
|
||||
<string name="use_optimized_vertex_buffers_description">Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers. Will crash on older drivers.</string>
|
||||
<string name="use_optimized_vertex_buffers_description">Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers/ QCOM drivers. Will crash on older Turnip drivers.</string>
|
||||
|
||||
<string name="hacks">Hacks</string>
|
||||
|
||||
@@ -510,7 +508,9 @@
|
||||
<string name="skip_cpu_inner_invalidation">Skip CPU Inner Invalidation</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string>
|
||||
<string name="fix_bloom_effects">Fix Bloom Effects</string>
|
||||
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno 700), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
|
||||
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno A6XX - A7XX/ Turnip), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
|
||||
<string name="emulate_bgr565">Emulate BGR565</string>
|
||||
<string name="emulate_bgr565_description">Fixes problems with inverted colors in games or strange artifacts or strange shadows.</string>
|
||||
<string name="renderer_asynchronous_shaders">Use asynchronous shaders</string>
|
||||
<string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches.</string>
|
||||
<string name="gpu_unswizzle_settings">GPU Unswizzle Settings</string>
|
||||
|
||||
@@ -388,10 +388,6 @@ struct Values {
|
||||
true,
|
||||
true};
|
||||
|
||||
SwitchableSetting<SpirvOptimizeMode, true> optimize_spirv_output{linkage,
|
||||
SpirvOptimizeMode::Never,
|
||||
"optimize_spirv_output",
|
||||
Category::Renderer};
|
||||
SwitchableSetting<bool> use_asynchronous_gpu_emulation{
|
||||
linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer};
|
||||
// *nix platforms may have issues with the borderless windowed fullscreen mode.
|
||||
@@ -555,6 +551,9 @@ struct Values {
|
||||
SwitchableSetting<bool> fix_bloom_effects{linkage, false, "fix_bloom_effects",
|
||||
Category::RendererHacks};
|
||||
|
||||
SwitchableSetting<bool> emulate_bgr565{linkage, false, "emulate_bgr565",
|
||||
Category::RendererHacks};
|
||||
|
||||
SwitchableSetting<bool> rescale_hack{linkage, false, "rescale_hack",
|
||||
Category::RendererHacks};
|
||||
|
||||
@@ -584,7 +583,7 @@ struct Values {
|
||||
|
||||
SwitchableSetting<ExtendedDynamicState> dyna_state{linkage,
|
||||
#if defined(ANDROID)
|
||||
ExtendedDynamicState::EDS1,
|
||||
ExtendedDynamicState::Disabled,
|
||||
#elif defined(__APPLE__)
|
||||
ExtendedDynamicState::Disabled,
|
||||
#else
|
||||
|
||||
@@ -65,17 +65,6 @@ static inline u64 xgetbv(u32 index) {
|
||||
|
||||
namespace Common {
|
||||
|
||||
CPUCaps::Manufacturer CPUCaps::ParseManufacturer(std::string_view brand_string) {
|
||||
if (brand_string == "GenuineIntel") {
|
||||
return Manufacturer::Intel;
|
||||
} else if (brand_string == "AuthenticAMD") {
|
||||
return Manufacturer::AMD;
|
||||
} else if (brand_string == "HygonGenuine") {
|
||||
return Manufacturer::Hygon;
|
||||
}
|
||||
return Manufacturer::Unknown;
|
||||
}
|
||||
|
||||
// Detects the various CPU features
|
||||
static CPUCaps Detect() {
|
||||
CPUCaps caps = {};
|
||||
@@ -94,8 +83,6 @@ static CPUCaps Detect() {
|
||||
std::memcpy(&caps.brand_string[4], &cpu_id[3], sizeof(u32));
|
||||
std::memcpy(&caps.brand_string[8], &cpu_id[2], sizeof(u32));
|
||||
|
||||
caps.manufacturer = CPUCaps::ParseManufacturer(caps.brand_string);
|
||||
|
||||
// Set reasonable default cpu string even if brand string not available
|
||||
std::strncpy(caps.cpu_string, caps.brand_string, std::size(caps.brand_string));
|
||||
|
||||
@@ -134,14 +121,21 @@ static CPUCaps Detect() {
|
||||
__cpuidex(cpu_id, 0x00000007, 0x00000000);
|
||||
// Can't enable AVX{2,512} unless the XSAVE/XGETBV checks above passed
|
||||
if (caps.avx) {
|
||||
// ebx
|
||||
caps.avx2 = Common::Bit<5>(cpu_id[1]);
|
||||
caps.avx512f = Common::Bit<16>(cpu_id[1]);
|
||||
caps.avx512dq = Common::Bit<17>(cpu_id[1]);
|
||||
caps.avx512cd = Common::Bit<28>(cpu_id[1]);
|
||||
caps.avx512bw = Common::Bit<30>(cpu_id[1]);
|
||||
caps.avx512vl = Common::Bit<31>(cpu_id[1]);
|
||||
// ecx
|
||||
caps.avx512vbmi = Common::Bit<1>(cpu_id[2]);
|
||||
caps.avx512vbmi2 = Common::Bit<6>(cpu_id[2]);
|
||||
caps.avx512vnni = Common::Bit<11>(cpu_id[2]);
|
||||
caps.avx512bitalg = Common::Bit<12>(cpu_id[2]);
|
||||
caps.avx512popcntq = Common::Bit<14>(cpu_id[2]);
|
||||
// edx
|
||||
caps.avx512bf16 = Common::Bit<7>(cpu_id[3]);
|
||||
}
|
||||
|
||||
caps.bmi1 = Common::Bit<3>(cpu_id[1]);
|
||||
@@ -221,17 +215,15 @@ std::optional<int> GetProcessorCount() {
|
||||
LOG_ERROR(Frontend, "Failed to query core count.");
|
||||
return std::nullopt;
|
||||
}
|
||||
std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(
|
||||
length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
|
||||
std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
|
||||
// Now query the core count.
|
||||
if (!GetLogicalProcessorInformation(buffer.data(), &length)) {
|
||||
LOG_ERROR(Frontend, "Failed to query core count.");
|
||||
return std::nullopt;
|
||||
}
|
||||
return static_cast<int>(
|
||||
std::count_if(buffer.cbegin(), buffer.cend(), [](const auto& proc_info) {
|
||||
return proc_info.Relationship == RelationProcessorCore;
|
||||
}));
|
||||
return int(std::count_if(buffer.cbegin(), buffer.cend(), [](const auto& proc_info) {
|
||||
return proc_info.Relationship == RelationProcessorCore;
|
||||
}));
|
||||
#elif defined(__unix__)
|
||||
const int thread_count = std::thread::hardware_concurrency();
|
||||
std::ifstream smt("/sys/devices/system/cpu/smt/active");
|
||||
|
||||
+44
-48
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2013 Dolphin Emulator Project / 2015 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
@@ -12,17 +15,6 @@ namespace Common {
|
||||
|
||||
/// x86/x64 CPU capabilities that may be detected by this module
|
||||
struct CPUCaps {
|
||||
|
||||
enum class Manufacturer : u8 {
|
||||
Unknown = 0,
|
||||
Intel = 1,
|
||||
AMD = 2,
|
||||
Hygon = 3,
|
||||
};
|
||||
|
||||
static Manufacturer ParseManufacturer(std::string_view brand_string);
|
||||
|
||||
Manufacturer manufacturer;
|
||||
char brand_string[13];
|
||||
|
||||
char cpu_string[48];
|
||||
@@ -36,45 +28,49 @@ struct CPUCaps {
|
||||
u32 crystal_frequency;
|
||||
u64 tsc_frequency; // Derived from the above three values
|
||||
|
||||
bool sse : 1;
|
||||
bool sse2 : 1;
|
||||
bool sse3 : 1;
|
||||
bool ssse3 : 1;
|
||||
bool sse4_1 : 1;
|
||||
bool sse4_2 : 1;
|
||||
|
||||
bool avx : 1;
|
||||
bool avx_vnni : 1;
|
||||
bool avx2 : 1;
|
||||
bool avx512f : 1;
|
||||
bool avx512dq : 1;
|
||||
bool avx512cd : 1;
|
||||
bool avx512bw : 1;
|
||||
bool avx512vl : 1;
|
||||
bool avx512vbmi : 1;
|
||||
bool avx512bitalg : 1;
|
||||
|
||||
bool aes : 1;
|
||||
bool bmi1 : 1;
|
||||
bool bmi2 : 1;
|
||||
bool f16c : 1;
|
||||
bool fma : 1;
|
||||
bool fma4 : 1;
|
||||
bool gfni : 1;
|
||||
bool invariant_tsc : 1;
|
||||
bool lzcnt : 1;
|
||||
bool monitorx : 1;
|
||||
bool movbe : 1;
|
||||
bool pclmulqdq : 1;
|
||||
bool popcnt : 1;
|
||||
bool sha : 1;
|
||||
bool waitpkg : 1;
|
||||
#define CPU_CAPS_LIST \
|
||||
CPU_CAPS_ELEM(sse) \
|
||||
CPU_CAPS_ELEM(sse2) \
|
||||
CPU_CAPS_ELEM(sse3) \
|
||||
CPU_CAPS_ELEM(ssse3) \
|
||||
CPU_CAPS_ELEM(sse4_1) \
|
||||
CPU_CAPS_ELEM(sse4_2) \
|
||||
CPU_CAPS_ELEM(avx) \
|
||||
CPU_CAPS_ELEM(avx_vnni) \
|
||||
CPU_CAPS_ELEM(avx2) \
|
||||
CPU_CAPS_ELEM(avx512f) \
|
||||
CPU_CAPS_ELEM(avx512dq) \
|
||||
CPU_CAPS_ELEM(avx512cd) \
|
||||
CPU_CAPS_ELEM(avx512bw) \
|
||||
CPU_CAPS_ELEM(avx512vl) \
|
||||
CPU_CAPS_ELEM(avx512vbmi) \
|
||||
CPU_CAPS_ELEM(avx512vbmi2) \
|
||||
CPU_CAPS_ELEM(avx512vnni) \
|
||||
CPU_CAPS_ELEM(avx512bitalg) \
|
||||
CPU_CAPS_ELEM(avx512popcntq) \
|
||||
CPU_CAPS_ELEM(avx512bf16) \
|
||||
CPU_CAPS_ELEM(aes) \
|
||||
CPU_CAPS_ELEM(bmi1) \
|
||||
CPU_CAPS_ELEM(bmi2) \
|
||||
CPU_CAPS_ELEM(f16c) \
|
||||
CPU_CAPS_ELEM(fma) \
|
||||
CPU_CAPS_ELEM(fma4) \
|
||||
CPU_CAPS_ELEM(gfni) \
|
||||
CPU_CAPS_ELEM(invariant_tsc) \
|
||||
CPU_CAPS_ELEM(lzcnt) \
|
||||
CPU_CAPS_ELEM(monitorx) \
|
||||
CPU_CAPS_ELEM(movbe) \
|
||||
CPU_CAPS_ELEM(pclmulqdq) \
|
||||
CPU_CAPS_ELEM(popcnt) \
|
||||
CPU_CAPS_ELEM(sha) \
|
||||
CPU_CAPS_ELEM(waitpkg)
|
||||
#define CPU_CAPS_ELEM(n) bool n : 1;
|
||||
CPU_CAPS_LIST
|
||||
#undef CPU_CAPS_ELEM
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the supported capabilities of the host CPU
|
||||
* @return Reference to a CPUCaps struct with the detected host CPU capabilities
|
||||
*/
|
||||
/// Gets the supported capabilities of the host CPU
|
||||
/// @return Reference to a CPUCaps struct with the detected host CPU capabilities
|
||||
const CPUCaps& GetCPUCaps();
|
||||
|
||||
/// Detects CPU core count
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <fmt/format.h>
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/fs_types.h"
|
||||
@@ -25,7 +26,10 @@ std::vector<std::filesystem::path> GetModFolder(const std::string& root) {
|
||||
"romfslite"};
|
||||
|
||||
if (std::ranges::find(valid_names, name) != valid_names.end()) {
|
||||
paths.emplace_back(entry.path().parent_path());
|
||||
const auto parent = entry.path().parent_path();
|
||||
if (std::ranges::find(paths, parent) == paths.end()) {
|
||||
paths.emplace_back(parent);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -80,55 +80,24 @@ std::optional<std::string> UpdateChecker::GetResponse(std::string url, std::stri
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<UpdateChecker::Update> UpdateChecker::GetLatestRelease(bool include_prereleases) {
|
||||
std::optional<UpdateChecker::Update> UpdateChecker::GetLatestRelease() {
|
||||
#ifdef YUZU_BUNDLED_OPENSSL
|
||||
const auto update_check_url = fmt::format("https://{}", Common::g_build_auto_update_api);
|
||||
#else
|
||||
const auto update_check_url = std::string{Common::g_build_auto_update_api};
|
||||
#endif
|
||||
|
||||
auto update_check_path = fmt::format("{}{}", std::string{Common::g_build_auto_update_api_path},
|
||||
std::string{Common::g_build_auto_update_repo});
|
||||
auto update_check_path = std::string{Common::g_build_auto_update_api_path};
|
||||
try {
|
||||
if (include_prereleases) { // This can return either a prerelease or a stable release,
|
||||
// whichever is more recent.
|
||||
const auto update_check_tags_path = update_check_path + "/tags";
|
||||
const auto update_check_releases_path = update_check_path + "/releases";
|
||||
const auto response = UpdateChecker::GetResponse(update_check_url, update_check_path);
|
||||
|
||||
const auto tags_response = UpdateChecker::GetResponse(update_check_url, update_check_tags_path);
|
||||
const auto releases_response = UpdateChecker::GetResponse(update_check_url, update_check_releases_path);
|
||||
if (!response)
|
||||
return {};
|
||||
|
||||
if (!tags_response || !releases_response)
|
||||
return {};
|
||||
|
||||
const std::string latest_tag
|
||||
= nlohmann::json::parse(tags_response.value()).at(0).at("name");
|
||||
const std::string latest_name =
|
||||
nlohmann::json::parse(releases_response.value()).at(0).at("name");
|
||||
|
||||
const bool latest_tag_has_release = releases_response.value().find(
|
||||
fmt::format("\"{}\"", latest_tag))
|
||||
!= std::string::npos;
|
||||
|
||||
// If there is a newer tag, but that tag has no associated release, don't prompt the
|
||||
// user to update.
|
||||
if (!latest_tag_has_release)
|
||||
return {};
|
||||
|
||||
return Update{latest_tag, latest_name};
|
||||
} else { // This is a stable release, only check for other stable releases.
|
||||
update_check_path += "/releases/latest";
|
||||
const auto response = UpdateChecker::GetResponse(update_check_url, update_check_path);
|
||||
|
||||
if (!response)
|
||||
return {};
|
||||
|
||||
const std::string latest_tag = nlohmann::json::parse(response.value()).at("tag_name");
|
||||
const std::string latest_name = nlohmann::json::parse(response.value()).at("name");
|
||||
|
||||
return Update{latest_tag, latest_name};
|
||||
}
|
||||
const std::string latest_tag = nlohmann::json::parse(response.value()).at("tag_name");
|
||||
const std::string latest_name = nlohmann::json::parse(response.value()).at("name");
|
||||
|
||||
return Update{latest_tag, latest_name};
|
||||
} catch (nlohmann::detail::out_of_range&) {
|
||||
LOG_ERROR(Frontend,
|
||||
"Parsing JSON response from {}{} failed during update check: "
|
||||
@@ -147,12 +116,8 @@ std::optional<UpdateChecker::Update> UpdateChecker::GetLatestRelease(bool includ
|
||||
}
|
||||
|
||||
std::optional<UpdateChecker::Update> UpdateChecker::GetUpdate() {
|
||||
const bool is_prerelease = ((strstr(Common::g_build_version, "pre-alpha") != NULL) ||
|
||||
(strstr(Common::g_build_version, "alpha") != NULL) ||
|
||||
(strstr(Common::g_build_version, "beta") != NULL) ||
|
||||
(strstr(Common::g_build_version, "rc") != NULL));
|
||||
const std::optional<UpdateChecker::Update> latest_release_tag =
|
||||
UpdateChecker::GetLatestRelease(is_prerelease);
|
||||
UpdateChecker::GetLatestRelease();
|
||||
|
||||
if (!latest_release_tag)
|
||||
goto empty;
|
||||
|
||||
@@ -18,6 +18,6 @@ typedef struct {
|
||||
} Update;
|
||||
|
||||
std::optional<std::string> GetResponse(std::string url, std::string path);
|
||||
std::optional<Update> GetLatestRelease(bool include_prereleases);
|
||||
std::optional<Update> GetLatestRelease();
|
||||
std::optional<Update> GetUpdate();
|
||||
} // namespace UpdateChecker
|
||||
|
||||
@@ -165,10 +165,6 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
|
||||
INSERT(Settings, use_disk_shader_cache, tr("Use persistent pipeline cache"),
|
||||
tr("Allows saving shaders to storage for faster loading on following game "
|
||||
"boots.\nDisabling it is only intended for debugging."));
|
||||
INSERT(Settings, optimize_spirv_output, tr("Optimize SPIRV output"),
|
||||
tr("Runs an additional optimization pass over generated SPIRV shaders.\n"
|
||||
"Will increase time required for shader compilation.\nMay slightly improve "
|
||||
"performance.\nThis feature is experimental."));
|
||||
INSERT(Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"),
|
||||
tr("Uses an extra CPU thread for rendering.\nThis option should always remain enabled."));
|
||||
INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"),
|
||||
|
||||
@@ -101,8 +101,10 @@ QStringList GetModFolders(const QString& root, const QString& fallbackName) {
|
||||
} else {
|
||||
// Rename the existing mod folder.
|
||||
const auto new_path = std_path.parent_path() / name.toStdString();
|
||||
fs::remove_all(new_path);
|
||||
fs::rename(std_path, new_path);
|
||||
if (new_path != std_path) {
|
||||
fs::remove_all(new_path);
|
||||
fs::rename(std_path, new_path);
|
||||
}
|
||||
std_path = new_path;
|
||||
}
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ add_library(shader_recompiler STATIC
|
||||
|
||||
)
|
||||
|
||||
target_link_libraries(shader_recompiler PUBLIC common fmt::fmt sirit::sirit SPIRV-Tools::SPIRV-Tools)
|
||||
target_link_libraries(shader_recompiler PUBLIC common fmt::fmt sirit::sirit)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(shader_recompiler PRIVATE
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <spirv-tools/optimizer.hpp>
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "shader_recompiler/backend/spirv/emit_spirv.h"
|
||||
@@ -22,15 +21,7 @@ namespace Shader::Backend::SPIRV {
|
||||
namespace {
|
||||
template <class Func>
|
||||
struct FuncTraits {};
|
||||
thread_local std::unique_ptr<spvtools::Optimizer> thread_optimizer;
|
||||
|
||||
spvtools::Optimizer& GetThreadOptimizer() {
|
||||
if (!thread_optimizer) {
|
||||
thread_optimizer = std::make_unique<spvtools::Optimizer>(SPV_ENV_VULKAN_1_3);
|
||||
thread_optimizer->RegisterPerformancePasses();
|
||||
}
|
||||
return *thread_optimizer;
|
||||
}
|
||||
template <class ReturnType_, class... Args>
|
||||
struct FuncTraits<ReturnType_ (*)(Args...)> {
|
||||
using ReturnType = ReturnType_;
|
||||
@@ -501,8 +492,7 @@ void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info,
|
||||
IR::Program& program, Bindings& bindings, bool optimize) {
|
||||
std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, IR::Program& program, Bindings& bindings) {
|
||||
EmitContext ctx{profile, runtime_info, program, bindings};
|
||||
const Id main{DefineMain(ctx, program)};
|
||||
DefineEntryPoint(program, ctx, main);
|
||||
@@ -514,29 +504,7 @@ std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_in
|
||||
SetupCapabilities(profile, program.info, ctx);
|
||||
SetupTransformFeedbackCapabilities(ctx, main);
|
||||
PatchPhiNodes(program, ctx);
|
||||
|
||||
if (!optimize) {
|
||||
return ctx.Assemble();
|
||||
} else {
|
||||
std::vector<u32> spirv = ctx.Assemble();
|
||||
|
||||
// Use thread-local optimizer instead of creating a new one
|
||||
auto& spv_opt = GetThreadOptimizer();
|
||||
spv_opt.SetMessageConsumer([](spv_message_level_t, const char*, const spv_position_t&, const char* m) {
|
||||
LOG_ERROR(HW_GPU, "spirv-opt: {}", m);
|
||||
});
|
||||
|
||||
spvtools::OptimizerOptions opt_options;
|
||||
opt_options.set_run_validator(false);
|
||||
|
||||
std::vector<u32> result;
|
||||
if (!spv_opt.Run(spirv.data(), spirv.size(), &result, opt_options)) {
|
||||
LOG_ERROR(HW_GPU,
|
||||
"Failed to optimize SPIRV shader output, continuing without optimization");
|
||||
result = std::move(spirv);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return ctx.Assemble();
|
||||
}
|
||||
|
||||
Id EmitPhi(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
@@ -33,13 +33,10 @@ constexpr u32 RESCALING_LAYOUT_WORDS_OFFSET = offsetof(RescalingLayout, rescalin
|
||||
constexpr u32 RESCALING_LAYOUT_DOWN_FACTOR_OFFSET = offsetof(RescalingLayout, down_factor);
|
||||
constexpr u32 RENDERAREA_LAYOUT_OFFSET = offsetof(RenderAreaLayout, render_area);
|
||||
|
||||
[[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info,
|
||||
IR::Program& program, Bindings& bindings, bool optimize);
|
||||
|
||||
[[nodiscard]] inline std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program,
|
||||
bool optimize) {
|
||||
[[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, IR::Program& program, Bindings& bindings);
|
||||
[[nodiscard]] inline std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program) {
|
||||
Bindings binding;
|
||||
return EmitSPIRV(profile, {}, program, binding, optimize);
|
||||
return EmitSPIRV(profile, {}, program, binding);
|
||||
}
|
||||
|
||||
} // namespace Shader::Backend::SPIRV
|
||||
|
||||
@@ -178,6 +178,9 @@ void DefineGenericOutput(EmitContext& ctx, size_t index, std::optional<u32> invo
|
||||
ctx.Decorate(id, spv::Decoration::XfbBuffer, xfb_varying->buffer);
|
||||
ctx.Decorate(id, spv::Decoration::XfbStride, xfb_varying->stride);
|
||||
ctx.Decorate(id, spv::Decoration::Offset, xfb_varying->offset);
|
||||
if (ctx.stage == Stage::Geometry && xfb_varying->stream != 0) {
|
||||
ctx.Decorate(id, spv::Decoration::Stream, xfb_varying->stream);
|
||||
}
|
||||
}
|
||||
if (num_components < 4 || element > 0) {
|
||||
const std::string_view subswizzle{swizzle.substr(element, num_components)};
|
||||
|
||||
@@ -979,7 +979,7 @@ private:
|
||||
Environment& env;
|
||||
IR::AbstractSyntaxList& syntax_list;
|
||||
bool uses_demote_to_helper{};
|
||||
const Flow::Block dummy_flow_block;
|
||||
const Flow::Block dummy_flow_block{};
|
||||
};
|
||||
} // Anonymous namespace
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ enum class TessSpacing {
|
||||
|
||||
struct TransformFeedbackVarying {
|
||||
u32 buffer{};
|
||||
u32 stream{};
|
||||
u32 stride{};
|
||||
u32 offset{};
|
||||
u32 components{};
|
||||
|
||||
@@ -1067,26 +1067,29 @@ void BufferCache<P>::BindHostTransformFeedbackBuffers() {
|
||||
HostBindings<typename P::Buffer> host_bindings;
|
||||
for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) {
|
||||
const Binding& binding = channel_state->transform_feedback_buffers[index];
|
||||
if (maxwell3d->regs.transform_feedback.controls[index].varying_count == 0 &&
|
||||
maxwell3d->regs.transform_feedback.controls[index].stride == 0) {
|
||||
break;
|
||||
const auto& control = maxwell3d->regs.transform_feedback.controls[index];
|
||||
const bool has_layout = control.varying_count != 0 || control.stride != 0;
|
||||
|
||||
Buffer* host_buffer = &slot_buffers[NULL_BUFFER_ID];
|
||||
u32 offset = 0;
|
||||
u32 size = 0;
|
||||
|
||||
if (has_layout && binding.buffer_id != NULL_BUFFER_ID && binding.size != 0) {
|
||||
Buffer& buffer = slot_buffers[binding.buffer_id];
|
||||
TouchBuffer(buffer, binding.buffer_id);
|
||||
size = binding.size;
|
||||
SynchronizeBuffer(buffer, binding.device_addr, size);
|
||||
MarkWrittenBuffer(binding.buffer_id, binding.device_addr, size);
|
||||
offset = buffer.Offset(binding.device_addr);
|
||||
buffer.MarkUsage(offset, size);
|
||||
host_buffer = &buffer;
|
||||
}
|
||||
Buffer& buffer = slot_buffers[binding.buffer_id];
|
||||
TouchBuffer(buffer, binding.buffer_id);
|
||||
const u32 size = binding.size;
|
||||
SynchronizeBuffer(buffer, binding.device_addr, size);
|
||||
|
||||
MarkWrittenBuffer(binding.buffer_id, binding.device_addr, size);
|
||||
|
||||
const u32 offset = buffer.Offset(binding.device_addr);
|
||||
buffer.MarkUsage(offset, size);
|
||||
host_bindings.buffers.push_back(&buffer);
|
||||
host_bindings.buffers.push_back(host_buffer);
|
||||
host_bindings.offsets.push_back(offset);
|
||||
host_bindings.sizes.push_back(size);
|
||||
}
|
||||
if (host_bindings.buffers.size() > 0) {
|
||||
runtime.BindTransformFeedbackBuffers(host_bindings);
|
||||
}
|
||||
runtime.BindTransformFeedbackBuffers(host_bindings);
|
||||
}
|
||||
|
||||
template <class P>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
@@ -92,7 +92,16 @@ void ThreadManager::InvalidateRegion(DAddr addr, u64 size) {
|
||||
}
|
||||
|
||||
void ThreadManager::FlushAndInvalidateRegion(DAddr addr, u64 size) {
|
||||
// Skip flush on asynch mode, as FlushAndInvalidateRegion is not used for anything too important
|
||||
if (Settings::IsGPULevelHigh()) {
|
||||
if (!is_async) {
|
||||
PushCommand(FlushRegionCommand(addr, size));
|
||||
} else {
|
||||
auto& gpu = system.GPU();
|
||||
const u64 fence = gpu.RequestFlush(addr, size);
|
||||
TickGPU();
|
||||
gpu.WaitForSyncOperation(fence);
|
||||
}
|
||||
}
|
||||
rasterizer->OnCacheInvalidation(addr, size);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
@@ -5,16 +8,22 @@
|
||||
|
||||
layout(local_size_x = 1) in;
|
||||
|
||||
layout(std430, binding = 0) buffer Query {
|
||||
uvec2 initial;
|
||||
uvec2 unknown;
|
||||
uvec2 current;
|
||||
layout(std430, binding = 0) readonly buffer Query {
|
||||
uint data[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 1) buffer Result {
|
||||
layout(std430, binding = 1) writeonly buffer Result {
|
||||
uint result;
|
||||
};
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
uint compare_to_zero;
|
||||
};
|
||||
|
||||
void main() {
|
||||
result = all(equal(initial, current)) ? 1 : 0;
|
||||
if (compare_to_zero != 0u) {
|
||||
result = (data[0] != 0u && data[1] != 0u) ? 1u : 0u;
|
||||
} else {
|
||||
result = (data[0] == data[4] && data[1] == data[5]) ? 1u : 0u;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,11 +285,11 @@ void HLE_MultiDrawIndexedIndirectCount::Fallback(Engines::Maxwell3D& maxwell3d,
|
||||
}
|
||||
void HLE_DrawIndirectByteCount::Execute(Engines::Maxwell3D& maxwell3d, std::span<const u32> parameters, [[maybe_unused]] u32 method) {
|
||||
const bool force = maxwell3d.Rasterizer().HasDrawTransformFeedback();
|
||||
auto topology = Maxwell3D::Regs::PrimitiveTopology(parameters[0] & 0xFFFFU);
|
||||
if (!force && (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology))) {
|
||||
if (!force) {
|
||||
Fallback(maxwell3d, parameters);
|
||||
return;
|
||||
}
|
||||
auto topology = Maxwell3D::Regs::PrimitiveTopology(parameters[0] & 0xFFFFU);
|
||||
auto& params = maxwell3d.draw_manager->GetIndirectParams();
|
||||
params.is_byte_count = true;
|
||||
params.is_indexed = false;
|
||||
|
||||
@@ -412,6 +412,7 @@ bool QueryCacheBase<Traits>::AccelerateHostConditionalRendering() {
|
||||
.found_query = nullptr,
|
||||
};
|
||||
}
|
||||
it_current = it_current_2;
|
||||
}
|
||||
auto* query = impl->ObtainQuery(it_current->second);
|
||||
qc_dirty |= True(query->flags & QueryFlagBits::IsHostManaged) &&
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
@@ -75,7 +78,7 @@ public:
|
||||
}
|
||||
|
||||
u64 GetDependentMask() const {
|
||||
return dependence_mask;
|
||||
return dependent_mask;
|
||||
}
|
||||
|
||||
u64 GetAmendValue() const {
|
||||
|
||||
@@ -629,6 +629,9 @@ void RasterizerOpenGL::ReleaseFences(bool force) {
|
||||
|
||||
void RasterizerOpenGL::FlushAndInvalidateRegion(DAddr addr, u64 size,
|
||||
VideoCommon::CacheType which) {
|
||||
if (Settings::IsGPULevelHigh()) {
|
||||
FlushRegion(addr, size, which);
|
||||
}
|
||||
InvalidateRegion(addr, size, which);
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,6 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
||||
state_tracker{state_tracker_}, shader_notify{shader_notify_},
|
||||
use_asynchronous_shaders{device.UseAsynchronousShaders()},
|
||||
strict_context_required{device.StrictContextRequired()},
|
||||
optimize_spirv_output{Settings::values.optimize_spirv_output.GetValue() != Settings::SpirvOptimizeMode::Never},
|
||||
profile{
|
||||
.supported_spirv = 0x00010000,
|
||||
|
||||
@@ -348,10 +347,6 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
|
||||
if (!use_asynchronous_shaders) {
|
||||
workers.reset();
|
||||
}
|
||||
|
||||
if (Settings::values.optimize_spirv_output.GetValue() != Settings::SpirvOptimizeMode::Always) {
|
||||
this->optimize_spirv_output = false;
|
||||
}
|
||||
}
|
||||
|
||||
GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
|
||||
@@ -537,7 +532,7 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
||||
break;
|
||||
case Settings::RendererBackend::OpenGL_SPIRV:
|
||||
ConvertLegacyToGeneric(program, runtime_info);
|
||||
sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding, this->optimize_spirv_output);
|
||||
sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@@ -598,7 +593,7 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
|
||||
code = EmitGLASM(profile, info, program);
|
||||
break;
|
||||
case Settings::RendererBackend::OpenGL_SPIRV:
|
||||
code_spirv = EmitSPIRV(profile, program, this->optimize_spirv_output);
|
||||
code_spirv = EmitSPIRV(profile, program);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
||||
@@ -76,7 +76,6 @@ private:
|
||||
VideoCore::ShaderNotify& shader_notify;
|
||||
const bool use_asynchronous_shaders;
|
||||
const bool strict_context_required;
|
||||
bool optimize_spirv_output{};
|
||||
|
||||
GraphicsPipelineKey graphics_key{};
|
||||
GraphicsPipeline* current_pipeline{};
|
||||
|
||||
@@ -190,9 +190,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!extended_dynamic_state_3_enables) {
|
||||
dynamic_state.Refresh3(regs);
|
||||
}
|
||||
dynamic_state.Refresh3(regs, features);
|
||||
if (xfb_enabled) {
|
||||
RefreshXfbState(xfb_state, regs);
|
||||
}
|
||||
@@ -295,16 +293,22 @@ void FixedPipelineState::DynamicState::Refresh2(const Maxwell& regs,
|
||||
depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
void FixedPipelineState::DynamicState::Refresh3(const Maxwell& regs) {
|
||||
logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0);
|
||||
depth_clamp_disabled.Assign(regs.viewport_clip_control.geometry_clip ==
|
||||
Maxwell::ViewportClipControl::GeometryClip::Passthrough ||
|
||||
regs.viewport_clip_control.geometry_clip ==
|
||||
Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ ||
|
||||
regs.viewport_clip_control.geometry_clip ==
|
||||
Maxwell::ViewportClipControl::GeometryClip::FrustumZ);
|
||||
|
||||
line_stipple_enable.Assign(regs.line_stipple_enable);
|
||||
void FixedPipelineState::DynamicState::Refresh3(const Maxwell& regs,
|
||||
const DynamicFeatures& features) {
|
||||
if (!features.has_dynamic_state3_logic_op_enable) {
|
||||
logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0);
|
||||
}
|
||||
if (!features.has_dynamic_state3_depth_clamp_enable) {
|
||||
depth_clamp_disabled.Assign(regs.viewport_clip_control.geometry_clip ==
|
||||
Maxwell::ViewportClipControl::GeometryClip::Passthrough ||
|
||||
regs.viewport_clip_control.geometry_clip ==
|
||||
Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ ||
|
||||
regs.viewport_clip_control.geometry_clip ==
|
||||
Maxwell::ViewportClipControl::GeometryClip::FrustumZ);
|
||||
}
|
||||
if (!features.has_dynamic_state3_line_stipple_enable) {
|
||||
line_stipple_enable.Assign(regs.line_stipple_enable);
|
||||
}
|
||||
}
|
||||
|
||||
size_t FixedPipelineState::Hash() const noexcept {
|
||||
|
||||
@@ -27,6 +27,9 @@ struct DynamicFeatures {
|
||||
bool has_extended_dynamic_state_2_patch_control_points;
|
||||
bool has_extended_dynamic_state_3_blend;
|
||||
bool has_extended_dynamic_state_3_enables;
|
||||
bool has_dynamic_state3_depth_clamp_enable;
|
||||
bool has_dynamic_state3_logic_op_enable;
|
||||
bool has_dynamic_state3_line_stipple_enable;
|
||||
bool has_dynamic_vertex_input;
|
||||
bool has_provoking_vertex;
|
||||
bool has_provoking_vertex_first_mode;
|
||||
@@ -175,7 +178,7 @@ struct FixedPipelineState {
|
||||
void Refresh(const Maxwell& regs);
|
||||
void Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology,
|
||||
bool base_features_supported);
|
||||
void Refresh3(const Maxwell& regs);
|
||||
void Refresh3(const Maxwell& regs, const DynamicFeatures& features);
|
||||
|
||||
Maxwell::ComparisonOp DepthTestFunc() const noexcept {
|
||||
return UnpackComparisonOp(depth_test_func);
|
||||
@@ -265,8 +268,7 @@ struct FixedPipelineState {
|
||||
return sizeof(*this);
|
||||
}
|
||||
if (dynamic_vertex_input && extended_dynamic_state_3_blend) {
|
||||
// Exclude dynamic state and attributes
|
||||
return offsetof(FixedPipelineState, dynamic_state);
|
||||
return offsetof(FixedPipelineState, attachments);
|
||||
}
|
||||
if (dynamic_vertex_input) {
|
||||
// Exclude dynamic state
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -171,7 +172,11 @@ try
|
||||
|
||||
RendererVulkan::~RendererVulkan() {
|
||||
scheduler.RegisterOnSubmit([] {});
|
||||
void(device.GetLogical().WaitIdle());
|
||||
scheduler.Finish();
|
||||
{
|
||||
std::scoped_lock lock{scheduler.submit_mutex};
|
||||
void(device.GetLogical().WaitIdle());
|
||||
}
|
||||
}
|
||||
|
||||
void RendererVulkan::Composite(std::span<const Tegra::FramebufferConfig> framebuffers) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#include <mutex>
|
||||
#include "video_core/framebuffer_config.h"
|
||||
#include "video_core/present.h"
|
||||
#include "video_core/renderer_vulkan/present/filters.h"
|
||||
@@ -31,7 +32,10 @@ BlitScreen::~BlitScreen() = default;
|
||||
void BlitScreen::WaitIdle() {
|
||||
present_manager.WaitPresent();
|
||||
scheduler.Finish();
|
||||
device.GetLogical().WaitIdle();
|
||||
{
|
||||
std::scoped_lock lock{scheduler.submit_mutex};
|
||||
device.GetLogical().WaitIdle();
|
||||
}
|
||||
}
|
||||
|
||||
void BlitScreen::SetWindowAdaptPass() {
|
||||
|
||||
@@ -637,12 +637,10 @@ void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings<
|
||||
for (u32 i = 0; i < bindings.buffers.size(); ++i) {
|
||||
auto handle = bindings.buffers[i]->Handle();
|
||||
if (handle == VK_NULL_HANDLE) {
|
||||
ReserveNullBuffer();
|
||||
handle = *null_buffer;
|
||||
bindings.offsets[i] = 0;
|
||||
bindings.sizes[i] = VK_WHOLE_SIZE;
|
||||
if (!device.HasNullDescriptor()) {
|
||||
ReserveNullBuffer();
|
||||
handle = *null_buffer;
|
||||
}
|
||||
bindings.sizes[i] = 0;
|
||||
}
|
||||
buffer_handles[i] = handle;
|
||||
}
|
||||
|
||||
@@ -228,6 +228,10 @@ struct QueriesPrefixScanPushConstants {
|
||||
u32 accumulation_limit;
|
||||
u32 buffer_offset;
|
||||
};
|
||||
|
||||
struct ConditionalRenderingResolvePushConstants {
|
||||
u32 compare_to_zero;
|
||||
};
|
||||
} // Anonymous namespace
|
||||
|
||||
ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool,
|
||||
@@ -413,7 +417,8 @@ ConditionalRenderingResolvePass::ConditionalRenderingResolvePass(
|
||||
const Device& device_, Scheduler& scheduler_, DescriptorPool& descriptor_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
||||
: ComputePass(device_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS,
|
||||
INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, nullptr,
|
||||
INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO,
|
||||
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(ConditionalRenderingResolvePushConstants)>,
|
||||
RESOLVE_CONDITIONAL_RENDER_COMP_SPV),
|
||||
scheduler{scheduler_}, compute_pass_descriptor_queue{compute_pass_descriptor_queue_} {}
|
||||
|
||||
@@ -430,7 +435,7 @@ void ConditionalRenderingResolvePass::Resolve(VkBuffer dst_buffer, VkBuffer src_
|
||||
const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()};
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([this, descriptor_data](vk::CommandBuffer cmdbuf) {
|
||||
scheduler.Record([this, descriptor_data, compare_to_zero](vk::CommandBuffer cmdbuf) {
|
||||
static constexpr VkMemoryBarrier read_barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
@@ -443,6 +448,9 @@ void ConditionalRenderingResolvePass::Resolve(VkBuffer dst_buffer, VkBuffer src_
|
||||
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT,
|
||||
};
|
||||
const ConditionalRenderingResolvePushConstants uniforms{
|
||||
.compare_to_zero = compare_to_zero ? 1U : 0U,
|
||||
};
|
||||
const VkDescriptorSet set = descriptor_allocator.Commit();
|
||||
device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data);
|
||||
|
||||
@@ -450,9 +458,11 @@ void ConditionalRenderingResolvePass::Resolve(VkBuffer dst_buffer, VkBuffer src_
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, read_barrier);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {});
|
||||
cmdbuf.PushConstants(*layout, VK_SHADER_STAGE_COMPUTE_BIT, uniforms);
|
||||
cmdbuf.Dispatch(1, 1, 1);
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, write_barrier);
|
||||
VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT, 0,
|
||||
write_barrier);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -520,7 +530,7 @@ void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffe
|
||||
const VkDescriptorSet set = descriptor_allocator.Commit();
|
||||
device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data);
|
||||
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, read_barrier);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {});
|
||||
|
||||
@@ -467,6 +467,10 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||
bind_stage_info(4);
|
||||
}
|
||||
|
||||
if (regs.transform_feedback_enabled != 0) {
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
}
|
||||
|
||||
buffer_cache.UpdateGraphicsBuffers(is_indexed);
|
||||
buffer_cache.BindHostGeometryBuffers(is_indexed);
|
||||
|
||||
|
||||
@@ -369,7 +369,6 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
||||
texture_cache{texture_cache_}, shader_notify{shader_notify_},
|
||||
use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()},
|
||||
use_vulkan_pipeline_cache{Settings::values.use_vulkan_driver_pipeline_cache.GetValue()},
|
||||
optimize_spirv_output{Settings::values.optimize_spirv_output.GetValue() != Settings::SpirvOptimizeMode::Never},
|
||||
workers(device.HasBrokenParallelShaderCompiling() ? 1ULL : GetTotalPipelineWorkers(),
|
||||
"VkPipelineBuilder"),
|
||||
serialization_thread(1, "VkPipelineSerialization") {
|
||||
@@ -485,6 +484,12 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
||||
device.IsExtExtendedDynamicState3BlendingSupported();
|
||||
dynamic_features.has_extended_dynamic_state_3_enables =
|
||||
device.IsExtExtendedDynamicState3EnablesSupported();
|
||||
dynamic_features.has_dynamic_state3_depth_clamp_enable =
|
||||
device.SupportsDynamicState3DepthClampEnable();
|
||||
dynamic_features.has_dynamic_state3_logic_op_enable =
|
||||
device.SupportsDynamicState3LogicOpEnable();
|
||||
dynamic_features.has_dynamic_state3_line_stipple_enable =
|
||||
device.SupportsDynamicState3LineStippleEnable();
|
||||
|
||||
// VIDS: Independent toggle (not affected by dyna_state levels)
|
||||
dynamic_features.has_dynamic_vertex_input =
|
||||
@@ -663,10 +668,6 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
|
||||
if (state.statistics) {
|
||||
state.statistics->Report();
|
||||
}
|
||||
|
||||
if (Settings::values.optimize_spirv_output.GetValue() != Settings::SpirvOptimizeMode::Always) {
|
||||
this->optimize_spirv_output = false;
|
||||
}
|
||||
}
|
||||
|
||||
GraphicsPipeline* PipelineCache::CurrentGraphicsPipelineSlowPath() {
|
||||
@@ -771,7 +772,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
||||
|
||||
const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage, device)};
|
||||
ConvertLegacyToGeneric(program, runtime_info);
|
||||
const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding, this->optimize_spirv_output)};
|
||||
const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding)};
|
||||
device.SaveShader(code);
|
||||
modules[stage_index] = BuildShader(device, code);
|
||||
|
||||
@@ -889,7 +890,7 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
||||
max_shared_memory / 1024);
|
||||
program.shared_memory_size = max_shared_memory;
|
||||
}
|
||||
const std::vector<u32> code{EmitSPIRV(profile, program, this->optimize_spirv_output)};
|
||||
const std::vector<u32> code{EmitSPIRV(profile, program)};
|
||||
device.SaveShader(code);
|
||||
vk::ShaderModule spv_module{BuildShader(device, code)};
|
||||
|
||||
|
||||
@@ -153,7 +153,6 @@ private:
|
||||
VideoCore::ShaderNotify& shader_notify;
|
||||
bool use_asynchronous_shaders{};
|
||||
bool use_vulkan_pipeline_cache{};
|
||||
bool optimize_spirv_output{};
|
||||
|
||||
GraphicsPipelineCacheKey graphics_key{};
|
||||
GraphicsPipeline* current_pipeline{};
|
||||
|
||||
@@ -189,7 +189,7 @@ void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat
|
||||
frame->image = memory_allocator.CreateImage({
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
|
||||
.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT,
|
||||
.imageType = VK_IMAGE_TYPE_2D,
|
||||
.format = swapchain.GetImageFormat(),
|
||||
.extent =
|
||||
|
||||
@@ -157,8 +157,9 @@ public:
|
||||
ReserveHostQuery();
|
||||
|
||||
scheduler.Record([query_pool = current_query_pool,
|
||||
query_index = current_bank_slot](vk::CommandBuffer cmdbuf) {
|
||||
query_index = current_bank_slot](vk::CommandBuffer cmdbuf) {
|
||||
const bool use_precise = Settings::IsGPULevelHigh();
|
||||
cmdbuf.ResetQueryPool(query_pool, static_cast<u32>(query_index), 1);
|
||||
cmdbuf.BeginQuery(query_pool, static_cast<u32>(query_index),
|
||||
use_precise ? VK_QUERY_CONTROL_PRECISE_BIT : 0);
|
||||
});
|
||||
@@ -220,8 +221,7 @@ public:
|
||||
}
|
||||
PauseCounter();
|
||||
const auto driver_id = device.GetDriverID();
|
||||
if (driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
|
||||
driver_id == VK_DRIVER_ID_ARM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP) {
|
||||
if (driver_id == VK_DRIVER_ID_ARM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP) {
|
||||
pending_sync.clear();
|
||||
sync_values_stash.clear();
|
||||
return;
|
||||
@@ -666,13 +666,18 @@ public:
|
||||
offsets.fill(0);
|
||||
last_queries.fill(0);
|
||||
last_queries_stride.fill(1);
|
||||
stream_to_slot.fill(INVALID_SLOT);
|
||||
VkBufferUsageFlags counter_buffer_usage =
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
if (device.IsExtTransformFeedbackSupported()) {
|
||||
counter_buffer_usage |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
|
||||
}
|
||||
const VkBufferCreateInfo buffer_ci = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.size = TFBQueryBank::QUERY_SIZE * NUM_STREAMS,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT,
|
||||
.usage = counter_buffer_usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.pQueueFamilyIndices = nullptr,
|
||||
@@ -692,6 +697,9 @@ public:
|
||||
~TFBCounterStreamer() = default;
|
||||
|
||||
void StartCounter() override {
|
||||
if (!device.IsExtTransformFeedbackSupported()) {
|
||||
return;
|
||||
}
|
||||
FlushBeginTFB();
|
||||
has_started = true;
|
||||
}
|
||||
@@ -706,7 +714,9 @@ public:
|
||||
|
||||
void CloseCounter() override {
|
||||
if (has_flushed_end_pending) {
|
||||
FlushEndTFB();
|
||||
if (scheduler.IsRenderPassActive()) {
|
||||
FlushEndTFB();
|
||||
}
|
||||
}
|
||||
runtime.View3DRegs([this](Maxwell3D& maxwell3d) {
|
||||
if (maxwell3d.regs.transform_feedback_enabled == 0) {
|
||||
@@ -756,18 +766,33 @@ public:
|
||||
if (has_timestamp) {
|
||||
new_query->flags |= VideoCommon::QueryFlagBits::HasTimestamp;
|
||||
}
|
||||
if (!device.IsExtTransformFeedbackSupported()) {
|
||||
new_query->flags |= VideoCommon::QueryFlagBits::IsFinalValueSynced;
|
||||
return index;
|
||||
}
|
||||
if (!subreport_) {
|
||||
new_query->flags |= VideoCommon::QueryFlagBits::IsFinalValueSynced;
|
||||
return index;
|
||||
}
|
||||
const size_t subreport = static_cast<size_t>(*subreport_);
|
||||
if (subreport >= NUM_STREAMS) {
|
||||
new_query->flags |= VideoCommon::QueryFlagBits::IsFinalValueSynced;
|
||||
return index;
|
||||
}
|
||||
last_queries[subreport] = address;
|
||||
if ((streams_mask & (1ULL << subreport)) == 0) {
|
||||
new_query->flags |= VideoCommon::QueryFlagBits::IsFinalValueSynced;
|
||||
return index;
|
||||
}
|
||||
const size_t slot = stream_to_slot[subreport];
|
||||
if (slot >= NUM_STREAMS) {
|
||||
new_query->flags |= VideoCommon::QueryFlagBits::IsFinalValueSynced;
|
||||
return index;
|
||||
}
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
CloseCounter();
|
||||
auto [bank_slot, data_slot] = ProduceCounterBuffer(subreport);
|
||||
auto [bank_slot, data_slot] = ProduceCounterBuffer(slot);
|
||||
new_query->start_bank_id = static_cast<u32>(bank_slot);
|
||||
new_query->size_banks = 1;
|
||||
new_query->start_slot = static_cast<u32>(data_slot);
|
||||
@@ -778,6 +803,9 @@ public:
|
||||
}
|
||||
|
||||
std::optional<std::pair<DAddr, size_t>> GetLastQueryStream(size_t stream) {
|
||||
if (stream >= NUM_STREAMS) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (last_queries[stream] != 0) {
|
||||
std::pair<DAddr, size_t> result(last_queries[stream], last_queries_stride[stream]);
|
||||
return result;
|
||||
@@ -789,6 +817,10 @@ public:
|
||||
return out_topology;
|
||||
}
|
||||
|
||||
u32 GetPatchVertices() const {
|
||||
return patch_vertices;
|
||||
}
|
||||
|
||||
bool HasUnsyncedQueries() const override {
|
||||
return !pending_flush_queries.empty();
|
||||
}
|
||||
@@ -855,6 +887,9 @@ public:
|
||||
|
||||
private:
|
||||
void FlushBeginTFB() {
|
||||
if (!device.IsExtTransformFeedbackSupported()) [[unlikely]] {
|
||||
return;
|
||||
}
|
||||
if (has_flushed_end_pending) [[unlikely]] {
|
||||
return;
|
||||
}
|
||||
@@ -868,12 +903,24 @@ private:
|
||||
});
|
||||
return;
|
||||
}
|
||||
static constexpr VkMemoryBarrier COUNTER_RESUME_BARRIER{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT,
|
||||
};
|
||||
scheduler.Record([this, total = static_cast<u32>(buffers_count)](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
|
||||
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, 0,
|
||||
COUNTER_RESUME_BARRIER);
|
||||
cmdbuf.BeginTransformFeedbackEXT(0, total, counter_buffers.data(), offsets.data());
|
||||
});
|
||||
}
|
||||
|
||||
void FlushEndTFB() {
|
||||
if (!device.IsExtTransformFeedbackSupported()) [[unlikely]] {
|
||||
return;
|
||||
}
|
||||
if (!has_flushed_end_pending) [[unlikely]] {
|
||||
UNREACHABLE();
|
||||
return;
|
||||
@@ -899,28 +946,48 @@ private:
|
||||
void UpdateBuffers() {
|
||||
last_queries.fill(0);
|
||||
last_queries_stride.fill(1);
|
||||
stream_to_slot.fill(INVALID_SLOT);
|
||||
streams_mask = 0; // reset previously recorded streams
|
||||
runtime.View3DRegs([this](Maxwell3D& maxwell3d) {
|
||||
buffers_count = 0;
|
||||
out_topology = maxwell3d.draw_manager->GetDrawState().topology;
|
||||
patch_vertices = std::max(maxwell3d.regs.patch_vertices, 1U);
|
||||
if (out_topology == Maxwell3D::Regs::PrimitiveTopology::Patches) {
|
||||
switch (maxwell3d.regs.tessellation.params.output_primitives.Value()) {
|
||||
case Maxwell3D::Regs::Tessellation::OutputPrimitives::Points:
|
||||
out_topology = Maxwell3D::Regs::PrimitiveTopology::Points;
|
||||
break;
|
||||
case Maxwell3D::Regs::Tessellation::OutputPrimitives::Lines:
|
||||
out_topology = Maxwell3D::Regs::PrimitiveTopology::LineStrip;
|
||||
break;
|
||||
case Maxwell3D::Regs::Tessellation::OutputPrimitives::Triangles_CW:
|
||||
case Maxwell3D::Regs::Tessellation::OutputPrimitives::Triangles_CCW:
|
||||
out_topology = Maxwell3D::Regs::PrimitiveTopology::TriangleStrip;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < Maxwell3D::Regs::NumTransformFeedbackBuffers; i++) {
|
||||
const auto& tf = maxwell3d.regs.transform_feedback;
|
||||
if (tf.buffers[i].enable == 0) {
|
||||
continue;
|
||||
}
|
||||
buffers_count = std::max<size_t>(buffers_count, i + 1);
|
||||
const size_t stream = tf.controls[i].stream;
|
||||
if (stream >= last_queries_stride.size()) {
|
||||
LOG_WARNING(Render_Vulkan, "TransformFeedback stream {} out of range", stream);
|
||||
continue;
|
||||
}
|
||||
if ((streams_mask & (1ULL << stream)) != 0) {
|
||||
continue;
|
||||
}
|
||||
last_queries_stride[stream] = tf.controls[i].stride;
|
||||
stream_to_slot[stream] = i;
|
||||
streams_mask |= 1ULL << stream;
|
||||
buffers_count = std::max<size_t>(buffers_count, stream + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::pair<size_t, size_t> ProduceCounterBuffer(size_t stream) {
|
||||
std::pair<size_t, size_t> ProduceCounterBuffer(size_t slot_index) {
|
||||
if (current_bank == nullptr || current_bank->IsClosed()) {
|
||||
current_bank_id =
|
||||
bank_pool.ReserveBank([this](std::deque<TFBQueryBank>& queue, size_t index) {
|
||||
@@ -946,7 +1013,8 @@ private:
|
||||
};
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([dst_buffer = current_bank->GetBuffer(),
|
||||
src_buffer = counter_buffers[stream], src_offset = offsets[stream],
|
||||
src_buffer = counter_buffers[slot_index],
|
||||
src_offset = offsets[slot_index],
|
||||
slot](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER);
|
||||
@@ -965,6 +1033,7 @@ private:
|
||||
friend class PrimitivesSucceededStreamer;
|
||||
|
||||
static constexpr size_t NUM_STREAMS = 4;
|
||||
static constexpr size_t INVALID_SLOT = NUM_STREAMS;
|
||||
|
||||
QueryCacheRuntime& runtime;
|
||||
const Device& device;
|
||||
@@ -994,7 +1063,9 @@ private:
|
||||
std::array<VkDeviceSize, NUM_STREAMS> offsets{};
|
||||
std::array<DAddr, NUM_STREAMS> last_queries;
|
||||
std::array<size_t, NUM_STREAMS> last_queries_stride;
|
||||
std::array<size_t, NUM_STREAMS> stream_to_slot;
|
||||
Maxwell3D::Regs::PrimitiveTopology out_topology;
|
||||
u32 patch_vertices{1};
|
||||
u64 streams_mask;
|
||||
};
|
||||
|
||||
@@ -1015,6 +1086,7 @@ public:
|
||||
u64 stride{};
|
||||
DAddr dependant_address{};
|
||||
Maxwell3D::Regs::PrimitiveTopology topology{Maxwell3D::Regs::PrimitiveTopology::Points};
|
||||
u32 patch_vertices{1};
|
||||
size_t dependant_index{};
|
||||
bool dependant_manage{};
|
||||
};
|
||||
@@ -1031,6 +1103,10 @@ public:
|
||||
|
||||
~PrimitivesSucceededStreamer() = default;
|
||||
|
||||
void ResetCounter() override {
|
||||
tfb_streamer.ResetCounter();
|
||||
}
|
||||
|
||||
size_t WriteCounter(DAddr address, bool has_timestamp, u32 value,
|
||||
std::optional<u32> subreport_) override {
|
||||
auto index = BuildQuery();
|
||||
@@ -1048,6 +1124,7 @@ public:
|
||||
auto dependant_address_opt = tfb_streamer.GetLastQueryStream(subreport);
|
||||
bool must_manage_dependance = false;
|
||||
new_query->topology = tfb_streamer.GetOutputTopology();
|
||||
new_query->patch_vertices = tfb_streamer.GetPatchVertices();
|
||||
if (dependant_address_opt) {
|
||||
auto [dep_address, stride] = *dependant_address_opt;
|
||||
new_query->dependant_address = dep_address;
|
||||
@@ -1068,6 +1145,7 @@ public:
|
||||
}
|
||||
new_query->stride = 1;
|
||||
runtime.View3DRegs([new_query, subreport](Maxwell3D& maxwell3d) {
|
||||
new_query->patch_vertices = std::max(maxwell3d.regs.patch_vertices, 1U);
|
||||
for (size_t i = 0; i < Maxwell3D::Regs::NumTransformFeedbackBuffers; i++) {
|
||||
const auto& tf = maxwell3d.regs.transform_feedback;
|
||||
if (tf.buffers[i].enable == 0) {
|
||||
@@ -1131,27 +1209,39 @@ public:
|
||||
}
|
||||
}
|
||||
query->value = [&]() -> u64 {
|
||||
const auto saturating_subtract = [](u64 value, u64 amount) {
|
||||
return value > amount ? value - amount : 0;
|
||||
};
|
||||
switch (query->topology) {
|
||||
case Maxwell3D::Regs::PrimitiveTopology::Points:
|
||||
return num_vertices;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::Lines:
|
||||
return num_vertices / 2;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::LineLoop:
|
||||
return (num_vertices / 2) + 1;
|
||||
return num_vertices > 1 ? num_vertices : 0;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::LineStrip:
|
||||
return num_vertices - 1;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::Patches:
|
||||
return saturating_subtract(num_vertices, 1);
|
||||
case Maxwell3D::Regs::PrimitiveTopology::LinesAdjacency:
|
||||
return num_vertices / 4;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::LineStripAdjacency:
|
||||
return saturating_subtract(num_vertices, 3);
|
||||
case Maxwell3D::Regs::PrimitiveTopology::Triangles:
|
||||
case Maxwell3D::Regs::PrimitiveTopology::TrianglesAdjacency:
|
||||
return num_vertices / 3;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::TrianglesAdjacency:
|
||||
return num_vertices / 6;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::TriangleFan:
|
||||
case Maxwell3D::Regs::PrimitiveTopology::TriangleStrip:
|
||||
return saturating_subtract(num_vertices, 2);
|
||||
case Maxwell3D::Regs::PrimitiveTopology::TriangleStripAdjacency:
|
||||
return num_vertices - 2;
|
||||
return num_vertices > 4 ? (num_vertices - 4) / 2 : 0;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::Quads:
|
||||
return num_vertices / 4;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::QuadStrip:
|
||||
return num_vertices > 2 ? (num_vertices - 2) / 2 : 0;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::Polygon:
|
||||
return 1U;
|
||||
return num_vertices >= 3 ? 1U : 0U;
|
||||
case Maxwell3D::Regs::PrimitiveTopology::Patches:
|
||||
return num_vertices / std::max<u64>(query->patch_vertices, 1U);
|
||||
default:
|
||||
return num_vertices;
|
||||
}
|
||||
@@ -1202,16 +1292,24 @@ struct QueryCacheRuntimeImpl {
|
||||
hcr_setup.pNext = nullptr;
|
||||
hcr_setup.flags = 0;
|
||||
|
||||
conditional_resolve_pass = std::make_unique<ConditionalRenderingResolvePass>(
|
||||
device, scheduler, descriptor_pool, compute_pass_descriptor_queue);
|
||||
const bool has_conditional_rendering = device.IsExtConditionalRendering();
|
||||
if (has_conditional_rendering) {
|
||||
conditional_resolve_pass = std::make_unique<ConditionalRenderingResolvePass>(
|
||||
device, scheduler, descriptor_pool, compute_pass_descriptor_queue);
|
||||
}
|
||||
|
||||
VkBufferUsageFlags hcr_buffer_usage =
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
if (has_conditional_rendering) {
|
||||
hcr_buffer_usage |= VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT;
|
||||
}
|
||||
|
||||
const VkBufferCreateInfo buffer_ci = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.size = sizeof(u32),
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT,
|
||||
.usage = hcr_buffer_usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.pQueueFamilyIndices = nullptr,
|
||||
@@ -1338,15 +1436,17 @@ void QueryCacheRuntime::HostConditionalRenderingCompareValueImpl(VideoCommon::Lo
|
||||
}
|
||||
}
|
||||
|
||||
void QueryCacheRuntime::HostConditionalRenderingCompareBCImpl(DAddr address, bool is_equal) {
|
||||
void QueryCacheRuntime::HostConditionalRenderingCompareBCImpl(DAddr address, bool is_equal,
|
||||
bool compare_to_zero) {
|
||||
VkBuffer to_resolve;
|
||||
u32 to_resolve_offset;
|
||||
const u32 resolve_size = compare_to_zero ? 8 : 24;
|
||||
{
|
||||
std::scoped_lock lk(impl->buffer_cache.mutex);
|
||||
static constexpr auto sync_info = VideoCommon::ObtainBufferSynchronize::NoSynchronize;
|
||||
const auto sync_info = VideoCommon::ObtainBufferSynchronize::FullSynchronize;
|
||||
const auto post_op = VideoCommon::ObtainBufferOperation::DoNothing;
|
||||
const auto [buffer, offset] =
|
||||
impl->buffer_cache.ObtainCPUBuffer(address, 24, sync_info, post_op);
|
||||
impl->buffer_cache.ObtainCPUBuffer(address, resolve_size, sync_info, post_op);
|
||||
to_resolve = buffer->Handle();
|
||||
to_resolve_offset = static_cast<u32>(offset);
|
||||
}
|
||||
@@ -1355,7 +1455,7 @@ void QueryCacheRuntime::HostConditionalRenderingCompareBCImpl(DAddr address, boo
|
||||
PauseHostConditionalRendering();
|
||||
}
|
||||
impl->conditional_resolve_pass->Resolve(*impl->hcr_resolve_buffer, to_resolve,
|
||||
to_resolve_offset, false);
|
||||
to_resolve_offset, compare_to_zero);
|
||||
impl->hcr_setup.buffer = *impl->hcr_resolve_buffer;
|
||||
impl->hcr_setup.offset = 0;
|
||||
impl->hcr_setup.flags = is_equal ? 0 : VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT;
|
||||
@@ -1371,7 +1471,7 @@ bool QueryCacheRuntime::HostConditionalRenderingCompareValue(VideoCommon::Lookup
|
||||
if (!impl->device.IsExtConditionalRendering()) {
|
||||
return false;
|
||||
}
|
||||
HostConditionalRenderingCompareValueImpl(object_1, false);
|
||||
HostConditionalRenderingCompareBCImpl(object_1.address, true, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1420,7 +1520,8 @@ bool QueryCacheRuntime::HostConditionalRenderingCompareValues(VideoCommon::Looku
|
||||
auto driver_id = impl->device.GetDriverID();
|
||||
const bool is_gpu_high = Settings::IsGPULevelHigh();
|
||||
|
||||
if ((!is_gpu_high && driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) || driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY || driver_id == VK_DRIVER_ID_ARM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP) {
|
||||
if ((!is_gpu_high && driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) || driver_id == VK_DRIVER_ID_ARM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP) {
|
||||
EndHostConditionalRendering();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1437,10 +1538,12 @@ bool QueryCacheRuntime::HostConditionalRenderingCompareValues(VideoCommon::Looku
|
||||
}
|
||||
|
||||
if (!is_gpu_high) {
|
||||
EndHostConditionalRendering();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_in_bc[0] && !is_in_bc[1]) {
|
||||
EndHostConditionalRendering();
|
||||
return true;
|
||||
}
|
||||
HostConditionalRenderingCompareBCImpl(object_1.address, equal_check);
|
||||
|
||||
@@ -63,7 +63,8 @@ public:
|
||||
|
||||
private:
|
||||
void HostConditionalRenderingCompareValueImpl(VideoCommon::LookupData object, bool is_equal);
|
||||
void HostConditionalRenderingCompareBCImpl(DAddr address, bool is_equal);
|
||||
void HostConditionalRenderingCompareBCImpl(DAddr address, bool is_equal,
|
||||
bool compare_to_zero = false);
|
||||
friend struct QueryCacheRuntimeImpl;
|
||||
std::unique_ptr<QueryCacheRuntimeImpl> impl;
|
||||
};
|
||||
|
||||
@@ -173,6 +173,28 @@ DrawParams MakeDrawParams(const MaxwellDrawState& draw_state, u32 num_instances,
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
bool SupportsPrimitiveRestart(VkPrimitiveTopology topology) {
|
||||
switch (topology) {
|
||||
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
|
||||
case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsPrimitiveRestartSupported(const Device& device, VkPrimitiveTopology topology) {
|
||||
return ((topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST &&
|
||||
device.IsTopologyListPrimitiveRestartSupported()) ||
|
||||
SupportsPrimitiveRestart(topology) ||
|
||||
(topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST &&
|
||||
device.IsPatchListPrimitiveRestartSupported()));
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
|
||||
@@ -225,6 +247,7 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) {
|
||||
|
||||
UpdateDynamicStates();
|
||||
|
||||
query_cache.NotifySegment(true);
|
||||
HandleTransformFeedback();
|
||||
query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64,
|
||||
maxwell3d->regs.zpass_pixel_count_enable);
|
||||
@@ -336,6 +359,7 @@ void RasterizerVulkan::DrawTexture() {
|
||||
|
||||
UpdateDynamicStates();
|
||||
|
||||
query_cache.NotifySegment(true);
|
||||
query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64,
|
||||
maxwell3d->regs.zpass_pixel_count_enable);
|
||||
const auto& draw_texture_state = maxwell3d->draw_manager->GetDrawTextureState();
|
||||
@@ -575,11 +599,17 @@ void RasterizerVulkan::DispatchCompute() {
|
||||
}
|
||||
|
||||
void RasterizerVulkan::ResetCounter(VideoCommon::QueryType type) {
|
||||
if (type != VideoCommon::QueryType::ZPassPixelCount64) {
|
||||
switch (type) {
|
||||
case VideoCommon::QueryType::ZPassPixelCount64:
|
||||
case VideoCommon::QueryType::StreamingByteCount:
|
||||
case VideoCommon::QueryType::StreamingPrimitivesSucceeded:
|
||||
case VideoCommon::QueryType::VtgPrimitivesOut:
|
||||
query_cache.CounterReset(type);
|
||||
return;
|
||||
default:
|
||||
LOG_DEBUG(Render_Vulkan, "Unimplemented counter reset={}", type);
|
||||
return;
|
||||
}
|
||||
query_cache.CounterReset(type);
|
||||
}
|
||||
|
||||
void RasterizerVulkan::Query(GPUVAddr gpu_addr, VideoCommon::QueryType type,
|
||||
@@ -766,6 +796,9 @@ void RasterizerVulkan::ReleaseFences(bool force) {
|
||||
|
||||
void RasterizerVulkan::FlushAndInvalidateRegion(DAddr addr, u64 size,
|
||||
VideoCommon::CacheType which) {
|
||||
if (Settings::IsGPULevelHigh()) {
|
||||
FlushRegion(addr, size, which);
|
||||
}
|
||||
InvalidateRegion(addr, size, which);
|
||||
}
|
||||
|
||||
@@ -830,6 +863,10 @@ bool RasterizerVulkan::AccelerateConditionalRendering() {
|
||||
return query_cache.AccelerateHostConditionalRendering();
|
||||
}
|
||||
|
||||
bool RasterizerVulkan::HasDrawTransformFeedback() {
|
||||
return device.IsTransformFeedbackDrawSupported();
|
||||
}
|
||||
|
||||
bool RasterizerVulkan::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surface& src,
|
||||
const Tegra::Engines::Fermi2D::Surface& dst,
|
||||
const Tegra::Engines::Fermi2D::Config& copy_config) {
|
||||
@@ -976,6 +1013,12 @@ bool AccelerateDMA::BufferToImage(const Tegra::DMA::ImageCopy& copy_info,
|
||||
|
||||
void RasterizerVulkan::UpdateDynamicStates() {
|
||||
auto& regs = maxwell3d->regs;
|
||||
auto& flags = maxwell3d->dirty.flags;
|
||||
const auto topology = maxwell3d->draw_manager->GetDrawState().topology;
|
||||
if (state_tracker.ChangePrimitiveTopology(topology)) {
|
||||
flags[Dirty::DepthBiasEnable] = true;
|
||||
flags[Dirty::PrimitiveRestartEnable] = true;
|
||||
}
|
||||
|
||||
// Core Dynamic States (Vulkan 1.0) - Always active regardless of dyna_state setting
|
||||
UpdateViewportsState(regs);
|
||||
@@ -1084,6 +1127,9 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
|
||||
if (!state_tracker.TouchViewports()) {
|
||||
return;
|
||||
}
|
||||
|
||||
maxwell3d->dirty.flags[Dirty::Scissors] = true;
|
||||
|
||||
if (!regs.viewport_scale_offset_enabled) {
|
||||
float x = static_cast<float>(regs.surface_clip.x);
|
||||
float y = static_cast<float>(regs.surface_clip.y);
|
||||
@@ -1101,8 +1147,12 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
|
||||
.minDepth = 0.0f,
|
||||
.maxDepth = 1.0f,
|
||||
};
|
||||
scheduler.Record([viewport](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetViewport(0, viewport);
|
||||
scheduler.Record([this, viewport](vk::CommandBuffer cmdbuf) {
|
||||
const u32 num_viewports = std::min<u32>(device.GetMaxViewports(), Maxwell::NumViewports);
|
||||
std::array<VkViewport, Maxwell::NumViewports> viewport_list{};
|
||||
viewport_list.fill(viewport);
|
||||
const vk::Span<VkViewport> viewports(viewport_list.data(), num_viewports);
|
||||
cmdbuf.SetViewport(0, viewports);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -1142,8 +1192,12 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs
|
||||
scissor.offset.y = static_cast<int32_t>(y);
|
||||
scissor.extent.width = width;
|
||||
scissor.extent.height = height;
|
||||
scheduler.Record([scissor](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetScissor(0, scissor);
|
||||
scheduler.Record([this, scissor](vk::CommandBuffer cmdbuf) {
|
||||
const u32 num_scissors = std::min<u32>(device.GetMaxViewports(), Maxwell::NumViewports);
|
||||
std::array<VkRect2D, Maxwell::NumViewports> scissor_list{};
|
||||
scissor_list.fill(scissor);
|
||||
const vk::Span<VkRect2D> scissors(scissor_list.data(), num_scissors);
|
||||
cmdbuf.SetScissor(0, scissors);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -1388,7 +1442,17 @@ void RasterizerVulkan::UpdatePrimitiveRestartEnable(Tegra::Engines::Maxwell3D::R
|
||||
if (!state_tracker.TouchPrimitiveRestartEnable()) {
|
||||
return;
|
||||
}
|
||||
scheduler.Record([enable = regs.primitive_restart.enabled](vk::CommandBuffer cmdbuf) {
|
||||
|
||||
bool enable = regs.primitive_restart.enabled != 0;
|
||||
if (device.IsMoltenVK()) {
|
||||
enable = true;
|
||||
} else if (enable) {
|
||||
const auto topology =
|
||||
MaxwellToVK::PrimitiveTopology(device, maxwell3d->draw_manager->GetDrawState().topology);
|
||||
enable = IsPrimitiveRestartSupported(device, topology);
|
||||
}
|
||||
|
||||
scheduler.Record([enable](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetPrimitiveRestartEnableEXT(enable);
|
||||
});
|
||||
}
|
||||
@@ -1727,7 +1791,9 @@ void RasterizerVulkan::UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs&
|
||||
|
||||
void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs) {
|
||||
auto& dirty{maxwell3d->dirty.flags};
|
||||
if (!dirty[Dirty::VertexInput]) {
|
||||
const bool vertex_input_dirty = dirty[Dirty::VertexInput];
|
||||
const bool vertex_buffers_dirty = dirty[VideoCommon::Dirty::VertexBuffers];
|
||||
if (!vertex_input_dirty && !vertex_buffers_dirty) {
|
||||
return;
|
||||
}
|
||||
dirty[Dirty::VertexInput] = false;
|
||||
@@ -1735,38 +1801,31 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
|
||||
boost::container::static_vector<VkVertexInputBindingDescription2EXT, 32> bindings;
|
||||
boost::container::static_vector<VkVertexInputAttributeDescription2EXT, 32> attributes;
|
||||
|
||||
// There seems to be a bug on Nvidia's driver where updating only higher attributes ends up
|
||||
// generating dirty state. Track the highest dirty attribute and update all attributes until
|
||||
// that one.
|
||||
size_t highest_dirty_attr{};
|
||||
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
|
||||
if (dirty[Dirty::VertexAttribute0 + index]) {
|
||||
highest_dirty_attr = index;
|
||||
}
|
||||
}
|
||||
for (size_t index = 0; index < highest_dirty_attr; ++index) {
|
||||
const u32 max_attributes =
|
||||
static_cast<u32>(std::min<size_t>(Maxwell::NumVertexAttributes,
|
||||
device.GetMaxVertexInputAttributes()));
|
||||
const u32 max_bindings =
|
||||
static_cast<u32>(std::min<size_t>(Maxwell::NumVertexArrays,
|
||||
device.GetMaxVertexInputBindings()));
|
||||
|
||||
|
||||
for (u32 index = 0; index < max_attributes; ++index) {
|
||||
const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]};
|
||||
const u32 binding{attribute.buffer};
|
||||
dirty[Dirty::VertexAttribute0 + index] = false;
|
||||
dirty[Dirty::VertexBinding0 + static_cast<size_t>(binding)] = true;
|
||||
if (!attribute.constant) {
|
||||
attributes.push_back({
|
||||
.sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT,
|
||||
.pNext = nullptr,
|
||||
.location = static_cast<u32>(index),
|
||||
.binding = binding,
|
||||
.format = MaxwellToVK::VertexFormat(device, attribute.type, attribute.size),
|
||||
.offset = attribute.offset,
|
||||
});
|
||||
}
|
||||
}
|
||||
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
|
||||
if (!dirty[Dirty::VertexBinding0 + index]) {
|
||||
if (attribute.constant || binding >= max_bindings) {
|
||||
continue;
|
||||
}
|
||||
dirty[Dirty::VertexBinding0 + index] = false;
|
||||
attributes.push_back({
|
||||
.sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT,
|
||||
.pNext = nullptr,
|
||||
.location = index,
|
||||
.binding = binding,
|
||||
.format = MaxwellToVK::VertexFormat(device, attribute.type, attribute.size),
|
||||
.offset = attribute.offset,
|
||||
});
|
||||
}
|
||||
|
||||
const u32 binding{static_cast<u32>(index)};
|
||||
for (u32 binding = 0; binding < max_bindings; ++binding) {
|
||||
const auto& input_binding{regs.vertex_streams[binding]};
|
||||
const bool is_instanced{regs.vertex_stream_instances.IsInstancingEnabled(binding)};
|
||||
bindings.push_back({
|
||||
@@ -1778,6 +1837,14 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
|
||||
.divisor = is_instanced ? input_binding.frequency : 1,
|
||||
});
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
|
||||
dirty[Dirty::VertexAttribute0 + index] = false;
|
||||
}
|
||||
for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
|
||||
dirty[Dirty::VertexBinding0 + index] = false;
|
||||
}
|
||||
|
||||
scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetVertexInputEXT(bindings, attributes);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
@@ -122,6 +122,7 @@ public:
|
||||
void FlushCommands() override;
|
||||
void TickFrame() override;
|
||||
bool AccelerateConditionalRendering() override;
|
||||
bool HasDrawTransformFeedback() override;
|
||||
bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surface& src,
|
||||
const Tegra::Engines::Fermi2D::Surface& dst,
|
||||
const Tegra::Engines::Fermi2D::Config& copy_config) override;
|
||||
|
||||
@@ -324,6 +324,8 @@ void Scheduler::EndRenderPass()
|
||||
return;
|
||||
}
|
||||
|
||||
query_cache->CounterClose(VideoCommon::QueryType::StreamingByteCount);
|
||||
|
||||
// Log render pass end
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
Settings::values.gpu_log_vulkan_calls.GetValue()) {
|
||||
|
||||
@@ -63,6 +63,11 @@ public:
|
||||
/// of a renderpass.
|
||||
void RequestOutsideRenderPassOperationContext();
|
||||
|
||||
/// Returns true when a render pass is currently active in the scheduler state.
|
||||
bool IsRenderPassActive() const {
|
||||
return state.renderpass != VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
/// Update the pipeline to the current execution context.
|
||||
bool UpdateGraphicsPipeline(GraphicsPipeline* pipeline);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
@@ -87,6 +87,7 @@ Flags MakeInvalidationFlags() {
|
||||
void SetupDirtyViewports(Tables& tables) {
|
||||
FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports);
|
||||
FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports);
|
||||
FillBlock(tables[1], OFF(surface_clip), NUM(surface_clip), Viewports);
|
||||
tables[0][OFF(viewport_scale_offset_enabled)] = Viewports;
|
||||
tables[1][OFF(window_origin)] = Viewports;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
|
||||
@@ -176,7 +176,18 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
|
||||
.pViewFormats = view_formats.data(),
|
||||
};
|
||||
if (view_formats.size() > 1) {
|
||||
image_ci.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
image_ci.flags |=
|
||||
VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
||||
|
||||
const bool has_storage_compatible_view =
|
||||
std::any_of(view_formats.begin(), view_formats.end(), [&device](VkFormat view_format) {
|
||||
return device.IsFormatSupported(view_format, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT,
|
||||
FormatType::Optimal);
|
||||
});
|
||||
if (has_storage_compatible_view) {
|
||||
image_ci.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
}
|
||||
|
||||
if (device.IsKhrImageFormatListSupported()) {
|
||||
image_ci.pNext = &image_format_list;
|
||||
}
|
||||
@@ -668,11 +679,16 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
|
||||
}
|
||||
|
||||
void TryTransformSwizzleIfNeeded(PixelFormat format, std::array<SwizzleSource, 4>& swizzle,
|
||||
bool emulate_a4b4g4r4) {
|
||||
bool emulate_bgr565, bool emulate_a4b4g4r4) {
|
||||
switch (format) {
|
||||
case PixelFormat::A1B5G5R5_UNORM:
|
||||
std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed);
|
||||
break;
|
||||
case PixelFormat::B5G6R5_UNORM:
|
||||
if (emulate_bgr565) {
|
||||
std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed);
|
||||
}
|
||||
break;
|
||||
case PixelFormat::A5B5G5R1_UNORM:
|
||||
std::ranges::transform(swizzle, swizzle.begin(), SwapSpecial);
|
||||
break;
|
||||
@@ -2119,22 +2135,21 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
||||
if (!info.IsRenderTarget()) {
|
||||
swizzle = info.Swizzle();
|
||||
TryTransformSwizzleIfNeeded(format, swizzle,
|
||||
!device->IsExt4444FormatsSupported());
|
||||
device->MustEmulateBGR565(),
|
||||
!device->IsExt4444FormatsSupported());
|
||||
if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) {
|
||||
std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed);
|
||||
SanitizeDepthStencilSwizzle(swizzle, device->SupportsDepthStencilSwizzleOne());
|
||||
}
|
||||
}
|
||||
const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format);
|
||||
if (ImageUsageFlags(format_info, format) != image.UsageFlags()) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Image view format {} has different usage flags than image format {}", format,
|
||||
image.info.format);
|
||||
}
|
||||
const VkImageUsageFlags requested_view_usage = ImageUsageFlags(format_info, format);
|
||||
const VkImageUsageFlags image_usage = image.UsageFlags();
|
||||
const VkImageUsageFlags clamped_view_usage = requested_view_usage & image_usage;
|
||||
const VkImageViewUsageCreateInfo image_view_usage{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.usage = ImageUsageFlags(format_info, format),
|
||||
.usage = clamped_view_usage,
|
||||
};
|
||||
const VkImageViewCreateInfo create_info{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
@@ -2300,23 +2315,18 @@ vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_
|
||||
|
||||
Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& tsc) {
|
||||
const auto& device = runtime.device;
|
||||
// Check if custom border colors are supported
|
||||
const bool has_custom_border_colors = runtime.device.IsCustomBorderColorsSupported();
|
||||
const bool has_format_undefined = runtime.device.IsCustomBorderColorWithoutFormatSupported();
|
||||
const bool has_custom_border_extension = runtime.device.IsExtCustomBorderColorSupported();
|
||||
const bool has_format_undefined =
|
||||
has_custom_border_extension && runtime.device.IsCustomBorderColorWithoutFormatSupported();
|
||||
const bool has_custom_border_colors =
|
||||
has_format_undefined && runtime.device.IsCustomBorderColorsSupported();
|
||||
const auto color = tsc.BorderColor();
|
||||
|
||||
// Determine border format based on available features:
|
||||
// - If customBorderColorWithoutFormat is available: use VK_FORMAT_UNDEFINED (most flexible)
|
||||
// - If only customBorderColors is available: use concrete format (R8G8B8A8_UNORM)
|
||||
// - If neither is available: use standard border colors (handled by ConvertBorderColor)
|
||||
const VkFormat border_format = has_format_undefined ? VK_FORMAT_UNDEFINED
|
||||
: VK_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
const VkSamplerCustomBorderColorCreateInfoEXT border_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT,
|
||||
.pNext = nullptr,
|
||||
.customBorderColor = std::bit_cast<VkClearColorValue>(color),
|
||||
.format = border_format,
|
||||
.format = VK_FORMAT_UNDEFINED,
|
||||
};
|
||||
const void* pnext = nullptr;
|
||||
if (has_custom_border_colors) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
@@ -88,13 +88,13 @@ std::pair<std::array<Shader::TransformFeedbackVarying, 256>, u32> MakeTransformF
|
||||
return 0;
|
||||
};
|
||||
|
||||
UNIMPLEMENTED_IF_MSG(layout.stream != 0, "Stream is not zero: {}", layout.stream);
|
||||
Shader::TransformFeedbackVarying varying{
|
||||
.buffer = static_cast<u32>(buffer),
|
||||
.stride = layout.stride,
|
||||
.offset = offset * 4,
|
||||
.components = 1,
|
||||
};
|
||||
varying.stream = layout.stream;
|
||||
const u32 base_offset = offset;
|
||||
const auto attribute{get_attribute(offset)};
|
||||
if (std::ranges::find(VECTORS, Common::AlignDown(attribute, 4)) != VECTORS.end()) {
|
||||
|
||||
@@ -869,6 +869,10 @@ bool Device::HasTimelineSemaphore() const {
|
||||
return features.timeline_semaphore.timelineSemaphore;
|
||||
}
|
||||
|
||||
bool Device::MustEmulateBGR565() const {
|
||||
return Settings::values.emulate_bgr565.GetValue();
|
||||
}
|
||||
|
||||
bool Device::GetSuitability(bool requires_swapchain) {
|
||||
// Assume we will be suitable.
|
||||
bool suitable = true;
|
||||
@@ -919,6 +923,17 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
||||
FOR_EACH_VK_FEATURE_EXT(FEATURE_EXTENSION);
|
||||
FOR_EACH_VK_EXTENSION(EXTENSION);
|
||||
|
||||
if (supported_extensions.contains(VK_KHR_ROBUSTNESS_2_EXTENSION_NAME)) {
|
||||
loaded_extensions.erase(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
||||
loaded_extensions.insert(VK_KHR_ROBUSTNESS_2_EXTENSION_NAME);
|
||||
extensions.robustness_2 = true;
|
||||
} else if (supported_extensions.contains(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) {
|
||||
loaded_extensions.insert(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
||||
extensions.robustness_2 = true;
|
||||
} else {
|
||||
extensions.robustness_2 = false;
|
||||
}
|
||||
|
||||
#undef FEATURE_EXTENSION
|
||||
#undef EXTENSION
|
||||
|
||||
@@ -1131,8 +1146,6 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
||||
|
||||
if (u32(Settings::values.dyna_state.GetValue()) == 0) {
|
||||
LOG_INFO(Render_Vulkan, "Extended Dynamic State disabled by user setting, clearing all EDS features");
|
||||
features.custom_border_color.customBorderColors = false;
|
||||
features.custom_border_color.customBorderColorWithoutFormat = false;
|
||||
features.extended_dynamic_state.extendedDynamicState = false;
|
||||
features.extended_dynamic_state2.extendedDynamicState2 = false;
|
||||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
|
||||
@@ -1148,24 +1161,13 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
||||
|
||||
void Device::RemoveUnsuitableExtensions() {
|
||||
// VK_EXT_custom_border_color
|
||||
// Enable extension if driver supports it, then check individual features
|
||||
// - customBorderColors: Required to use VK_BORDER_COLOR_FLOAT_CUSTOM_EXT
|
||||
// - customBorderColorWithoutFormat: Optional, allows VK_FORMAT_UNDEFINED
|
||||
// If only customBorderColors is available, we must provide a specific format
|
||||
if (extensions.custom_border_color) {
|
||||
// Verify that at least customBorderColors is available
|
||||
if (!features.custom_border_color.customBorderColors) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"VK_EXT_custom_border_color reported but customBorderColors feature not available, disabling");
|
||||
extensions.custom_border_color = false;
|
||||
}
|
||||
extensions.custom_border_color =
|
||||
features.custom_border_color.customBorderColors &&
|
||||
features.custom_border_color.customBorderColorWithoutFormat;
|
||||
}
|
||||
RemoveExtensionFeatureIfUnsuitable(extensions.custom_border_color, features.custom_border_color,
|
||||
VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
|
||||
// VK_KHR_unified_image_layouts
|
||||
extensions.unified_image_layouts = features.unified_image_layouts.unifiedImageLayouts;
|
||||
RemoveExtensionFeatureIfUnsuitable(extensions.unified_image_layouts, features.unified_image_layouts,
|
||||
VK_KHR_UNIFIED_IMAGE_LAYOUTS_EXTENSION_NAME);
|
||||
|
||||
// VK_EXT_depth_bias_control
|
||||
extensions.depth_bias_control =
|
||||
@@ -1251,16 +1253,22 @@ void Device::RemoveUnsuitableExtensions() {
|
||||
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
|
||||
|
||||
// VK_EXT_robustness2
|
||||
extensions.robustness_2 = features.robustness2.robustBufferAccess2 ||
|
||||
features.robustness2.robustImageAccess2 ||
|
||||
features.robustness2.nullDescriptor;
|
||||
features.robustness2.robustBufferAccess2 = VK_FALSE;
|
||||
features.robustness2.robustImageAccess2 = VK_FALSE;
|
||||
extensions.robustness_2 = features.robustness2.nullDescriptor;
|
||||
|
||||
const char* robustness2_extension_name =
|
||||
loaded_extensions.contains(VK_KHR_ROBUSTNESS_2_EXTENSION_NAME)
|
||||
? VK_KHR_ROBUSTNESS_2_EXTENSION_NAME
|
||||
: VK_EXT_ROBUSTNESS_2_EXTENSION_NAME;
|
||||
|
||||
RemoveExtensionFeatureIfUnsuitable(extensions.robustness_2, features.robustness2,
|
||||
VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
||||
robustness2_extension_name);
|
||||
|
||||
// VK_EXT_image_robustness
|
||||
extensions.image_robustness = features.image_robustness.robustImageAccess;
|
||||
RemoveExtensionFeatureIfUnsuitable(extensions.image_robustness, features.image_robustness,
|
||||
// Image robustness
|
||||
extensions.robust_image_access = features.robust_image_access.robustImageAccess;
|
||||
RemoveExtensionFeatureIfUnsuitable(extensions.robust_image_access,
|
||||
features.robust_image_access,
|
||||
VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME);
|
||||
|
||||
// VK_KHR_shader_atomic_int64
|
||||
@@ -1288,8 +1296,7 @@ void Device::RemoveUnsuitableExtensions() {
|
||||
// VK_EXT_transform_feedback
|
||||
extensions.transform_feedback =
|
||||
features.transform_feedback.transformFeedback &&
|
||||
properties.transform_feedback.maxTransformFeedbackBuffers > 0 &&
|
||||
properties.transform_feedback.transformFeedbackQueries;
|
||||
properties.transform_feedback.maxTransformFeedbackBuffers > 0;
|
||||
RemoveExtensionFeatureIfUnsuitable(extensions.transform_feedback, features.transform_feedback,
|
||||
VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||
FEATURE(KHR, TimelineSemaphore, TIMELINE_SEMAPHORE, timeline_semaphore)
|
||||
|
||||
#define FOR_EACH_VK_FEATURE_1_3(FEATURE) \
|
||||
FEATURE(EXT, ImageRobustness, IMAGE_ROBUSTNESS, image_robustness) \
|
||||
FEATURE(EXT, ImageRobustness, IMAGE_ROBUSTNESS, robust_image_access) \
|
||||
FEATURE(EXT, ShaderDemoteToHelperInvocation, SHADER_DEMOTE_TO_HELPER_INVOCATION, \
|
||||
shader_demote_to_helper_invocation) \
|
||||
FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control) \
|
||||
@@ -68,8 +68,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||
FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \
|
||||
pipeline_executable_properties) \
|
||||
FEATURE(KHR, WorkgroupMemoryExplicitLayout, WORKGROUP_MEMORY_EXPLICIT_LAYOUT, \
|
||||
workgroup_memory_explicit_layout) \
|
||||
FEATURE(KHR, UnifiedImageLayouts, UNIFIED_IMAGE_LAYOUTS, unified_image_layouts)
|
||||
workgroup_memory_explicit_layout)
|
||||
|
||||
|
||||
// Define miscellaneous extensions which may be used by the implementation here.
|
||||
@@ -124,7 +123,6 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME) \
|
||||
EXTENSION_NAME(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME) \
|
||||
EXTENSION_NAME(VK_EXT_4444_FORMATS_EXTENSION_NAME) \
|
||||
EXTENSION_NAME(VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME) \
|
||||
EXTENSION_NAME(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME) \
|
||||
EXTENSION_NAME(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) \
|
||||
EXTENSION_NAME(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME) \
|
||||
@@ -174,13 +172,11 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||
FEATURE_NAME(depth_bias_control, depthBiasExact) \
|
||||
FEATURE_NAME(extended_dynamic_state, extendedDynamicState) \
|
||||
FEATURE_NAME(format_a4b4g4r4, formatA4B4G4R4) \
|
||||
FEATURE_NAME(image_robustness, robustImageAccess) \
|
||||
FEATURE_NAME(robust_image_access, robustImageAccess) \
|
||||
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) \
|
||||
@@ -542,6 +538,17 @@ public:
|
||||
return extensions.transform_feedback;
|
||||
}
|
||||
|
||||
/// Returns true if transform feedback draw commands are supported.
|
||||
bool IsTransformFeedbackDrawSupported() const {
|
||||
return extensions.transform_feedback && properties.transform_feedback.transformFeedbackDraw;
|
||||
}
|
||||
|
||||
/// Returns true if transform feedback query types are supported.
|
||||
bool IsTransformFeedbackQueriesSupported() const {
|
||||
return extensions.transform_feedback &&
|
||||
properties.transform_feedback.transformFeedbackQueries;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_EXT_transform_feedback properly.
|
||||
bool AreTransformFeedbackGeometryStreamsSupported() const {
|
||||
return features.transform_feedback.geometryStreams;
|
||||
@@ -552,36 +559,6 @@ public:
|
||||
return extensions.custom_border_color;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_EXT_image_robustness.
|
||||
bool IsExtImageRobustnessSupported() const {
|
||||
return extensions.image_robustness;
|
||||
}
|
||||
|
||||
/// Returns true if robustImageAccess is supported.
|
||||
bool IsRobustImageAccessSupported() const {
|
||||
return features.image_robustness.robustImageAccess;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_EXT_robustness2.
|
||||
bool IsExtRobustness2Supported() const {
|
||||
return extensions.robustness_2;
|
||||
}
|
||||
|
||||
/// Returns true if robustBufferAccess2 is supported.
|
||||
bool IsRobustBufferAccess2Supported() const {
|
||||
return features.robustness2.robustBufferAccess2;
|
||||
}
|
||||
|
||||
/// Returns true if robustImageAccess2 is supported.
|
||||
bool IsRobustImageAccess2Supported() const {
|
||||
return features.robustness2.robustImageAccess2;
|
||||
}
|
||||
|
||||
/// Returns true if nullDescriptor is supported.
|
||||
bool IsNullDescriptorSupported() const {
|
||||
return features.robustness2.nullDescriptor;
|
||||
}
|
||||
|
||||
/// Returns true if customBorderColors feature is available.
|
||||
bool IsCustomBorderColorsSupported() const {
|
||||
return features.custom_border_color.customBorderColors;
|
||||
@@ -805,6 +782,8 @@ public:
|
||||
return features.robustness2.nullDescriptor;
|
||||
}
|
||||
|
||||
bool MustEmulateBGR565() const;
|
||||
|
||||
bool HasExactDepthBiasControl() const {
|
||||
return features.depth_bias_control.depthBiasExact;
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
||||
X(vkCmdEndDebugUtilsLabelEXT);
|
||||
X(vkCmdFillBuffer);
|
||||
X(vkCmdPipelineBarrier);
|
||||
X(vkCmdResetQueryPool);
|
||||
X(vkCmdPushConstants);
|
||||
X(vkCmdPushDescriptorSetWithTemplateKHR);
|
||||
X(vkCmdSetBlendConstants);
|
||||
|
||||
@@ -225,6 +225,7 @@ struct DeviceDispatch : InstanceDispatch {
|
||||
PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT{};
|
||||
PFN_vkCmdFillBuffer vkCmdFillBuffer{};
|
||||
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier{};
|
||||
PFN_vkCmdResetQueryPool vkCmdResetQueryPool{};
|
||||
PFN_vkCmdPushConstants vkCmdPushConstants{};
|
||||
PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR{};
|
||||
PFN_vkCmdResolveImage vkCmdResolveImage{};
|
||||
@@ -1168,6 +1169,10 @@ public:
|
||||
dld->vkCmdEndQuery(handle, query_pool, query);
|
||||
}
|
||||
|
||||
void ResetQueryPool(VkQueryPool query_pool, u32 first_query, u32 query_count) const noexcept {
|
||||
dld->vkCmdResetQueryPool(handle, query_pool, first_query, query_count);
|
||||
}
|
||||
|
||||
void BindDescriptorSets(VkPipelineBindPoint bind_point, VkPipelineLayout layout, u32 first,
|
||||
Span<VkDescriptorSet> sets, Span<u32> dynamic_offsets) const noexcept {
|
||||
dld->vkCmdBindDescriptorSets(handle, bind_point, layout, first, sets.size(), sets.data(),
|
||||
|
||||
@@ -31,11 +31,10 @@ ModSelectDialog::ModSelectDialog(const QStringList& mods, QWidget* parent)
|
||||
}
|
||||
|
||||
ui->treeView->expandAll();
|
||||
ui->treeView->resizeColumnToContents(0);
|
||||
|
||||
int rows = item_model->rowCount();
|
||||
int height =
|
||||
ui->treeView->contentsMargins().top() * 4 + ui->treeView->contentsMargins().bottom() * 4;
|
||||
4 + ui->treeView->contentsMargins().top() * 4 + ui->treeView->contentsMargins().bottom() * 4;
|
||||
int width = 0;
|
||||
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
@@ -46,7 +45,7 @@ ModSelectDialog::ModSelectDialog(const QStringList& mods, QWidget* parent)
|
||||
width +=
|
||||
ui->treeView->contentsMargins().left() * 4 + ui->treeView->contentsMargins().right() * 4;
|
||||
ui->treeView->setMinimumHeight(qMin(height, 600));
|
||||
ui->treeView->setMinimumWidth(qMin(width, 700));
|
||||
ui->treeView->setMinimumWidth(qMax(width, 540));
|
||||
adjustSize();
|
||||
|
||||
connect(this, &QDialog::accepted, this, [this]() {
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<width>580</width>
|
||||
<height>430</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
<string>Import Mods</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
|
||||
+18
-36
@@ -488,49 +488,31 @@ MainWindow::MainWindow(bool has_broken_vulkan)
|
||||
QtCommon::system->HIDCore().ReloadInputDevices();
|
||||
controller_dialog->refreshConfiguration();
|
||||
|
||||
const auto branch_name = std::string(Common::g_scm_branch);
|
||||
const auto description = std::string(Common::g_scm_desc);
|
||||
const auto build_id = std::string(Common::g_build_id);
|
||||
|
||||
const auto yuzu_build = fmt::format("Eden Development Build | {}-{}", branch_name, description);
|
||||
const auto override_build =
|
||||
fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id);
|
||||
const auto yuzu_build = fmt::format("Eden | {}-{}", Common::g_scm_branch, Common::g_scm_desc);
|
||||
const auto override_build = fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), Common::g_build_id);
|
||||
const auto yuzu_build_version = override_build.empty() ? yuzu_build : override_build;
|
||||
const auto processor_count = std::thread::hardware_concurrency();
|
||||
|
||||
LOG_INFO(Frontend, "Eden Version: {}", yuzu_build_version);
|
||||
LogRuntimes();
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
const auto& caps = Common::GetCPUCaps();
|
||||
std::string cpu_string = caps.cpu_string;
|
||||
if (caps.avx || caps.avx2 || caps.avx512f) {
|
||||
cpu_string += " | AVX";
|
||||
if (caps.avx512f) {
|
||||
cpu_string += "512";
|
||||
} else if (caps.avx2) {
|
||||
cpu_string += '2';
|
||||
}
|
||||
if (caps.fma || caps.fma4) {
|
||||
cpu_string += " | FMA";
|
||||
}
|
||||
}
|
||||
LOG_INFO(Frontend, "Host CPU: {}", cpu_string);
|
||||
if (std::optional<int> processor_core = Common::GetProcessorCount()) {
|
||||
LOG_INFO(Frontend, "Host CPU Cores: {}", *processor_core);
|
||||
auto const& caps = Common::GetCPUCaps();
|
||||
std::string ext_string{};
|
||||
#define CPU_CAPS_ELEM(n) if (caps.n) ext_string += " | " #n;
|
||||
CPU_CAPS_LIST
|
||||
#undef CPU_CAPS_ELEM
|
||||
if (auto const processor_core = Common::GetProcessorCount()) {
|
||||
LOG_INFO(Frontend, "Host CPU: {} ({} cores, {} threads) {}", caps.cpu_string, *processor_core, processor_count, ext_string);
|
||||
} else {
|
||||
LOG_INFO(Frontend, "Host CPU: {} ({} threads) {}", caps.cpu_string, processor_count, ext_string);
|
||||
}
|
||||
#endif
|
||||
LOG_INFO(Frontend, "Host CPU Threads: {}", processor_count);
|
||||
LOG_INFO(Frontend, "Host OS: {}", PrettyProductName().toStdString());
|
||||
LOG_INFO(Frontend, "Host RAM: {:.2f} GiB",
|
||||
Common::GetMemInfo().TotalPhysicalMemory / f64{1_GiB});
|
||||
LOG_INFO(Frontend, "Host RAM: {:.2f} GiB", Common::GetMemInfo().TotalPhysicalMemory / f64{1_GiB});
|
||||
LOG_INFO(Frontend, "Host Swap: {:.2f} GiB", Common::GetMemInfo().TotalSwapMemory / f64{1_GiB});
|
||||
#ifdef _WIN32
|
||||
LOG_INFO(Frontend, "Host Timer Resolution: {:.4f} ms",
|
||||
std::chrono::duration_cast<std::chrono::duration<f64, std::milli>>(
|
||||
Common::Windows::SetCurrentTimerResolutionToMaximum())
|
||||
.count());
|
||||
QtCommon::system->CoreTiming().SetTimerResolutionNs(
|
||||
Common::Windows::GetCurrentTimerResolution());
|
||||
LOG_INFO(Frontend, "Host Timer Resolution: {:.4f} ms", std::chrono::duration_cast<std::chrono::duration<f64, std::milli>>(Common::Windows::SetCurrentTimerResolutionToMaximum()).count());
|
||||
QtCommon::system->CoreTiming().SetTimerResolutionNs(Common::Windows::GetCurrentTimerResolution());
|
||||
#endif
|
||||
UpdateWindowTitle();
|
||||
|
||||
@@ -538,10 +520,10 @@ MainWindow::MainWindow(bool has_broken_vulkan)
|
||||
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
if (UISettings::values.check_for_updates) {
|
||||
update_future = QtConcurrent::run(
|
||||
[]() -> std::optional<UpdateChecker::Update> { return UpdateChecker::GetUpdate(); });
|
||||
update_watcher.connect(&update_watcher, &QFutureWatcher<QString>::finished, this,
|
||||
&MainWindow::OnEmulatorUpdateAvailable);
|
||||
update_future = QtConcurrent::run([] -> std::optional<UpdateChecker::Update> {
|
||||
return UpdateChecker::GetUpdate();
|
||||
});
|
||||
update_watcher.connect(&update_watcher, &QFutureWatcher<QString>::finished, this, &MainWindow::OnEmulatorUpdateAvailable);
|
||||
update_watcher.setFuture(update_future);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user