Merge from latest upstream (#22)

* externals: bump xbyak to v6.68

* externals: point to upstream dynarmic

* build: Update to support multi-arch builds.

* ci: Generate universal macOS build.

* macOS: Make Citra show up in the Launchpad Games folder (#6245)

* Instead of there being an "Abort/Continue" prompt when a savestate fails to save or load, it just brings up a warning box. (#6236)

* This fixes #6041 by changing OnCoreError. Instead of there being an "Abort/Continue" prompt when a savestate fails to save or load, it just brings up a warning box.

I also changed "Abort/Continue" to "Quit Game/Continue" for better clarity

* Fixed formatting

* externals: Switch to newer cryptopp-cmake. (#6242)

* Implement svcGetHandleInfo, svcOpenProcess/Thread, svcGetProcessList (#6243)

* Implement svcGetHandleInfo, svcOpenProcess/Thread, svcGetProcessList

* Apply suggestions

* Add comment to stubbed enum values in svcGetHandleInfo

* Revert u32 -> size_t

Co-authored-by: SachinVin <sachinvinayak2000@gmail.com>
Co-authored-by: SachinVin <26602104+SachinVin@users.noreply.github.com>
Co-authored-by: UltraHDR <108294295+UltraHDR@users.noreply.github.com>
Co-authored-by: upadsamay387 <56898833+upadsamay387@users.noreply.github.com>
Co-authored-by: PabloMK7 <hackyglitch2@gmail.com>
This commit is contained in:
Steveice10
2023-01-17 03:11:41 -08:00
committed by GitHub
parent 489248e77f
commit 0e0771ad74
40 changed files with 329 additions and 570 deletions

View File

@@ -2,7 +2,6 @@
set -o pipefail set -o pipefail
export Qt5_DIR=$(brew --prefix)/opt/qt5
export PATH="/usr/local/opt/ccache/libexec:$PATH" export PATH="/usr/local/opt/ccache/libexec:$PATH"
# ccache configurations # ccache configurations
export CCACHE_CPP2=yes export CCACHE_CPP2=yes
@@ -16,13 +15,16 @@ export ASM="clang"
ccache -s ccache -s
mkdir build && cd build mkdir build && cd build
# TODO: LibreSSL ASM disabled due to platform detection issues in build.
cmake .. -DCMAKE_BUILD_TYPE=Release \ cmake .. -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" \
-DENABLE_QT_TRANSLATION=ON \ -DENABLE_QT_TRANSLATION=ON \
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \ -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \ -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
-DUSE_DISCORD_PRESENCE=ON \ -DUSE_DISCORD_PRESENCE=ON \
-DENABLE_FFMPEG_AUDIO_DECODER=ON \ -DENABLE_FFMPEG_AUDIO_DECODER=ON \
-DENABLE_FFMPEG_VIDEO_DUMPER=ON \ -DENABLE_FFMPEG_VIDEO_DUMPER=ON \
-DENABLE_ASM=OFF \
-GNinja -GNinja
ninja ninja

View File

@@ -1,28 +1,25 @@
#!/bin/sh -ex #!/bin/sh -ex
brew update brew install ccache ninja || true
brew unlink python@2 || true
rm '/usr/local/bin/2to3' || true
brew install qt5 p7zip ccache ninja wget || true
pip3 install macpack pip3 install macpack
export SDL_VER=2.0.16 export FFMPEG_VER=5.1
export FFMPEG_VER=4.4 export QT_VER=5.15.8
export VULKAN_SDK_VER=1.3.236.0 export VULKAN_SDK_VER=1.3.236.0
mkdir tmp mkdir tmp
cd tmp/ cd tmp/
# install SDL
wget https://github.com/SachinVin/ext-macos-bin/raw/main/sdl2/sdl-${SDL_VER}.7z
7z x sdl-${SDL_VER}.7z
cp -rv $(pwd)/sdl-${SDL_VER}/* /
# install FFMPEG # install FFMPEG
wget https://github.com/SachinVin/ext-macos-bin/raw/main/ffmpeg/ffmpeg-${FFMPEG_VER}.7z wget https://github.com/SachinVin/ext-macos-bin/raw/main/ffmpeg/ffmpeg-${FFMPEG_VER}.7z
7z x ffmpeg-${FFMPEG_VER}.7z 7z x ffmpeg-${FFMPEG_VER}.7z
cp -rv $(pwd)/ffmpeg-${FFMPEG_VER}/* / cp -rv $(pwd)/ffmpeg-${FFMPEG_VER}/* /
# install Qt
wget https://github.com/SachinVin/ext-macos-bin/raw/main/qt/qt-${QT_VER}.7z
7z x qt-${QT_VER}.7z
sudo cp -rv $(pwd)/qt-${QT_VER}/* /usr/local/
# install Vulkan SDK # install Vulkan SDK
wget https://sdk.lunarg.com/sdk/download/1.3.236.0/mac/vulkansdk-macos-${VULKAN_SDK_VER}.dmg wget https://sdk.lunarg.com/sdk/download/1.3.236.0/mac/vulkansdk-macos-${VULKAN_SDK_VER}.dmg
hdiutil attach vulkansdk-macos-${VULKAN_SDK_VER}.dmg hdiutil attach vulkansdk-macos-${VULKAN_SDK_VER}.dmg

View File

@@ -23,7 +23,7 @@ CITRA_STANDALONE_PATH="$REV_NAME/citra"
# move libs into folder for deployment # move libs into folder for deployment
macpack $BUNDLE_EXECUTABLE_PATH -d "../Frameworks" macpack $BUNDLE_EXECUTABLE_PATH -d "../Frameworks"
# move qt frameworks into app bundle for deployment # move qt frameworks into app bundle for deployment
$(brew --prefix)/opt/qt5/bin/macdeployqt $BUNDLE_PATH -executable=$BUNDLE_EXECUTABLE_PATH macdeployqt $BUNDLE_PATH -executable=$BUNDLE_EXECUTABLE_PATH
# move libs into folder for deployment # move libs into folder for deployment
macpack $CITRA_STANDALONE_PATH -d "libs" macpack $CITRA_STANDALONE_PATH -d "libs"

8
.gitmodules vendored
View File

@@ -12,13 +12,10 @@
url = https://github.com/catchorg/Catch2 url = https://github.com/catchorg/Catch2
[submodule "dynarmic"] [submodule "dynarmic"]
path = externals/dynarmic path = externals/dynarmic
url = https://github.com/citra-emu/dynarmic.git url = https://github.com/merryhime/dynarmic.git
[submodule "xbyak"] [submodule "xbyak"]
path = externals/xbyak path = externals/xbyak
url = https://github.com/herumi/xbyak.git url = https://github.com/herumi/xbyak.git
[submodule "cryptopp"]
path = externals/cryptopp/cryptopp
url = https://github.com/weidai11/cryptopp.git
[submodule "fmt"] [submodule "fmt"]
path = externals/fmt path = externals/fmt
url = https://github.com/fmtlib/fmt.git url = https://github.com/fmtlib/fmt.git
@@ -58,6 +55,9 @@
[submodule "sdl2"] [submodule "sdl2"]
path = externals/sdl2/SDL path = externals/sdl2/SDL
url = https://github.com/libsdl-org/SDL url = https://github.com/libsdl-org/SDL
[submodule "cryptopp-cmake"]
path = externals/cryptopp-cmake
url = https://github.com/abdes/cryptopp-cmake.git
[submodule "vulkan-headers"] [submodule "vulkan-headers"]
path = externals/vulkan-headers path = externals/vulkan-headers
url = https://github.com/KhronosGroup/Vulkan-Headers url = https://github.com/KhronosGroup/Vulkan-Headers

View File

@@ -147,14 +147,14 @@ function(detect_architecture symbol arch)
# CMake's crazy scope rules will keep it defined # CMake's crazy scope rules will keep it defined
if (ARCHITECTURE_${arch}) if (ARCHITECTURE_${arch})
set(ARCHITECTURE "${arch}" PARENT_SCOPE) set(ARCHITECTURE "${arch}" PARENT_SCOPE)
set(ARCHITECTURE_${arch} 1 PARENT_SCOPE)
add_definitions(-DARCHITECTURE_${arch}=1)
endif() endif()
endif() endif()
endfunction() endfunction()
if (NOT ENABLE_GENERIC) if (NOT ENABLE_GENERIC)
if (MSVC) if (CMAKE_OSX_ARCHITECTURES)
set(ARCHITECTURE "${CMAKE_OSX_ARCHITECTURES}")
elseif (MSVC)
detect_architecture("_M_AMD64" x86_64) detect_architecture("_M_AMD64" x86_64)
detect_architecture("_M_IX86" x86) detect_architecture("_M_IX86" x86)
detect_architecture("_M_ARM" arm) detect_architecture("_M_ARM" arm)
@@ -168,8 +168,6 @@ if (NOT ENABLE_GENERIC)
endif() endif()
if (NOT DEFINED ARCHITECTURE) if (NOT DEFINED ARCHITECTURE)
set(ARCHITECTURE "GENERIC") set(ARCHITECTURE "GENERIC")
set(ARCHITECTURE_GENERIC 1)
add_definitions(-DARCHITECTURE_GENERIC=1)
endif() endif()
message(STATUS "Target architecture: ${ARCHITECTURE}") message(STATUS "Target architecture: ${ARCHITECTURE}")
@@ -195,7 +193,7 @@ find_package(Threads REQUIRED)
if (ENABLE_QT) if (ENABLE_QT)
if (CITRA_USE_BUNDLED_QT) if (CITRA_USE_BUNDLED_QT)
if (MSVC_VERSION GREATER_EQUAL 1920 AND ARCHITECTURE_x86_64) if (MSVC_VERSION GREATER_EQUAL 1920 AND "x86_64" IN_LIST ARCHITECTURE)
set(QT_VER qt-5.15.7-msvc2019_64) set(QT_VER qt-5.15.7-msvc2019_64)
else() else()
message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.") message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.")
@@ -232,7 +230,7 @@ endif()
if (ENABLE_FFMPEG) if (ENABLE_FFMPEG)
if (CITRA_USE_BUNDLED_FFMPEG) if (CITRA_USE_BUNDLED_FFMPEG)
if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND ARCHITECTURE_x86_64) if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND "x86_64" IN_LIST ARCHITECTURE)
set(FFmpeg_VER "ffmpeg-4.1-win64") set(FFmpeg_VER "ffmpeg-4.1-win64")
else() else()
message(FATAL_ERROR "No bundled FFmpeg binaries for your toolchain. Disable CITRA_USE_BUNDLED_FFMPEG and provide your own.") message(FATAL_ERROR "No bundled FFmpeg binaries for your toolchain. Disable CITRA_USE_BUNDLED_FFMPEG and provide your own.")

View File

@@ -29,25 +29,38 @@ set(CATCH_INSTALL_EXTRAS OFF)
add_subdirectory(catch2) add_subdirectory(catch2)
# Crypto++ # Crypto++
add_subdirectory(cryptopp) set(CRYPTOPP_BUILD_DOCUMENTATION OFF)
set(CRYPTOPP_BUILD_TESTING OFF)
set(CRYPTOPP_INSTALL OFF)
add_subdirectory(cryptopp-cmake)
# HACK: The logic to set up the base include directory for CryptoPP does not work with Android SDK CMake 3.22.1.
# Until there is a fixed version available, this code will detect and add in the proper include if it does not exist.
if(ANDROID)
message(STATUS "Applying CryptoPP include fix.")
get_target_property(CRYPTOPP_INCLUDES cryptopp INTERFACE_INCLUDE_DIRECTORIES)
foreach(CRYPTOPP_INCLUDE ${CRYPTOPP_INCLUDES})
if("${CRYPTOPP_INCLUDE}" MATCHES "\\$<BUILD_INTERFACE:(.*)/cryptopp>")
message(STATUS "Fixed include path: ${CMAKE_MATCH_1}")
target_include_directories(cryptopp PUBLIC $<BUILD_INTERFACE:${CMAKE_MATCH_1}>)
break()
endif()
endforeach()
endif()
# fmt and Xbyak need to be added before dynarmic # fmt and Xbyak need to be added before dynarmic
# libfmt # libfmt
option(FMT_INSTALL "" ON)
add_subdirectory(fmt) add_subdirectory(fmt)
# Xbyak # Xbyak
if (ARCHITECTURE_x86_64) if ("x86_64" IN_LIST ARCHITECTURE)
add_library(xbyak INTERFACE) add_subdirectory(xbyak)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/xbyak/xbyak DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
target_include_directories(xbyak SYSTEM INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES)
endif() endif()
# Dynarmic # Dynarmic
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE)
set(DYNARMIC_TESTS OFF) set(DYNARMIC_TESTS OFF)
set(DYNARMIC_NO_BUNDLED_FMT ON)
set(DYNARMIC_FRONTENDS "A32") set(DYNARMIC_FRONTENDS "A32")
add_subdirectory(dynarmic) add_subdirectory(dynarmic)
endif() endif()

1
externals/cryptopp-cmake vendored Submodule

View File

@@ -1,449 +0,0 @@
# A trimmed down version of the CMakeLists.txt from noloader/cryptopp-cmake
# The differences are:
# - removed support for legacy CMake versions
# - removed support for 32-bit
# - added prefix "CRYPTOPP_OPT_" to all option names
# - disabled testing
# - disabled installation
# - disabled documentation
# - configured to build a static library only
# - adds include directories to the library target
cmake_minimum_required(VERSION 3.1)
if (POLICY CMP0048)
cmake_policy(SET CMP0048 NEW)
endif ()
project(cryptopp VERSION 8.5.0)
if (POLICY CMP0054)
cmake_policy(SET CMP0054 NEW)
endif ()
set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cryptopp)
include(TestBigEndian)
include(GNUInstallDirs)
include(CheckCXXCompilerFlag)
set(TEST_PROG_DIR ${SRC_DIR}/TestPrograms)
set(TEST_CXX_FILE ${TEST_PROG_DIR}/test_cxx.cxx)
#============================================================================
# Settable options
#============================================================================
option(CRYPTOPP_OPT_DISABLE_ASM "Disable ASM" OFF)
option(CRYPTOPP_OPT_DISABLE_SSSE3 "Disable SSSE3" OFF)
option(CRYPTOPP_OPT_DISABLE_SSE4 "Disable SSE4" OFF)
option(CRYPTOPP_OPT_DISABLE_AESNI "Disable AES-NI" OFF)
option(CRYPTOPP_OPT_DISABLE_SHA "Disable SHA" OFF)
option(CRYPTOPP_OPT_DISABLE_AVX "Disable AVX" OFF)
option(CRYPTOPP_OPT_DISABLE_AVX2 "Disable AVX2" OFF)
#============================================================================
# Compiler options
#============================================================================
# Only set when cross-compiling, http://www.vtk.org/Wiki/CMake_Cross_Compiling
if (NOT (CMAKE_SYSTEM_VERSION AND CMAKE_SYSTEM_PROCESSOR))
set(CRYPTOPP_CROSS_COMPILE 1)
else()
set(CRYPTOPP_CROSS_COMPILE 0)
endif()
set(CRYPTOPP_COMPILE_DEFINITIONS)
set(CRYPTOPP_COMPILE_OPTIONS)
# Don't use RPATH's. The resulting binary could fail a security audit.
set(CMAKE_MACOSX_RPATH 0)
if(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
list(APPEND CRYPTOPP_COMPILE_OPTIONS -wd68 -wd186 -wd279 -wd327 -wd161 -wd3180)
endif()
if(MSVC)
# Disable C4390: empty controlled statement found: is this the intent?
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4390")
endif()
# Endianness
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
if(IS_BIG_ENDIAN)
add_definitions(-DIS_BIG_ENDIAN)
endif()
if (CRYPTOPP_OPT_DISABLE_ASM)
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS CRYPTOPP_DISABLE_ASM)
endif ()
if (CRYPTOPP_OPT_DISABLE_SSSE3)
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS CRYPTOPP_DISABLE_SSSE3)
endif ()
if (CRYPTOPP_OPT_DISABLE_SSE4)
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS CRYPTOPP_DISABLE_SSSE4)
endif ()
if (CRYPTOPP_OPT_DISABLE_CLMUL)
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS CRYPTOPP_DISABLE_CLMUL)
endif ()
if (CRYPTOPP_OPT_DISABLE_AESNI)
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS CRYPTOPP_DISABLE_AESNI)
endif ()
if (CRYPTOPP_OPT_DISABLE_RDRAND)
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS CRYPTOPP_DISABLE_RDRAND)
endif ()
if (CRYPTOPP_OPT_DISABLE_RDSEED)
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS CRYPTOPP_DISABLE_RDSEED)
endif ()
if (CRYPTOPP_OPT_DISABLE_AVX)
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS CRYPTOPP_DISABLE_AVX)
endif ()
if (CRYPTOPP_OPT_DISABLE_AVX2)
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS CRYPTOPP_DISABLE_AVX2)
endif ()
if (CRYPTOPP_OPT_DISABLE_SHA)
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS CRYPTOPP_DISABLE_SHA)
endif ()
# We need the output 'uname -s' for Unix and Linux system detection
if (NOT CRYPTOPP_CROSS_COMPILE)
set (UNAME_CMD "uname")
set (UNAME_ARG "-s")
execute_process(COMMAND ${UNAME_CMD} ${UNAME_ARG}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE UNAME_RESULT
OUTPUT_VARIABLE UNAME_SYSTEM)
string(REGEX REPLACE "\n$" "" UNAME_SYSTEM "${UNAME_SYSTEM}")
endif()
# We need the output 'uname -m' for Unix and Linux platform detection
if (NOT CRYPTOPP_CROSS_COMPILE)
set (UNAME_CMD "uname")
set (UNAME_ARG "-m")
execute_process(COMMAND ${UNAME_CMD} ${UNAME_ARG}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE UNAME_RESULT
OUTPUT_VARIABLE UNAME_MACHINE)
string(REGEX REPLACE "\n$" "" UNAME_MACHINE "${UNAME_MACHINE}")
endif()
###############################################################################
# Try to find a Posix compatible grep and sed. Solaris, Digital Unix,
# Tru64, HP-UX and a few others need tweaking
if (EXISTS /usr/xpg4/bin/grep)
set(GREP_CMD /usr/xpg4/bin/grep)
elseif (EXISTS /usr/gnu/bin/grep)
set(GREP_CMD /usr/gnu/bin/grep)
elseif (EXISTS /usr/linux/bin/grep)
set(GREP_CMD /usr/linux/bin/grep)
else ()
set(GREP_CMD grep)
endif ()
if (EXISTS /usr/xpg4/bin/sed)
set(SED_CMD /usr/xpg4/bin/sed)
elseif (EXISTS /usr/gnu/bin/sed)
set(SED_CMD /usr/gnu/bin/sed)
elseif (EXISTS /usr/linux/bin/sed)
set(SED_CMD /usr/linux/bin/sed)
else ()
set(SED_CMD sed)
endif ()
###############################################################################
function(CheckCompileOption opt var)
CHECK_CXX_COMPILER_FLAG(${opt} ${var})
endfunction(CheckCompileOption)
function(CheckCompileLinkOption opt var prog)
if (MSVC)
# TODO: improve this...
CHECK_CXX_COMPILER_FLAG(${opt} ${var})
elseif (APPLE)
message(STATUS "Performing Test ${var}")
try_compile(COMMAND_SUCCESS ${CMAKE_BINARY_DIR} ${prog} COMPILE_DEFINITIONS ${opt})
if (COMMAND_SUCCESS)
set(${var} 1 PARENT_SCOPE)
message(STATUS "Performing Test ${var} - Success")
else ()
set(${var} 0 PARENT_SCOPE)
message(STATUS "Performing Test ${var} - Failed")
endif ()
else ()
message(STATUS "Performing Test ${var}")
try_compile(COMMAND_SUCCESS ${CMAKE_BINARY_DIR} ${prog} COMPILE_DEFINITIONS ${opt})
if (COMMAND_SUCCESS)
set(${var} 1 PARENT_SCOPE)
message(STATUS "Performing Test ${var} - Success")
else ()
set(${var} 0 PARENT_SCOPE)
message(STATUS "Performing Test ${var} - Failed")
endif ()
endif ()
endfunction(CheckCompileLinkOption)
function(AddCompileOption opt)
if ("${COMMAND_OUTPUT}" NOT STREQUAL "")
list(APPEND CRYPTOPP_COMPILE_OPTIONS "${opt}")
endif ()
endfunction(AddCompileOption)
###############################################################################
function(DumpMachine output pattern)
if (MSVC)
# CMake does not provide a generic shell/terminal mechanism
# and Microsoft environments don't know what 'sh' is.
set(${output} 0 PARENT_SCOPE)
else ()
if(CMAKE_SYSTEM_PROCESSOR MATCHES ${pattern})
set(${output} TRUE PARENT_SCOPE)
endif()
endif()
endfunction(DumpMachine)
# Thansk to Anonimal for MinGW; see http://github.com/weidai11/cryptopp/issues/466
DumpMachine(CRYPTOPP_AMD64 "(x86_64|AMD64|amd64)")
DumpMachine(CRYPTOPP_I386 "(i.86)")
DumpMachine(CRYPTOPP_MINGW64 "(w64-mingw32)|(mingw64)")
DumpMachine(CRYPTOPP_ARMV8 "(armv8|aarch64)")
###############################################################################
if(MSVC)
if(CMAKE_SYSTEM_VERSION MATCHES "10\\.0.*")
list(APPEND CRYPTOPP_COMPILE_DEFINITIONS "_WIN32_WINNT=0x0A00")
endif()
list(APPEND CRYPTOPP_COMPILE_OPTIONS /FI winapifamily.h)
endif()
# Enable PIC for all targets except Windows and 32-bit x86.
# Avoid on 32-bit x86 due to register pressures.
if ((NOT CRYPTOPP_CROSS_COMPILE) AND (NOT (WINDOWS OR WINDOWS_STORE OR WINDOWS_PHONE)))
# Use Regex; match i386, i486, i586 and i686
if (NOT (${UNAME_MACHINE} MATCHES "i.86"))
SET(CMAKE_POSITION_INDEPENDENT_CODE 1)
endif()
endif()
# Link is driven through the compiler, but CXXFLAGS are not used. Also see
# http://public.kitware.com/pipermail/cmake/2003-June/003967.html
if (NOT (WINDOWS OR WINDOWS_STORE OR WINDOWS_PHONE))
SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
#============================================================================
# Sources & headers
#============================================================================
# Library headers
file(GLOB cryptopp_HEADERS ${SRC_DIR}/*.h)
# Remove headers used to build test suite
list(REMOVE_ITEM cryptopp_HEADERS
${SRC_DIR}/bench.h
${SRC_DIR}/validate.h
)
# Library sources.
# These have been trimmed to include only things Citra uses. This speeds up
# compiles and reduces the amount of compilation breakage.
set(cryptopp_SOURCES
# The Crypto++ readme says you should put these 3 object files first,
# to avoid "problems associated with C++ static initialization order",
# but doesn't actually tell what could go wrong. Better safe than sorry
# I guess...
${SRC_DIR}/cryptlib.cpp
${SRC_DIR}/cpu.cpp
${SRC_DIR}/integer.cpp
${SRC_DIR}/algparam.cpp
${SRC_DIR}/allocate.cpp
${SRC_DIR}/asn.cpp
${SRC_DIR}/authenc.cpp
${SRC_DIR}/base64.cpp
${SRC_DIR}/basecode.cpp
${SRC_DIR}/ccm.cpp
${SRC_DIR}/crc_simd.cpp
${SRC_DIR}/des.cpp
${SRC_DIR}/dessp.cpp
${SRC_DIR}/dll.cpp
${SRC_DIR}/ec2n.cpp
${SRC_DIR}/ecp.cpp
${SRC_DIR}/filters.cpp
${SRC_DIR}/fips140.cpp
${SRC_DIR}/gcm_simd.cpp
${SRC_DIR}/gf2n_simd.cpp
${SRC_DIR}/gf2n.cpp
${SRC_DIR}/gfpcrypt.cpp
${SRC_DIR}/hex.cpp
${SRC_DIR}/hmac.cpp
${SRC_DIR}/hrtimer.cpp
${SRC_DIR}/iterhash.cpp
${SRC_DIR}/md5.cpp
${SRC_DIR}/misc.cpp
${SRC_DIR}/modes.cpp
${SRC_DIR}/mqueue.cpp
${SRC_DIR}/nbtheory.cpp
${SRC_DIR}/neon_simd.cpp
${SRC_DIR}/oaep.cpp
${SRC_DIR}/osrng.cpp
${SRC_DIR}/ppc_power7.cpp
${SRC_DIR}/ppc_power8.cpp
${SRC_DIR}/ppc_power9.cpp
${SRC_DIR}/ppc_simd.cpp
${SRC_DIR}/pubkey.cpp
${SRC_DIR}/queue.cpp
${SRC_DIR}/randpool.cpp
${SRC_DIR}/rdtables.cpp
${SRC_DIR}/rijndael_simd.cpp
${SRC_DIR}/rijndael.cpp
${SRC_DIR}/rng.cpp
${SRC_DIR}/sha_simd.cpp
${SRC_DIR}/sha.cpp
${SRC_DIR}/sse_simd.cpp
)
if(ANDROID)
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
list(APPEND cryptopp_SOURCES ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
endif()
set(cryptopp_SOURCES_ASM)
if (MSVC AND NOT DISABLE_ASM)
if (${CMAKE_GENERATOR} MATCHES ".*ARM")
message(STATUS "Disabling ASM because ARM is specified as target platform.")
else ()
enable_language(ASM_MASM)
list(APPEND cryptopp_SOURCES_ASM
${SRC_DIR}/rdrand.asm
${SRC_DIR}/rdseed.asm
)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND cryptopp_SOURCES_ASM
${SRC_DIR}/x64dll.asm
${SRC_DIR}/x64masm.asm
)
set_source_files_properties(${cryptopp_SOURCES_ASM} PROPERTIES COMPILE_DEFINITIONS "_M_X64")
else ()
set_source_files_properties(${cryptopp_SOURCES_ASM} PROPERTIES COMPILE_DEFINITIONS "_M_X86" COMPILE_FLAGS "/safeseh")
endif ()
set_source_files_properties(${cryptopp_SOURCES_ASM} PROPERTIES LANGUAGE ASM_MASM)
endif ()
endif ()
#============================================================================
# Architecture flags
#============================================================================
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Intel" OR CMAKE_CXX_COMPILER MATCHES "xlC")
if (CRYPTOPP_AMD64 OR CRYPTOPP_I386)
CheckCompileLinkOption("-msse2" CRYPTOPP_IA32_SSE2
"${TEST_PROG_DIR}/test_x86_sse2.cxx")
CheckCompileLinkOption("-mssse3" CRYPTOPP_IA32_SSSE3
"${TEST_PROG_DIR}/test_x86_ssse3.cxx")
CheckCompileLinkOption("-msse4.1" CRYPTOPP_IA32_SSE41
"${TEST_PROG_DIR}/test_x86_sse41.cxx")
CheckCompileLinkOption("-msse4.2" CRYPTOPP_IA32_SSE42
"${TEST_PROG_DIR}/test_x86_sse42.cxx")
CheckCompileLinkOption("-mssse3 -mpclmul" CRYPTOPP_IA32_CLMUL
"${TEST_PROG_DIR}/test_x86_clmul.cxx")
CheckCompileLinkOption("-msse4.1 -maes" CRYPTOPP_IA32_AES
"${TEST_PROG_DIR}/test_x86_aes.cxx")
CheckCompileLinkOption("-mavx" CRYPTOPP_IA32_AVX
"${TEST_PROG_DIR}/test_x86_avx.cxx")
CheckCompileLinkOption("-mavx2" CRYPTOPP_IA32_AVX2
"${TEST_PROG_DIR}/test_x86_avx2.cxx")
CheckCompileLinkOption("-msse4.2 -msha" CRYPTOPP_IA32_SHA
"${TEST_PROG_DIR}/test_x86_sha.cxx")
if (EXISTS "${TEST_PROG_DIR}/test_asm_mixed.cxx")
CheckCompileLinkOption("" CRYPTOPP_MIXED_ASM
"${TEST_PROG_DIR}/test_asm_mixed.cxx")
else ()
CheckCompileLinkOption("" CRYPTOPP_MIXED_ASM
"${TEST_PROG_DIR}/test_mixed_asm.cxx")
endif ()
if (NOT CRYPTOPP_MIXED_ASM)
list(APPEND CRYPTOPP_COMPILE_OPTIONS "-DCRYPTOPP_DISABLE_MIXED_ASM")
endif ()
if (NOT CRYPTOPP_IA32_SSE2 AND NOT CRYPTOPP_DISABLE_ASM)
list(APPEND CRYPTOPP_COMPILE_OPTIONS "-DCRYPTOPP_DISABLE_ASM")
elseif (CRYPTOPP_IA32_SSE2 AND NOT CRYPTOPP_DISABLE_ASM)
set_source_files_properties(${SRC_DIR}/sse_simd.cpp PROPERTIES COMPILE_FLAGS "-msse2")
endif ()
if (NOT CRYPTOPP_IA32_SSSE3 AND NOT CRYPTOPP_DISABLE_SSSE3)
list(APPEND CRYPTOPP_COMPILE_OPTIONS "-DCRYPTOPP_DISABLE_SSSE3")
elseif (CRYPTOPP_IA32_SSSE3 AND NOT CRYPTOPP_DISABLE_SSSE3)
if (NOT CRYPTOPP_IA32_SSE41 AND NOT CRYPTOPP_DISABLE_SSE4)
list(APPEND CRYPTOPP_COMPILE_OPTIONS "-DCRYPTOPP_DISABLE_SSE4")
endif ()
if (NOT CRYPTOPP_IA32_SSE42 AND NOT CRYPTOPP_DISABLE_SSE4)
list(APPEND CRYPTOPP_COMPILE_OPTIONS "-DCRYPTOPP_DISABLE_SSE4")
elseif (CRYPTOPP_IA32_SSE42 AND NOT CRYPTOPP_DISABLE_SSE4)
set_source_files_properties(${SRC_DIR}/crc_simd.cpp PROPERTIES COMPILE_FLAGS "-msse4.2")
if (NOT CRYPTOPP_IA32_CLMUL AND NOT CRYPTOPP_DISABLE_CLMUL)
list(APPEND CRYPTOPP_COMPILE_OPTIONS "-DCRYPTOPP_DISABLE_CLMUL")
elseif (CRYPTOPP_IA32_CLMUL AND NOT CRYPTOPP_DISABLE_CLMUL)
set_source_files_properties(${SRC_DIR}/gcm_simd.cpp PROPERTIES COMPILE_FLAGS "-mssse3 -mpclmul")
set_source_files_properties(${SRC_DIR}/gf2n_simd.cpp PROPERTIES COMPILE_FLAGS "-mpclmul")
endif ()
if (NOT CRYPTOPP_IA32_AES AND NOT CRYPTOPP_DISABLE_AES)
list(APPEND CRYPTOPP_COMPILE_OPTIONS "-DCRYPTOPP_DISABLE_AESNI")
elseif (CRYPTOPP_IA32_AES AND NOT CRYPTOPP_DISABLE_AES)
set_source_files_properties(${SRC_DIR}/rijndael_simd.cpp PROPERTIES COMPILE_FLAGS "-msse4.1 -maes")
endif ()
if (NOT CRYPTOPP_IA32_AVX2 AND NOT CRYPTOPP_DISABLE_AVX2)
list(APPEND CRYPTOPP_COMPILE_OPTIONS "-DCRYPTOPP_DISABLE_AVX2")
endif ()
if (NOT CRYPTOPP_IA32_SHA AND NOT CRYPTOPP_DISABLE_SHA)
list(APPEND CRYPTOPP_COMPILE_OPTIONS "-DCRYPTOPP_DISABLE_SHANI")
elseif (CRYPTOPP_IA32_SHA AND NOT CRYPTOPP_DISABLE_SHA)
set_source_files_properties(${SRC_DIR}/sha_simd.cpp PROPERTIES COMPILE_FLAGS "-msse4.2 -msha")
endif ()
endif ()
endif ()
endif ()
endif ()
#============================================================================
# Compile targets
#============================================================================
set(cryptopp_LIBRARY_SOURCES ${cryptopp_SOURCES_ASM})
list(APPEND cryptopp_LIBRARY_SOURCES ${cryptopp_SOURCES})
add_library(cryptopp STATIC ${cryptopp_LIBRARY_SOURCES})
target_compile_definitions(cryptopp PUBLIC ${CRYPTOPP_COMPILE_DEFINITIONS})
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
target_include_directories(cryptopp INTERFACE .)
#============================================================================
# Third-party libraries
#============================================================================
find_package(Threads)
target_link_libraries(cryptopp PRIVATE ${CMAKE_THREAD_LIBS_INIT})
if(ANDROID)
include(AndroidNdkModules)
android_ndk_import_module_cpufeatures()
target_link_libraries(cryptopp PRIVATE cpufeatures)
endif()

View File

@@ -96,7 +96,7 @@ android {
externalNativeBuild { externalNativeBuild {
cmake { cmake {
version "3.18.1" version "3.22.1"
path "../../../CMakeLists.txt" path "../../../CMakeLists.txt"
} }
} }

View File

@@ -13,3 +13,4 @@ org.gradle.jvmargs=-Xmx1536m
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true # org.gradle.parallel=true
android.native.buildOutput=verbose

View File

@@ -40,5 +40,7 @@
<string>This app requires camera access to emulate the 3DS's cameras.</string> <string>This app requires camera access to emulate the 3DS's cameras.</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone access to emulate the 3DS's microphone.</string> <string>This app requires microphone access to emulate the 3DS's microphone.</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
</dict> </dict>
</plist> </plist>

View File

@@ -54,6 +54,7 @@
#include "citra_qt/uisettings.h" #include "citra_qt/uisettings.h"
#include "citra_qt/updater/updater.h" #include "citra_qt/updater/updater.h"
#include "citra_qt/util/clickable_label.h" #include "citra_qt/util/clickable_label.h"
#include "common/arch.h"
#include "common/common_paths.h" #include "common/common_paths.h"
#include "common/detached_tasks.h" #include "common/detached_tasks.h"
#include "common/file_util.h" #include "common/file_util.h"
@@ -65,7 +66,7 @@
#include "common/scm_rev.h" #include "common/scm_rev.h"
#include "common/scope_exit.h" #include "common/scope_exit.h"
#include "common/string_util.h" #include "common/string_util.h"
#ifdef ARCHITECTURE_x86_64 #if CITRA_ARCH(x86_64)
#include "common/x64/cpu_detect.h" #include "common/x64/cpu_detect.h"
#endif #endif
#include "common/settings.h" #include "common/settings.h"
@@ -200,7 +201,7 @@ GMainWindow::GMainWindow()
LOG_INFO(Frontend, "Citra Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, LOG_INFO(Frontend, "Citra Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,
Common::g_scm_desc); Common::g_scm_desc);
#ifdef ARCHITECTURE_x86_64 #if CITRA_ARCH(x86_64)
const auto& caps = Common::GetCPUCaps(); const auto& caps = Common::GetCPUCaps();
std::string cpu_string = caps.cpu_string; std::string cpu_string = caps.cpu_string;
if (caps.avx || caps.avx2 || caps.avx512) { if (caps.avx || caps.avx2 || caps.avx512) {
@@ -2288,6 +2289,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
QString status_message; QString status_message;
QString title, message; QString title, message;
QMessageBox::Icon error_severity_icon;
if (result == Core::System::ResultStatus::ErrorSystemFiles) { if (result == Core::System::ResultStatus::ErrorSystemFiles) {
const QString common_message = const QString common_message =
tr("%1 is missing. Please <a " tr("%1 is missing. Please <a "
@@ -2303,9 +2305,11 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
title = tr("System Archive Not Found"); title = tr("System Archive Not Found");
status_message = tr("System Archive Missing"); status_message = tr("System Archive Missing");
error_severity_icon = QMessageBox::Icon::Critical;
} else if (result == Core::System::ResultStatus::ErrorSavestate) { } else if (result == Core::System::ResultStatus::ErrorSavestate) {
title = tr("Save/load Error"); title = tr("Save/load Error");
message = QString::fromStdString(details); message = QString::fromStdString(details);
error_severity_icon = QMessageBox::Icon::Warning;
} else { } else {
title = tr("Fatal Error"); title = tr("Fatal Error");
message = message =
@@ -2314,30 +2318,39 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
"the log</a> for details." "the log</a> for details."
"<br/>Continuing emulation may result in crashes and bugs."); "<br/>Continuing emulation may result in crashes and bugs.");
status_message = tr("Fatal Error encountered"); status_message = tr("Fatal Error encountered");
error_severity_icon = QMessageBox::Icon::Critical;
} }
QMessageBox message_box; QMessageBox message_box;
message_box.setWindowTitle(title); message_box.setWindowTitle(title);
message_box.setText(message); message_box.setText(message);
message_box.setIcon(QMessageBox::Icon::Critical); message_box.setIcon(error_severity_icon);
message_box.addButton(tr("Continue"), QMessageBox::RejectRole); if (error_severity_icon == QMessageBox::Icon::Critical) {
QPushButton* abort_button = message_box.addButton(tr("Abort"), QMessageBox::AcceptRole); message_box.addButton(tr("Continue"), QMessageBox::RejectRole);
if (result != Core::System::ResultStatus::ShutdownRequested) QPushButton* abort_button = message_box.addButton(tr("Quit Game"), QMessageBox::AcceptRole);
message_box.exec(); if (result != Core::System::ResultStatus::ShutdownRequested)
message_box.exec();
if (result == Core::System::ResultStatus::ShutdownRequested || if (result == Core::System::ResultStatus::ShutdownRequested ||
message_box.clickedButton() == abort_button) { message_box.clickedButton() == abort_button) {
if (emu_thread) { if (emu_thread) {
ShutdownGame(); ShutdownGame();
return;
}
} }
} else { } else {
// Only show the message if the game is still running. // This block should run when the error isn't too big of a deal
if (emu_thread) { // e.g. when a save state can't be saved or loaded
emu_thread->SetRunning(true); message_box.addButton(tr("OK"), QMessageBox::RejectRole);
message_label->setText(status_message); message_box.exec();
message_label->setVisible(true); }
message_label_used_for_movie = false;
} // Only show the message if the game is still running.
if (emu_thread) {
emu_thread->SetRunning(true);
message_label->setText(status_message);
message_label->setVisible(true);
message_label_used_for_movie = false;
} }
} }

View File

@@ -54,6 +54,8 @@ add_custom_command(OUTPUT scm_rev.cpp
) )
add_library(common STATIC add_library(common STATIC
aarch64/cpu_detect.cpp
aarch64/cpu_detect.h
alignment.h alignment.h
announce_multiplayer_room.h announce_multiplayer_room.h
archives.h archives.h
@@ -129,34 +131,21 @@ add_library(common STATIC
unique_function.h unique_function.h
vector_math.h vector_math.h
web_result.h web_result.h
x64/cpu_detect.cpp
x64/cpu_detect.h
x64/xbyak_abi.h
x64/xbyak_util.h
zstd_compression.cpp zstd_compression.cpp
zstd_compression.h zstd_compression.h
) )
if(ARCHITECTURE_x86_64)
target_sources(common
PRIVATE
x64/cpu_detect.cpp
x64/cpu_detect.h
x64/xbyak_abi.h
x64/xbyak_util.h
)
elseif(ARCHITECTURE_arm64)
target_sources(common
PRIVATE
aarch64/cpu_detect.cpp
aarch64/cpu_detect.h
)
endif()
create_target_directory_groups(common) create_target_directory_groups(common)
target_link_libraries(common PUBLIC fmt::fmt microprofile Boost::boost Boost::serialization) target_link_libraries(common PUBLIC fmt::fmt microprofile Boost::boost Boost::serialization)
target_link_libraries(common PRIVATE libzstd_static) target_link_libraries(common PRIVATE libzstd_static)
set_target_properties(common PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${ENABLE_LTO}) set_target_properties(common PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${ENABLE_LTO})
if (ARCHITECTURE_x86_64) if ("x86_64" IN_LIST ARCHITECTURE)
target_link_libraries(common PRIVATE xbyak) target_link_libraries(common PRIVATE xbyak)
endif() endif()

View File

@@ -2,6 +2,9 @@
// Licensed under GPLv2+ // Licensed under GPLv2+
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common/arch.h"
#if CITRA_ARCH(arm64)
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
#include <string> #include <string>
@@ -110,3 +113,5 @@ const CPUCaps& GetCPUCaps() {
} }
} // namespace Common } // namespace Common
#endif // CITRA_ARCH(arm64)

View File

@@ -4,6 +4,9 @@
#pragma once #pragma once
#include "common/arch.h"
#if CITRA_ARCH(arm64)
#include <string> #include <string>
namespace Common { namespace Common {
@@ -29,3 +32,5 @@ struct CPUCaps {
const CPUCaps& GetCPUCaps(); const CPUCaps& GetCPUCaps();
} // namespace Common } // namespace Common
#endif // CITRA_ARCH(arm64)

13
src/common/arch.h Normal file
View File

@@ -0,0 +1,13 @@
// Copyright 2023 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <boost/predef.h>
#define CITRA_ARCH(NAME) (CITRA_ARCH_##NAME)
#define CITRA_ARCH_x86_64 BOOST_ARCH_X86_64
#define CITRA_ARCH_arm64 \
(BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER(8, 0, 0) && BOOST_ARCH_WORD_BITS == 64)

View File

@@ -5,8 +5,9 @@
#pragma once #pragma once
#include <string> #include <string>
#include "common/arch.h"
#if !defined(ARCHITECTURE_x86_64) #if !CITRA_ARCH(x86_64)
#include <cstdlib> // for exit #include <cstdlib> // for exit
#endif #endif
#include "common/common_types.h" #include "common/common_types.h"
@@ -36,7 +37,7 @@
#ifndef _MSC_VER #ifndef _MSC_VER
#ifdef ARCHITECTURE_x86_64 #if CITRA_ARCH(x86_64)
#define Crash() __asm__ __volatile__("int $3") #define Crash() __asm__ __volatile__("int $3")
#else #else
#define Crash() exit(1) #define Crash() exit(1)

View File

@@ -4,11 +4,12 @@
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include "common/arch.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/scm_rev.h" #include "common/scm_rev.h"
#include "common/telemetry.h" #include "common/telemetry.h"
#ifdef ARCHITECTURE_x86_64 #if CITRA_ARCH(x86_64)
#include "common/x64/cpu_detect.h" #include "common/x64/cpu_detect.h"
#endif #endif
@@ -54,7 +55,7 @@ void AppendBuildInfo(FieldCollection& fc) {
} }
void AppendCPUInfo(FieldCollection& fc) { void AppendCPUInfo(FieldCollection& fc) {
#ifdef ARCHITECTURE_x86_64 #if CITRA_ARCH(x86_64)
fc.AddField(FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string); fc.AddField(FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string);
fc.AddField(FieldType::UserSystem, "CPU_BrandString", Common::GetCPUCaps().brand_string); fc.AddField(FieldType::UserSystem, "CPU_BrandString", Common::GetCPUCaps().brand_string);
fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AES", Common::GetCPUCaps().aes); fc.AddField(FieldType::UserSystem, "CPU_Extension_x64_AES", Common::GetCPUCaps().aes);

View File

@@ -2,6 +2,9 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common/arch.h"
#if CITRA_ARCH(x86_64)
#include <cstring> #include <cstring>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/x64/cpu_detect.h" #include "common/x64/cpu_detect.h"
@@ -144,3 +147,5 @@ const CPUCaps& GetCPUCaps() {
} }
} // namespace Common } // namespace Common
#endif // CITRA_ARCH(x86_64)

View File

@@ -4,6 +4,9 @@
#pragma once #pragma once
#include "common/arch.h"
#if CITRA_ARCH(x86_64)
namespace Common { namespace Common {
/// x86/x64 CPU capabilities that may be detected by this module /// x86/x64 CPU capabilities that may be detected by this module
@@ -33,3 +36,5 @@ struct CPUCaps {
const CPUCaps& GetCPUCaps(); const CPUCaps& GetCPUCaps();
} // namespace Common } // namespace Common
#endif // CITRA_ARCH(x86_64)

View File

@@ -4,6 +4,9 @@
#pragma once #pragma once
#include "common/arch.h"
#if CITRA_ARCH(x86_64)
#include <bitset> #include <bitset>
#include <initializer_list> #include <initializer_list>
#include <xbyak/xbyak.h> #include <xbyak/xbyak.h>
@@ -228,3 +231,5 @@ inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bits
} }
} // namespace Common::X64 } // namespace Common::X64
#endif // CITRA_ARCH(x86_64)

View File

@@ -4,6 +4,9 @@
#pragma once #pragma once
#include "common/arch.h"
#if CITRA_ARCH(x86_64)
#include <type_traits> #include <type_traits>
#include <xbyak/xbyak.h> #include <xbyak/xbyak.h>
#include "common/x64/xbyak_abi.h" #include "common/x64/xbyak_abi.h"
@@ -45,3 +48,5 @@ inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) {
} }
} // namespace Common::X64 } // namespace Common::X64
#endif // CITRA_ARCH(x86_64)

View File

@@ -486,7 +486,7 @@ if (ENABLE_WEB_SERVICE)
endif() endif()
endif() endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE)
target_sources(core PRIVATE target_sources(core PRIVATE
arm/dynarmic/arm_dynarmic.cpp arm/dynarmic/arm_dynarmic.cpp
arm/dynarmic/arm_dynarmic.h arm/dynarmic/arm_dynarmic.h

View File

@@ -1,7 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) #include "common/arch.h"
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
#include "core/arm/dynarmic/arm_exclusive_monitor.h" #include "core/arm/dynarmic/arm_exclusive_monitor.h"
#endif #endif
#include "common/settings.h" #include "common/settings.h"
@@ -14,7 +15,7 @@ ExclusiveMonitor::~ExclusiveMonitor() = default;
std::unique_ptr<Core::ExclusiveMonitor> MakeExclusiveMonitor(Memory::MemorySystem& memory, std::unique_ptr<Core::ExclusiveMonitor> MakeExclusiveMonitor(Memory::MemorySystem& memory,
std::size_t num_cores) { std::size_t num_cores) {
#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) #if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
if (Settings::values.use_cpu_jit) { if (Settings::values.use_cpu_jit) {
return std::make_unique<Core::DynarmicExclusiveMonitor>(memory, num_cores); return std::make_unique<Core::DynarmicExclusiveMonitor>(memory, num_cores);
} }

View File

@@ -10,11 +10,12 @@
#include "audio_core/dsp_interface.h" #include "audio_core/dsp_interface.h"
#include "audio_core/hle/hle.h" #include "audio_core/hle/hle.h"
#include "audio_core/lle/lle.h" #include "audio_core/lle/lle.h"
#include "common/arch.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/texture.h" #include "common/texture.h"
#include "core/arm/arm_interface.h" #include "core/arm/arm_interface.h"
#include "core/arm/exclusive_monitor.h" #include "core/arm/exclusive_monitor.h"
#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) #if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
#include "core/arm/dynarmic/arm_dynarmic.h" #include "core/arm/dynarmic/arm_dynarmic.h"
#endif #endif
#include "core/arm/dyncom/arm_dyncom.h" #include "core/arm/dyncom/arm_dyncom.h"
@@ -372,7 +373,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
exclusive_monitor = MakeExclusiveMonitor(*memory, num_cores); exclusive_monitor = MakeExclusiveMonitor(*memory, num_cores);
if (Settings::values.use_cpu_jit) { if (Settings::values.use_cpu_jit) {
#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) #if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
for (u32 i = 0; i < num_cores; ++i) { for (u32 i = 0; i < num_cores; ++i) {
cpu_cores.push_back(std::make_shared<ARM_Dynarmic>( cpu_cores.push_back(std::make_shared<ARM_Dynarmic>(
this, *memory, i, timing->GetTimer(i), *exclusive_monitor)); this, *memory, i, timing->GetTimer(i), *exclusive_monitor));

View File

@@ -224,6 +224,10 @@ public:
/// Retrieves a process from the current list of processes. /// Retrieves a process from the current list of processes.
std::shared_ptr<Process> GetProcessById(u32 process_id) const; std::shared_ptr<Process> GetProcessById(u32 process_id) const;
const std::vector<std::shared_ptr<Process>>& GetProcessList() const {
return process_list;
}
std::shared_ptr<Process> GetCurrentProcess() const; std::shared_ptr<Process> GetCurrentProcess() const;
void SetCurrentProcess(std::shared_ptr<Process> process); void SetCurrentProcess(std::shared_ptr<Process> process);
void SetCurrentProcessForCPU(std::shared_ptr<Process> process, u32 core_id); void SetCurrentProcessForCPU(std::shared_ptr<Process> process, u32 core_id);

View File

@@ -44,6 +44,7 @@ void Process::serialize(Archive& ar, const unsigned int file_version) {
ar& ideal_processor; ar& ideal_processor;
ar& status; ar& status;
ar& process_id; ar& process_id;
ar& creation_time_ticks;
ar& vm_manager; ar& vm_manager;
ar& memory_used; ar& memory_used;
ar& memory_region; ar& memory_region;
@@ -72,6 +73,7 @@ std::shared_ptr<Process> KernelSystem::CreateProcess(std::shared_ptr<CodeSet> co
process->flags.memory_region.Assign(MemoryRegion::APPLICATION); process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
process->status = ProcessStatus::Created; process->status = ProcessStatus::Created;
process->process_id = ++next_process_id; process->process_id = ++next_process_id;
process->creation_time_ticks = timing.GetTicks();
process_list.push_back(process); process_list.push_back(process);
return process; return process;

View File

@@ -185,6 +185,9 @@ public:
/// The id of this process /// The id of this process
u32 process_id; u32 process_id;
// Creation time in ticks of the process.
u64 creation_time_ticks;
/** /**
* Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
* to this process. * to this process.

View File

@@ -80,6 +80,22 @@ struct PageInfo {
u32 flags; u32 flags;
}; };
// Values accepted by svcGetHandleInfo.
enum class HandleInfoType {
/**
* Returns the time in ticks the KProcess referenced by the handle was created.
*/
KPROCESS_ELAPSED_TICKS = 0,
/**
* Get internal refcount for kernel object.
*/
REFERENCE_COUNT = 1,
STUBBED_1 = 2,
STUBBED_2 = 0x32107,
};
/// Values accepted by svcGetSystemInfo's type parameter. /// Values accepted by svcGetSystemInfo's type parameter.
enum class SystemInfoType { enum class SystemInfoType {
/** /**
@@ -358,6 +374,8 @@ private:
ResultCode UnmapMemoryBlock(Handle handle, u32 addr); ResultCode UnmapMemoryBlock(Handle handle, u32 addr);
ResultCode ConnectToPort(Handle* out_handle, VAddr port_name_address); ResultCode ConnectToPort(Handle* out_handle, VAddr port_name_address);
ResultCode SendSyncRequest(Handle handle); ResultCode SendSyncRequest(Handle handle);
ResultCode OpenProcess(Handle* out_handle, u32 process_id);
ResultCode OpenThread(Handle* out_handle, Handle process_handle, u32 thread_id);
ResultCode CloseHandle(Handle handle); ResultCode CloseHandle(Handle handle);
ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds); ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds);
ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle_count, ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle_count,
@@ -399,6 +417,7 @@ private:
ResultCode CancelTimer(Handle handle); ResultCode CancelTimer(Handle handle);
void SleepThread(s64 nanoseconds); void SleepThread(s64 nanoseconds);
s64 GetSystemTick(); s64 GetSystemTick();
ResultCode GetHandleInfo(s64* out, Handle handle, u32 type);
ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission, ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission,
u32 other_permission); u32 other_permission);
ResultCode CreatePort(Handle* server_port, Handle* client_port, VAddr name_address, ResultCode CreatePort(Handle* server_port, Handle* client_port, VAddr name_address,
@@ -409,6 +428,8 @@ private:
ResultCode GetSystemInfo(s64* out, u32 type, s32 param); ResultCode GetSystemInfo(s64* out, u32 type, s32 param);
ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type); ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type);
ResultCode GetThreadInfo(s64* out, Handle thread_handle, u32 type); ResultCode GetThreadInfo(s64* out, Handle thread_handle, u32 type);
ResultCode GetProcessList(s32* process_count, VAddr out_process_array,
s32 out_process_array_count);
ResultCode InvalidateInstructionCacheRange(u32 addr, u32 size); ResultCode InvalidateInstructionCacheRange(u32 addr, u32 size);
ResultCode InvalidateEntireInstructionCache(); ResultCode InvalidateEntireInstructionCache();
u32 ConvertVaToPa(u32 addr); u32 ConvertVaToPa(u32 addr);
@@ -594,14 +615,16 @@ ResultCode SVC::UnmapMemoryBlock(Handle handle, u32 addr) {
/// Connect to an OS service given the port name, returns the handle to the port to out /// Connect to an OS service given the port name, returns the handle to the port to out
ResultCode SVC::ConnectToPort(Handle* out_handle, VAddr port_name_address) { ResultCode SVC::ConnectToPort(Handle* out_handle, VAddr port_name_address) {
if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), port_name_address)) if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), port_name_address)) {
return ERR_NOT_FOUND; return ERR_NOT_FOUND;
}
static constexpr std::size_t PortNameMaxLength = 11; static constexpr std::size_t PortNameMaxLength = 11;
// Read 1 char beyond the max allowed port name to detect names that are too long. // Read 1 char beyond the max allowed port name to detect names that are too long.
std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1); std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1);
if (port_name.size() > PortNameMaxLength) if (port_name.size() > PortNameMaxLength) {
return ERR_PORT_NAME_TOO_LONG; return ERR_PORT_NAME_TOO_LONG;
}
LOG_TRACE(Kernel_SVC, "called port_name={}", port_name); LOG_TRACE(Kernel_SVC, "called port_name={}", port_name);
@@ -642,6 +665,50 @@ ResultCode SVC::SendSyncRequest(Handle handle) {
return session->SendSyncRequest(thread); return session->SendSyncRequest(thread);
} }
ResultCode SVC::OpenProcess(Handle* out_handle, u32 process_id) {
std::shared_ptr<Process> process = kernel.GetProcessById(process_id);
if (!process) {
// Result 0xd9001818 (process not found?)
return ResultCode(24, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent);
}
auto result_handle = kernel.GetCurrentProcess()->handle_table.Create(process);
if (result_handle.empty()) {
return result_handle.Code();
}
*out_handle = result_handle.Unwrap();
return RESULT_SUCCESS;
}
ResultCode SVC::OpenThread(Handle* out_handle, Handle process_handle, u32 thread_id) {
if (process_handle == 0) {
LOG_ERROR(Kernel_SVC, "Uninplemented svcOpenThread process_handle=0");
// Result 0xd9001819 (thread not found?)
return ResultCode(25, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent);
}
std::shared_ptr<Process> process =
kernel.GetCurrentProcess()->handle_table.Get<Process>(process_handle);
if (!process) {
return ERR_INVALID_HANDLE;
}
for (u32 core_id = 0; core_id < system.GetNumCores(); core_id++) {
auto& thread_list = kernel.GetThreadManager(core_id).GetThreadList();
for (auto& thread : thread_list) {
if (thread->owner_process.lock() == process && thread.get()->thread_id == thread_id) {
auto result_handle = kernel.GetCurrentProcess()->handle_table.Create(thread);
if (result_handle.empty()) {
return result_handle.Code();
}
*out_handle = result_handle.Unwrap();
return RESULT_SUCCESS;
}
}
}
// Result 0xd9001819 (thread not found?)
return ResultCode(25, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent);
}
/// Close a handle /// Close a handle
ResultCode SVC::CloseHandle(Handle handle) { ResultCode SVC::CloseHandle(Handle handle) {
LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
@@ -761,16 +828,18 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle
bool wait_all, s64 nano_seconds) { bool wait_all, s64 nano_seconds) {
Thread* thread = kernel.GetCurrentThreadManager().GetCurrentThread(); Thread* thread = kernel.GetCurrentThreadManager().GetCurrentThread();
if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address)) if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address)) {
return ERR_INVALID_POINTER; return ERR_INVALID_POINTER;
}
// NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If // NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If
// this happens, the running application will crash. // this happens, the running application will crash.
ASSERT_MSG(out != nullptr, "invalid output pointer specified!"); ASSERT_MSG(out != nullptr, "invalid output pointer specified!");
// Check if 'handle_count' is invalid // Check if 'handle_count' is invalid
if (handle_count < 0) if (handle_count < 0) {
return ERR_OUT_OF_RANGE; return ERR_OUT_OF_RANGE;
}
using ObjectPtr = std::shared_ptr<WaitObject>; using ObjectPtr = std::shared_ptr<WaitObject>;
std::vector<ObjectPtr> objects(handle_count); std::vector<ObjectPtr> objects(handle_count);
@@ -907,12 +976,14 @@ static ResultCode ReceiveIPCRequest(Kernel::KernelSystem& kernel, Memory::Memory
/// In a single operation, sends a IPC reply and waits for a new request. /// In a single operation, sends a IPC reply and waits for a new request.
ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_count, ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_count,
Handle reply_target) { Handle reply_target) {
if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address)) if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), handles_address)) {
return ERR_INVALID_POINTER; return ERR_INVALID_POINTER;
}
// Check if 'handle_count' is invalid // Check if 'handle_count' is invalid
if (handle_count < 0) if (handle_count < 0) {
return ERR_OUT_OF_RANGE; return ERR_OUT_OF_RANGE;
}
using ObjectPtr = std::shared_ptr<WaitObject>; using ObjectPtr = std::shared_ptr<WaitObject>;
std::vector<ObjectPtr> objects(handle_count); std::vector<ObjectPtr> objects(handle_count);
@@ -1522,6 +1593,40 @@ s64 SVC::GetSystemTick() {
return result; return result;
} }
// Returns information of the specified handle
ResultCode SVC::GetHandleInfo(s64* out, Handle handle, u32 type) {
std::shared_ptr<Object> KObject = kernel.GetCurrentProcess()->handle_table.GetGeneric(handle);
if (!KObject) {
return ERR_INVALID_HANDLE;
}
// Not initialized in real kernel, but we don't want to leak memory.
s64 value = 0;
std::shared_ptr<Process> process;
switch (static_cast<HandleInfoType>(type)) {
case HandleInfoType::KPROCESS_ELAPSED_TICKS:
process = DynamicObjectCast<Process>(KObject);
if (process) {
value = process->creation_time_ticks;
}
break;
case HandleInfoType::REFERENCE_COUNT:
// This is the closest approximation we can get without a full KObject impl.
value = KObject.use_count() - 1;
break;
// These values are stubbed in real kernel, they do nothing.
case HandleInfoType::STUBBED_1:
case HandleInfoType::STUBBED_2:
break;
default:
return ERR_INVALID_ENUM_VALUE;
}
*out = value;
return RESULT_SUCCESS;
}
/// Creates a memory block at the specified address with the specified permissions and size /// Creates a memory block at the specified address with the specified permissions and size
ResultCode SVC::CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission, ResultCode SVC::CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission,
u32 other_permission) { u32 other_permission) {
@@ -1833,6 +1938,25 @@ ResultCode SVC::GetThreadInfo(s64* out, Handle thread_handle, u32 type) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
ResultCode SVC::GetProcessList(s32* process_count, VAddr out_process_array,
s32 out_process_array_count) {
if (!memory.IsValidVirtualAddress(*kernel.GetCurrentProcess(), out_process_array)) {
return ERR_INVALID_POINTER;
}
s32 written = 0;
for (const auto process : kernel.GetProcessList()) {
if (written >= out_process_array_count) {
break;
}
if (process) {
memory.Write32(out_process_array + written++ * sizeof(u32), process->process_id);
}
}
*process_count = written;
return RESULT_SUCCESS;
}
ResultCode SVC::InvalidateInstructionCacheRange(u32 addr, u32 size) { ResultCode SVC::InvalidateInstructionCacheRange(u32 addr, u32 size) {
Core::GetRunningCore().InvalidateCacheRange(addr, size); Core::GetRunningCore().InvalidateCacheRange(addr, size);
return RESULT_SUCCESS; return RESULT_SUCCESS;
@@ -1952,8 +2076,8 @@ ResultCode SVC::ControlProcess(Handle process_handle, u32 process_OP, u32 varg2,
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
case ControlProcessOP::PROCESSOP_SCHEDULE_THREADS_WITHOUT_TLS_MAGIC: { case ControlProcessOP::PROCESSOP_SCHEDULE_THREADS_WITHOUT_TLS_MAGIC: {
for (u32 i = 0; i < system.GetNumCores(); i++) { for (u32 core_id = 0; core_id < system.GetNumCores(); core_id++) {
auto& thread_list = kernel.GetThreadManager(i).GetThreadList(); auto& thread_list = kernel.GetThreadManager(core_id).GetThreadList();
for (auto& thread : thread_list) { for (auto& thread : thread_list) {
if (thread->owner_process.lock() != process) { if (thread->owner_process.lock() != process) {
continue; continue;
@@ -2026,7 +2150,7 @@ const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
{0x26, nullptr, "SignalAndWait"}, {0x26, nullptr, "SignalAndWait"},
{0x27, &SVC::Wrap<&SVC::DuplicateHandle>, "DuplicateHandle"}, {0x27, &SVC::Wrap<&SVC::DuplicateHandle>, "DuplicateHandle"},
{0x28, &SVC::Wrap<&SVC::GetSystemTick>, "GetSystemTick"}, {0x28, &SVC::Wrap<&SVC::GetSystemTick>, "GetSystemTick"},
{0x29, nullptr, "GetHandleInfo"}, {0x29, &SVC::Wrap<&SVC::GetHandleInfo>, "GetHandleInfo"},
{0x2A, &SVC::Wrap<&SVC::GetSystemInfo>, "GetSystemInfo"}, {0x2A, &SVC::Wrap<&SVC::GetSystemInfo>, "GetSystemInfo"},
{0x2B, &SVC::Wrap<&SVC::GetProcessInfo>, "GetProcessInfo"}, {0x2B, &SVC::Wrap<&SVC::GetProcessInfo>, "GetProcessInfo"},
{0x2C, &SVC::Wrap<&SVC::GetThreadInfo>, "GetThreadInfo"}, {0x2C, &SVC::Wrap<&SVC::GetThreadInfo>, "GetThreadInfo"},
@@ -2036,8 +2160,8 @@ const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
{0x30, nullptr, "SendSyncRequest3"}, {0x30, nullptr, "SendSyncRequest3"},
{0x31, nullptr, "SendSyncRequest4"}, {0x31, nullptr, "SendSyncRequest4"},
{0x32, &SVC::Wrap<&SVC::SendSyncRequest>, "SendSyncRequest"}, {0x32, &SVC::Wrap<&SVC::SendSyncRequest>, "SendSyncRequest"},
{0x33, nullptr, "OpenProcess"}, {0x33, &SVC::Wrap<&SVC::OpenProcess>, "OpenProcess"},
{0x34, nullptr, "OpenThread"}, {0x34, &SVC::Wrap<&SVC::OpenThread>, "OpenThread"},
{0x35, &SVC::Wrap<&SVC::GetProcessId>, "GetProcessId"}, {0x35, &SVC::Wrap<&SVC::GetProcessId>, "GetProcessId"},
{0x36, &SVC::Wrap<&SVC::GetProcessIdOfThread>, "GetProcessIdOfThread"}, {0x36, &SVC::Wrap<&SVC::GetProcessIdOfThread>, "GetProcessIdOfThread"},
{0x37, &SVC::Wrap<&SVC::GetThreadId>, "GetThreadId"}, {0x37, &SVC::Wrap<&SVC::GetThreadId>, "GetThreadId"},
@@ -2086,7 +2210,7 @@ const std::array<SVC::FunctionDef, 180> SVC::SVC_Table{{
{0x62, nullptr, "TerminateDebugProcess"}, {0x62, nullptr, "TerminateDebugProcess"},
{0x63, nullptr, "GetProcessDebugEvent"}, {0x63, nullptr, "GetProcessDebugEvent"},
{0x64, nullptr, "ContinueDebugEvent"}, {0x64, nullptr, "ContinueDebugEvent"},
{0x65, nullptr, "GetProcessList"}, {0x65, &SVC::Wrap<&SVC::GetProcessList>, "GetProcessList"},
{0x66, nullptr, "GetThreadList"}, {0x66, nullptr, "GetThreadList"},
{0x67, nullptr, "GetDebugThreadContext"}, {0x67, nullptr, "GetDebugThreadContext"},
{0x68, nullptr, "SetDebugThreadContext"}, {0x68, nullptr, "SetDebugThreadContext"},

View File

@@ -12,15 +12,9 @@ add_executable(tests
precompiled_headers.h precompiled_headers.h
audio_core/audio_fixures.h audio_core/audio_fixures.h
audio_core/decoder_tests.cpp audio_core/decoder_tests.cpp
video_core/shader/shader_jit_x64_compiler.cpp
) )
if (ARCHITECTURE_x86_64)
target_sources(tests
PRIVATE
video_core/shader/shader_jit_x64_compiler.cpp
)
endif()
create_target_directory_groups(tests) create_target_directory_groups(tests)
target_link_libraries(tests PRIVATE common core video_core audio_core) target_link_libraries(tests PRIVATE common core video_core audio_core)

View File

@@ -2,6 +2,9 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common/arch.h"
#if CITRA_ARCH(x86_64)
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <memory> #include <memory>
@@ -158,3 +161,5 @@ TEST_CASE("Nested Loop", "[video_core][shader][shader_jit]") {
REQUIRE(shader_unit_jit.registers.output[0].x.ToFloat32() == Catch::Approx(expected_out)); REQUIRE(shader_unit_jit.registers.output[0].x.ToFloat32() == Catch::Approx(expected_out));
} }
} }
#endif // CITRA_ARCH(x86_64)

View File

@@ -129,6 +129,10 @@ add_library(video_core STATIC
shader/shader_cache.h shader/shader_cache.h
shader/shader_interpreter.cpp shader/shader_interpreter.cpp
shader/shader_interpreter.h shader/shader_interpreter.h
shader/shader_jit_x64.cpp
shader/shader_jit_x64_compiler.cpp
shader/shader_jit_x64.h
shader/shader_jit_x64_compiler.h
shader/shader_uniforms.cpp shader/shader_uniforms.cpp
shader/shader_uniforms.h shader/shader_uniforms.h
swrasterizer/clipper.cpp swrasterizer/clipper.cpp
@@ -158,17 +162,6 @@ add_library(video_core STATIC
target_include_directories(video_core PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(video_core PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
if(ARCHITECTURE_x86_64)
target_sources(video_core
PRIVATE
shader/shader_jit_x64.cpp
shader/shader_jit_x64_compiler.cpp
shader/shader_jit_x64.h
shader/shader_jit_x64_compiler.h
)
endif()
create_target_directory_groups(video_core) create_target_directory_groups(video_core)
# Ignore nullability warnings generated from VMA # Ignore nullability warnings generated from VMA
@@ -184,7 +177,7 @@ target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE})
target_link_libraries(video_core PRIVATE vulkan-headers vma sirit SPIRV glslang glad) target_link_libraries(video_core PRIVATE vulkan-headers vma sirit SPIRV glslang glad)
target_link_libraries(video_core PRIVATE nihstro-headers Boost::serialization glm::glm) target_link_libraries(video_core PRIVATE nihstro-headers Boost::serialization glm::glm)
if (ARCHITECTURE_x86_64) if ("x86_64" IN_LIST ARCHITECTURE)
target_link_libraries(video_core PUBLIC xbyak) target_link_libraries(video_core PUBLIC xbyak)
endif() endif()

View File

@@ -4,6 +4,7 @@
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
#include "common/arch.h"
#include "common/bit_set.h" #include "common/bit_set.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/microprofile.h" #include "common/microprofile.h"
@@ -12,9 +13,9 @@
#include "video_core/regs_shader.h" #include "video_core/regs_shader.h"
#include "video_core/shader/shader.h" #include "video_core/shader/shader.h"
#include "video_core/shader/shader_interpreter.h" #include "video_core/shader/shader_interpreter.h"
#ifdef ARCHITECTURE_x86_64 #if CITRA_ARCH(x86_64)
#include "video_core/shader/shader_jit_x64.h" #include "video_core/shader/shader_jit_x64.h"
#endif // ARCHITECTURE_x86_64 #endif // CITRA_ARCH(x86_64)
#include "video_core/video_core.h" #include "video_core/video_core.h"
namespace Pica::Shader { namespace Pica::Shader {
@@ -134,13 +135,13 @@ void GSUnitState::ConfigOutput(const ShaderRegs& config) {
MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240)); MICROPROFILE_DEFINE(GPU_Shader, "GPU", "Shader", MP_RGB(50, 50, 240));
#ifdef ARCHITECTURE_x86_64 #if CITRA_ARCH(x86_64)
static std::unique_ptr<JitX64Engine> jit_engine; static std::unique_ptr<JitX64Engine> jit_engine;
#endif // ARCHITECTURE_x86_64 #endif // CITRA_ARCH(x86_64)
static InterpreterEngine interpreter_engine; static InterpreterEngine interpreter_engine;
ShaderEngine* GetEngine() { ShaderEngine* GetEngine() {
#ifdef ARCHITECTURE_x86_64 #if CITRA_ARCH(x86_64)
// TODO(yuriks): Re-initialize on each change rather than being persistent // TODO(yuriks): Re-initialize on each change rather than being persistent
if (VideoCore::g_shader_jit_enabled) { if (VideoCore::g_shader_jit_enabled) {
if (jit_engine == nullptr) { if (jit_engine == nullptr) {
@@ -148,15 +149,15 @@ ShaderEngine* GetEngine() {
} }
return jit_engine.get(); return jit_engine.get();
} }
#endif // ARCHITECTURE_x86_64 #endif // CITRA_ARCH(x86_64)
return &interpreter_engine; return &interpreter_engine;
} }
void Shutdown() { void Shutdown() {
#ifdef ARCHITECTURE_x86_64 #if CITRA_ARCH(x86_64)
jit_engine = nullptr; jit_engine = nullptr;
#endif // ARCHITECTURE_x86_64 #endif // CITRA_ARCH(x86_64)
} }
} // namespace Pica::Shader } // namespace Pica::Shader

View File

@@ -2,6 +2,9 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common/arch.h"
#if CITRA_ARCH(x86_64)
#include "common/microprofile.h" #include "common/microprofile.h"
#include "video_core/shader/shader.h" #include "video_core/shader/shader.h"
#include "video_core/shader/shader_jit_x64.h" #include "video_core/shader/shader_jit_x64.h"
@@ -43,3 +46,5 @@ void JitX64Engine::Run(const ShaderSetup& setup, UnitState& state) const {
} }
} // namespace Pica::Shader } // namespace Pica::Shader
#endif // CITRA_ARCH(x86_64)

View File

@@ -4,6 +4,9 @@
#pragma once #pragma once
#include "common/arch.h"
#if CITRA_ARCH(x86_64)
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include "common/common_types.h" #include "common/common_types.h"
@@ -26,3 +29,5 @@ private:
}; };
} // namespace Pica::Shader } // namespace Pica::Shader
#endif // CITRA_ARCH(x86_64)

View File

@@ -2,6 +2,9 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common/arch.h"
#if CITRA_ARCH(x86_64)
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <cstdint> #include <cstdint>
@@ -1131,3 +1134,5 @@ Xbyak::Label JitShader::CompilePrelude_Exp2() {
} }
} // namespace Pica::Shader } // namespace Pica::Shader
#endif // CITRA_ARCH(x86_64)

View File

@@ -4,6 +4,9 @@
#pragma once #pragma once
#include "common/arch.h"
#if CITRA_ARCH(x86_64)
#include <array> #include <array>
#include <bitset> #include <bitset>
#include <cstddef> #include <cstddef>
@@ -138,3 +141,5 @@ private:
}; };
} // namespace Pica::Shader } // namespace Pica::Shader
#endif