mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-06-06 01:13:45 -04:00
Compare commits
33 commits
e48caec38e
...
c864f08b62
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c864f08b62 | ||
|
|
17eb266d93 | ||
|
|
0f0adc8872 | ||
|
|
5027aecf77 | ||
|
|
f39e985434 | ||
|
|
f8f5a9b1a2 | ||
|
|
a8047d3b12 | ||
|
|
cc8451f764 | ||
|
|
27189f39d2 | ||
|
|
683e6249c3 | ||
|
|
eaece15dbd | ||
|
|
8e5419209c | ||
|
|
8fac95dcc0 | ||
|
|
706a3d0764 | ||
|
|
3d19743d95 | ||
|
|
bd2d344040 | ||
|
|
5f4a286046 | ||
|
|
b7fcec4985 | ||
|
|
0473747f94 | ||
|
|
23bb909bc9 | ||
|
|
e94ac63a5e | ||
|
|
88ff086d13 | ||
|
|
116377f6d9 | ||
|
|
7c32cf03a1 | ||
|
|
ff7bbaea7d | ||
|
|
c84d605426 | ||
|
|
def03f6589 | ||
|
|
5ea24621cf | ||
|
|
251a3470dc | ||
|
|
08f65cbd01 | ||
|
|
8fd495f906 | ||
|
|
9d55875377 | ||
|
|
8a11bec55a |
194 changed files with 19642 additions and 14025 deletions
214
.patch/openssl-cmake/0001-cpmutil-compat.patch
Normal file
214
.patch/openssl-cmake/0001-cpmutil-compat.patch
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
From ec4c1fdf526cb9ad045abf59b29ee495bbf5023a Mon Sep 17 00:00:00 2001
|
||||
From: crueter <crueter@eden-emu.dev>
|
||||
Date: Sat, 30 May 2026 20:56:35 -0400
|
||||
Subject: [PATCH] cpmutil compat
|
||||
|
||||
---
|
||||
CMakeLists.txt | 31 ++++++++-----------
|
||||
cmake/FetchOpenSSL.cmake | 64 ----------------------------------------
|
||||
cmake/GetCPM.cmake | 5 ----
|
||||
3 files changed, 13 insertions(+), 87 deletions(-)
|
||||
delete mode 100644 cmake/FetchOpenSSL.cmake
|
||||
delete mode 100644 cmake/GetCPM.cmake
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 5420ecc..9ffd5a0 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -19,9 +19,7 @@ include(FetchContent)
|
||||
include(ProcessorCount)
|
||||
include(cmake/ConfigureOpenSSL.cmake)
|
||||
include(cmake/DetectTargetPlatform.cmake)
|
||||
-include(cmake/FetchOpenSSL.cmake)
|
||||
include(cmake/FindVcvarsall.cmake)
|
||||
-include(cmake/GetCPM.cmake)
|
||||
|
||||
# Custom options
|
||||
option(OPENSSL_BUILD_VERBOSE "Enable verbose output from build" OFF)
|
||||
@@ -47,9 +45,6 @@ if("${OPENSSL_TARGET_PLATFORM}" STREQUAL "")
|
||||
detect_target_platform(OPENSSL_TARGET_PLATFORM)
|
||||
endif()
|
||||
|
||||
-# Fetch OpenSSL source
|
||||
-fetch_openssl()
|
||||
-
|
||||
# Apply patches
|
||||
foreach(patch IN LISTS OPENSSL_PATCH)
|
||||
if(EXISTS "${patch}" AND NOT IS_DIRECTORY "${patch}")
|
||||
@@ -59,13 +54,13 @@ foreach(patch IN LISTS OPENSSL_PATCH)
|
||||
|
||||
execute_process(
|
||||
COMMAND git init
|
||||
- WORKING_DIRECTORY ${openssl_SOURCE_DIR}
|
||||
+ WORKING_DIRECTORY ${OpenSSL_SOURCE_DIR}
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET
|
||||
)
|
||||
execute_process(
|
||||
COMMAND git apply ${patch}
|
||||
- WORKING_DIRECTORY ${openssl_SOURCE_DIR}
|
||||
+ WORKING_DIRECTORY ${OpenSSL_SOURCE_DIR}
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET
|
||||
)
|
||||
@@ -161,8 +156,8 @@ list(PREPEND OPENSSL_CONFIGURE_OPTIONS ${OPENSSL_TARGET_PLATFORM})
|
||||
# Configure OpenSSL
|
||||
configure_openssl(
|
||||
COMMAND ${VCVARSALL_COMMAND}
|
||||
- FILE ${openssl_SOURCE_DIR}/Configure
|
||||
- BUILD_DIR ${openssl_BINARY_DIR}
|
||||
+ FILE ${OpenSSL_SOURCE_DIR}/Configure
|
||||
+ BUILD_DIR ${OpenSSL_BINARY_DIR}
|
||||
OPTIONS ${OPENSSL_CONFIGURE_OPTIONS}
|
||||
)
|
||||
|
||||
@@ -203,8 +198,8 @@ endif()
|
||||
# Parse Makefile
|
||||
parse_makefile(${OPENSSL_MAKEFILE} "INSTALL_LIBS" OPENSSL_STATIC_LIBS)
|
||||
parse_makefile(${OPENSSL_MAKEFILE} "INSTALL_SHLIBS" OPENSSL_SHARED_LIBS)
|
||||
-list(TRANSFORM OPENSSL_STATIC_LIBS PREPEND "${openssl_BINARY_DIR}/")
|
||||
-list(TRANSFORM OPENSSL_SHARED_LIBS PREPEND "${openssl_BINARY_DIR}/")
|
||||
+list(TRANSFORM OPENSSL_STATIC_LIBS PREPEND "${OpenSSL_BINARY_DIR}/")
|
||||
+list(TRANSFORM OPENSSL_SHARED_LIBS PREPEND "${OpenSSL_BINARY_DIR}/")
|
||||
|
||||
foreach(LIBRARY IN LISTS OPENSSL_STATIC_LIBS)
|
||||
if(LIBRARY MATCHES "crypto")
|
||||
@@ -239,14 +234,14 @@ endif()
|
||||
|
||||
# Provide same targets and variables as FindOpenSSL module
|
||||
set(OPENSSL_FOUND ON CACHE BOOL "Override FindOpenSSL variables" FORCE)
|
||||
-set(OPENSSL_INCLUDE_DIR ${openssl_SOURCE_DIR}/include ${openssl_BINARY_DIR}/include CACHE STRING "Override FindOpenSSL variables" FORCE)
|
||||
+set(OPENSSL_INCLUDE_DIR ${OpenSSL_SOURCE_DIR}/include ${OpenSSL_BINARY_DIR}/include CACHE STRING "Override FindOpenSSL variables" FORCE)
|
||||
set(OPENSSL_CRYPTO_LIBRARY ${OPENSSL_${OPENSSL_LIBRARY_TYPE}_CRYPTO_LIBRARY} CACHE STRING "Override FindOpenSSL variables" FORCE)
|
||||
set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY} ${OPENSSL_DEPENDENCIES} CACHE STRING "Override FindOpenSSL variables" FORCE)
|
||||
set(OPENSSL_SSL_LIBRARY ${OPENSSL_${OPENSSL_LIBRARY_TYPE}_SSL_LIBRARY} CACHE STRING "Override FindOpenSSL variables" FORCE)
|
||||
set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_DEPENDENCIES} CACHE STRING "Override FindOpenSSL variables" FORCE)
|
||||
set(OPENSSL_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_DEPENDENCIES} CACHE STRING "Override FindOpenSSL variables" FORCE)
|
||||
set(OPENSSL_VERSION ${OPENSSL_CONFIGURED_VERSION} CACHE STRING "Override FindOpenSSL variables" FORCE)
|
||||
-set(OPENSSL_APPLINK_SOURCE ${openssl_SOURCE_DIR}/ms/applink.c CACHE STRING "Override FindOpenSSL variables" FORCE)
|
||||
+set(OPENSSL_APPLINK_SOURCE ${OpenSSL_SOURCE_DIR}/ms/applink.c CACHE STRING "Override FindOpenSSL variables" FORCE)
|
||||
|
||||
add_library(OpenSSL::Crypto ${OPENSSL_LIBRARY_TYPE} IMPORTED GLOBAL)
|
||||
add_library(OpenSSL::SSL ${OPENSSL_LIBRARY_TYPE} IMPORTED GLOBAL)
|
||||
@@ -308,8 +303,8 @@ if(ANDROID)
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE OPENSSL_SOURCES
|
||||
- ${openssl_SOURCE_DIR}/*.[ch]
|
||||
- ${openssl_SOURCE_DIR}/*.[ch].in
|
||||
+ ${OpenSSL_SOURCE_DIR}/*.[ch]
|
||||
+ ${OpenSSL_SOURCE_DIR}/*.[ch].in
|
||||
)
|
||||
|
||||
set(OPENSSL_BUILD_OUTPUT
|
||||
@@ -322,7 +317,7 @@ add_custom_command(
|
||||
OUTPUT ${OPENSSL_BUILD_OUTPUT}
|
||||
COMMAND ${OPENSSL_BUILD_COMMAND}
|
||||
DEPENDS ${OPENSSL_SOURCES}
|
||||
- WORKING_DIRECTORY ${openssl_BINARY_DIR}
|
||||
+ WORKING_DIRECTORY ${OpenSSL_BINARY_DIR}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
@@ -341,7 +336,7 @@ if(OPENSSL_TEST AND NOT CMAKE_CROSSCOMPILING)
|
||||
add_test(
|
||||
NAME openssl-test
|
||||
COMMAND ${OPENSSL_BUILD_TOOL} test VERBOSE_FAILURE=yes HARNESS_JOBS=${NUMBER_OF_THREADS}
|
||||
- WORKING_DIRECTORY ${openssl_BINARY_DIR}
|
||||
+ WORKING_DIRECTORY ${OpenSSL_BINARY_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -356,7 +351,7 @@ if(OPENSSL_INSTALL)
|
||||
install(CODE
|
||||
"execute_process(
|
||||
COMMAND ${OPENSSL_INSTALL_COMMAND}
|
||||
- WORKING_DIRECTORY \"${openssl_BINARY_DIR}\"
|
||||
+ WORKING_DIRECTORY \"${OpenSSL_BINARY_DIR}\"
|
||||
)"
|
||||
)
|
||||
endif()
|
||||
diff --git a/cmake/FetchOpenSSL.cmake b/cmake/FetchOpenSSL.cmake
|
||||
deleted file mode 100644
|
||||
index a43505d..0000000
|
||||
--- a/cmake/FetchOpenSSL.cmake
|
||||
+++ /dev/null
|
||||
@@ -1,64 +0,0 @@
|
||||
-function(fetch_openssl)
|
||||
- if(EXISTS "${OPENSSL_SOURCE}" AND IS_DIRECTORY "${OPENSSL_SOURCE}")
|
||||
- # Fetch the local OpenSSL source
|
||||
- if(NOT IS_ABSOLUTE "${OPENSSL_SOURCE}")
|
||||
- string(PREPEND OPENSSL_SOURCE ${CMAKE_SOURCE_DIR}/)
|
||||
- endif()
|
||||
-
|
||||
- string(REPLACE "\\" "/" openssl-source_SOURCE_DIR "${OPENSSL_SOURCE}")
|
||||
- set(openssl-source_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/openssl-source-build)
|
||||
- else()
|
||||
- set(CPM_OPTIONS
|
||||
- NAME openssl-source
|
||||
- DOWNLOAD_ONLY ON
|
||||
- )
|
||||
-
|
||||
- if(NOT OPENSSL_CONFIGURE_VERBOSE)
|
||||
- list(APPEND CPM_OPTIONS QUIET)
|
||||
- endif()
|
||||
-
|
||||
- if("${OPENSSL_SOURCE}" MATCHES "^http")
|
||||
- # Download OpenSSL source from the internet
|
||||
- list(APPEND CPM_OPTIONS URL ${OPENSSL_SOURCE})
|
||||
- else()
|
||||
- # Download OpenSSL source from the official website
|
||||
- if("${OPENSSL_TARGET_VERSION}" STREQUAL "")
|
||||
- set(OPENSSL_TARGET_VERSION ${PROJECT_VERSION})
|
||||
- endif()
|
||||
-
|
||||
- if(OPENSSL_TARGET_VERSION VERSION_EQUAL PROJECT_VERSION)
|
||||
- list(APPEND CPM_OPTIONS URL_HASH SHA256=aaf51a1fe064384f811daeaeb4ec4dce7340ec8bd893027eee676af31e83a04f)
|
||||
- endif()
|
||||
-
|
||||
- if(OPENSSL_TARGET_VERSION MATCHES "^1\.1\.1[a-w]$")
|
||||
- string(REPLACE "." "_" OPENSSL_TAGGED_VERSION ${OPENSSL_TARGET_VERSION})
|
||||
- list(APPEND CPM_OPTIONS URL https://github.com/openssl/openssl/releases/download/OpenSSL_${OPENSSL_TAGGED_VERSION}/openssl-${OPENSSL_TARGET_VERSION}.tar.gz)
|
||||
- else()
|
||||
- list(APPEND CPM_OPTIONS URL https://github.com/openssl/openssl/releases/download/openssl-${OPENSSL_TARGET_VERSION}/openssl-${OPENSSL_TARGET_VERSION}.tar.gz)
|
||||
- endif()
|
||||
- endif()
|
||||
-
|
||||
- CPMAddPackage(${CPM_OPTIONS})
|
||||
- endif()
|
||||
-
|
||||
- # Clean build directory if source directory has changed
|
||||
- if(DEFINED CACHE{openssl-source_SOURCE_DIR_OLD} AND NOT openssl-source_SOURCE_DIR STREQUAL openssl-source_SOURCE_DIR_OLD)
|
||||
- set(openssl-source_SOURCE_DIR_OLD ${openssl-source_SOURCE_DIR} CACHE INTERNAL "Previously fetched OpenSSL source")
|
||||
-
|
||||
- if(IS_DIRECTORY ${openssl-source_BINARY_DIR})
|
||||
- file(REMOVE_RECURSE ${openssl-source_BINARY_DIR})
|
||||
- file(MAKE_DIRECTORY ${openssl-source_BINARY_DIR})
|
||||
- endif()
|
||||
- endif()
|
||||
-
|
||||
- # Override the FindOpenSSL module
|
||||
- FetchContent_Declare(
|
||||
- OpenSSL
|
||||
- SOURCE_DIR ${openssl-source_SOURCE_DIR}
|
||||
- BINARY_DIR ${openssl-source_BINARY_DIR}
|
||||
- OVERRIDE_FIND_PACKAGE
|
||||
- )
|
||||
- FetchContent_MakeAvailable(OpenSSL)
|
||||
-
|
||||
- return(PROPAGATE openssl_SOURCE_DIR openssl_BINARY_DIR)
|
||||
-endfunction()
|
||||
diff --git a/cmake/GetCPM.cmake b/cmake/GetCPM.cmake
|
||||
deleted file mode 100644
|
||||
index bfc50f5..0000000
|
||||
--- a/cmake/GetCPM.cmake
|
||||
+++ /dev/null
|
||||
@@ -1,5 +0,0 @@
|
||||
-file(
|
||||
- DOWNLOAD https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake
|
||||
- ${CMAKE_CURRENT_BINARY_DIR}/get_cpm.cmake
|
||||
-)
|
||||
-include(${CMAKE_CURRENT_BINARY_DIR}/get_cpm.cmake)
|
||||
--
|
||||
2.54.0
|
||||
|
||||
54
.patch/openssl-cmake/0002-use-ccache.patch
Normal file
54
.patch/openssl-cmake/0002-use-ccache.patch
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
From d46675fbb61eb6d51e478023ce4075e545ad4cfd Mon Sep 17 00:00:00 2001
|
||||
From: crueter <crueter@eden-emu.dev>
|
||||
Date: Sat, 30 May 2026 21:11:55 -0400
|
||||
Subject: [PATCH] use ccache
|
||||
|
||||
---
|
||||
CMakeLists.txt | 1 -
|
||||
cmake/ConfigureOpenSSL.cmake | 12 +++---------
|
||||
2 files changed, 3 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 9ffd5a0..9ff14c8 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -28,7 +28,6 @@ option(OPENSSL_ENABLE_PARALLEL "Build and test in parallel if possible" ON)
|
||||
option(OPENSSL_INSTALL "Install OpenSSL components to the <prefix> directory" OFF)
|
||||
option(OPENSSL_INSTALL_CERT "Install cert.pem to the <openssldir> directory" OFF)
|
||||
option(OPENSSL_TEST "Enable testing and build OpenSSL self tests" OFF)
|
||||
-option(OPENSSL_USE_CCACHE "Use ccache if available" ON)
|
||||
|
||||
if("${OPENSSL_BUILD_TARGET}" STREQUAL "")
|
||||
# Makefile target for build
|
||||
diff --git a/cmake/ConfigureOpenSSL.cmake b/cmake/ConfigureOpenSSL.cmake
|
||||
index 211c18b..3d8cbed 100644
|
||||
--- a/cmake/ConfigureOpenSSL.cmake
|
||||
+++ b/cmake/ConfigureOpenSSL.cmake
|
||||
@@ -69,15 +69,9 @@ function(apply_ccache FILE)
|
||||
message(FATAL_ERROR "Couldn't find Makefile")
|
||||
endif()
|
||||
|
||||
- if(OPENSSL_USE_CCACHE)
|
||||
- find_program(CCACHE ccache)
|
||||
-
|
||||
- if(NOT CCACHE)
|
||||
- return()
|
||||
- endif()
|
||||
-
|
||||
+ if(USE_CCACHE)
|
||||
file(READ ${FILE} MAKEFILE)
|
||||
- string(REPLACE "\nCC=" "\nCC=ccache " MAKEFILE "${MAKEFILE}")
|
||||
+ string(REPLACE "\nCC=" "\nCC=${CCACHE_BINARY} " MAKEFILE "${MAKEFILE}")
|
||||
|
||||
if(MSVC)
|
||||
string(REPLACE "/Zi /Fdossl_static.pdb " "" MAKEFILE "${MAKEFILE}")
|
||||
@@ -171,4 +165,4 @@ function(configure_openssl)
|
||||
string(REPLACE "/W3" "/W0" MAKEFILE "${MAKEFILE}")
|
||||
file(WRITE ${OPENSSL_MAKEFILE} "${MAKEFILE}")
|
||||
endif()
|
||||
-endfunction()
|
||||
\ No newline at end of file
|
||||
+endfunction()
|
||||
--
|
||||
2.54.0
|
||||
|
||||
28
.patch/openssl-cmake/0003-use-cmake-compiler-flags.patch
Normal file
28
.patch/openssl-cmake/0003-use-cmake-compiler-flags.patch
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
From 4a3cc92a7abad403529ed1cb4255ca63d9252de4 Mon Sep 17 00:00:00 2001
|
||||
From: crueter <crueter@eden-emu.dev>
|
||||
Date: Sat, 30 May 2026 21:48:42 -0400
|
||||
Subject: [PATCH 2/2] use cmake compiler flags
|
||||
|
||||
---
|
||||
cmake/ConfigureOpenSSL.cmake | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cmake/ConfigureOpenSSL.cmake b/cmake/ConfigureOpenSSL.cmake
|
||||
index 3d8cbed..3012e05 100644
|
||||
--- a/cmake/ConfigureOpenSSL.cmake
|
||||
+++ b/cmake/ConfigureOpenSSL.cmake
|
||||
@@ -135,7 +135,10 @@ function(configure_openssl)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
- COMMAND ${CONFIGURE_COMMAND}
|
||||
+ COMMAND ${CMAKE_COMMAND} -E env
|
||||
+ "CFLAGS=${CMAKE_C_FLAGS}"
|
||||
+ "CXXFLAGS=${CMAKE_CXX_FLAGS}"
|
||||
+ ${CONFIGURE_COMMAND}
|
||||
WORKING_DIRECTORY ${CONFIGURE_BUILD_DIR}
|
||||
${VERBOSE_OPTION}
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
--
|
||||
2.54.0
|
||||
|
||||
39
.patch/openssl-cmake/0004-use-shell-wrapper.patch
Normal file
39
.patch/openssl-cmake/0004-use-shell-wrapper.patch
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
--- a/CMakeLists.txt 2026-06-01 23:53:16.498043856 -0400
|
||||
+++ b/CMakeLists.txt 2026-06-01 23:53:23.910543615 -0400
|
||||
@@ -312,13 +312,29 @@
|
||||
${OPENSSL_SHARED_CRYPTO_LIBRARY}
|
||||
${OPENSSL_SHARED_SSL_LIBRARY}
|
||||
)
|
||||
-add_custom_command(
|
||||
- OUTPUT ${OPENSSL_BUILD_OUTPUT}
|
||||
- COMMAND ${OPENSSL_BUILD_COMMAND}
|
||||
- DEPENDS ${OPENSSL_SOURCES}
|
||||
- WORKING_DIRECTORY ${OpenSSL_BINARY_DIR}
|
||||
- VERBATIM
|
||||
-)
|
||||
+if (WIN32)
|
||||
+ add_custom_command(
|
||||
+ OUTPUT ${OPENSSL_BUILD_OUTPUT}
|
||||
+ COMMAND ${OPENSSL_BUILD_COMMAND}
|
||||
+ DEPENDS ${OPENSSL_SOURCES}
|
||||
+ WORKING_DIRECTORY ${OpenSSL_BINARY_DIR}
|
||||
+ VERBATIM)
|
||||
+else()
|
||||
+ set(_openssl_build_script "${CMAKE_CURRENT_BINARY_DIR}/BuildOpenSSL.cmake")
|
||||
+ file(WRITE ${_openssl_build_script}
|
||||
+ "execute_process(\n"
|
||||
+ " COMMAND ${OPENSSL_BUILD_COMMAND}\n"
|
||||
+ " WORKING_DIRECTORY ${OpenSSL_BINARY_DIR}\n"
|
||||
+ " RESULT_VARIABLE _r)\n"
|
||||
+ "if(_r)\n"
|
||||
+ " message(FATAL_ERROR \"OpenSSL build failed: \${_r}\")\n"
|
||||
+ "endif()\n")
|
||||
+ add_custom_command(
|
||||
+ OUTPUT ${OPENSSL_BUILD_OUTPUT}
|
||||
+ COMMAND ${CMAKE_COMMAND} -P ${_openssl_build_script}
|
||||
+ DEPENDS ${OPENSSL_SOURCES}
|
||||
+ VERBATIM)
|
||||
+endif()
|
||||
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
add_custom_target(openssl-build ALL DEPENDS ${OPENSSL_BUILD_OUTPUT})
|
||||
3665
.patch/openssl/0001-add-bundled-cert.patch
Normal file
3665
.patch/openssl/0001-add-bundled-cert.patch
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -383,13 +383,20 @@ find_package(RenderDoc MODULE)
|
|||
# openssl funniness
|
||||
if (YUZU_USE_BUNDLED_OPENSSL)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
AddJsonPackage(openssl-ci)
|
||||
else()
|
||||
AddJsonPackage(openssl)
|
||||
set(OPENSSL_BUILD_VERBOSE ON)
|
||||
set(OPENSSL_CONFIGURE_VERBOSE ON)
|
||||
|
||||
if (OpenSSL_ADDED)
|
||||
add_compile_definitions(YUZU_BUNDLED_OPENSSL)
|
||||
AddJsonPackage(openssl-cmake)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL 3 REQUIRED)
|
||||
if (OpenSSL_ADDED)
|
||||
add_compile_definitions(YUZU_BUNDLED_OPENSSL)
|
||||
endif()
|
||||
|
||||
message(STATUS "Fetching needed dependencies with CPM")
|
||||
|
||||
|
|
@ -505,7 +512,7 @@ endfunction()
|
|||
# =============================================
|
||||
|
||||
if (APPLE)
|
||||
foreach(fw Carbon Metal Cocoa IOKit CoreVideo CoreMedia Security)
|
||||
foreach(fw Carbon Metal Cocoa IOKit CoreVideo CoreMedia Security UniformTypeIdentifiers)
|
||||
find_library(${fw}_LIBRARY ${fw} REQUIRED)
|
||||
list(APPEND PLATFORM_LIBRARIES ${${fw}_LIBRARY})
|
||||
endforeach()
|
||||
|
|
|
|||
30
cpmfile.json
30
cpmfile.json
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"openssl": {
|
||||
"openssl-ci": {
|
||||
"ci": true,
|
||||
"package": "OpenSSL",
|
||||
"name": "openssl",
|
||||
|
|
@ -7,6 +7,34 @@
|
|||
"version": "3.6.0-1cb0d36b39",
|
||||
"min_version": "3"
|
||||
},
|
||||
"openssl-cmake": {
|
||||
"repo": "jimmy-park/openssl-cmake",
|
||||
"hash": "2cc185c924fd70e7d886257ca0caa42b3b8f7f712f2052b4f94dde74759e27022de76178460e18c9bdfc57c366583999e198fbb6052d4e7d91c099d15a0ca63e",
|
||||
"git_version": "3.6.2",
|
||||
"tag": "%VERSION%",
|
||||
"bundled": true,
|
||||
"options": [
|
||||
"OPENSSL_CONFIGURE_OPTIONS threads"
|
||||
],
|
||||
"patches": [
|
||||
"0001-cpmutil-compat.patch",
|
||||
"0002-use-ccache.patch",
|
||||
"0003-use-cmake-compiler-flags.patch",
|
||||
"0004-use-shell-wrapper.patch"
|
||||
]
|
||||
},
|
||||
"openssl": {
|
||||
"repo": "openssl/openssl",
|
||||
"package": "OpenSSL",
|
||||
"min_version": "3",
|
||||
"version": "3",
|
||||
"hash": "29002ce50cb95a4f4f1d0e9d3f684401fbd4eac34203dc2eef3b6334af5d44aa46bf788b63a6f5c139c383eafb7269ae87a58a9a3ad5912903b9773e545ccc0a",
|
||||
"git_version": "3.6.2",
|
||||
"tag": "openssl-%VERSION%",
|
||||
"patches": [
|
||||
"0001-add-bundled-cert.patch"
|
||||
]
|
||||
},
|
||||
"boost": {
|
||||
"package": "Boost",
|
||||
"repo": "boostorg/boost",
|
||||
|
|
|
|||
890
dist/languages/ar.ts
vendored
890
dist/languages/ar.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/ca.ts
vendored
889
dist/languages/ca.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/cs.ts
vendored
889
dist/languages/cs.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/da.ts
vendored
889
dist/languages/da.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/de.ts
vendored
889
dist/languages/de.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/el.ts
vendored
889
dist/languages/el.ts
vendored
File diff suppressed because it is too large
Load diff
902
dist/languages/es.ts
vendored
902
dist/languages/es.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/fi.ts
vendored
889
dist/languages/fi.ts
vendored
File diff suppressed because it is too large
Load diff
891
dist/languages/fr.ts
vendored
891
dist/languages/fr.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/hu.ts
vendored
889
dist/languages/hu.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/id.ts
vendored
889
dist/languages/id.ts
vendored
File diff suppressed because it is too large
Load diff
891
dist/languages/it.ts
vendored
891
dist/languages/it.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/ja_JP.ts
vendored
889
dist/languages/ja_JP.ts
vendored
File diff suppressed because it is too large
Load diff
891
dist/languages/ko_KR.ts
vendored
891
dist/languages/ko_KR.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/nb.ts
vendored
889
dist/languages/nb.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/nl.ts
vendored
889
dist/languages/nl.ts
vendored
File diff suppressed because it is too large
Load diff
891
dist/languages/pl.ts
vendored
891
dist/languages/pl.ts
vendored
File diff suppressed because it is too large
Load diff
891
dist/languages/pt_BR.ts
vendored
891
dist/languages/pt_BR.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/pt_PT.ts
vendored
889
dist/languages/pt_PT.ts
vendored
File diff suppressed because it is too large
Load diff
891
dist/languages/ru_RU.ts
vendored
891
dist/languages/ru_RU.ts
vendored
File diff suppressed because it is too large
Load diff
891
dist/languages/sv.ts
vendored
891
dist/languages/sv.ts
vendored
File diff suppressed because it is too large
Load diff
891
dist/languages/tr_TR.ts
vendored
891
dist/languages/tr_TR.ts
vendored
File diff suppressed because it is too large
Load diff
890
dist/languages/uk.ts
vendored
890
dist/languages/uk.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/vi.ts
vendored
889
dist/languages/vi.ts
vendored
File diff suppressed because it is too large
Load diff
889
dist/languages/vi_VN.ts
vendored
889
dist/languages/vi_VN.ts
vendored
File diff suppressed because it is too large
Load diff
891
dist/languages/zh_CN.ts
vendored
891
dist/languages/zh_CN.ts
vendored
File diff suppressed because it is too large
Load diff
891
dist/languages/zh_TW.ts
vendored
891
dist/languages/zh_TW.ts
vendored
File diff suppressed because it is too large
Load diff
5
externals/CMakeLists.txt
vendored
5
externals/CMakeLists.txt
vendored
|
|
@ -82,6 +82,11 @@ if (ARCHITECTURE_riscv64)
|
|||
AddJsonPackage(biscuit)
|
||||
endif()
|
||||
|
||||
# Lagoon
|
||||
if (ARCHITECTURE_loongarch64)
|
||||
AddJsonPackage(lagoon)
|
||||
endif()
|
||||
|
||||
# Vulkan stuff
|
||||
AddDependentPackages(vulkan-headers vulkan-utility-libraries)
|
||||
|
||||
|
|
|
|||
6
externals/cpmfile.json
vendored
6
externals/cpmfile.json
vendored
|
|
@ -67,6 +67,12 @@
|
|||
"tag": "v%VERSION%",
|
||||
"hash": "9697e80a7d5d9bcb3ce51051a9a24962fb90ca79d215f1f03ae6b58da8ba13a63b5dda1b4dde3d26ac6445029696b8ef2883f4e5a777b342bba01283ed293856"
|
||||
},
|
||||
"lagoon": {
|
||||
"repo": "loongson-community/lagoon",
|
||||
"tag": "%VERSION%",
|
||||
"version": "1.0.0",
|
||||
"hash": "b9380f99c6effaeccc6d8f81d4942e852c11ad28613df637e155451556ae5826f93765bee57a5c87a9740d2bd1db463ad0f55a947772fe9d57eeabae3efa373e"
|
||||
},
|
||||
"libadrenotools": {
|
||||
"repo": "eden-emulator/libadrenotools",
|
||||
"sha": "8ba23b42d7",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
include_directories(.)
|
||||
|
||||
# Dynarmic
|
||||
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64) AND NOT YUZU_STATIC_ROOM)
|
||||
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64 OR ARCHITECTURE_loongarch64) AND NOT YUZU_STATIC_ROOM)
|
||||
add_subdirectory(dynarmic)
|
||||
add_library(dynarmic::dynarmic ALIAS dynarmic)
|
||||
endif()
|
||||
|
|
@ -21,20 +21,41 @@ if (YUZU_STATIC_BUILD)
|
|||
add_compile_definitions(QT_STATICPLUGIN)
|
||||
endif()
|
||||
|
||||
# Build identifiers
|
||||
if (NIGHTLY_BUILD)
|
||||
add_compile_definitions(NIGHTLY_BUILD)
|
||||
endif()
|
||||
|
||||
# Legacy (android only)
|
||||
if (YUZU_LEGACY)
|
||||
message(WARNING "Making legacy build. Performance may suffer.")
|
||||
add_compile_definitions(YUZU_LEGACY)
|
||||
endif()
|
||||
|
||||
# Genshin Spoof (android only)
|
||||
if (GENSHIN_SPOOF)
|
||||
message(WARNING "Making Genshin spoof build")
|
||||
add_compile_definitions(GENSHIN_SPOOF)
|
||||
endif()
|
||||
|
||||
# Build ID (mingw only right now)
|
||||
# Pretty much just refers to the CI "target" for this build
|
||||
if (NOT BUILD_ID)
|
||||
if (ARCHITECTURE_x86_64)
|
||||
set(BUILD_ID amd64)
|
||||
elseif(ARCHITECTURE_arm64)
|
||||
if (WIN32)
|
||||
set(BUILD_ID arm64)
|
||||
else()
|
||||
set(BUILD_ID aarch64)
|
||||
endif()
|
||||
else()
|
||||
set(BUILD_ID "${ARCHITECTURE}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_compile_definitions(BUILD_ID="${BUILD_ID}")
|
||||
|
||||
# Set compilation flags
|
||||
if (MSVC AND NOT CXX_CLANG)
|
||||
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import android.content.BroadcastReceiver
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.Icon
|
||||
|
|
@ -101,7 +100,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||
private var romSwapGeneration = 0
|
||||
private var hasEmulationSession = processHasEmulationSession
|
||||
private val romSwapStopTimeoutRunnable = Runnable { onRomSwapStopTimeout() }
|
||||
private val pictureInPictureFailureActions: MutableSet<String> = mutableSetOf()
|
||||
|
||||
private fun onRomSwapStopTimeout() {
|
||||
if (!isWaitingForRomSwapStop) {
|
||||
|
|
@ -270,18 +268,12 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||
}
|
||||
|
||||
override fun onUserLeaveHint() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ||
|
||||
!isPictureInPictureSupported() ||
|
||||
!BooleanSetting.PICTURE_IN_PICTURE.getBoolean() ||
|
||||
isInPictureInPictureMode
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
|
||||
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
|
||||
runPictureInPictureAction("enter picture-in-picture mode") {
|
||||
enterPictureInPictureMode(pictureInPictureParamsBuilder.build())
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||
if (BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && !isInPictureInPictureMode) {
|
||||
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
|
||||
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
|
||||
enterPictureInPictureMode(pictureInPictureParamsBuilder.build())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -661,29 +653,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||
return this.apply { setActions(pictureInPictureActions) }
|
||||
}
|
||||
|
||||
private fun isPictureInPictureSupported() =
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
|
||||
packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
|
||||
|
||||
private fun runPictureInPictureAction(actionName: String, action: () -> Unit) {
|
||||
try {
|
||||
action()
|
||||
} catch (e: IllegalStateException) {
|
||||
if (pictureInPictureFailureActions.add(actionName)) {
|
||||
Log.warning("[PiP] Failed to $actionName: ${e.message}")
|
||||
}
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
if (pictureInPictureFailureActions.add(actionName)) {
|
||||
Log.warning("[PiP] Failed to $actionName: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun buildPictureInPictureParams() {
|
||||
if (!isPictureInPictureSupported()) {
|
||||
return
|
||||
}
|
||||
|
||||
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
|
||||
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
|
|
@ -693,9 +663,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
|||
BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && isEmulationActive
|
||||
)
|
||||
}
|
||||
runPictureInPictureAction("set picture-in-picture params") {
|
||||
setPictureInPictureParams(pictureInPictureParamsBuilder.build())
|
||||
}
|
||||
setPictureInPictureParams(pictureInPictureParamsBuilder.build())
|
||||
}
|
||||
|
||||
fun displayMultiplayerDialog() {
|
||||
|
|
|
|||
|
|
@ -462,8 +462,8 @@
|
|||
<string name="renderer_resolution">الدقة (الإرساء/محمول)</string>
|
||||
<string name="renderer_vsync">VSync وضع</string>
|
||||
<string name="renderer_scaling_filter">مرشح ملائم للنافذة</string>
|
||||
<string name="fsr_sharpness">حدة FSR</string>
|
||||
<string name="fsr_sharpness_description">يحدد مدى وضوح الصورة عند استخدام التباين الديناميكي لـ FSR</string>
|
||||
<string name="fsr_sharpness">حدة FSR/SGSR</string>
|
||||
<string name="fsr_sharpness_description">يحدد مدى وضوح الصورة عند استخدام مرشحات FSR أو SGSR</string>
|
||||
<string name="renderer_anti_aliasing">طريقة مضاد التعرج</string>
|
||||
|
||||
|
||||
|
|
@ -503,6 +503,8 @@
|
|||
<string name="fast_gpu_time_description">يُجبر هذا الخيار معظم الألعاب على العمل بأعلى دقة عرض أصلية. استخدم 256 للحصول على أقصى أداء و512 للحصول على أعلى جودة رسومات.</string>
|
||||
<string name="skip_cpu_inner_invalidation">تخطي إبطال صلاحية وحدة المعالجة المركزية الداخلية</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقتة من جانب وحدة المعالجة المركزية أثناء تحديثات الذاكرة، مما يقلل من استخدام وحدة المعالجة المركزية ويحسن أداءها. قد يتسبب ذلك في حدوث أعطال أو تعطل في بعض الألعاب.</string>
|
||||
<string name="antiflicker">مضاد الوميض</string>
|
||||
<string name="antiflicker_description">يُجبر هذا الوضع وظائف وحدة معالجة الرسومات على الانتظار حتى يتم إرسال العمل إليها. استخدمه مع وضع وحدة معالجة الرسومات السريع لتجنب الوميض مع تأثير أقل على الأداء.</string>
|
||||
<string name="fix_bloom_effects">إصلاح تأثيرات التوهج</string>
|
||||
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno A6XX - A7XX/ Turnip)، ويزيل التوهج في Burnout. تحذير: قد يسبب تشوهات رسومية في ألعاب أخرى.</string>
|
||||
<string name="emulate_bgr565">محاكاة BGR565</string>
|
||||
|
|
|
|||
|
|
@ -329,8 +329,6 @@
|
|||
<string name="renderer_resolution">ڕوونی (دۆخی دەستی/دۆخی دۆک)</string>
|
||||
<string name="renderer_vsync">دۆخی VSync</string>
|
||||
<string name="renderer_scaling_filter">فلتەری گونجاندنی پەنجەرە</string>
|
||||
<string name="fsr_sharpness">تیژی FSR</string>
|
||||
<string name="fsr_sharpness_description">دیاریکردنی تیژی وێنە لە کاتی بەکارهێنانی FSR</string>
|
||||
<string name="renderer_anti_aliasing">شێوازی دژە-خاوڕۆیی</string>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -439,8 +439,6 @@
|
|||
<string name="renderer_resolution">Rozlišení (Handheld/V doku)</string>
|
||||
<string name="renderer_vsync">Režim VSync</string>
|
||||
<string name="renderer_scaling_filter">Škálovací filtr</string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -439,8 +439,6 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
|
|||
<string name="renderer_resolution">Auflösung (Handheld/Gedockt)</string>
|
||||
<string name="renderer_vsync">VSync-Modus</string>
|
||||
<string name="renderer_scaling_filter">Skalierungsfilter</string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@
|
|||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
<string name="qlaunch_description">Iniciar aplicaciones desde la pantalla de inicio del sistema</string>
|
||||
<string name="applets">Lanzador de Applet</string>
|
||||
<string name="applets_description">Ejecutar applets de sistema usando el firmware instalado</string>
|
||||
<string name="applets_description">Ejecutar applets del sistema usando el firmware instalado</string>
|
||||
<string name="applets_error_firmware">El firmware no está instalado</string>
|
||||
<string name="applets_error_applet">Applet no disponible</string>
|
||||
<string name="applets_error_description"><![CDATA[Por favor, asegúrese de que su archivo <a href=\"https://yuzu-mirror.github.io/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> y el <a href=\"https://yuzu-mirror.github.io/help/quickstart/#dumping-system-firmware\">firmware</a> están instalados e inténtelo de nuevo.]]></string>
|
||||
|
|
@ -456,8 +456,8 @@
|
|||
<string name="renderer_resolution">Resolución (Portátil/Sobremesa)</string>
|
||||
<string name="renderer_vsync">Modo de sincronización vertical</string>
|
||||
<string name="renderer_scaling_filter">Filtro de adaptación de ventana</string>
|
||||
<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="fsr_sharpness">Nitidez FSR/SGSR</string>
|
||||
<string name="fsr_sharpness_description">Determina el grado de nitidez de la imagen al usar filtros FSR o SGSR</string>
|
||||
<string name="renderer_anti_aliasing">Método de suavizado de bordes</string>
|
||||
|
||||
|
||||
|
|
@ -497,6 +497,8 @@
|
|||
<string name="fast_gpu_time_description">Fuerza a la mayoría de los juegos a ejecutarse a su resolución nativa más alta. Usa 256 para un máximo rendimiento y 512 para una fidelidad gráfica óptima.</string>
|
||||
<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="antiflicker">Antiparpadeo</string>
|
||||
<string name="antiflicker_description">Fuerza a las funciones de devolución de llamada de la GPU a esperar a que se envíen las tareas a la GPU.\nÚsalo con el modo de GPU rápida para evitar el parpadeo con un menor impacto en el rendimiento.</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 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>
|
||||
|
|
@ -1072,7 +1074,7 @@
|
|||
|
||||
<!-- Black backgrounds theme -->
|
||||
<string name="use_black_backgrounds">Fondos oscuros</string>
|
||||
<string name="use_black_backgrounds_description">Cuando utilice el modo oscuro, aplique fondos negros.</string>
|
||||
<string name="use_black_backgrounds_description">Cuando se usa el modo oscuro, aplicar fondos de pantalla negros.</string>
|
||||
|
||||
<!-- Buttons -->
|
||||
<string name="enable_folder_button">Carpeta</string>
|
||||
|
|
|
|||
|
|
@ -454,8 +454,6 @@
|
|||
<string name="renderer_resolution">Résolution (Mode Portable/Mode TV)</string>
|
||||
<string name="renderer_vsync">Mode VSync</string>
|
||||
<string name="renderer_scaling_filter">Filtre de fenêtre adaptatif</string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -359,8 +359,6 @@
|
|||
<string name="renderer_resolution">רזולוציה (מעוגן/נייד)</string>
|
||||
<string name="renderer_vsync">מצב VSync</string>
|
||||
<string name="renderer_scaling_filter">פילטר מתאם חלון</string>
|
||||
<string name="fsr_sharpness">חדות FSR</string>
|
||||
<string name="fsr_sharpness_description">קובע את מידת החדות בעת שימוש ב-FSR.</string>
|
||||
<string name="renderer_anti_aliasing">שיטת Anti-aliasing</string>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -348,8 +348,6 @@
|
|||
<string name="renderer_resolution">Felbontás (Kézi/Dockolt)</string>
|
||||
<string name="renderer_vsync">VSync mód</string>
|
||||
<string name="renderer_scaling_filter">Ablakhoz alkalmazkodó szűrő</string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -380,8 +380,6 @@
|
|||
<string name="renderer_resolution">Resolusi (Handheld/Docked)</string>
|
||||
<string name="renderer_vsync">Mode Sinkronisasi Vertikal</string>
|
||||
<string name="renderer_scaling_filter">Filter penyesuaian jendela</string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -387,8 +387,6 @@
|
|||
<string name="renderer_resolution">Risoluzione (Portatile/Docked)</string>
|
||||
<string name="renderer_vsync">Modalità VSync</string>
|
||||
<string name="renderer_scaling_filter">Filtro adattivo della finestra </string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -329,8 +329,6 @@
|
|||
<string name="renderer_resolution">Oppløsning (håndholdt/dokket)</string>
|
||||
<string name="renderer_vsync">VSync-modus</string>
|
||||
<string name="renderer_scaling_filter">Filter for vindustilpasning</string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -439,8 +439,6 @@
|
|||
<string name="renderer_resolution">Rozdzielczość (Handheld/Zadokowany)</string>
|
||||
<string name="renderer_vsync">Synchronizacja pionowa VSync</string>
|
||||
<string name="renderer_scaling_filter">Filtr adaptacji rozdzielczości</string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -430,8 +430,6 @@
|
|||
<string name="renderer_resolution">Resolução (Portátil/Modo TV)</string>
|
||||
<string name="renderer_vsync">Modo de VSync</string>
|
||||
<string name="renderer_scaling_filter">Filtro de Adaptação da Janela</string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -352,8 +352,6 @@
|
|||
<string name="renderer_resolution">Resolução (Portátil/Ancorado)</string>
|
||||
<string name="renderer_vsync">Modo VSync</string>
|
||||
<string name="renderer_scaling_filter">Filtro de Adaptação da Janela</string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -458,8 +458,8 @@
|
|||
<string name="renderer_resolution">Разрешение (портативное/в док-станции)</string>
|
||||
<string name="renderer_vsync">Режим верт. синхронизации</string>
|
||||
<string name="renderer_scaling_filter">Фильтр адаптации окна</string>
|
||||
<string name="fsr_sharpness">Резкость FSR</string>
|
||||
<string name="fsr_sharpness_description">Определяет, насколько чётким будет изображение при использовании динамического контраста FSR.</string>
|
||||
<string name="fsr_sharpness">Резкость FSR/SGSR</string>
|
||||
<string name="fsr_sharpness_description">Определяет, насколько чётким будет изображение при использовании динамического контраста FSR или SGSR фильтров</string>
|
||||
<string name="renderer_anti_aliasing">Метод сглаживания</string>
|
||||
|
||||
|
||||
|
|
@ -499,6 +499,8 @@
|
|||
<string name="fast_gpu_time_description">Принудительно запускает большинство игр в их максимальном нативном разрешении. Используйте значение 256 для максимальной производительности и 512 для максимального качества графики.</string>
|
||||
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
|
||||
<string name="antiflicker">Анти-мерцание</string>
|
||||
<string name="antiflicker_description">Принудительно заставляет обратные вызовы ГПУ-фильтра ожидать выполнения отправленных задач на ГПУ. Используйте с Быстрым режимом ГПУ, что бы избежать мерцаний с меньшим влиянием на производительность.</string>
|
||||
<string name="fix_bloom_effects">Исправить эффекты размытия</string>
|
||||
<string name="fix_bloom_effects_description">Частично убирает размытие в LA/EOW (Adreno A6XX - A7XX/ Turnip), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх.</string>
|
||||
<string name="emulate_bgr565">Эмулировать BGR565</string>
|
||||
|
|
|
|||
|
|
@ -351,8 +351,6 @@
|
|||
<string name="renderer_resolution">Резолуција (ручно / прикључено)</string>
|
||||
<string name="renderer_vsync">Всинц мод</string>
|
||||
<string name="renderer_scaling_filter">Филтер прилагођавања прозора</string>
|
||||
<string name="fsr_sharpness">ФСР оштрина</string>
|
||||
<string name="fsr_sharpness_description">Одређује колико ће се слика наоштрен трајати док користи \"ФСР\" динамички контраст</string>
|
||||
<string name="renderer_anti_aliasing">Метода против алиасирања</string>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -458,8 +458,8 @@
|
|||
<string name="renderer_resolution">Роздільна здатність (Портативний/Док)</string>
|
||||
<string name="renderer_vsync">Режим верт. синхронізації</string>
|
||||
<string name="renderer_scaling_filter">Фільтр масштабування вікна</string>
|
||||
<string name="fsr_sharpness">Різкість FSR</string>
|
||||
<string name="fsr_sharpness_description">Визначає різкість зображення при використанні FSR.</string>
|
||||
<string name="fsr_sharpness">Різкість FSR/SGSR</string>
|
||||
<string name="fsr_sharpness_description">Визначає різкість зображення при використанні фільтрів FSR або SGSR.</string>
|
||||
<string name="renderer_anti_aliasing">Згладжування</string>
|
||||
|
||||
|
||||
|
|
@ -499,6 +499,8 @@
|
|||
<string name="fast_gpu_time_description">Примушує більшість ігор працювати на їхній максимальній нативній роздільності. Використовуйте 256 для максимальної продуктивності та 512 для найкращої якості.</string>
|
||||
<string name="skip_cpu_inner_invalidation">Пропустити внутрішнє інвалідування CPU</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
|
||||
<string name="antiflicker">Антимерехтіння</string>
|
||||
<string name="antiflicker_description">Змушує механізм синхронізації чекати, доки ГП завершить подані завдання. Використовуйте з режимом ГП «Швидко», щоб уникнути мерехтіння з меншими втратами продуктивності.</string>
|
||||
<string name="fix_bloom_effects">Виправити ефекти світіння</string>
|
||||
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno A6XX–A7XX / Turnip), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
|
||||
<string name="emulate_bgr565">Емулювати BGR565</string>
|
||||
|
|
|
|||
|
|
@ -327,8 +327,6 @@
|
|||
<string name="renderer_resolution">Độ phân giải (Handheld/Docked)</string>
|
||||
<string name="renderer_vsync">Chế độ VSync</string>
|
||||
<string name="renderer_scaling_filter">Bộ lọc điều chỉnh cửa sổ</string>
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -452,8 +452,8 @@
|
|||
<string name="renderer_resolution">分辨率 (掌机模式/主机模式)</string>
|
||||
<string name="renderer_vsync">垂直同步模式</string>
|
||||
<string name="renderer_scaling_filter">窗口滤镜</string>
|
||||
<string name="fsr_sharpness">FSR 锐化度</string>
|
||||
<string name="fsr_sharpness_description">确定使用 FSR 的动态对比度功能时的图像锐化程度</string>
|
||||
<string name="fsr_sharpness">FSR/SGSR 锐度</string>
|
||||
<string name="fsr_sharpness_description">确定在使用 FSR 或 SGSR 过滤器时的图像锐度</string>
|
||||
<string name="renderer_anti_aliasing">抗锯齿方式</string>
|
||||
|
||||
|
||||
|
|
@ -493,6 +493,8 @@
|
|||
<string name="fast_gpu_time_description">强制大多数游戏以其最高原生分辨率运行。设置为 256 可获得最佳性能,设置为 512 可获得最佳画面保真度。</string>
|
||||
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
|
||||
<string name="skip_cpu_inner_invalidation_description">在内存更新期间跳过某些CPU端缓存无效化,减少CPU使用率并提高其性能。可能会导致某些游戏出现故障或崩溃。</string>
|
||||
<string name="antiflicker">防闪烁</string>
|
||||
<string name="antiflicker_description">强制 GPU 围栏回调等待已提交的 GPU 任务。配合“快速 GPU 模式”一起使用,以避免画面闪烁现象,仅会牺牲少量性能。</string>
|
||||
<string name="fix_bloom_effects">修复 Bloom 效果</string>
|
||||
<string name="fix_bloom_effects_description">减少《塞尔达传说:智慧的再现》(Adreno A6XX - A7XX/ Turnip)中的 bloom 模糊,并移除《Burnout》中的 bloom 效果。警告:可能会导致在其他游戏中出现图形异常。</string>
|
||||
<string name="emulate_bgr565">模拟 BGR565</string>
|
||||
|
|
|
|||
|
|
@ -437,8 +437,6 @@
|
|||
<string name="renderer_resolution">解析度 (手提/底座)</string>
|
||||
<string name="renderer_vsync">垂直同步</string>
|
||||
<string name="renderer_scaling_filter">視窗適應過濾器</string>
|
||||
<string name="fsr_sharpness">FSR 銳化度</string>
|
||||
<string name="fsr_sharpness_description">使用 FSR 時圖片的銳化程度</string>
|
||||
<string name="renderer_anti_aliasing">抗鋸齒</string>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 2018 yuzu Emulator Project
|
||||
|
|
@ -177,10 +177,8 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
|
|||
queued_buffers.store(0);
|
||||
release_cv.notify_one();
|
||||
}
|
||||
|
||||
static constexpr std::array<s16, 6> silence{};
|
||||
for (size_t i = 0; i < num_frames; i++)
|
||||
std::memcpy(&output_buffer[i * frame_size], silence.data(), frame_size_bytes);
|
||||
std::memset(&output_buffer[i * frame_size], 0, frame_size_bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,12 +141,12 @@ add_library(
|
|||
vector_math.h
|
||||
virtual_buffer.cpp
|
||||
virtual_buffer.h
|
||||
wall_clock.cpp
|
||||
wall_clock.h
|
||||
zstd_compression.cpp
|
||||
zstd_compression.h
|
||||
fs/ryujinx_compat.h fs/ryujinx_compat.cpp
|
||||
fs/symlink.h fs/symlink.cpp
|
||||
cpu_features.cpp
|
||||
cpu_features.h
|
||||
httplib.h
|
||||
net/net.h net/net.cpp)
|
||||
|
||||
|
|
@ -180,10 +180,7 @@ endif()
|
|||
if(ARCHITECTURE_x86_64)
|
||||
target_sources(
|
||||
common
|
||||
PRIVATE x64/cpu_detect.cpp
|
||||
x64/cpu_detect.h
|
||||
x64/cpu_wait.cpp
|
||||
x64/cpu_wait.h
|
||||
PRIVATE
|
||||
x64/rdtsc.cpp
|
||||
x64/rdtsc.h
|
||||
x64/xbyak.h)
|
||||
|
|
@ -234,7 +231,7 @@ if(CXX_CLANG)
|
|||
endif()
|
||||
|
||||
if (BOOST_NO_HEADERS)
|
||||
target_link_libraries(common PUBLIC Boost::algorithm Boost::icl Boost::pool)
|
||||
target_link_libraries(common PUBLIC Boost::algorithm Boost::heap Boost::icl Boost::pool)
|
||||
else()
|
||||
target_link_libraries(common PUBLIC Boost::headers)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2005-2014 Daniel James
|
||||
// SPDX-FileCopyrightText: 2016 Austin Appleby
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <climits>
|
||||
#include <cstdint>
|
||||
|
|
|
|||
|
|
@ -10,34 +10,32 @@
|
|||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "common/bit_util.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging.h"
|
||||
#include "common/x64/cpu_detect.h"
|
||||
#include "common/x64/rdtsc.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
|
||||
static inline u64 xgetbv(u32 index) {
|
||||
return _xgetbv(index);
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
// clang-format off
|
||||
#elif defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
#include <sys/types.h>
|
||||
#include <machine/cpufunc.h>
|
||||
// clang-format on
|
||||
#elif defined(__ANDROID__)
|
||||
#include <sys/system_properties.h>
|
||||
#endif
|
||||
|
||||
#include "common/steady_clock.h"
|
||||
#include "common/uint128.h"
|
||||
#include "common/bit_util.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/cpu_features.h"
|
||||
#include "common/logging.h"
|
||||
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
#include "common/x64/rdtsc.h"
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
static inline u64 xgetbv(u32 index) { return _xgetbv(index); }
|
||||
#else
|
||||
static inline void __cpuidex(int info[4], u32 function_id, u32 subfunction_id) {
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
// Despite the name, this is just do_cpuid() with ECX as second input.
|
||||
|
|
@ -50,11 +48,7 @@ static inline void __cpuidex(int info[4], u32 function_id, u32 subfunction_id) {
|
|||
: "a"(function_id), "c"(subfunction_id));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void __cpuid(int info[4], u32 function_id) {
|
||||
return __cpuidex(info, function_id, 0);
|
||||
}
|
||||
|
||||
static inline void __cpuid(int info[4], u32 function_id) { return __cpuidex(info, function_id, 0); }
|
||||
#define _XCR_XFEATURE_ENABLED_MASK 0
|
||||
static inline u64 xgetbv(u32 index) {
|
||||
u32 eax, edx;
|
||||
|
|
@ -62,9 +56,10 @@ static inline u64 xgetbv(u32 index) {
|
|||
return ((u64)edx << 32) | eax;
|
||||
}
|
||||
#endif // _MSC_VER
|
||||
#endif
|
||||
|
||||
namespace Common {
|
||||
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
CPUCaps::Manufacturer CPUCaps::ParseManufacturer(std::string_view brand_string) {
|
||||
if (brand_string == "GenuineIntel") {
|
||||
return Manufacturer::Intel;
|
||||
|
|
@ -76,13 +71,53 @@ CPUCaps::Manufacturer CPUCaps::ParseManufacturer(std::string_view brand_string)
|
|||
return Manufacturer::Unknown;
|
||||
}
|
||||
|
||||
// Detects the various CPU features
|
||||
static CPUCaps Detect() {
|
||||
std::optional<int> GetProcessorCount() {
|
||||
#if defined(_WIN32)
|
||||
// Get the buffer length.
|
||||
DWORD length = 0;
|
||||
GetLogicalProcessorInformation(nullptr, &length);
|
||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
||||
LOG_ERROR(Frontend, "Failed to query core count.");
|
||||
return std::nullopt;
|
||||
}
|
||||
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;
|
||||
}));
|
||||
#elif defined(__unix__)
|
||||
const int thread_count = std::thread::hardware_concurrency();
|
||||
std::ifstream smt("/sys/devices/system/cpu/smt/active");
|
||||
char state = '0';
|
||||
if (smt) {
|
||||
smt.read(&state, sizeof(state));
|
||||
}
|
||||
switch (state) {
|
||||
case '0':
|
||||
return thread_count;
|
||||
case '1':
|
||||
return thread_count / 2;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
#else
|
||||
// Shame on you
|
||||
return std::nullopt;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// @brief Detects the various CPU features
|
||||
const CPUCaps g_cpu_caps = [] {
|
||||
CPUCaps caps = {};
|
||||
|
||||
// Assumes the CPU supports the CPUID instruction. Those that don't would likely not support
|
||||
// yuzu at all anyway
|
||||
|
||||
int cpu_id[4];
|
||||
|
||||
// Detect CPU's CPUID capabilities and grab manufacturer string
|
||||
|
|
@ -183,9 +218,8 @@ static CPUCaps Detect() {
|
|||
// https://github.com/torvalds/linux/blob/master/tools/power/x86/turbostat/turbostat.c#L5569
|
||||
// but it's easier to just estimate the TSC tick rate for these cases.
|
||||
if (caps.tsc_crystal_ratio_denominator) {
|
||||
caps.tsc_frequency = static_cast<u64>(caps.crystal_frequency) *
|
||||
caps.tsc_crystal_ratio_numerator /
|
||||
caps.tsc_crystal_ratio_denominator;
|
||||
caps.tsc_frequency = u64(caps.crystal_frequency)
|
||||
* caps.tsc_crystal_ratio_numerator / caps.tsc_crystal_ratio_denominator;
|
||||
} else {
|
||||
caps.tsc_frequency = X64::EstimateRDTSCFrequency();
|
||||
}
|
||||
|
|
@ -197,54 +231,196 @@ static CPUCaps Detect() {
|
|||
caps.max_frequency = cpu_id[1];
|
||||
caps.bus_frequency = cpu_id[2];
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
}();
|
||||
|
||||
const CPUCaps& GetCPUCaps() {
|
||||
static CPUCaps caps = Detect();
|
||||
return caps;
|
||||
}
|
||||
|
||||
std::optional<int> GetProcessorCount() {
|
||||
#if defined(_WIN32)
|
||||
// Get the buffer length.
|
||||
DWORD length = 0;
|
||||
GetLogicalProcessorInformation(nullptr, &length);
|
||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
||||
LOG_ERROR(Frontend, "Failed to query core count.");
|
||||
return std::nullopt;
|
||||
}
|
||||
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;
|
||||
}));
|
||||
#elif defined(__unix__)
|
||||
const int thread_count = std::thread::hardware_concurrency();
|
||||
std::ifstream smt("/sys/devices/system/cpu/smt/active");
|
||||
char state = '0';
|
||||
if (smt) {
|
||||
smt.read(&state, sizeof(state));
|
||||
}
|
||||
switch (state) {
|
||||
case '0':
|
||||
return thread_count;
|
||||
case '1':
|
||||
return thread_count / 2;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
#else
|
||||
// Shame on you
|
||||
return std::nullopt;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept
|
||||
: rdtsc_frequency{rdtsc_frequency_}
|
||||
, ns_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency_) : 0}
|
||||
, us_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency_) : 0}
|
||||
, ms_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency_) : 0}
|
||||
, rdtsc_ns_factor{invariant_ ? GetFixedPoint64Factor(rdtsc_frequency_, NsRatio::den) : 1}
|
||||
, cntpct_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency_) : 0}
|
||||
, gputick_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency_) : 0}
|
||||
, invariant{invariant_}
|
||||
{}
|
||||
|
||||
std::chrono::nanoseconds WallClock::GetTimeNS() const {
|
||||
if (!invariant)
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch());
|
||||
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)};
|
||||
}
|
||||
|
||||
std::chrono::microseconds WallClock::GetTimeUS() const {
|
||||
if (!invariant)
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch());
|
||||
return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_rdtsc_factor)};
|
||||
}
|
||||
|
||||
std::chrono::milliseconds WallClock::GetTimeMS() const {
|
||||
if (!invariant)
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch());
|
||||
return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_rdtsc_factor)};
|
||||
}
|
||||
|
||||
s64 WallClock::GetCNTPCT() const {
|
||||
if (!invariant)
|
||||
return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
|
||||
return MultiplyHigh(GetUptime(), cntpct_rdtsc_factor);
|
||||
}
|
||||
|
||||
s64 WallClock::GetGPUTick() const {
|
||||
if (!invariant)
|
||||
return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
|
||||
return MultiplyHigh(GetUptime(), gputick_rdtsc_factor);
|
||||
}
|
||||
|
||||
s64 WallClock::GetUptime() const {
|
||||
if (!invariant)
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
return s64(Common::X64::FencedRDTSC());
|
||||
}
|
||||
|
||||
bool WallClock::IsNative() const {
|
||||
return invariant;
|
||||
}
|
||||
|
||||
u64 WallClock::NsToTicks(std::chrono::nanoseconds ns) const {
|
||||
return invariant ? MultiplyHigh(ns.count(), rdtsc_ns_factor) : ns.count();
|
||||
}
|
||||
#elif defined(HAS_NCE)
|
||||
namespace {
|
||||
[[nodiscard]] Common::WallClock::FactorType GetFixedPointFactor(u64 num, u64 den) noexcept {
|
||||
return (Common::WallClock::FactorType(num) << 64) / den;
|
||||
}
|
||||
[[nodiscard]] u64 MultiplyHigh(u64 m, Common::WallClock::FactorType factor) noexcept {
|
||||
return static_cast<u64>((m * factor) >> 64);
|
||||
}
|
||||
[[nodiscard]] s64 GetHostCNTFRQ() noexcept {
|
||||
u64 cntfrq_el0 = 0;
|
||||
#ifdef ANDROID
|
||||
std::string_view board{""};
|
||||
char buffer[PROP_VALUE_MAX];
|
||||
int len{__system_property_get("ro.product.board", buffer)};
|
||||
board = std::string_view(buffer, static_cast<size_t>(len));
|
||||
if (board == "s5e9925") { // Exynos 2200
|
||||
cntfrq_el0 = 25600000;
|
||||
} else if (board == "exynos2100") { // Exynos 2100
|
||||
cntfrq_el0 = 26000000;
|
||||
} else if (board == "exynos9810") { // Exynos 9810
|
||||
cntfrq_el0 = 26000000;
|
||||
} else if (board == "s5e8825") { // Exynos 1280
|
||||
cntfrq_el0 = 26000000;
|
||||
} else {
|
||||
asm volatile("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0));
|
||||
}
|
||||
return cntfrq_el0;
|
||||
#else
|
||||
asm volatile("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0));
|
||||
return cntfrq_el0;
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept {
|
||||
const u64 host_cntfrq = std::max<u64>(GetHostCNTFRQ(), 1);
|
||||
ns_cntfrq_factor = GetFixedPointFactor(NsRatio::den, host_cntfrq);
|
||||
us_cntfrq_factor = GetFixedPointFactor(UsRatio::den, host_cntfrq);
|
||||
ms_cntfrq_factor = GetFixedPointFactor(MsRatio::den, host_cntfrq);
|
||||
cntfrq_ns_factor = GetFixedPointFactor(host_cntfrq, NsRatio::den);
|
||||
guest_cntfrq_factor = GetFixedPointFactor(CNTFRQ, host_cntfrq);
|
||||
gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq);
|
||||
}
|
||||
|
||||
std::chrono::nanoseconds WallClock::GetTimeNS() const {
|
||||
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)};
|
||||
}
|
||||
|
||||
std::chrono::microseconds WallClock::GetTimeUS() const {
|
||||
return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_cntfrq_factor)};
|
||||
}
|
||||
|
||||
std::chrono::milliseconds WallClock::GetTimeMS() const {
|
||||
return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_cntfrq_factor)};
|
||||
}
|
||||
|
||||
s64 WallClock::GetCNTPCT() const {
|
||||
return MultiplyHigh(GetUptime(), guest_cntfrq_factor);
|
||||
}
|
||||
|
||||
s64 WallClock::GetGPUTick() const {
|
||||
return MultiplyHigh(GetUptime(), gputick_cntfrq_factor);
|
||||
}
|
||||
|
||||
s64 WallClock::GetUptime() const {
|
||||
s64 cntvct_el0 = 0;
|
||||
asm volatile(
|
||||
"dsb ish\n\t"
|
||||
"mrs %[cntvct_el0], cntvct_el0\n\t"
|
||||
"dsb ish\n\t"
|
||||
: [cntvct_el0] "=r"(cntvct_el0)
|
||||
);
|
||||
return cntvct_el0;
|
||||
}
|
||||
|
||||
bool WallClock::IsNative() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 WallClock::NsToTicks(std::chrono::nanoseconds ns) const {
|
||||
return MultiplyHigh(ns.count(), cntfrq_ns_factor);
|
||||
}
|
||||
#else
|
||||
WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept {}
|
||||
|
||||
std::chrono::nanoseconds WallClock::GetTimeNS() const {
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch());
|
||||
}
|
||||
|
||||
std::chrono::microseconds WallClock::GetTimeUS() const {
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch());
|
||||
}
|
||||
|
||||
std::chrono::milliseconds WallClock::GetTimeMS() const {
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch());
|
||||
}
|
||||
|
||||
s64 WallClock::GetCNTPCT() const {
|
||||
return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
|
||||
}
|
||||
|
||||
s64 WallClock::GetGPUTick() const {
|
||||
return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
|
||||
}
|
||||
|
||||
s64 WallClock::GetUptime() const {
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
bool WallClock::IsNative() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 WallClock::NsToTicks(std::chrono::nanoseconds ns) const {
|
||||
return ns.count();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Wall clock MUST be initialized AFTER g_cpu_caps
|
||||
// C++ only guarantees ctor init in the order they appear in TU
|
||||
const WallClock g_wall_clock = [] {
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
auto const& caps = Common::g_cpu_caps;
|
||||
return WallClock(caps.invariant_tsc && caps.tsc_frequency >= std::nano::den, caps.tsc_frequency);
|
||||
#elif defined(HAS_NCE)
|
||||
return WallClock(false, 1);
|
||||
#else
|
||||
return WallClock(true, 1);
|
||||
#endif
|
||||
}();
|
||||
} // namespace Common
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2013 Dolphin Emulator Project / 2015 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <ratio>
|
||||
|
|
@ -43,6 +46,9 @@ public:
|
|||
/// @returns Whether the clock directly uses the host's hardware clock.
|
||||
bool IsNative() const;
|
||||
|
||||
// @returns Nanoseconds to native ticks
|
||||
u64 NsToTicks(std::chrono::nanoseconds ns) const;
|
||||
|
||||
static inline u64 NSToCNTPCT(u64 ns) {
|
||||
return ns * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
|
||||
}
|
||||
|
|
@ -69,7 +75,6 @@ public:
|
|||
return cpu_tick * CPUTickToGPUTickRatio::num / CPUTickToGPUTickRatio::den;
|
||||
}
|
||||
|
||||
protected:
|
||||
using NsRatio = std::nano;
|
||||
using UsRatio = std::micro;
|
||||
using MsRatio = std::milli;
|
||||
|
|
@ -87,31 +92,96 @@ protected:
|
|||
using CPUTickToGPUTickRatio = std::ratio<GPUTickFreq, CPUTickFreq>;
|
||||
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
bool invariant;
|
||||
u64 rdtsc_frequency;
|
||||
u64 ns_rdtsc_factor;
|
||||
u64 us_rdtsc_factor;
|
||||
u64 ms_rdtsc_factor;
|
||||
u64 rdtsc_ns_factor;
|
||||
u64 cntpct_rdtsc_factor;
|
||||
u64 gputick_rdtsc_factor;
|
||||
bool invariant;
|
||||
#elif defined(HAS_NCE)
|
||||
public:
|
||||
using FactorType = unsigned __int128;
|
||||
|
||||
FactorType GetGuestCNTFRQFactor() const {
|
||||
[[nodiscard]] inline FactorType GetGuestCNTFRQFactor() const {
|
||||
return guest_cntfrq_factor;
|
||||
}
|
||||
protected:
|
||||
FactorType ns_cntfrq_factor;
|
||||
FactorType us_cntfrq_factor;
|
||||
FactorType ms_cntfrq_factor;
|
||||
FactorType cntfrq_ns_factor;
|
||||
FactorType guest_cntfrq_factor;
|
||||
FactorType gputick_cntfrq_factor;
|
||||
#else
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
[[nodiscard]] WallClock CreateOptimalClock() noexcept;
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
/// 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];
|
||||
|
||||
u32 base_frequency;
|
||||
u32 max_frequency;
|
||||
u32 bus_frequency;
|
||||
|
||||
u32 tsc_crystal_ratio_denominator;
|
||||
u32 tsc_crystal_ratio_numerator;
|
||||
u32 crystal_frequency;
|
||||
u64 tsc_frequency; // Derived from the above three values
|
||||
|
||||
bool sse3 : 1;
|
||||
bool ssse3 : 1;
|
||||
bool sse4_1 : 1;
|
||||
bool sse4_2 : 1;
|
||||
|
||||
bool avx : 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 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;
|
||||
};
|
||||
#else
|
||||
struct CPUCaps {
|
||||
bool padding;
|
||||
};
|
||||
#endif
|
||||
|
||||
/// Detects CPU core count
|
||||
std::optional<int> GetProcessorCount();
|
||||
|
||||
/// @brief Global cpu caps
|
||||
extern const CPUCaps g_cpu_caps;
|
||||
/// @brief Global wall clock
|
||||
extern const WallClock g_wall_clock;
|
||||
|
||||
} // namespace Common
|
||||
|
|
@ -62,16 +62,20 @@ std::vector<Asset> Release::GetPlatformAssets() const {
|
|||
|
||||
#ifdef _WIN32
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
find_asset("Standard", {"amd64-msvc-standard.exe", "amd64-msvc-standard.zip", "mingw-amd64-gcc-standard.exe", "mingw-amd64-gcc-standard.zip"});
|
||||
find_asset("PGO", {"mingw-amd64-clang-pgo.exe", "mingw-amd64-clang-pgo.zip"});
|
||||
#ifdef _MSC_VER
|
||||
find_asset("Standard", {"amd64-msvc-standard.exe", "amd64-msvc-standard.zip"});
|
||||
#else // _MSC_VER
|
||||
find_asset("Standard", {BUILD_ID "-gcc-standard.exe", BUILD_ID "-gcc-standard.zip"});
|
||||
find_asset("PGO", {BUILD_ID "-clang-pgo.exe", BUILD_ID "-clang-pgo.zip"});
|
||||
#endif // _MSC_VER
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
find_asset("Standard", {"mingw-arm64-clang-standard.exe", "mingw-arm64-clang-standard.zip"});
|
||||
find_asset("PGO", {"mingw-arm64-clang-pgo.exe", "mingw-arm64-clang-pgo.zip"});
|
||||
#endif
|
||||
find_asset("Standard", {"arm64-clang-standard.exe", "arm64-clang-standard.zip"});
|
||||
find_asset("PGO", {"arm64-clang-pgo.exe", "arm64-clang-pgo.zip"});
|
||||
#endif // ARCHITECTURE_arm64
|
||||
#elif defined(__APPLE__)
|
||||
#ifdef ARCHITECTURE_arm64
|
||||
find_asset("Standard", {".dmg", ".tar.gz"});
|
||||
#endif
|
||||
#endif // ARCHITECTURE_arm64
|
||||
#elif defined(__ANDROID__)
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
find_asset("Standard", {"chromeos.apk"});
|
||||
|
|
@ -82,9 +86,9 @@ std::vector<Asset> Release::GetPlatformAssets() const {
|
|||
find_asset("Standard", {"optimized.apk"});
|
||||
#else
|
||||
find_asset("Standard", {"standard.apk"});
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif // GENSHIN_SPOOF
|
||||
#endif // ARCHITECTURE_arm64
|
||||
#endif // __APPLE__
|
||||
return found_assets;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -20,10 +20,14 @@
|
|||
namespace Common {
|
||||
|
||||
struct SlotId {
|
||||
static constexpr u32 TAGGED_MASK = 0x7fffffff;
|
||||
static constexpr u32 TAGGED_VALUE = 0x80000000;
|
||||
static constexpr u32 INVALID_INDEX = (std::numeric_limits<u32>::max)();
|
||||
|
||||
constexpr u32 Value() const noexcept {
|
||||
return index & (~TAGGED_VALUE);
|
||||
}
|
||||
constexpr auto operator<=>(const SlotId&) const noexcept = default;
|
||||
|
||||
constexpr explicit operator bool() const noexcept {
|
||||
return index != INVALID_INDEX;
|
||||
}
|
||||
|
|
@ -47,12 +51,12 @@ public:
|
|||
Iterator& operator++() noexcept {
|
||||
const u64* const bitset = slot_vector->stored_bitset.data();
|
||||
const u32 size = static_cast<u32>(slot_vector->stored_bitset.size()) * 64;
|
||||
if (id.index < size) {
|
||||
if (id.Value() < size) {
|
||||
do {
|
||||
++id.index;
|
||||
} while (id.index < size && !IsValid(bitset));
|
||||
if (id.index == size) {
|
||||
id.index = SlotId::INVALID_INDEX;
|
||||
} while (id.Value() < size && !IsValid(bitset));
|
||||
if (id.Value() == size) {
|
||||
id = SlotId{};
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
|
|
@ -85,7 +89,7 @@ public:
|
|||
: slot_vector{slot_vector_}, id{id_} {}
|
||||
|
||||
bool IsValid(const u64* bitset) const noexcept {
|
||||
return ((bitset[id.index / 64] >> (id.index % 64)) & 1) != 0;
|
||||
return ((bitset[id.Value() / 64] >> (id.Value() % 64)) & 1) != 0;
|
||||
}
|
||||
|
||||
SlotVector<T>* slot_vector;
|
||||
|
|
@ -107,12 +111,12 @@ public:
|
|||
|
||||
[[nodiscard]] T& operator[](SlotId id) noexcept {
|
||||
ValidateIndex(id);
|
||||
return values[id.index].object;
|
||||
return values[id.Value()].object;
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& operator[](SlotId id) const noexcept {
|
||||
ValidateIndex(id);
|
||||
return values[id.index].object;
|
||||
return values[id.Value()].object;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
|
|
@ -125,9 +129,9 @@ public:
|
|||
}
|
||||
|
||||
void erase(SlotId id) noexcept {
|
||||
values[id.index].object.~T();
|
||||
free_list.push_back(id.index);
|
||||
ResetStorageBit(id.index);
|
||||
values[id.Value()].object.~T();
|
||||
free_list.push_back(id.Value());
|
||||
ResetStorageBit(id.Value());
|
||||
}
|
||||
|
||||
[[nodiscard]] Iterator begin() noexcept {
|
||||
|
|
@ -141,7 +145,7 @@ public:
|
|||
}
|
||||
|
||||
[[nodiscard]] Iterator end() noexcept {
|
||||
return Iterator(this, SlotId{SlotId::INVALID_INDEX});
|
||||
return Iterator(this, SlotId{});
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t size() const noexcept {
|
||||
|
|
@ -175,8 +179,8 @@ private:
|
|||
|
||||
void ValidateIndex(SlotId id) const noexcept {
|
||||
DEBUG_ASSERT(id);
|
||||
DEBUG_ASSERT(id.index / 64 < stored_bitset.size());
|
||||
DEBUG_ASSERT(((stored_bitset[id.index / 64] >> (id.index % 64)) & 1) != 0);
|
||||
DEBUG_ASSERT(id.Value() / 64 < stored_bitset.size());
|
||||
DEBUG_ASSERT(((stored_bitset[id.Value() / 64] >> (id.Value() % 64)) & 1) != 0);
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 FreeValueIndex() noexcept {
|
||||
|
|
@ -208,9 +212,7 @@ private:
|
|||
|
||||
const size_t old_free_size = free_list.size();
|
||||
free_list.resize(old_free_size + (new_capacity - values_capacity));
|
||||
std::iota(free_list.begin() + old_free_size, free_list.end(),
|
||||
static_cast<u32>(values_capacity));
|
||||
|
||||
std::iota(free_list.begin() + old_free_size, free_list.end(), u32(values_capacity));
|
||||
delete[] values;
|
||||
values = new_values;
|
||||
values_capacity = new_capacity;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
|
|
@ -18,24 +20,35 @@
|
|||
#elif defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include "common/string_util.h"
|
||||
#include "common/windows/timer_resolution.h"
|
||||
#else
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/cpuset.h>
|
||||
#include <sys/_cpuset.h>
|
||||
#include <pthread_np.h>
|
||||
// Compatibility with CPUset
|
||||
#define cpu_set_t cpuset_t
|
||||
#elif defined(__DragonFly__) || defined(__OpenBSD__) || defined(__Bitrig__)
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# define cpu_set_t cpuset_t
|
||||
#include "common/cpu_features.h"
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
#include "common/x64/rdtsc.h"
|
||||
#endif
|
||||
#include "core/core_timing.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
|
@ -144,4 +157,102 @@ void PinCurrentThreadToPerformanceCore(size_t core_id) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
// On Linux and UNIX systems, a futex would nominally be used to cover the costs
|
||||
// the idea is that it's intuitivelly cheaper to use a direct instruction as opposed to a full futex call
|
||||
// the underlying libc++ implementation uses pthread_cond_timedwait which MAY invoke a futex
|
||||
// Let's pretend the OS is too expensive to jump into, and avoid ANY context switches
|
||||
// this should *IN THEORY* lower CPU usage while just waiting for stuff effectively
|
||||
// For windows the minimal quanta resolution is about 500us, and normal CRT cond var is 1.5ms(?)
|
||||
// so may as well avoid that too
|
||||
// Let's just give ALL platforms the same mechanisms (almost) for when they have umonitor OR waitpkg
|
||||
#ifdef __clang__
|
||||
__attribute__((target("waitpkg,mwaitx")))
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC target("waitpkg")
|
||||
#pragma GCC target("mwaitx")
|
||||
#endif
|
||||
bool Event::WaitFor(const std::chrono::nanoseconds time) {
|
||||
#ifdef _WIN32
|
||||
auto const start = Common::X64::FencedRDTSC();
|
||||
auto const& caps = Common::g_cpu_caps;
|
||||
[[maybe_unused]] auto const end = start + Common::g_wall_clock.NsToTicks(time);
|
||||
if (caps.monitorx) {
|
||||
while (true) {
|
||||
// Armed monitor, as per manual, MWAITX must be conditional if the condition isn't satisfied
|
||||
// to prevent a race condition.
|
||||
_mm_monitorx(reinterpret_cast<u64*>(std::addressof(is_set)), 0, 0);
|
||||
if (!is_set.load()) {
|
||||
// RDTSC may be fenced here due to atomic load
|
||||
#ifdef _MSC_VER
|
||||
auto const now = __rdtsc();
|
||||
#else
|
||||
auto const now = _rdtsc();
|
||||
#endif
|
||||
if (end > now) {
|
||||
u32 const cycles = std::min<u32>((std::numeric_limits<u32>::max)(), s64(end) - s64(now));
|
||||
// See here: https://github.com/torvalds/linux/blob/948a64995aca6820abefd17f1a4258f5835c5ad9/arch/x86/lib/delay.c#L93
|
||||
// MWAITX accepts a 32-bit input timer which determines the total number of cycles to wait for
|
||||
// NOT THE TOTAL ABSOLUTE TSC VALUE, it's just a delta
|
||||
// BIT[1] = use a timer
|
||||
// Hint = 0: Use C1 state when sleepy (means slower wakeup but better savings)
|
||||
_mm_mwaitx(1 << 1, 0u, cycles);
|
||||
if (!is_set.load())
|
||||
return false;
|
||||
} else
|
||||
return false; //timeout
|
||||
}
|
||||
bool expected = true;
|
||||
if (is_set.compare_exchange_weak(expected, false, std::memory_order_release))
|
||||
return true;
|
||||
}
|
||||
} else if (caps.waitpkg) {
|
||||
// #UD If CPUID.7.0:ECX.WAITPKG[bit 5]=0.
|
||||
while (true) {
|
||||
_umonitor(std::addressof(is_set));
|
||||
if (!is_set.load() && !_umwait(0, end)) //umwait is absolute time!!!
|
||||
return false;
|
||||
bool expected = true;
|
||||
if (is_set.compare_exchange_weak(expected, false, std::memory_order_release))
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
#ifdef _MSC_VER
|
||||
while (!is_set.load() && end > __rdtsc())
|
||||
Common::Windows::SleepForOneTick();
|
||||
#else
|
||||
while (!is_set.load() && end > _rdtsc())
|
||||
Common::Windows::SleepForOneTick();
|
||||
#endif
|
||||
if (is_set.load())
|
||||
Reset();
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
std::unique_lock lk{mutex};
|
||||
if (!condvar.wait_for(lk, time, [this] { return is_set.load(); }))
|
||||
return false;
|
||||
is_set = false;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
bool Event::WaitFor(const std::chrono::nanoseconds time) {
|
||||
#ifdef _WIN32
|
||||
auto const end = Common::g_wall_clock.GetTimeNS() + time;
|
||||
while (!is_set.load() && end > Common::g_wall_clock.GetTimeNS())
|
||||
Common::Windows::SleepForOneTick();
|
||||
if (is_set.load())
|
||||
Reset();
|
||||
return true;
|
||||
#else
|
||||
std::unique_lock lk{mutex};
|
||||
if (!condvar.wait_for(lk, time, [this] { return is_set.load(); }))
|
||||
return false;
|
||||
is_set = false;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Common
|
||||
|
|
|
|||
|
|
@ -34,16 +34,10 @@ public:
|
|||
is_set = false;
|
||||
}
|
||||
|
||||
bool WaitFor(const std::chrono::nanoseconds& time) {
|
||||
std::unique_lock lk{mutex};
|
||||
if (!condvar.wait_for(lk, time, [this] { return is_set.load(); }))
|
||||
return false;
|
||||
is_set = false;
|
||||
return true;
|
||||
}
|
||||
bool WaitFor(const std::chrono::nanoseconds time);
|
||||
|
||||
template <class Clock, class Duration>
|
||||
bool WaitUntil(const std::chrono::time_point<Clock, Duration>& time) {
|
||||
template<class Clock, class Duration>
|
||||
bool WaitUntil(const std::chrono::time_point<Clock, Duration> time) {
|
||||
std::unique_lock lk{mutex};
|
||||
if (!condvar.wait_until(lk, time, [this] { return is_set.load(); }))
|
||||
return false;
|
||||
|
|
@ -63,9 +57,9 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
alignas(64) std::atomic<bool> is_set{false};
|
||||
std::condition_variable condvar;
|
||||
std::mutex mutex;
|
||||
std::atomic_bool is_set{false};
|
||||
};
|
||||
|
||||
class Barrier {
|
||||
|
|
|
|||
|
|
@ -1,197 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/steady_clock.h"
|
||||
#include "common/uint128.h"
|
||||
#include "common/wall_clock.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <sys/system_properties.h>
|
||||
#endif
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
#include "common/x64/cpu_detect.h"
|
||||
#include "common/x64/rdtsc.h"
|
||||
#endif
|
||||
|
||||
namespace Common {
|
||||
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept
|
||||
: invariant{invariant_}
|
||||
, rdtsc_frequency{rdtsc_frequency_}
|
||||
, ns_rdtsc_factor{invariant_ ? 0 : GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency_)}
|
||||
, us_rdtsc_factor{invariant_ ? 0 : GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency_)}
|
||||
, ms_rdtsc_factor{invariant_ ? 0 : GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency_)}
|
||||
, cntpct_rdtsc_factor{invariant_ ? 0 : GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency_)}
|
||||
, gputick_rdtsc_factor{invariant_ ? 0 : GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency_)}
|
||||
{}
|
||||
|
||||
std::chrono::nanoseconds WallClock::GetTimeNS() const {
|
||||
if (invariant)
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)};
|
||||
}
|
||||
|
||||
std::chrono::microseconds WallClock::GetTimeUS() const {
|
||||
if (invariant)
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_rdtsc_factor)};
|
||||
}
|
||||
|
||||
std::chrono::milliseconds WallClock::GetTimeMS() const {
|
||||
if (invariant)
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_rdtsc_factor)};
|
||||
}
|
||||
|
||||
s64 WallClock::GetCNTPCT() const {
|
||||
if (invariant)
|
||||
return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
|
||||
return MultiplyHigh(GetUptime(), cntpct_rdtsc_factor);
|
||||
}
|
||||
|
||||
s64 WallClock::GetGPUTick() const {
|
||||
if (invariant)
|
||||
return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
|
||||
return MultiplyHigh(GetUptime(), gputick_rdtsc_factor);
|
||||
}
|
||||
|
||||
s64 WallClock::GetUptime() const {
|
||||
if (invariant)
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
return s64(Common::X64::FencedRDTSC());
|
||||
}
|
||||
|
||||
bool WallClock::IsNative() const {
|
||||
if (invariant)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#elif defined(HAS_NCE)
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] WallClock::FactorType GetFixedPointFactor(u64 num, u64 den) noexcept {
|
||||
return (WallClock::FactorType(num) << 64) / den;
|
||||
}
|
||||
|
||||
[[nodiscard]] u64 MultiplyHigh(u64 m, WallClock::FactorType factor) noexcept {
|
||||
return static_cast<u64>((m * factor) >> 64);
|
||||
}
|
||||
|
||||
[[nodiscard]] s64 GetHostCNTFRQ() noexcept {
|
||||
u64 cntfrq_el0 = 0;
|
||||
#ifdef ANDROID
|
||||
std::string_view board{""};
|
||||
char buffer[PROP_VALUE_MAX];
|
||||
int len{__system_property_get("ro.product.board", buffer)};
|
||||
board = std::string_view(buffer, static_cast<size_t>(len));
|
||||
if (board == "s5e9925") { // Exynos 2200
|
||||
cntfrq_el0 = 25600000;
|
||||
} else if (board == "exynos2100") { // Exynos 2100
|
||||
cntfrq_el0 = 26000000;
|
||||
} else if (board == "exynos9810") { // Exynos 9810
|
||||
cntfrq_el0 = 26000000;
|
||||
} else if (board == "s5e8825") { // Exynos 1280
|
||||
cntfrq_el0 = 26000000;
|
||||
} else {
|
||||
asm volatile("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0));
|
||||
}
|
||||
return cntfrq_el0;
|
||||
#else
|
||||
asm volatile("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0));
|
||||
return cntfrq_el0;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept {
|
||||
const u64 host_cntfrq = std::max<u64>(GetHostCNTFRQ(), 1);
|
||||
ns_cntfrq_factor = GetFixedPointFactor(NsRatio::den, host_cntfrq);
|
||||
us_cntfrq_factor = GetFixedPointFactor(UsRatio::den, host_cntfrq);
|
||||
ms_cntfrq_factor = GetFixedPointFactor(MsRatio::den, host_cntfrq);
|
||||
guest_cntfrq_factor = GetFixedPointFactor(CNTFRQ, host_cntfrq);
|
||||
gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq);
|
||||
}
|
||||
|
||||
std::chrono::nanoseconds WallClock::GetTimeNS() const {
|
||||
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)};
|
||||
}
|
||||
|
||||
std::chrono::microseconds WallClock::GetTimeUS() const {
|
||||
return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_cntfrq_factor)};
|
||||
}
|
||||
|
||||
std::chrono::milliseconds WallClock::GetTimeMS() const {
|
||||
return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_cntfrq_factor)};
|
||||
}
|
||||
|
||||
s64 WallClock::GetCNTPCT() const {
|
||||
return MultiplyHigh(GetUptime(), guest_cntfrq_factor);
|
||||
}
|
||||
|
||||
s64 WallClock::GetGPUTick() const {
|
||||
return MultiplyHigh(GetUptime(), gputick_cntfrq_factor);
|
||||
}
|
||||
|
||||
s64 WallClock::GetUptime() const {
|
||||
s64 cntvct_el0 = 0;
|
||||
asm volatile(
|
||||
"dsb ish\n\t"
|
||||
"mrs %[cntvct_el0], cntvct_el0\n\t"
|
||||
"dsb ish\n\t"
|
||||
: [cntvct_el0] "=r"(cntvct_el0)
|
||||
);
|
||||
return cntvct_el0;
|
||||
}
|
||||
|
||||
bool WallClock::IsNative() const {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept {}
|
||||
|
||||
std::chrono::nanoseconds WallClock::GetTimeNS() const {
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
}
|
||||
|
||||
std::chrono::microseconds WallClock::GetTimeUS() const {
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
}
|
||||
|
||||
std::chrono::milliseconds WallClock::GetTimeMS() const {
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
}
|
||||
|
||||
s64 WallClock::GetCNTPCT() const {
|
||||
return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
|
||||
}
|
||||
|
||||
s64 WallClock::GetGPUTick() const {
|
||||
return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
|
||||
}
|
||||
|
||||
s64 WallClock::GetUptime() const {
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
bool WallClock::IsNative() const {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
WallClock CreateOptimalClock() noexcept {
|
||||
#if defined(ARCHITECTURE_x86_64)
|
||||
auto const& caps = GetCPUCaps();
|
||||
return WallClock(!(caps.invariant_tsc && caps.tsc_frequency >= std::nano::den), caps.tsc_frequency);
|
||||
#elif defined(HAS_NCE)
|
||||
return WallClock(false, 1);
|
||||
#else
|
||||
return WallClock(true, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
// 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include "common/common_types.h"
|
||||
|
||||
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];
|
||||
|
||||
u32 base_frequency;
|
||||
u32 max_frequency;
|
||||
u32 bus_frequency;
|
||||
|
||||
u32 tsc_crystal_ratio_denominator;
|
||||
u32 tsc_crystal_ratio_numerator;
|
||||
u32 crystal_frequency;
|
||||
u64 tsc_frequency; // Derived from the above three values
|
||||
|
||||
bool sse3 : 1;
|
||||
bool ssse3 : 1;
|
||||
bool sse4_1 : 1;
|
||||
bool sse4_2 : 1;
|
||||
|
||||
bool avx : 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 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
std::optional<int> GetProcessorCount();
|
||||
|
||||
} // namespace Common
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <thread>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#include "common/x64/cpu_detect.h"
|
||||
#include "common/x64/cpu_wait.h"
|
||||
#include "common/x64/rdtsc.h"
|
||||
|
||||
namespace Common::X64 {
|
||||
|
||||
namespace {
|
||||
|
||||
// 100,000 cycles is a reasonable amount of time to wait to save on CPU resources.
|
||||
// For reference:
|
||||
// At 1 GHz, 100K cycles is 100us
|
||||
// At 2 GHz, 100K cycles is 50us
|
||||
// At 4 GHz, 100K cycles is 25us
|
||||
constexpr auto PauseCycles = 100'000U;
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
__forceinline static void TPAUSE() {
|
||||
static constexpr auto RequestC02State = 0U;
|
||||
_tpause(RequestC02State, FencedRDTSC() + PauseCycles);
|
||||
}
|
||||
|
||||
__forceinline static void MWAITX() {
|
||||
static constexpr auto EnableWaitTimeFlag = 1U << 1;
|
||||
static constexpr auto RequestC1State = 0U;
|
||||
|
||||
// monitor_var should be aligned to a cache line.
|
||||
alignas(64) u64 monitor_var{};
|
||||
_mm_monitorx(&monitor_var, 0, 0);
|
||||
_mm_mwaitx(EnableWaitTimeFlag, RequestC1State, PauseCycles);
|
||||
}
|
||||
#else
|
||||
static void TPAUSE() {
|
||||
static constexpr auto RequestC02State = 0U;
|
||||
const auto tsc = FencedRDTSC() + PauseCycles;
|
||||
const auto eax = static_cast<u32>(tsc & 0xFFFFFFFF);
|
||||
const auto edx = static_cast<u32>(tsc >> 32);
|
||||
asm volatile("tpause %0" : : "r"(RequestC02State), "d"(edx), "a"(eax));
|
||||
}
|
||||
|
||||
static void MWAITX() {
|
||||
static constexpr auto EnableWaitTimeFlag = 1U << 1;
|
||||
static constexpr auto RequestC1State = 0U;
|
||||
|
||||
// monitor_var should be aligned to a cache line.
|
||||
alignas(64) u64 monitor_var{};
|
||||
asm volatile("monitorx" : : "a"(&monitor_var), "c"(0), "d"(0));
|
||||
asm volatile("mwaitx" : : "a"(RequestC1State), "b"(PauseCycles), "c"(EnableWaitTimeFlag));
|
||||
}
|
||||
#endif
|
||||
|
||||
void MicroSleep() {
|
||||
static const bool has_waitpkg = GetCPUCaps().waitpkg;
|
||||
static const bool has_monitorx = GetCPUCaps().monitorx;
|
||||
|
||||
if (has_waitpkg) {
|
||||
TPAUSE();
|
||||
} else if (has_monitorx) {
|
||||
MWAITX();
|
||||
} else {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Common::X64
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Common::X64 {
|
||||
|
||||
void MicroSleep();
|
||||
|
||||
} // namespace Common::X64
|
||||
|
|
@ -1200,7 +1200,7 @@ else()
|
|||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-cast-function-type>
|
||||
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>)
|
||||
# pre-clang19 will spam with "OH DID YOU MEAN THIS?" otherwise...
|
||||
if (CXX_CLANG AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19)
|
||||
if (CXX_CLANG AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 20)
|
||||
target_compile_options(core PRIVATE $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-cast-function-type-mismatch>)
|
||||
endif()
|
||||
endif()
|
||||
|
|
@ -1246,7 +1246,7 @@ if (HAS_NCE)
|
|||
target_link_libraries(core PRIVATE merry::oaknut)
|
||||
endif()
|
||||
|
||||
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64)
|
||||
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64 OR ARCHITECTURE_loongarch64)
|
||||
target_sources(core PRIVATE
|
||||
arm/dynarmic/arm_dynarmic.h
|
||||
arm/dynarmic/arm_dynarmic_64.cpp
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
// 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 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <dynarmic/interface/halt_reason.h>
|
||||
|
||||
#include "core/arm/arm_interface.h"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
// 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 Skyline Team and Contributors
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <numeric>
|
||||
#include <bit>
|
||||
#include "common/wall_clock.h"
|
||||
#include "common/cpu_features.h"
|
||||
#include "common/alignment.h"
|
||||
#include "common/literals.h"
|
||||
#include "core/arm/nce/arm_nce.h"
|
||||
|
|
|
|||
|
|
@ -8,15 +8,13 @@
|
|||
#include <mutex>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include "common/cpu_features.h"
|
||||
#include "common/cpu_features.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common/windows/timer_resolution.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
#include "common/x64/cpu_wait.h"
|
||||
#endif
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hardware_properties.h"
|
||||
|
|
@ -47,8 +45,7 @@ struct CoreTiming::Event {
|
|||
}
|
||||
};
|
||||
|
||||
CoreTiming::CoreTiming() : clock{Common::CreateOptimalClock()} {}
|
||||
|
||||
CoreTiming::CoreTiming() = default;
|
||||
CoreTiming::~CoreTiming() {
|
||||
Reset();
|
||||
}
|
||||
|
|
@ -64,31 +61,16 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
|
|||
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
|
||||
on_thread_init();
|
||||
has_started = true;
|
||||
|
||||
// base frequency in MHz: 1ns (10^-9) = 1GHz (10^9)
|
||||
while (!stop_token.stop_requested()) {
|
||||
while (!paused && !stop_token.stop_requested()) {
|
||||
paused_set = false;
|
||||
if (auto const next_time = Advance(); next_time) {
|
||||
// There are more events left in the queue, wait until the next event.
|
||||
auto wait_time = *next_time - GetGlobalTimeNs().count();
|
||||
auto const wait_time = *next_time - GetGlobalTimeNs().count();
|
||||
if (wait_time > 0) {
|
||||
#ifdef _WIN32
|
||||
while (!paused && !event.IsSet() && wait_time > 0) {
|
||||
wait_time = *next_time - GetGlobalTimeNs().count();
|
||||
if (wait_time >= timer_resolution_ns) {
|
||||
Common::Windows::SleepForOneTick();
|
||||
} else {
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
Common::X64::MicroSleep();
|
||||
#else
|
||||
std::this_thread::yield();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (event.IsSet())
|
||||
event.Reset();
|
||||
#else
|
||||
event.WaitFor(std::chrono::nanoseconds(wait_time));
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
// Queue is empty, wait until another event is scheduled and signals us to
|
||||
|
|
@ -226,7 +208,7 @@ void CoreTiming::ResetTicks() {
|
|||
}
|
||||
|
||||
u64 CoreTiming::GetClockTicks() const {
|
||||
u64 fres = is_multicore ? clock.GetCNTPCT() : Common::WallClock::CPUTickToCNTPCT(cpu_ticks);
|
||||
u64 fres = is_multicore ? Common::g_wall_clock.GetCNTPCT() : Common::WallClock::CPUTickToCNTPCT(cpu_ticks);
|
||||
if (auto const overclock = Settings::values.fast_cpu_time.GetValue(); overclock != Settings::CpuClock::Off) {
|
||||
fres = u64(f64(fres) * (1.7 + 0.3 * u32(overclock)));
|
||||
}
|
||||
|
|
@ -240,7 +222,7 @@ u64 CoreTiming::GetClockTicks() const {
|
|||
|
||||
u64 CoreTiming::GetGPUTicks() const {
|
||||
return is_multicore
|
||||
? clock.GetGPUTick()
|
||||
? Common::g_wall_clock.GetGPUTick()
|
||||
: Common::WallClock::CPUTickToGPUTick(cpu_ticks);
|
||||
}
|
||||
|
||||
|
|
@ -317,14 +299,14 @@ void CoreTiming::Reset() {
|
|||
/// @brief Returns current time in nanoseconds.
|
||||
std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const noexcept {
|
||||
return is_multicore
|
||||
? clock.GetTimeNS()
|
||||
? Common::g_wall_clock.GetTimeNS()
|
||||
: std::chrono::nanoseconds{Common::WallClock::CPUTickToNS(cpu_ticks)};
|
||||
}
|
||||
|
||||
/// @brief Returns current time in microseconds.
|
||||
std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const noexcept {
|
||||
return is_multicore
|
||||
? clock.GetTimeUS()
|
||||
? Common::g_wall_clock.GetTimeUS()
|
||||
: std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "common/common_types.h"
|
||||
#include "common/thread.h"
|
||||
#include "common/wall_clock.h"
|
||||
#include "common/cpu_features.h"
|
||||
|
||||
namespace Core::Timing {
|
||||
|
||||
|
|
@ -142,37 +142,28 @@ public:
|
|||
|
||||
void Reset();
|
||||
|
||||
Common::WallClock clock;
|
||||
|
||||
using heap_t = boost::heap::fibonacci_heap<CoreTiming::Event, boost::heap::compare<std::greater<>>>;
|
||||
heap_t event_queue;
|
||||
s64 global_timer = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
s64 timer_resolution_ns;
|
||||
#endif
|
||||
|
||||
using heap_t =
|
||||
boost::heap::fibonacci_heap<CoreTiming::Event, boost::heap::compare<std::greater<>>>;
|
||||
|
||||
heap_t event_queue;
|
||||
u64 event_fifo_id = 0;
|
||||
|
||||
s64 pause_end_time{};
|
||||
/// Cycle timing
|
||||
u64 cpu_ticks{};
|
||||
s64 downcount{};
|
||||
Common::Event event{};
|
||||
Common::Event pause_event{};
|
||||
std::function<void()> on_thread_init{};
|
||||
std::jthread timer_thread;
|
||||
mutable std::mutex basic_lock;
|
||||
std::mutex advance_lock;
|
||||
std::jthread timer_thread;
|
||||
std::atomic<bool> paused{};
|
||||
std::atomic<bool> paused_set{};
|
||||
std::atomic<bool> wait_set{};
|
||||
std::atomic<bool> has_started{};
|
||||
std::function<void()> on_thread_init{};
|
||||
|
||||
bool is_multicore{};
|
||||
s64 pause_end_time{};
|
||||
|
||||
/// Cycle timing
|
||||
u64 cpu_ticks{};
|
||||
s64 downcount{};
|
||||
};
|
||||
|
||||
/// Creates a core timing event with the given name and callback.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
// 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-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/typed_address.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
|
|
|||
|
|
@ -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-2.0-or-later
|
||||
|
||||
|
|
@ -12,8 +15,8 @@ Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t pro
|
|||
}
|
||||
|
||||
Result BreakDebugProcess(Core::System& system, Handle debug_handle) {
|
||||
UNIMPLEMENTED();
|
||||
R_THROW(ResultNotImplemented);
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result TerminateDebugProcess(Core::System& system, Handle debug_handle) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -372,6 +375,10 @@ bool LifecycleManager::UpdateRequestedFocusState() {
|
|||
// Mark the focus state as ready for update.
|
||||
m_requested_focus_state = new_state;
|
||||
|
||||
if (m_is_application) {
|
||||
m_has_focus_state_changed = true;
|
||||
}
|
||||
|
||||
// We changed the focus state.
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ Result IFileSystem::GetTotalSpaceSize(
|
|||
Result IFileSystem::GetFileTimeStampRaw(
|
||||
Out<FileSys::FileTimeStampRaw> out_timestamp,
|
||||
const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) {
|
||||
LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", path->str);
|
||||
LOG_DEBUG(Service_FS, "(Partial Implementation) called. file={}", path->str);
|
||||
|
||||
FileSys::FileTimeStampRaw vfs_timestamp{};
|
||||
R_TRY(backend->GetFileTimeStampRaw(&vfs_timestamp, FileSys::Path(path->str)));
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "common/assert.h"
|
||||
#include "common/logging.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/cpu_features.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
|
|
@ -28,7 +29,6 @@ BufferQueueProducer::BufferQueueProducer(Service::KernelHelpers::ServiceContext&
|
|||
Service::Nvidia::NvCore::NvMap& nvmap_)
|
||||
: service_context{service_context_}, core{std::move(buffer_queue_core_)}
|
||||
, slots(core->slots)
|
||||
, clock{Common::CreateOptimalClock()}
|
||||
, nvmap(nvmap_)
|
||||
{
|
||||
buffer_wait_event = service_context.CreateEvent("BufferQueue:WaitEvent");
|
||||
|
|
@ -488,7 +488,7 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
|
|||
slots[slot].buffer_state = BufferState::Queued;
|
||||
slots[slot].frame_number = core->frame_counter;
|
||||
slots[slot].queue_time = timestamp;
|
||||
slots[slot].presentation_time = clock.GetTimeNS().count();
|
||||
slots[slot].presentation_time = Common::g_wall_clock.GetTimeNS().count();
|
||||
slots[slot].fence = fence;
|
||||
|
||||
item.slot = slot;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
#include <mutex>
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/wall_clock.h"
|
||||
#include "common/cpu_features.h"
|
||||
#include "core/hle/service/nvdrv/nvdata.h"
|
||||
#include "core/hle/service/nvnflinger/binder.h"
|
||||
#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
|
||||
|
|
@ -89,7 +89,6 @@ private:
|
|||
s32 next_callback_ticket{};
|
||||
s32 current_callback_ticket{};
|
||||
std::condition_variable_any callback_condition;
|
||||
Common::WallClock clock;
|
||||
Service::Nvidia::NvCore::NvMap& nvmap;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
||||
#include "common/uuid.h"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/ns/ns_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "common/uuid.h"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -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 2023 yuzu Emulator Project
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
#include "common/common_types.h"
|
||||
#include "common/intrusive_list.h"
|
||||
#include "common/uuid.h"
|
||||
#include "common/wall_clock.h"
|
||||
#include "common/cpu_features.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/psc/time/errors.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
// 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-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Service::RO {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
// 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 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/math_util.h"
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/nvnflinger/ui/fence.h"
|
||||
|
|
|
|||
|
|
@ -130,6 +130,10 @@ if ("riscv64" IN_LIST ARCHITECTURE)
|
|||
find_package(biscuit 0.9.1 REQUIRED)
|
||||
endif()
|
||||
|
||||
if ("loongarch64" IN_LIST ARCHITECTURE)
|
||||
find_package(lagoon REQUIRED)
|
||||
endif()
|
||||
|
||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
||||
find_package(xbyak 7 CONFIG)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -295,6 +295,20 @@ if ("riscv64" IN_LIST ARCHITECTURE)
|
|||
message(WARNING "TODO: Incomplete frontend for this host architecture")
|
||||
endif()
|
||||
|
||||
if ("loongarch64" IN_LIST ARCHITECTURE)
|
||||
target_link_libraries(dynarmic PRIVATE lagoon::lagoon)
|
||||
|
||||
target_sources(dynarmic PRIVATE
|
||||
backend/loongarch64/exclusive_monitor.cpp
|
||||
backend/loongarch64/a32_interface.cpp
|
||||
backend/loongarch64/a64_interface.cpp
|
||||
backend/loongarch64/code_block.h
|
||||
|
||||
common/spin_lock_loongarch64.cpp
|
||||
)
|
||||
message(WARNING "TODO: Incomplete frontend for this host architecture")
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
target_sources(dynarmic PRIVATE backend/exception_handler_windows.cpp)
|
||||
elseif (APPLE)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
|
||||
namespace oaknut {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
|
|||
constexpr std::size_t xmrx(std::size_t x) noexcept {
|
||||
x ^= x >> 32;
|
||||
x *= 0xff51afd7ed558ccd;
|
||||
x ^= mcl::bit::rotate_right(x, 47) ^ mcl::bit::rotate_right(x, 23);
|
||||
x ^= std::rotr(x, 47) ^ std::rotr(x, 23);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ class CodeBlock;
|
|||
namespace Dynarmic::Backend::RV64 {
|
||||
class CodeBlock;
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
#elif defined(ARCHITECTURE_loongarch64)
|
||||
namespace Dynarmic::Backend::LoongArch64 {
|
||||
class CodeBlock;
|
||||
} // namespace Dynarmic::Backend::LoongArch64
|
||||
#else
|
||||
# error "Invalid architecture"
|
||||
#endif
|
||||
|
|
@ -45,6 +49,10 @@ struct FakeCall {
|
|||
struct FakeCall {
|
||||
u64 call_sepc;
|
||||
};
|
||||
#elif defined(ARCHITECTURE_loongarch64)
|
||||
struct FakeCall {
|
||||
u64 call_pc;
|
||||
};
|
||||
#else
|
||||
# error "Invalid architecture"
|
||||
#endif
|
||||
|
|
@ -60,6 +68,8 @@ public:
|
|||
void Register(oaknut::CodeBlock& mem, std::size_t mem_size);
|
||||
#elif defined(ARCHITECTURE_riscv64)
|
||||
void Register(RV64::CodeBlock& mem, std::size_t mem_size);
|
||||
#elif defined(ARCHITECTURE_loongarch64)
|
||||
void Register(LoongArch64::CodeBlock& mem, std::size_t mem_size);
|
||||
#else
|
||||
# error "Invalid architecture"
|
||||
#endif
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue