diff options
47 files changed, 1441 insertions, 713 deletions
diff --git a/.ci/scripts/common/post-upload.sh b/.ci/scripts/common/post-upload.sh index bb4e9d328..b80868635 100644 --- a/.ci/scripts/common/post-upload.sh +++ b/.ci/scripts/common/post-upload.sh | |||
| @@ -1,12 +1,12 @@ | |||
| 1 | #!/bin/bash -ex | 1 | #!/bin/bash -ex |
| 2 | 2 | ||
| 3 | # Copy documentation | 3 | # Copy documentation |
| 4 | cp license.txt "$REV_NAME" | 4 | cp license.txt "$DIR_NAME" |
| 5 | cp README.md "$REV_NAME" | 5 | cp README.md "$DIR_NAME" |
| 6 | 6 | ||
| 7 | tar $COMPRESSION_FLAGS "$ARCHIVE_NAME" "$REV_NAME" | 7 | tar $COMPRESSION_FLAGS "$ARCHIVE_NAME" "$DIR_NAME" |
| 8 | 8 | ||
| 9 | mv "$REV_NAME" $RELEASE_NAME | 9 | mv "$DIR_NAME" $RELEASE_NAME |
| 10 | 10 | ||
| 11 | 7z a "$REV_NAME.7z" $RELEASE_NAME | 11 | 7z a "$REV_NAME.7z" $RELEASE_NAME |
| 12 | 12 | ||
diff --git a/.ci/scripts/linux/docker.sh b/.ci/scripts/linux/docker.sh index 090ca75f1..5559a527c 100644 --- a/.ci/scripts/linux/docker.sh +++ b/.ci/scripts/linux/docker.sh | |||
| @@ -11,5 +11,4 @@ ninja | |||
| 11 | 11 | ||
| 12 | ccache -s | 12 | ccache -s |
| 13 | 13 | ||
| 14 | # Ignore zlib's tests, since they aren't gated behind a CMake option. | 14 | ctest -VV -C Release |
| 15 | ctest -VV -E "(example|example64)" -C Release | ||
diff --git a/.ci/scripts/linux/upload.sh b/.ci/scripts/linux/upload.sh index 0d131d1dd..ecd77e267 100644 --- a/.ci/scripts/linux/upload.sh +++ b/.ci/scripts/linux/upload.sh | |||
| @@ -6,9 +6,15 @@ REV_NAME="yuzu-linux-${GITDATE}-${GITREV}" | |||
| 6 | ARCHIVE_NAME="${REV_NAME}.tar.xz" | 6 | ARCHIVE_NAME="${REV_NAME}.tar.xz" |
| 7 | COMPRESSION_FLAGS="-cJvf" | 7 | COMPRESSION_FLAGS="-cJvf" |
| 8 | 8 | ||
| 9 | mkdir "$REV_NAME" | 9 | if [ "${RELEASE_NAME}" = "mainline" ]; then |
| 10 | DIR_NAME="${REV_NAME}_${RELEASE_NAME}" | ||
| 11 | else | ||
| 12 | DIR_NAME="${REV_NAME}" | ||
| 13 | fi | ||
| 10 | 14 | ||
| 11 | cp build/bin/yuzu-cmd "$REV_NAME" | 15 | mkdir "$DIR_NAME" |
| 12 | cp build/bin/yuzu "$REV_NAME" | 16 | |
| 17 | cp build/bin/yuzu-cmd "$DIR_NAME" | ||
| 18 | cp build/bin/yuzu "$DIR_NAME" | ||
| 13 | 19 | ||
| 14 | . .ci/scripts/common/post-upload.sh | 20 | . .ci/scripts/common/post-upload.sh |
diff --git a/.ci/scripts/windows/upload.ps1 b/.ci/scripts/windows/upload.ps1 index 3cb709924..9fb99eaa3 100644 --- a/.ci/scripts/windows/upload.ps1 +++ b/.ci/scripts/windows/upload.ps1 | |||
| @@ -1,6 +1,13 @@ | |||
| 1 | param($BUILD_NAME) | ||
| 2 | |||
| 1 | $GITDATE = $(git show -s --date=short --format='%ad') -replace "-","" | 3 | $GITDATE = $(git show -s --date=short --format='%ad') -replace "-","" |
| 2 | $GITREV = $(git show -s --format='%h') | 4 | $GITREV = $(git show -s --format='%h') |
| 3 | $RELEASE_DIST = "yuzu-windows-msvc" | 5 | |
| 6 | if ("$BUILD_NAME" -eq "mainline") { | ||
| 7 | $RELEASE_DIST = "yuzu-windows-msvc-$BUILD_NAME" | ||
| 8 | } else { | ||
| 9 | $RELEASE_DIST = "yuzu-windows-msvc" | ||
| 10 | } | ||
| 4 | 11 | ||
| 5 | $MSVC_BUILD_ZIP = "yuzu-windows-msvc-$GITDATE-$GITREV.zip" -replace " ", "" | 12 | $MSVC_BUILD_ZIP = "yuzu-windows-msvc-$GITDATE-$GITREV.zip" -replace " ", "" |
| 6 | $MSVC_BUILD_PDB = "yuzu-windows-msvc-$GITDATE-$GITREV-debugsymbols.zip" -replace " ", "" | 13 | $MSVC_BUILD_PDB = "yuzu-windows-msvc-$GITDATE-$GITREV-debugsymbols.zip" -replace " ", "" |
diff --git a/.ci/scripts/windows/upload.sh b/.ci/scripts/windows/upload.sh index de73d3541..41d87159f 100644 --- a/.ci/scripts/windows/upload.sh +++ b/.ci/scripts/windows/upload.sh | |||
| @@ -6,8 +6,14 @@ REV_NAME="yuzu-windows-mingw-${GITDATE}-${GITREV}" | |||
| 6 | ARCHIVE_NAME="${REV_NAME}.tar.gz" | 6 | ARCHIVE_NAME="${REV_NAME}.tar.gz" |
| 7 | COMPRESSION_FLAGS="-czvf" | 7 | COMPRESSION_FLAGS="-czvf" |
| 8 | 8 | ||
| 9 | mkdir "$REV_NAME" | 9 | if [ "${RELEASE_NAME}" = "mainline" ]; then |
| 10 | DIR_NAME="${REV_NAME}_${RELEASE_NAME}" | ||
| 11 | else | ||
| 12 | DIR_NAME="${REV_NAME}" | ||
| 13 | fi | ||
| 14 | |||
| 15 | mkdir "$DIR_NAME" | ||
| 10 | # get around the permission issues | 16 | # get around the permission issues |
| 11 | cp -r package/* "$REV_NAME" | 17 | cp -r package/* "$DIR_NAME" |
| 12 | 18 | ||
| 13 | . .ci/scripts/common/post-upload.sh | 19 | . .ci/scripts/common/post-upload.sh |
diff --git a/.ci/templates/build-msvc.yml b/.ci/templates/build-msvc.yml index b44a08247..52cebaee0 100644 --- a/.ci/templates/build-msvc.yml +++ b/.ci/templates/build-msvc.yml | |||
| @@ -17,6 +17,7 @@ steps: | |||
| 17 | inputs: | 17 | inputs: |
| 18 | targetType: 'filePath' | 18 | targetType: 'filePath' |
| 19 | filePath: './.ci/scripts/windows/upload.ps1' | 19 | filePath: './.ci/scripts/windows/upload.ps1' |
| 20 | arguments: '$(BuildName)' | ||
| 20 | - publish: artifacts | 21 | - publish: artifacts |
| 21 | artifact: 'yuzu-$(BuildName)-windows-msvc' | 22 | artifact: 'yuzu-$(BuildName)-windows-msvc' |
| 22 | displayName: 'Upload Artifacts' | 23 | displayName: 'Upload Artifacts' |
diff --git a/.gitmodules b/.gitmodules index ee0dc6c19..63bf2cda0 100644 --- a/.gitmodules +++ b/.gitmodules | |||
| @@ -47,8 +47,8 @@ | |||
| 47 | path = externals/sirit | 47 | path = externals/sirit |
| 48 | url = https://github.com/ReinUsesLisp/sirit | 48 | url = https://github.com/ReinUsesLisp/sirit |
| 49 | [submodule "libzip"] | 49 | [submodule "libzip"] |
| 50 | path = externals/libzip | 50 | path = externals/libzip/libzip |
| 51 | url = https://github.com/DarkLordZach/libzip | 51 | url = https://github.com/nih-at/libzip.git |
| 52 | [submodule "zlib"] | 52 | [submodule "zlib"] |
| 53 | path = externals/zlib | 53 | path = externals/zlib/zlib |
| 54 | url = https://github.com/madler/zlib | 54 | url = https://github.com/madler/zlib.git |
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index ac7529edd..61ad3487a 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt | |||
| @@ -76,6 +76,7 @@ endif() | |||
| 76 | 76 | ||
| 77 | # zlib | 77 | # zlib |
| 78 | add_subdirectory(zlib EXCLUDE_FROM_ALL) | 78 | add_subdirectory(zlib EXCLUDE_FROM_ALL) |
| 79 | set(ZLIB_LIBRARIES z) | ||
| 79 | 80 | ||
| 80 | # libzip | 81 | # libzip |
| 81 | add_subdirectory(libzip EXCLUDE_FROM_ALL) | 82 | add_subdirectory(libzip EXCLUDE_FROM_ALL) |
diff --git a/externals/libzip b/externals/libzip deleted file mode 160000 | |||
| Subproject bd7a8103e96bc6d50164447f6b7b57bb786d8e2 | |||
diff --git a/externals/libzip/CMakeLists.txt b/externals/libzip/CMakeLists.txt new file mode 100644 index 000000000..ea5329fa0 --- /dev/null +++ b/externals/libzip/CMakeLists.txt | |||
| @@ -0,0 +1,564 @@ | |||
| 1 | # TODO: | ||
| 2 | # create usable libtool .la file | ||
| 3 | |||
| 4 | CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2) | ||
| 5 | |||
| 6 | LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libzip") | ||
| 7 | |||
| 8 | PROJECT(libzip C) | ||
| 9 | |||
| 10 | OPTION(ENABLE_COMMONCRYPTO "Enable use of CommonCrypto" ON) | ||
| 11 | OPTION(ENABLE_GNUTLS "Enable use of GnuTLS" ON) | ||
| 12 | OPTION(ENABLE_MBEDTLS "Enable use of mbed TLS" ON) | ||
| 13 | OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON) | ||
| 14 | OPTION(ENABLE_WINDOWS_CRYPTO "Enable use of Windows cryptography libraries" ON) | ||
| 15 | |||
| 16 | OPTION(ENABLE_BZIP2 "Enable use of BZip2" OFF) | ||
| 17 | OPTION(ENABLE_LZMA "Enable use of LZMA" OFF) | ||
| 18 | |||
| 19 | INCLUDE(CheckFunctionExists) | ||
| 20 | INCLUDE(CheckIncludeFiles) | ||
| 21 | INCLUDE(CheckSymbolExists) | ||
| 22 | INCLUDE(CheckTypeSize) | ||
| 23 | INCLUDE(CheckCSourceRuns) | ||
| 24 | INCLUDE(CheckCSourceCompiles) | ||
| 25 | INCLUDE(CheckStructHasMember) | ||
| 26 | INCLUDE(TestBigEndian) | ||
| 27 | INCLUDE(GNUInstallDirs) | ||
| 28 | IF(ENABLE_COMMONCRYPTO) | ||
| 29 | CHECK_INCLUDE_FILES(CommonCrypto/CommonCrypto.h COMMONCRYPTO_FOUND) | ||
| 30 | ELSE() | ||
| 31 | SET(COMMONCRYPTO_FOUND FALSE) | ||
| 32 | ENDIF() | ||
| 33 | IF(ENABLE_GNUTLS) | ||
| 34 | INCLUDE(FindNettle) | ||
| 35 | INCLUDE(FindGnuTLS) | ||
| 36 | ELSE() | ||
| 37 | SET(GNUTLS_FOUND FALSE) | ||
| 38 | ENDIF() | ||
| 39 | IF(ENABLE_MBEDTLS) | ||
| 40 | FIND_PATH(MBEDTLS_INCLUDE_DIR mbedtls/aes.h) | ||
| 41 | FIND_LIBRARY(MBEDTLS_LIBRARIES NAMES mbedcrypto) | ||
| 42 | ELSE() | ||
| 43 | SET(MBEDTLS_LIBRARIES FALSE) | ||
| 44 | ENDIF() | ||
| 45 | IF(ENABLE_OPENSSL) | ||
| 46 | INCLUDE(FindOpenSSL) | ||
| 47 | ELSE() | ||
| 48 | SET(OPENSSL_FOUND FALSE) | ||
| 49 | ENDIF() | ||
| 50 | IF(WIN32) | ||
| 51 | IF(ENABLE_WINDOWS_CRYPTO) | ||
| 52 | SET(WINDOWS_CRYPTO_FOUND TRUE) | ||
| 53 | ENDIF() | ||
| 54 | ELSE() | ||
| 55 | SET(WINDOWS_CRYPTO_FOUND FALSE) | ||
| 56 | ENDIF() | ||
| 57 | |||
| 58 | OPTION(BUILD_SHARED_LIBS "Build shared libraries" ON) | ||
| 59 | OPTION(SHARED_LIB_VERSIONNING "Add SO version in .so build" ON) | ||
| 60 | |||
| 61 | SET(PACKAGE "libzip") | ||
| 62 | SET(PACKAGE_NAME ${PACKAGE}) | ||
| 63 | SET(PACKAGE_VERSION_MAJOR "1") | ||
| 64 | SET(PACKAGE_VERSION_MINOR "5") | ||
| 65 | SET(PACKAGE_VERSION_MICRO "2a") | ||
| 66 | #SET(VERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}") | ||
| 67 | SET(VERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_MICRO}") | ||
| 68 | SET(PACKAGE_VERSION ${VERSION}) | ||
| 69 | SET(LIBZIP_VERSION ${PACKAGE_VERSION}) | ||
| 70 | SET(LIBZIP_VERSION_MAJOR ${PACKAGE_VERSION_MAJOR}) | ||
| 71 | SET(LIBZIP_VERSION_MINOR ${PACKAGE_VERSION_MINOR}) | ||
| 72 | SET(LIBZIP_VERSION_MICRO ${PACKAGE_VERSION_MICRO}) | ||
| 73 | SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") | ||
| 74 | |||
| 75 | SET(ARCHIVE_NAME ${PACKAGE_NAME}-${PACKAGE_VERSION}) | ||
| 76 | IF(NOT TARGET dist) | ||
| 77 | ADD_CUSTOM_TARGET(dist | ||
| 78 | COMMAND git config tar.tar.xz.command "xz -c" | ||
| 79 | COMMAND git archive --prefix=${ARCHIVE_NAME}/ -o ${ARCHIVE_NAME}.tar.gz HEAD | ||
| 80 | COMMAND git archive --prefix=${ARCHIVE_NAME}/ -o ${ARCHIVE_NAME}.tar.xz HEAD | ||
| 81 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} | ||
| 82 | ) | ||
| 83 | ADD_CUSTOM_TARGET(distcheck | ||
| 84 | COMMAND chmod -R u+w ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest 2>/dev/null || true | ||
| 85 | COMMAND rm -rf ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest | ||
| 86 | COMMAND cmake -E tar xf ${ARCHIVE_NAME}.tar.gz | ||
| 87 | COMMAND chmod -R u-w ${ARCHIVE_NAME} | ||
| 88 | COMMAND mkdir ${ARCHIVE_NAME}-build | ||
| 89 | COMMAND mkdir ${ARCHIVE_NAME}-dest | ||
| 90 | COMMAND cd ${ARCHIVE_NAME}-build && cmake -DCMAKE_INSTALL_PREFIX=../${ARCHIVE_NAME}-dest ../${ARCHIVE_NAME} | ||
| 91 | COMMAND cd ${ARCHIVE_NAME}-build && make -j4 | ||
| 92 | COMMAND cd ${ARCHIVE_NAME}-build && make test | ||
| 93 | COMMAND cd ${ARCHIVE_NAME}-build && make install | ||
| 94 | # COMMAND cd ${ARCHIVE_NAME}-build && make uninstall | ||
| 95 | # COMMAND if [ `find ${ARCHIVE_NAME}-dest ! -type d | wc -l` -ne 0 ]; then echo leftover files in ${ARCHIVE_NAME}-dest; false; fi | ||
| 96 | COMMAND cd ${ARCHIVE_NAME}-build && make clean | ||
| 97 | COMMAND chmod -R u+w ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest | ||
| 98 | COMMAND rm -rf ${ARCHIVE_NAME} ${ARCHIVE_NAME}-build ${ARCHIVE_NAME}-dest | ||
| 99 | COMMAND echo "${ARCHIVE_NAME}.tar.gz is ready for distribution." | ||
| 100 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} | ||
| 101 | ) | ||
| 102 | ADD_DEPENDENCIES(distcheck dist) | ||
| 103 | ENDIF(NOT TARGET dist) | ||
| 104 | |||
| 105 | IF(BUILD_SHARED_LIBS) | ||
| 106 | SET(HAVE_SHARED TRUE) | ||
| 107 | ELSE() | ||
| 108 | SET(ZIP_STATIC TRUE) | ||
| 109 | ENDIF() | ||
| 110 | |||
| 111 | # Checks | ||
| 112 | |||
| 113 | CHECK_FUNCTION_EXISTS(_chmod HAVE__CHMOD) | ||
| 114 | CHECK_FUNCTION_EXISTS(_close HAVE__CLOSE) | ||
| 115 | CHECK_FUNCTION_EXISTS(_dup HAVE__DUP) | ||
| 116 | CHECK_FUNCTION_EXISTS(_fdopen HAVE__FDOPEN) | ||
| 117 | CHECK_FUNCTION_EXISTS(_fileno HAVE__FILENO) | ||
| 118 | CHECK_FUNCTION_EXISTS(_open HAVE__OPEN) | ||
| 119 | CHECK_FUNCTION_EXISTS(_setmode HAVE__SETMODE) | ||
| 120 | CHECK_FUNCTION_EXISTS(_snprintf HAVE__SNPRINTF) | ||
| 121 | CHECK_FUNCTION_EXISTS(_strdup HAVE__STRDUP) | ||
| 122 | CHECK_FUNCTION_EXISTS(_stricmp HAVE__STRICMP) | ||
| 123 | CHECK_FUNCTION_EXISTS(_strtoi64 HAVE__STRTOI64) | ||
| 124 | CHECK_FUNCTION_EXISTS(_strtoui64 HAVE__STRTOUI64) | ||
| 125 | CHECK_FUNCTION_EXISTS(_unlink HAVE__UNLINK) | ||
| 126 | CHECK_FUNCTION_EXISTS(arc4random HAVE_ARC4RANDOM) | ||
| 127 | CHECK_FUNCTION_EXISTS(clonefile HAVE_CLONEFILE) | ||
| 128 | CHECK_FUNCTION_EXISTS(explicit_bzero HAVE_EXPLICIT_BZERO) | ||
| 129 | CHECK_FUNCTION_EXISTS(explicit_memset HAVE_EXPLICIT_MEMSET) | ||
| 130 | CHECK_FUNCTION_EXISTS(fileno HAVE_FILENO) | ||
| 131 | CHECK_FUNCTION_EXISTS(fseeko HAVE_FSEEKO) | ||
| 132 | CHECK_FUNCTION_EXISTS(ftello HAVE_FTELLO) | ||
| 133 | CHECK_FUNCTION_EXISTS(getprogname HAVE_GETPROGNAME) | ||
| 134 | CHECK_FUNCTION_EXISTS(localtime_r HAVE_LOCALTIME_R) | ||
| 135 | CHECK_FUNCTION_EXISTS(open HAVE_OPEN) | ||
| 136 | CHECK_FUNCTION_EXISTS(setmode HAVE_SETMODE) | ||
| 137 | CHECK_FUNCTION_EXISTS(snprintf HAVE_SNPRINTF) | ||
| 138 | CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP) | ||
| 139 | CHECK_FUNCTION_EXISTS(strdup HAVE_STRDUP) | ||
| 140 | CHECK_FUNCTION_EXISTS(stricmp HAVE_STRICMP) | ||
| 141 | CHECK_FUNCTION_EXISTS(strtoll HAVE_STRTOLL) | ||
| 142 | CHECK_FUNCTION_EXISTS(strtoull HAVE_STRTOULL) | ||
| 143 | |||
| 144 | CHECK_INCLUDE_FILES("sys/types.h;sys/stat.h;fts.h" HAVE_FTS_H) | ||
| 145 | CHECK_INCLUDE_FILES(stdbool.h HAVE_STDBOOL_H) | ||
| 146 | CHECK_INCLUDE_FILES(strings.h HAVE_STRINGS_H) | ||
| 147 | CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H) | ||
| 148 | |||
| 149 | CHECK_INCLUDE_FILES(inttypes.h HAVE_INTTYPES_H_LIBZIP) | ||
| 150 | CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H_LIBZIP) | ||
| 151 | CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H_LIBZIP) | ||
| 152 | |||
| 153 | # TODO: fix test | ||
| 154 | # this test does not find __progname even when it exists | ||
| 155 | #CHECK_SYMBOL_EXISTS(__progname stdlib.h HAVE___PROGNAME) | ||
| 156 | |||
| 157 | CHECK_TYPE_SIZE(__int8 __INT8_LIBZIP) | ||
| 158 | CHECK_TYPE_SIZE(int8_t INT8_T_LIBZIP) | ||
| 159 | CHECK_TYPE_SIZE(uint8_t UINT8_T_LIBZIP) | ||
| 160 | CHECK_TYPE_SIZE(__int16 __INT16_LIBZIP) | ||
| 161 | CHECK_TYPE_SIZE(int16_t INT16_T_LIBZIP) | ||
| 162 | CHECK_TYPE_SIZE(uint16_t UINT16_T_LIBZIP) | ||
| 163 | CHECK_TYPE_SIZE(__int32 __INT32_LIBZIP) | ||
| 164 | CHECK_TYPE_SIZE(int32_t INT32_T_LIBZIP) | ||
| 165 | CHECK_TYPE_SIZE(uint32_t UINT32_T_LIBZIP) | ||
| 166 | CHECK_TYPE_SIZE(__int64 __INT64_LIBZIP) | ||
| 167 | CHECK_TYPE_SIZE(int64_t INT64_T_LIBZIP) | ||
| 168 | CHECK_TYPE_SIZE(uint64_t UINT64_T_LIBZIP) | ||
| 169 | CHECK_TYPE_SIZE("short" SHORT_LIBZIP) | ||
| 170 | CHECK_TYPE_SIZE("int" INT_LIBZIP) | ||
| 171 | CHECK_TYPE_SIZE("long" LONG_LIBZIP) | ||
| 172 | CHECK_TYPE_SIZE("long long" LONG_LONG_LIBZIP) | ||
| 173 | CHECK_TYPE_SIZE("off_t" SIZEOF_OFF_T) | ||
| 174 | CHECK_TYPE_SIZE("size_t" SIZE_T_LIBZIP) | ||
| 175 | CHECK_TYPE_SIZE("ssize_t" SSIZE_T_LIBZIP) | ||
| 176 | |||
| 177 | CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h> | ||
| 178 | #include <linux/fs.h> | ||
| 179 | int main(int argc, char *argv[]) { unsigned long x = FICLONERANGE; }" HAVE_FICLONERANGE) | ||
| 180 | |||
| 181 | CHECK_C_SOURCE_COMPILES(" | ||
| 182 | int foo(char * _Nullable bar); | ||
| 183 | int main(int argc, char *argv[]) { }" HAVE_NULLABLE) | ||
| 184 | |||
| 185 | TEST_BIG_ENDIAN(WORDS_BIGENDIAN) | ||
| 186 | |||
| 187 | #FIND_PACKAGE(ZLIB 1.1.2 REQUIRED) | ||
| 188 | INCLUDE_DIRECTORIES(../zlib/zlib) | ||
| 189 | SET(CMAKE_REQUIRED_INCLUDES ../zlib/zlib) | ||
| 190 | |||
| 191 | IF(ENABLE_BZIP2) | ||
| 192 | FIND_PACKAGE(BZip2) | ||
| 193 | IF(BZIP2_FOUND) | ||
| 194 | SET (HAVE_LIBBZ2 1) | ||
| 195 | |||
| 196 | INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR}) | ||
| 197 | SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${BZIP2_LIBRARIES}) | ||
| 198 | ELSE() | ||
| 199 | MESSAGE(WARNING "-- bzip2 library not found; bzip2 support disabled") | ||
| 200 | ENDIF(BZIP2_FOUND) | ||
| 201 | ENDIF(ENABLE_BZIP2) | ||
| 202 | |||
| 203 | IF(ENABLE_LZMA) | ||
| 204 | FIND_PACKAGE(LibLZMA) | ||
| 205 | IF(LIBLZMA_FOUND) | ||
| 206 | SET (HAVE_LIBLZMA 1) | ||
| 207 | |||
| 208 | INCLUDE_DIRECTORIES(${LIBLZMA_INCLUDE_DIR}) | ||
| 209 | SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${LIBLZMA_LIBRARY}) | ||
| 210 | ELSE() | ||
| 211 | MESSAGE(WARNING "-- lzma library not found; lzma support disabled") | ||
| 212 | ENDIF(LIBLZMA_FOUND) | ||
| 213 | ENDIF(ENABLE_LZMA) | ||
| 214 | |||
| 215 | |||
| 216 | IF (COMMONCRYPTO_FOUND) | ||
| 217 | SET (HAVE_CRYPTO 1) | ||
| 218 | SET (HAVE_COMMONCRYPTO 1) | ||
| 219 | ELSEIF (WINDOWS_CRYPTO_FOUND) | ||
| 220 | SET (HAVE_CRYPTO 1) | ||
| 221 | SET (HAVE_WINDOWS_CRYPTO 1) | ||
| 222 | ELSEIF (GNUTLS_FOUND AND NETTLE_FOUND) | ||
| 223 | SET (HAVE_CRYPTO 1) | ||
| 224 | SET (HAVE_GNUTLS 1) | ||
| 225 | INCLUDE_DIRECTORIES(${GNUTLS_INCLUDE_DIR} ${NETTLE_INCLUDE_DIR}) | ||
| 226 | SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${GNUTLS_LIBRARY} ${NETTLE_LIBRARY}) | ||
| 227 | ELSEIF (OPENSSL_FOUND) | ||
| 228 | SET (HAVE_CRYPTO 1) | ||
| 229 | SET (HAVE_OPENSSL 1) | ||
| 230 | INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) | ||
| 231 | SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${OPENSSL_LIBRARIES}) | ||
| 232 | ELSEIF (MBEDTLS_LIBRARIES) | ||
| 233 | SET (HAVE_CRYPTO 1) | ||
| 234 | SET (HAVE_MBEDTLS 1) | ||
| 235 | INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIR}) | ||
| 236 | SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} ${MBEDTLS_LIBRARIES}) | ||
| 237 | ENDIF() | ||
| 238 | |||
| 239 | IF (NOT HAVE_CRYPTO) | ||
| 240 | MESSAGE(WARNING "-- neither Common Crypto, GnuTLS, mbed TLS, OpenSSL, nor Windows Cryptography found; AES support disabled") | ||
| 241 | ENDIF() | ||
| 242 | |||
| 243 | IF(MSVC) | ||
| 244 | ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS") | ||
| 245 | ADD_DEFINITIONS("-D_CRT_NONSTDC_NO_DEPRECATE") | ||
| 246 | ENDIF(MSVC) | ||
| 247 | |||
| 248 | if(WIN32) | ||
| 249 | if(HAVE_WINDOWS_CRYPTO) | ||
| 250 | SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} bcrypt) | ||
| 251 | endif() | ||
| 252 | if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore) | ||
| 253 | ADD_DEFINITIONS(-DMS_UWP) | ||
| 254 | else(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore) | ||
| 255 | SET (OPTIONAL_LIBRARY ${OPTIONAL_LIBRARY} advapi32) | ||
| 256 | endif(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore) | ||
| 257 | endif(WIN32) | ||
| 258 | |||
| 259 | ADD_DEFINITIONS("-DHAVE_CONFIG_H") | ||
| 260 | |||
| 261 | # rpath handling: use rpath in installed binaries | ||
| 262 | IF(NOT CMAKE_SYSTEM_NAME MATCHES Linux) | ||
| 263 | SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") | ||
| 264 | SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) | ||
| 265 | ENDIF() | ||
| 266 | |||
| 267 | # fixed size integral types | ||
| 268 | |||
| 269 | IF(HAVE_INTTYPES_H_LIBZIP) | ||
| 270 | SET(LIBZIP_TYPES_INCLUDE "#define __STDC_FORMAT_MACROS 1 | ||
| 271 | #include <inttypes.h>") | ||
| 272 | ELSEIF(HAVE_STDINT_H_LIBZIP) | ||
| 273 | SET(LIBZIP_TYPES_INCLUDE "#include <stdint.h>") | ||
| 274 | ELSEIF(HAVE_SYS_TYPES_H_LIBZIP) | ||
| 275 | SET(LIBZIP_TYPES_INCLUDE "#include <sys/types.h>") | ||
| 276 | ENDIF() | ||
| 277 | |||
| 278 | IF(HAVE_INT8_T_LIBZIP) | ||
| 279 | SET(ZIP_INT8_T int8_t) | ||
| 280 | ELSEIF(HAVE___INT8_LIBZIP) | ||
| 281 | SET(ZIP_INT8_T __int8) | ||
| 282 | ELSE() | ||
| 283 | SET(ZIP_INT8_T "signed char") | ||
| 284 | ENDIF() | ||
| 285 | |||
| 286 | IF(HAVE_UINT8_T_LIBZIP) | ||
| 287 | SET(ZIP_UINT8_T uint8_t) | ||
| 288 | ELSEIF(HAVE___INT8_LIBZIP) | ||
| 289 | SET(ZIP_UINT8_T "unsigned __int8") | ||
| 290 | ELSE() | ||
| 291 | SET(ZIP_UINT8_T "unsigned char") | ||
| 292 | ENDIF() | ||
| 293 | |||
| 294 | IF(HAVE_INT16_T_LIBZIP) | ||
| 295 | SET(ZIP_INT16_T int16_t) | ||
| 296 | ELSEIF(HAVE___INT16_LIBZIP) | ||
| 297 | SET(INT16_T_LIBZIP __int16) | ||
| 298 | ELSEIF(SHORT_LIBZIP EQUAL 2) | ||
| 299 | SET(INT16_T_LIBZIP short) | ||
| 300 | ENDIF() | ||
| 301 | |||
| 302 | IF(HAVE_UINT16_T_LIBZIP) | ||
| 303 | SET(ZIP_UINT16_T uint16_t) | ||
| 304 | ELSEIF(HAVE___INT16_LIBZIP) | ||
| 305 | SET(UINT16_T_LIBZIP "unsigned __int16") | ||
| 306 | ELSEIF(SHORT_LIBZIP EQUAL 2) | ||
| 307 | SET(UINT16_T_LIBZIP "unsigned short") | ||
| 308 | ENDIF() | ||
| 309 | |||
| 310 | IF(HAVE_INT32_T_LIBZIP) | ||
| 311 | SET(ZIP_INT32_T int32_t) | ||
| 312 | ELSEIF(HAVE___INT32_LIBZIP) | ||
| 313 | SET(ZIP_INT32_T __int32) | ||
| 314 | ELSEIF(INT_LIBZIP EQUAL 4) | ||
| 315 | SET(ZIP_INT32_T int) | ||
| 316 | ELSEIF(LONG_LIBZIP EQUAL 4) | ||
| 317 | SET(ZIP_INT32_T long) | ||
| 318 | ENDIF() | ||
| 319 | |||
| 320 | IF(HAVE_UINT32_T_LIBZIP) | ||
| 321 | SET(ZIP_UINT32_T uint32_t) | ||
| 322 | ELSEIF(HAVE___INT32_LIBZIP) | ||
| 323 | SET(ZIP_UINT32_T "unsigned __int32") | ||
| 324 | ELSEIF(INT_LIBZIP EQUAL 4) | ||
| 325 | SET(ZIP_UINT32_T "unsigned int") | ||
| 326 | ELSEIF(LONG_LIBZIP EQUAL 4) | ||
| 327 | SET(ZIP_UINT32_T "unsigned long") | ||
| 328 | ENDIF() | ||
| 329 | |||
| 330 | IF(HAVE_INT64_T_LIBZIP) | ||
| 331 | SET(ZIP_INT64_T int64_t) | ||
| 332 | ELSEIF(HAVE___INT64_LIBZIP) | ||
| 333 | SET(ZIP_INT64_T __int64) | ||
| 334 | ELSEIF(LONG_LIBZIP EQUAL 8) | ||
| 335 | SET(ZIP_INT64_T long) | ||
| 336 | ELSEIF(LONG_LONG_LIBZIP EQUAL 8) | ||
| 337 | SET(ZIP_INT64_T "long long") | ||
| 338 | ENDIF() | ||
| 339 | |||
| 340 | IF(HAVE_UINT64_T_LIBZIP) | ||
| 341 | SET(ZIP_UINT64_T uint64_t) | ||
| 342 | ELSEIF(HAVE___INT64_LIBZIP) | ||
| 343 | SET(ZIP_UINT64_T "unsigned __int64") | ||
| 344 | ELSEIF(LONG_LIBZIP EQUAL 8) | ||
| 345 | SET(ZIP_UINT64_T "unsigned long") | ||
| 346 | ELSEIF(LONG_LONG_LIBZIP EQUAL 8) | ||
| 347 | SET(ZIP_UINT64_T "unsigned long long") | ||
| 348 | ENDIF() | ||
| 349 | |||
| 350 | IF(HAVE_NULLABLE) | ||
| 351 | SET(ZIP_NULLABLE_DEFINES) | ||
| 352 | ELSE() | ||
| 353 | SET(ZIP_NULLABLE_DEFINES "#define _Nullable | ||
| 354 | #define _Nonnull") | ||
| 355 | ENDIF() | ||
| 356 | |||
| 357 | # write out config file | ||
| 358 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libzip/cmake-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/libzip/config.h) | ||
| 359 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libzip/cmake-zipconf.h.in ${CMAKE_CURRENT_BINARY_DIR}/libzip/zipconf.h) | ||
| 360 | |||
| 361 | # installation | ||
| 362 | INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libzip/zipconf.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) | ||
| 363 | INSTALL(FILES libzip/lib/zip.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) | ||
| 364 | |||
| 365 | SET(CMAKE_C_VISIBILITY_PRESET hidden) | ||
| 366 | |||
| 367 | ADD_LIBRARY(zip | ||
| 368 | libzip/lib/zip_add.c | ||
| 369 | libzip/lib/zip_add_dir.c | ||
| 370 | libzip/lib/zip_add_entry.c | ||
| 371 | libzip/lib/zip_algorithm_deflate.c | ||
| 372 | libzip/lib/zip_buffer.c | ||
| 373 | libzip/lib/zip_close.c | ||
| 374 | libzip/lib/zip_delete.c | ||
| 375 | libzip/lib/zip_dir_add.c | ||
| 376 | libzip/lib/zip_dirent.c | ||
| 377 | libzip/lib/zip_discard.c | ||
| 378 | libzip/lib/zip_entry.c | ||
| 379 | libzip/lib/zip_err_str.c | ||
| 380 | libzip/lib/zip_error.c | ||
| 381 | libzip/lib/zip_error_clear.c | ||
| 382 | libzip/lib/zip_error_get.c | ||
| 383 | libzip/lib/zip_error_get_sys_type.c | ||
| 384 | libzip/lib/zip_error_strerror.c | ||
| 385 | libzip/lib/zip_error_to_str.c | ||
| 386 | libzip/lib/zip_extra_field.c | ||
| 387 | libzip/lib/zip_extra_field_api.c | ||
| 388 | libzip/lib/zip_fclose.c | ||
| 389 | libzip/lib/zip_fdopen.c | ||
| 390 | libzip/lib/zip_file_add.c | ||
| 391 | libzip/lib/zip_file_error_clear.c | ||
| 392 | libzip/lib/zip_file_error_get.c | ||
| 393 | libzip/lib/zip_file_get_comment.c | ||
| 394 | libzip/lib/zip_file_get_external_attributes.c | ||
| 395 | libzip/lib/zip_file_get_offset.c | ||
| 396 | libzip/lib/zip_file_rename.c | ||
| 397 | libzip/lib/zip_file_replace.c | ||
| 398 | libzip/lib/zip_file_set_comment.c | ||
| 399 | libzip/lib/zip_file_set_encryption.c | ||
| 400 | libzip/lib/zip_file_set_external_attributes.c | ||
| 401 | libzip/lib/zip_file_set_mtime.c | ||
| 402 | libzip/lib/zip_file_strerror.c | ||
| 403 | libzip/lib/zip_filerange_crc.c | ||
| 404 | libzip/lib/zip_fopen.c | ||
| 405 | libzip/lib/zip_fopen_encrypted.c | ||
| 406 | libzip/lib/zip_fopen_index.c | ||
| 407 | libzip/lib/zip_fopen_index_encrypted.c | ||
| 408 | libzip/lib/zip_fread.c | ||
| 409 | libzip/lib/zip_fseek.c | ||
| 410 | libzip/lib/zip_ftell.c | ||
| 411 | libzip/lib/zip_get_archive_comment.c | ||
| 412 | libzip/lib/zip_get_archive_flag.c | ||
| 413 | libzip/lib/zip_get_encryption_implementation.c | ||
| 414 | libzip/lib/zip_get_file_comment.c | ||
| 415 | libzip/lib/zip_get_name.c | ||
| 416 | libzip/lib/zip_get_num_entries.c | ||
| 417 | libzip/lib/zip_get_num_files.c | ||
| 418 | libzip/lib/zip_hash.c | ||
| 419 | libzip/lib/zip_io_util.c | ||
| 420 | libzip/lib/zip_libzip_version.c | ||
| 421 | libzip/lib/zip_memdup.c | ||
| 422 | libzip/lib/zip_name_locate.c | ||
| 423 | libzip/lib/zip_new.c | ||
| 424 | libzip/lib/zip_open.c | ||
| 425 | libzip/lib/zip_progress.c | ||
| 426 | libzip/lib/zip_rename.c | ||
| 427 | libzip/lib/zip_replace.c | ||
| 428 | libzip/lib/zip_set_archive_comment.c | ||
| 429 | libzip/lib/zip_set_archive_flag.c | ||
| 430 | libzip/lib/zip_set_default_password.c | ||
| 431 | libzip/lib/zip_set_file_comment.c | ||
| 432 | libzip/lib/zip_set_file_compression.c | ||
| 433 | libzip/lib/zip_set_name.c | ||
| 434 | libzip/lib/zip_source_accept_empty.c | ||
| 435 | libzip/lib/zip_source_begin_write.c | ||
| 436 | libzip/lib/zip_source_begin_write_cloning.c | ||
| 437 | libzip/lib/zip_source_buffer.c | ||
| 438 | libzip/lib/zip_source_call.c | ||
| 439 | libzip/lib/zip_source_close.c | ||
| 440 | libzip/lib/zip_source_commit_write.c | ||
| 441 | libzip/lib/zip_source_compress.c | ||
| 442 | libzip/lib/zip_source_crc.c | ||
| 443 | libzip/lib/zip_source_error.c | ||
| 444 | libzip/lib/zip_source_filep.c | ||
| 445 | libzip/lib/zip_source_free.c | ||
| 446 | libzip/lib/zip_source_function.c | ||
| 447 | libzip/lib/zip_source_get_compression_flags.c | ||
| 448 | libzip/lib/zip_source_is_deleted.c | ||
| 449 | libzip/lib/zip_source_layered.c | ||
| 450 | libzip/lib/zip_source_open.c | ||
| 451 | libzip/lib/zip_source_pkware.c | ||
| 452 | libzip/lib/zip_source_read.c | ||
| 453 | libzip/lib/zip_source_remove.c | ||
| 454 | libzip/lib/zip_source_rollback_write.c | ||
| 455 | libzip/lib/zip_source_seek.c | ||
| 456 | libzip/lib/zip_source_seek_write.c | ||
| 457 | libzip/lib/zip_source_stat.c | ||
| 458 | libzip/lib/zip_source_supports.c | ||
| 459 | libzip/lib/zip_source_tell.c | ||
| 460 | libzip/lib/zip_source_tell_write.c | ||
| 461 | libzip/lib/zip_source_window.c | ||
| 462 | libzip/lib/zip_source_write.c | ||
| 463 | libzip/lib/zip_source_zip.c | ||
| 464 | libzip/lib/zip_source_zip_new.c | ||
| 465 | libzip/lib/zip_stat.c | ||
| 466 | libzip/lib/zip_stat_index.c | ||
| 467 | libzip/lib/zip_stat_init.c | ||
| 468 | libzip/lib/zip_strerror.c | ||
| 469 | libzip/lib/zip_string.c | ||
| 470 | libzip/lib/zip_unchange.c | ||
| 471 | libzip/lib/zip_unchange_all.c | ||
| 472 | libzip/lib/zip_unchange_archive.c | ||
| 473 | libzip/lib/zip_unchange_data.c | ||
| 474 | libzip/lib/zip_utf-8.c | ||
| 475 | ) | ||
| 476 | |||
| 477 | IF(WIN32) | ||
| 478 | target_sources(zip PRIVATE | ||
| 479 | libzip/lib/zip_source_win32handle.c | ||
| 480 | libzip/lib/zip_source_win32utf8.c | ||
| 481 | libzip/lib/zip_source_win32w.c | ||
| 482 | ) | ||
| 483 | IF(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore) | ||
| 484 | ELSE() | ||
| 485 | target_sources(zip PRIVATE libzip/lib/zip_source_win32a.c) | ||
| 486 | ENDIF() | ||
| 487 | ELSE() | ||
| 488 | target_sources(zip PRIVATE | ||
| 489 | libzip/lib/zip_mkstempm.c | ||
| 490 | libzip/lib/zip_source_file.c | ||
| 491 | libzip/lib/zip_random_unix.c | ||
| 492 | ) | ||
| 493 | ENDIF() | ||
| 494 | |||
| 495 | IF(HAVE_LIBBZ2) | ||
| 496 | target_sources(zip PRIVATE libzip/lib/zip_algorithm_bzip2.c) | ||
| 497 | ENDIF() | ||
| 498 | |||
| 499 | IF(HAVE_LIBLZMA) | ||
| 500 | target_sources(zip PRIVATE libzip/lib/zip_algorithm_xz.c) | ||
| 501 | ENDIF() | ||
| 502 | |||
| 503 | IF(HAVE_COMMONCRYPTO) | ||
| 504 | target_sources(zip PRIVATE libzip/lib/zip_crypto_commoncrypto.c) | ||
| 505 | ELSEIF(HAVE_WINDOWS_CRYPTO) | ||
| 506 | target_sources(zip PRIVATE libzip/lib/zip_crypto_win.c) | ||
| 507 | ELSEIF(HAVE_GNUTLS) | ||
| 508 | target_sources(zip PRIVATE libzip/lib/zip_crypto_gnutls.c) | ||
| 509 | ELSEIF(HAVE_OPENSSL) | ||
| 510 | target_sources(zip PRIVATE libzip/lib/zip_crypto_openssl.c) | ||
| 511 | ELSEIF(HAVE_MBEDTLS) | ||
| 512 | target_sources(zip PRIVATE libzip/lib/zip_crypto_mbedtls.c) | ||
| 513 | ENDIF() | ||
| 514 | |||
| 515 | IF(HAVE_CRYPTO) | ||
| 516 | target_sources(zip PRIVATE | ||
| 517 | libzip/lib/zip_winzip_aes.c | ||
| 518 | libzip/lib/zip_source_winzip_aes_decode.c | ||
| 519 | libzip/lib/zip_source_winzip_aes_encode.c | ||
| 520 | ) | ||
| 521 | ENDIF() | ||
| 522 | |||
| 523 | target_include_directories(zip | ||
| 524 | PUBLIC | ||
| 525 | libzip/lib | ||
| 526 | ${CMAKE_CURRENT_BINARY_DIR}/libzip | ||
| 527 | ) | ||
| 528 | |||
| 529 | # pkgconfig file | ||
| 530 | SET(prefix ${CMAKE_INSTALL_PREFIX}) | ||
| 531 | SET(exec_prefix \${prefix}) | ||
| 532 | SET(bindir \${exec_prefix}/${CMAKE_INSTALL_BINDIR}) | ||
| 533 | SET(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR}) | ||
| 534 | SET(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR}) | ||
| 535 | IF(CMAKE_SYSTEM_NAME MATCHES BSD) | ||
| 536 | SET(PKG_CONFIG_RPATH "-Wl,-R\${libdir}") | ||
| 537 | ENDIF(CMAKE_SYSTEM_NAME MATCHES BSD) | ||
| 538 | get_target_property(LIBS_PRIVATE zip LINK_LIBRARIES) | ||
| 539 | foreach(LIB ${LIBS_PRIVATE}) | ||
| 540 | if(LIB MATCHES "^/") | ||
| 541 | get_filename_component(LIB ${LIB} NAME_WE) | ||
| 542 | string(REGEX REPLACE "^lib" "" LIB ${LIB}) | ||
| 543 | endif() | ||
| 544 | set(LIBS "${LIBS} -l${LIB}") | ||
| 545 | endforeach() | ||
| 546 | CONFIGURE_FILE(libzip/libzip.pc.in libzip/libzip.pc @ONLY) | ||
| 547 | INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libzip.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) | ||
| 548 | |||
| 549 | ADD_CUSTOM_TARGET(update_zip_err_str | ||
| 550 | COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/make_zip_err_str.sh ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/zip.h ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/zip_err_str.c | ||
| 551 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/zip.h ${CMAKE_CURRENT_SOURCE_DIR}/libzip/lib/make_zip_err_str.sh | ||
| 552 | ) | ||
| 553 | |||
| 554 | IF(SHARED_LIB_VERSIONNING) | ||
| 555 | SET_TARGET_PROPERTIES(zip PROPERTIES VERSION 5.0 SOVERSION 5) | ||
| 556 | ENDIF() | ||
| 557 | |||
| 558 | TARGET_LINK_LIBRARIES(zip ${ZLIB_LIBRARIES} ${OPTIONAL_LIBRARY}) | ||
| 559 | INSTALL(TARGETS zip | ||
| 560 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} | ||
| 561 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
| 562 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
| 563 | ) | ||
| 564 | |||
diff --git a/externals/libzip/libzip b/externals/libzip/libzip new file mode 160000 | |||
| Subproject 89bd6d63bdea9da7627695f6c82e54f16d368b5 | |||
diff --git a/externals/zlib/CMakeLists.txt b/externals/zlib/CMakeLists.txt new file mode 100644 index 000000000..0ca32aae4 --- /dev/null +++ b/externals/zlib/CMakeLists.txt | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | project(zlib C) | ||
| 2 | |||
| 3 | include(CheckTypeSize) | ||
| 4 | include(CheckFunctionExists) | ||
| 5 | include(CheckIncludeFile) | ||
| 6 | |||
| 7 | check_include_file(sys/types.h HAVE_SYS_TYPES_H) | ||
| 8 | check_include_file(stdint.h HAVE_STDINT_H) | ||
| 9 | check_include_file(stddef.h HAVE_STDDEF_H) | ||
| 10 | |||
| 11 | # Check to see if we have large file support | ||
| 12 | set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) | ||
| 13 | # We add these other definitions here because CheckTypeSize.cmake | ||
| 14 | # in CMake 2.4.x does not automatically do so and we want | ||
| 15 | # compatibility with CMake 2.4.x. | ||
| 16 | if(HAVE_SYS_TYPES_H) | ||
| 17 | list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) | ||
| 18 | endif() | ||
| 19 | if(HAVE_STDINT_H) | ||
| 20 | list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) | ||
| 21 | endif() | ||
| 22 | if(HAVE_STDDEF_H) | ||
| 23 | list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) | ||
| 24 | endif() | ||
| 25 | check_type_size(off64_t OFF64_T) | ||
| 26 | if(HAVE_OFF64_T) | ||
| 27 | add_definitions(-D_LARGEFILE64_SOURCE=1) | ||
| 28 | endif() | ||
| 29 | set(CMAKE_REQUIRED_DEFINITIONS) # clear variable | ||
| 30 | |||
| 31 | # Check for fseeko | ||
| 32 | check_function_exists(fseeko HAVE_FSEEKO) | ||
| 33 | if(NOT HAVE_FSEEKO) | ||
| 34 | add_definitions(-DNO_FSEEKO) | ||
| 35 | endif() | ||
| 36 | |||
| 37 | # Check for unistd.h | ||
| 38 | check_include_file(unistd.h HAVE_UNISTD_H) | ||
| 39 | if(HAVE_UNISTD_H) | ||
| 40 | add_definitions(-DHAVE_UNISTD_H) | ||
| 41 | endif() | ||
| 42 | |||
| 43 | if(MSVC) | ||
| 44 | add_definitions(-D_CRT_SECURE_NO_DEPRECATE) | ||
| 45 | add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) | ||
| 46 | endif() | ||
| 47 | |||
| 48 | add_library(z STATIC | ||
| 49 | zlib/adler32.c | ||
| 50 | zlib/compress.c | ||
| 51 | zlib/crc32.c | ||
| 52 | zlib/crc32.h | ||
| 53 | zlib/deflate.c | ||
| 54 | zlib/deflate.h | ||
| 55 | zlib/gzclose.c | ||
| 56 | zlib/gzguts.h | ||
| 57 | zlib/gzlib.c | ||
| 58 | zlib/gzread.c | ||
| 59 | zlib/gzwrite.c | ||
| 60 | zlib/inffast.h | ||
| 61 | zlib/inffixed.h | ||
| 62 | zlib/inflate.c | ||
| 63 | zlib/inflate.h | ||
| 64 | zlib/infback.c | ||
| 65 | zlib/inftrees.c | ||
| 66 | zlib/inftrees.h | ||
| 67 | zlib/inffast.c | ||
| 68 | zlib/trees.c | ||
| 69 | zlib/trees.h | ||
| 70 | zlib/uncompr.c | ||
| 71 | zlib/zconf.h | ||
| 72 | zlib/zlib.h | ||
| 73 | zlib/zutil.c | ||
| 74 | zlib/zutil.h | ||
| 75 | ) | ||
| 76 | add_library(ZLIB::ZLIB ALIAS z) | ||
| 77 | |||
| 78 | target_include_directories(z | ||
| 79 | PUBLIC | ||
| 80 | zlib/ | ||
| 81 | ) | ||
diff --git a/externals/zlib b/externals/zlib/zlib | |||
| Subproject cacf7f1d4e3d44d871b605da3b647f07d718623 | Subproject cacf7f1d4e3d44d871b605da3b647f07d718623 | ||
diff --git a/src/common/bit_field.h b/src/common/bit_field.h index 902e668e3..fd2bbbd99 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h | |||
| @@ -36,6 +36,13 @@ | |||
| 36 | #include "common/common_funcs.h" | 36 | #include "common/common_funcs.h" |
| 37 | #include "common/swap.h" | 37 | #include "common/swap.h" |
| 38 | 38 | ||
| 39 | // Inlining | ||
| 40 | #ifdef _WIN32 | ||
| 41 | #define FORCE_INLINE __forceinline | ||
| 42 | #else | ||
| 43 | #define FORCE_INLINE inline __attribute__((always_inline)) | ||
| 44 | #endif | ||
| 45 | |||
| 39 | /* | 46 | /* |
| 40 | * Abstract bitfield class | 47 | * Abstract bitfield class |
| 41 | * | 48 | * |
| @@ -168,11 +175,11 @@ public: | |||
| 168 | constexpr BitField(BitField&&) noexcept = default; | 175 | constexpr BitField(BitField&&) noexcept = default; |
| 169 | constexpr BitField& operator=(BitField&&) noexcept = default; | 176 | constexpr BitField& operator=(BitField&&) noexcept = default; |
| 170 | 177 | ||
| 171 | constexpr FORCE_INLINE operator T() const { | 178 | constexpr operator T() const { |
| 172 | return Value(); | 179 | return Value(); |
| 173 | } | 180 | } |
| 174 | 181 | ||
| 175 | constexpr FORCE_INLINE void Assign(const T& value) { | 182 | constexpr void Assign(const T& value) { |
| 176 | storage = (static_cast<StorageType>(storage) & ~mask) | FormatValue(value); | 183 | storage = (static_cast<StorageType>(storage) & ~mask) | FormatValue(value); |
| 177 | } | 184 | } |
| 178 | 185 | ||
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 04ecac959..c029dc7b3 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project | 1 | // Copyright 2019 yuzu emulator team |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <algorithm> | 7 | #include <algorithm> |
| 8 | #include <array> | ||
| 8 | #include <string> | 9 | #include <string> |
| 9 | 10 | ||
| 10 | #if !defined(ARCHITECTURE_x86_64) | 11 | #if !defined(ARCHITECTURE_x86_64) |
| @@ -16,18 +17,15 @@ | |||
| 16 | #define CONCAT2(x, y) DO_CONCAT2(x, y) | 17 | #define CONCAT2(x, y) DO_CONCAT2(x, y) |
| 17 | #define DO_CONCAT2(x, y) x##y | 18 | #define DO_CONCAT2(x, y) x##y |
| 18 | 19 | ||
| 19 | // helper macro to properly align structure members. | 20 | /// Helper macros to insert unused bytes or words to properly align structs. These values will be |
| 20 | // Calling INSERT_PADDING_BYTES will add a new member variable with a name like "pad121", | 21 | /// zero-initialized. |
| 21 | // depending on the current source line to make sure variable names are unique. | 22 | #define INSERT_PADDING_BYTES(num_bytes) std::array<u8, num_bytes> CONCAT2(pad, __LINE__){}; |
| 22 | #define INSERT_PADDING_BYTES(num_bytes) u8 CONCAT2(pad, __LINE__)[(num_bytes)] | 23 | #define INSERT_PADDING_WORDS(num_words) std::array<u32, num_words> CONCAT2(pad, __LINE__){}; |
| 23 | #define INSERT_PADDING_WORDS(num_words) u32 CONCAT2(pad, __LINE__)[(num_words)] | ||
| 24 | 24 | ||
| 25 | // Inlining | 25 | /// These are similar to the INSERT_PADDING_* macros, but are needed for padding unions. This is |
| 26 | #ifdef _WIN32 | 26 | /// because unions can only be initialized by one member. |
| 27 | #define FORCE_INLINE __forceinline | 27 | #define INSERT_UNION_PADDING_BYTES(num_bytes) std::array<u8, num_bytes> CONCAT2(pad, __LINE__); |
| 28 | #else | 28 | #define INSERT_UNION_PADDING_WORDS(num_words) std::array<u32, num_words> CONCAT2(pad, __LINE__); |
| 29 | #define FORCE_INLINE inline __attribute__((always_inline)) | ||
| 30 | #endif | ||
| 31 | 29 | ||
| 32 | #ifndef _MSC_VER | 30 | #ifndef _MSC_VER |
| 33 | 31 | ||
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index ea5c92f61..b8bbdd1ef 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp | |||
| @@ -32,11 +32,28 @@ enum class NCASectionFilesystemType : u8 { | |||
| 32 | ROMFS = 0x3, | 32 | ROMFS = 0x3, |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | struct IVFCLevel { | ||
| 36 | u64_le offset; | ||
| 37 | u64_le size; | ||
| 38 | u32_le block_size; | ||
| 39 | u32_le reserved; | ||
| 40 | }; | ||
| 41 | static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size."); | ||
| 42 | |||
| 43 | struct IVFCHeader { | ||
| 44 | u32_le magic; | ||
| 45 | u32_le magic_number; | ||
| 46 | INSERT_UNION_PADDING_BYTES(8); | ||
| 47 | std::array<IVFCLevel, 6> levels; | ||
| 48 | INSERT_UNION_PADDING_BYTES(64); | ||
| 49 | }; | ||
| 50 | static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size."); | ||
| 51 | |||
| 35 | struct NCASectionHeaderBlock { | 52 | struct NCASectionHeaderBlock { |
| 36 | INSERT_PADDING_BYTES(3); | 53 | INSERT_UNION_PADDING_BYTES(3); |
| 37 | NCASectionFilesystemType filesystem_type; | 54 | NCASectionFilesystemType filesystem_type; |
| 38 | NCASectionCryptoType crypto_type; | 55 | NCASectionCryptoType crypto_type; |
| 39 | INSERT_PADDING_BYTES(3); | 56 | INSERT_UNION_PADDING_BYTES(3); |
| 40 | }; | 57 | }; |
| 41 | static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size."); | 58 | static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size."); |
| 42 | 59 | ||
| @@ -44,7 +61,7 @@ struct NCASectionRaw { | |||
| 44 | NCASectionHeaderBlock header; | 61 | NCASectionHeaderBlock header; |
| 45 | std::array<u8, 0x138> block_data; | 62 | std::array<u8, 0x138> block_data; |
| 46 | std::array<u8, 0x8> section_ctr; | 63 | std::array<u8, 0x8> section_ctr; |
| 47 | INSERT_PADDING_BYTES(0xB8); | 64 | INSERT_UNION_PADDING_BYTES(0xB8); |
| 48 | }; | 65 | }; |
| 49 | static_assert(sizeof(NCASectionRaw) == 0x200, "NCASectionRaw has incorrect size."); | 66 | static_assert(sizeof(NCASectionRaw) == 0x200, "NCASectionRaw has incorrect size."); |
| 50 | 67 | ||
| @@ -52,19 +69,19 @@ struct PFS0Superblock { | |||
| 52 | NCASectionHeaderBlock header_block; | 69 | NCASectionHeaderBlock header_block; |
| 53 | std::array<u8, 0x20> hash; | 70 | std::array<u8, 0x20> hash; |
| 54 | u32_le size; | 71 | u32_le size; |
| 55 | INSERT_PADDING_BYTES(4); | 72 | INSERT_UNION_PADDING_BYTES(4); |
| 56 | u64_le hash_table_offset; | 73 | u64_le hash_table_offset; |
| 57 | u64_le hash_table_size; | 74 | u64_le hash_table_size; |
| 58 | u64_le pfs0_header_offset; | 75 | u64_le pfs0_header_offset; |
| 59 | u64_le pfs0_size; | 76 | u64_le pfs0_size; |
| 60 | INSERT_PADDING_BYTES(0x1B0); | 77 | INSERT_UNION_PADDING_BYTES(0x1B0); |
| 61 | }; | 78 | }; |
| 62 | static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size."); | 79 | static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size."); |
| 63 | 80 | ||
| 64 | struct RomFSSuperblock { | 81 | struct RomFSSuperblock { |
| 65 | NCASectionHeaderBlock header_block; | 82 | NCASectionHeaderBlock header_block; |
| 66 | IVFCHeader ivfc; | 83 | IVFCHeader ivfc; |
| 67 | INSERT_PADDING_BYTES(0x118); | 84 | INSERT_UNION_PADDING_BYTES(0x118); |
| 68 | }; | 85 | }; |
| 69 | static_assert(sizeof(RomFSSuperblock) == 0x200, "RomFSSuperblock has incorrect size."); | 86 | static_assert(sizeof(RomFSSuperblock) == 0x200, "RomFSSuperblock has incorrect size."); |
| 70 | 87 | ||
| @@ -72,24 +89,24 @@ struct BKTRHeader { | |||
| 72 | u64_le offset; | 89 | u64_le offset; |
| 73 | u64_le size; | 90 | u64_le size; |
| 74 | u32_le magic; | 91 | u32_le magic; |
| 75 | INSERT_PADDING_BYTES(0x4); | 92 | INSERT_UNION_PADDING_BYTES(0x4); |
| 76 | u32_le number_entries; | 93 | u32_le number_entries; |
| 77 | INSERT_PADDING_BYTES(0x4); | 94 | INSERT_UNION_PADDING_BYTES(0x4); |
| 78 | }; | 95 | }; |
| 79 | static_assert(sizeof(BKTRHeader) == 0x20, "BKTRHeader has incorrect size."); | 96 | static_assert(sizeof(BKTRHeader) == 0x20, "BKTRHeader has incorrect size."); |
| 80 | 97 | ||
| 81 | struct BKTRSuperblock { | 98 | struct BKTRSuperblock { |
| 82 | NCASectionHeaderBlock header_block; | 99 | NCASectionHeaderBlock header_block; |
| 83 | IVFCHeader ivfc; | 100 | IVFCHeader ivfc; |
| 84 | INSERT_PADDING_BYTES(0x18); | 101 | INSERT_UNION_PADDING_BYTES(0x18); |
| 85 | BKTRHeader relocation; | 102 | BKTRHeader relocation; |
| 86 | BKTRHeader subsection; | 103 | BKTRHeader subsection; |
| 87 | INSERT_PADDING_BYTES(0xC0); | 104 | INSERT_UNION_PADDING_BYTES(0xC0); |
| 88 | }; | 105 | }; |
| 89 | static_assert(sizeof(BKTRSuperblock) == 0x200, "BKTRSuperblock has incorrect size."); | 106 | static_assert(sizeof(BKTRSuperblock) == 0x200, "BKTRSuperblock has incorrect size."); |
| 90 | 107 | ||
| 91 | union NCASectionHeader { | 108 | union NCASectionHeader { |
| 92 | NCASectionRaw raw; | 109 | NCASectionRaw raw{}; |
| 93 | PFS0Superblock pfs0; | 110 | PFS0Superblock pfs0; |
| 94 | RomFSSuperblock romfs; | 111 | RomFSSuperblock romfs; |
| 95 | BKTRSuperblock bktr; | 112 | BKTRSuperblock bktr; |
diff --git a/src/core/file_sys/romfs.h b/src/core/file_sys/romfs.h index 0f35639bc..1c89be8a4 100644 --- a/src/core/file_sys/romfs.h +++ b/src/core/file_sys/romfs.h | |||
| @@ -13,25 +13,6 @@ | |||
| 13 | 13 | ||
| 14 | namespace FileSys { | 14 | namespace FileSys { |
| 15 | 15 | ||
| 16 | struct RomFSHeader; | ||
| 17 | |||
| 18 | struct IVFCLevel { | ||
| 19 | u64_le offset; | ||
| 20 | u64_le size; | ||
| 21 | u32_le block_size; | ||
| 22 | u32_le reserved; | ||
| 23 | }; | ||
| 24 | static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size."); | ||
| 25 | |||
| 26 | struct IVFCHeader { | ||
| 27 | u32_le magic; | ||
| 28 | u32_le magic_number; | ||
| 29 | INSERT_PADDING_BYTES(8); | ||
| 30 | std::array<IVFCLevel, 6> levels; | ||
| 31 | INSERT_PADDING_BYTES(64); | ||
| 32 | }; | ||
| 33 | static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size."); | ||
| 34 | |||
| 35 | enum class RomFSExtractionType { | 16 | enum class RomFSExtractionType { |
| 36 | Full, // Includes data directory | 17 | Full, // Includes data directory |
| 37 | Truncated, // Traverses into data directory | 18 | Truncated, // Traverses into data directory |
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index fc8755c78..e2a7eaf7b 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp | |||
| @@ -16,6 +16,7 @@ namespace FileSys { | |||
| 16 | constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size"; | 16 | constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size"; |
| 17 | 17 | ||
| 18 | namespace { | 18 | namespace { |
| 19 | |||
| 19 | void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) { | 20 | void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) { |
| 20 | if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { | 21 | if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { |
| 21 | if (meta.zero_1 != 0) { | 22 | if (meta.zero_1 != 0) { |
| @@ -52,6 +53,13 @@ void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) { | |||
| 52 | meta.user_id[1], meta.user_id[0]); | 53 | meta.user_id[1], meta.user_id[0]); |
| 53 | } | 54 | } |
| 54 | } | 55 | } |
| 56 | |||
| 57 | bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataDescriptor& desc) { | ||
| 58 | return desc.type == SaveDataType::CacheStorage || desc.type == SaveDataType::TemporaryStorage || | ||
| 59 | (space == SaveDataSpaceId::NandUser && ///< Normal Save Data -- Current Title & User | ||
| 60 | desc.type == SaveDataType::SaveData && desc.title_id == 0 && desc.save_id == 0); | ||
| 61 | } | ||
| 62 | |||
| 55 | } // Anonymous namespace | 63 | } // Anonymous namespace |
| 56 | 64 | ||
| 57 | std::string SaveDataDescriptor::DebugInfo() const { | 65 | std::string SaveDataDescriptor::DebugInfo() const { |
| @@ -96,6 +104,10 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space, | |||
| 96 | 104 | ||
| 97 | auto out = dir->GetDirectoryRelative(save_directory); | 105 | auto out = dir->GetDirectoryRelative(save_directory); |
| 98 | 106 | ||
| 107 | if (out == nullptr && ShouldSaveDataBeAutomaticallyCreated(space, meta)) { | ||
| 108 | return Create(space, meta); | ||
| 109 | } | ||
| 110 | |||
| 99 | // Return an error if the save data doesn't actually exist. | 111 | // Return an error if the save data doesn't actually exist. |
| 100 | if (out == nullptr) { | 112 | if (out == nullptr) { |
| 101 | // TODO(Subv): Find out correct error code. | 113 | // TODO(Subv): Find out correct error code. |
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h index fae54bcc7..7ce313190 100644 --- a/src/core/hle/ipc.h +++ b/src/core/hle/ipc.h | |||
| @@ -160,7 +160,7 @@ struct DomainMessageHeader { | |||
| 160 | // Used when responding to an IPC request, Server -> Client. | 160 | // Used when responding to an IPC request, Server -> Client. |
| 161 | struct { | 161 | struct { |
| 162 | u32_le num_objects; | 162 | u32_le num_objects; |
| 163 | INSERT_PADDING_WORDS(3); | 163 | INSERT_UNION_PADDING_WORDS(3); |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | // Used when performing an IPC request, Client -> Server. | 166 | // Used when performing an IPC request, Client -> Server. |
| @@ -171,8 +171,10 @@ struct DomainMessageHeader { | |||
| 171 | BitField<16, 16, u32> size; | 171 | BitField<16, 16, u32> size; |
| 172 | }; | 172 | }; |
| 173 | u32_le object_id; | 173 | u32_le object_id; |
| 174 | INSERT_PADDING_WORDS(2); | 174 | INSERT_UNION_PADDING_WORDS(2); |
| 175 | }; | 175 | }; |
| 176 | |||
| 177 | std::array<u32, 4> raw{}; | ||
| 176 | }; | 178 | }; |
| 177 | }; | 179 | }; |
| 178 | static_assert(sizeof(DomainMessageHeader) == 16, "DomainMessageHeader size is incorrect"); | 180 | static_assert(sizeof(DomainMessageHeader) == 16, "DomainMessageHeader size is incorrect"); |
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index e6dcb9639..0e2dbf13e 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -22,9 +22,9 @@ | |||
| 22 | 22 | ||
| 23 | namespace Kernel { | 23 | namespace Kernel { |
| 24 | 24 | ||
| 25 | GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} { | 25 | GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} {} |
| 26 | is_reselection_pending = false; | 26 | |
| 27 | } | 27 | GlobalScheduler::~GlobalScheduler() = default; |
| 28 | 28 | ||
| 29 | void GlobalScheduler::AddThread(SharedPtr<Thread> thread) { | 29 | void GlobalScheduler::AddThread(SharedPtr<Thread> thread) { |
| 30 | thread_list.push_back(std::move(thread)); | 30 | thread_list.push_back(std::move(thread)); |
| @@ -35,24 +35,11 @@ void GlobalScheduler::RemoveThread(const Thread* thread) { | |||
| 35 | thread_list.end()); | 35 | thread_list.end()); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | /* | ||
| 39 | * UnloadThread selects a core and forces it to unload its current thread's context | ||
| 40 | */ | ||
| 41 | void GlobalScheduler::UnloadThread(s32 core) { | 38 | void GlobalScheduler::UnloadThread(s32 core) { |
| 42 | Scheduler& sched = system.Scheduler(core); | 39 | Scheduler& sched = system.Scheduler(core); |
| 43 | sched.UnloadThread(); | 40 | sched.UnloadThread(); |
| 44 | } | 41 | } |
| 45 | 42 | ||
| 46 | /* | ||
| 47 | * SelectThread takes care of selecting the new scheduled thread. | ||
| 48 | * It does it in 3 steps: | ||
| 49 | * - First a thread is selected from the top of the priority queue. If no thread | ||
| 50 | * is obtained then we move to step two, else we are done. | ||
| 51 | * - Second we try to get a suggested thread that's not assigned to any core or | ||
| 52 | * that is not the top thread in that core. | ||
| 53 | * - Third is no suggested thread is found, we do a second pass and pick a running | ||
| 54 | * thread in another core and swap it with its current thread. | ||
| 55 | */ | ||
| 56 | void GlobalScheduler::SelectThread(u32 core) { | 43 | void GlobalScheduler::SelectThread(u32 core) { |
| 57 | const auto update_thread = [](Thread* thread, Scheduler& sched) { | 44 | const auto update_thread = [](Thread* thread, Scheduler& sched) { |
| 58 | if (thread != sched.selected_thread) { | 45 | if (thread != sched.selected_thread) { |
| @@ -114,30 +101,19 @@ void GlobalScheduler::SelectThread(u32 core) { | |||
| 114 | update_thread(current_thread, sched); | 101 | update_thread(current_thread, sched); |
| 115 | } | 102 | } |
| 116 | 103 | ||
| 117 | /* | ||
| 118 | * YieldThread takes a thread and moves it to the back of the it's priority list | ||
| 119 | * This operation can be redundant and no scheduling is changed if marked as so. | ||
| 120 | */ | ||
| 121 | bool GlobalScheduler::YieldThread(Thread* yielding_thread) { | 104 | bool GlobalScheduler::YieldThread(Thread* yielding_thread) { |
| 122 | // Note: caller should use critical section, etc. | 105 | // Note: caller should use critical section, etc. |
| 123 | const u32 core_id = static_cast<u32>(yielding_thread->GetProcessorID()); | 106 | const u32 core_id = static_cast<u32>(yielding_thread->GetProcessorID()); |
| 124 | const u32 priority = yielding_thread->GetPriority(); | 107 | const u32 priority = yielding_thread->GetPriority(); |
| 125 | 108 | ||
| 126 | // Yield the thread | 109 | // Yield the thread |
| 127 | ASSERT_MSG(yielding_thread == scheduled_queue[core_id].front(priority), | 110 | const Thread* const winner = scheduled_queue[core_id].front(priority); |
| 128 | "Thread yielding without being in front"); | 111 | ASSERT_MSG(yielding_thread == winner, "Thread yielding without being in front"); |
| 129 | scheduled_queue[core_id].yield(priority); | 112 | scheduled_queue[core_id].yield(priority); |
| 130 | 113 | ||
| 131 | Thread* winner = scheduled_queue[core_id].front(priority); | ||
| 132 | return AskForReselectionOrMarkRedundant(yielding_thread, winner); | 114 | return AskForReselectionOrMarkRedundant(yielding_thread, winner); |
| 133 | } | 115 | } |
| 134 | 116 | ||
| 135 | /* | ||
| 136 | * YieldThreadAndBalanceLoad takes a thread and moves it to the back of the it's priority list. | ||
| 137 | * Afterwards, tries to pick a suggested thread from the suggested queue that has worse time or | ||
| 138 | * a better priority than the next thread in the core. | ||
| 139 | * This operation can be redundant and no scheduling is changed if marked as so. | ||
| 140 | */ | ||
| 141 | bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) { | 117 | bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) { |
| 142 | // Note: caller should check if !thread.IsSchedulerOperationRedundant and use critical section, | 118 | // Note: caller should check if !thread.IsSchedulerOperationRedundant and use critical section, |
| 143 | // etc. | 119 | // etc. |
| @@ -189,12 +165,6 @@ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) { | |||
| 189 | return AskForReselectionOrMarkRedundant(yielding_thread, winner); | 165 | return AskForReselectionOrMarkRedundant(yielding_thread, winner); |
| 190 | } | 166 | } |
| 191 | 167 | ||
| 192 | /* | ||
| 193 | * YieldThreadAndWaitForLoadBalancing takes a thread and moves it out of the scheduling queue | ||
| 194 | * and into the suggested queue. If no thread can be squeduled afterwards in that core, | ||
| 195 | * a suggested thread is obtained instead. | ||
| 196 | * This operation can be redundant and no scheduling is changed if marked as so. | ||
| 197 | */ | ||
| 198 | bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread) { | 168 | bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread) { |
| 199 | // Note: caller should check if !thread.IsSchedulerOperationRedundant and use critical section, | 169 | // Note: caller should check if !thread.IsSchedulerOperationRedundant and use critical section, |
| 200 | // etc. | 170 | // etc. |
| @@ -280,7 +250,7 @@ void GlobalScheduler::PreemptThreads() { | |||
| 280 | if (winner->IsRunning()) { | 250 | if (winner->IsRunning()) { |
| 281 | UnloadThread(winner->GetProcessorID()); | 251 | UnloadThread(winner->GetProcessorID()); |
| 282 | } | 252 | } |
| 283 | TransferToCore(winner->GetPriority(), core_id, winner); | 253 | TransferToCore(winner->GetPriority(), s32(core_id), winner); |
| 284 | current_thread = | 254 | current_thread = |
| 285 | winner->GetPriority() <= current_thread->GetPriority() ? winner : current_thread; | 255 | winner->GetPriority() <= current_thread->GetPriority() ? winner : current_thread; |
| 286 | } | 256 | } |
| @@ -313,7 +283,7 @@ void GlobalScheduler::PreemptThreads() { | |||
| 313 | if (winner->IsRunning()) { | 283 | if (winner->IsRunning()) { |
| 314 | UnloadThread(winner->GetProcessorID()); | 284 | UnloadThread(winner->GetProcessorID()); |
| 315 | } | 285 | } |
| 316 | TransferToCore(winner->GetPriority(), core_id, winner); | 286 | TransferToCore(winner->GetPriority(), s32(core_id), winner); |
| 317 | current_thread = winner; | 287 | current_thread = winner; |
| 318 | } | 288 | } |
| 319 | } | 289 | } |
| @@ -331,12 +301,12 @@ void GlobalScheduler::Unsuggest(u32 priority, u32 core, Thread* thread) { | |||
| 331 | } | 301 | } |
| 332 | 302 | ||
| 333 | void GlobalScheduler::Schedule(u32 priority, u32 core, Thread* thread) { | 303 | void GlobalScheduler::Schedule(u32 priority, u32 core, Thread* thread) { |
| 334 | ASSERT_MSG(thread->GetProcessorID() == core, "Thread must be assigned to this core."); | 304 | ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core."); |
| 335 | scheduled_queue[core].add(thread, priority); | 305 | scheduled_queue[core].add(thread, priority); |
| 336 | } | 306 | } |
| 337 | 307 | ||
| 338 | void GlobalScheduler::SchedulePrepend(u32 priority, u32 core, Thread* thread) { | 308 | void GlobalScheduler::SchedulePrepend(u32 priority, u32 core, Thread* thread) { |
| 339 | ASSERT_MSG(thread->GetProcessorID() == core, "Thread must be assigned to this core."); | 309 | ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core."); |
| 340 | scheduled_queue[core].add(thread, priority, false); | 310 | scheduled_queue[core].add(thread, priority, false); |
| 341 | } | 311 | } |
| 342 | 312 | ||
| @@ -368,7 +338,8 @@ void GlobalScheduler::TransferToCore(u32 priority, s32 destination_core, Thread* | |||
| 368 | } | 338 | } |
| 369 | } | 339 | } |
| 370 | 340 | ||
| 371 | bool GlobalScheduler::AskForReselectionOrMarkRedundant(Thread* current_thread, Thread* winner) { | 341 | bool GlobalScheduler::AskForReselectionOrMarkRedundant(Thread* current_thread, |
| 342 | const Thread* winner) { | ||
| 372 | if (current_thread == winner) { | 343 | if (current_thread == winner) { |
| 373 | current_thread->IncrementYieldCount(); | 344 | current_thread->IncrementYieldCount(); |
| 374 | return true; | 345 | return true; |
| @@ -386,8 +357,6 @@ void GlobalScheduler::Shutdown() { | |||
| 386 | thread_list.clear(); | 357 | thread_list.clear(); |
| 387 | } | 358 | } |
| 388 | 359 | ||
| 389 | GlobalScheduler::~GlobalScheduler() = default; | ||
| 390 | |||
| 391 | Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, u32 core_id) | 360 | Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, u32 core_id) |
| 392 | : system(system), cpu_core(cpu_core), core_id(core_id) {} | 361 | : system(system), cpu_core(cpu_core), core_id(core_id) {} |
| 393 | 362 | ||
| @@ -470,7 +439,7 @@ void Scheduler::SwitchContext() { | |||
| 470 | 439 | ||
| 471 | // Load context of new thread | 440 | // Load context of new thread |
| 472 | if (new_thread) { | 441 | if (new_thread) { |
| 473 | ASSERT_MSG(new_thread->GetProcessorID() == this->core_id, | 442 | ASSERT_MSG(new_thread->GetProcessorID() == s32(this->core_id), |
| 474 | "Thread must be assigned to this core."); | 443 | "Thread must be assigned to this core."); |
| 475 | ASSERT_MSG(new_thread->GetStatus() == ThreadStatus::Ready, | 444 | ASSERT_MSG(new_thread->GetStatus() == ThreadStatus::Ready, |
| 476 | "Thread must be ready to become running."); | 445 | "Thread must be ready to become running."); |
diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index fcae28e0a..f2d6311b8 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h | |||
| @@ -26,6 +26,7 @@ public: | |||
| 26 | 26 | ||
| 27 | explicit GlobalScheduler(Core::System& system); | 27 | explicit GlobalScheduler(Core::System& system); |
| 28 | ~GlobalScheduler(); | 28 | ~GlobalScheduler(); |
| 29 | |||
| 29 | /// Adds a new thread to the scheduler | 30 | /// Adds a new thread to the scheduler |
| 30 | void AddThread(SharedPtr<Thread> thread); | 31 | void AddThread(SharedPtr<Thread> thread); |
| 31 | 32 | ||
| @@ -37,47 +38,57 @@ public: | |||
| 37 | return thread_list; | 38 | return thread_list; |
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | // Add a thread to the suggested queue of a cpu core. Suggested threads may be | 41 | /** |
| 41 | // picked if no thread is scheduled to run on the core. | 42 | * Add a thread to the suggested queue of a cpu core. Suggested threads may be |
| 43 | * picked if no thread is scheduled to run on the core. | ||
| 44 | */ | ||
| 42 | void Suggest(u32 priority, u32 core, Thread* thread); | 45 | void Suggest(u32 priority, u32 core, Thread* thread); |
| 43 | 46 | ||
| 44 | // Remove a thread to the suggested queue of a cpu core. Suggested threads may be | 47 | /** |
| 45 | // picked if no thread is scheduled to run on the core. | 48 | * Remove a thread to the suggested queue of a cpu core. Suggested threads may be |
| 49 | * picked if no thread is scheduled to run on the core. | ||
| 50 | */ | ||
| 46 | void Unsuggest(u32 priority, u32 core, Thread* thread); | 51 | void Unsuggest(u32 priority, u32 core, Thread* thread); |
| 47 | 52 | ||
| 48 | // Add a thread to the scheduling queue of a cpu core. The thread is added at the | 53 | /** |
| 49 | // back the queue in its priority level | 54 | * Add a thread to the scheduling queue of a cpu core. The thread is added at the |
| 55 | * back the queue in its priority level. | ||
| 56 | */ | ||
| 50 | void Schedule(u32 priority, u32 core, Thread* thread); | 57 | void Schedule(u32 priority, u32 core, Thread* thread); |
| 51 | 58 | ||
| 52 | // Add a thread to the scheduling queue of a cpu core. The thread is added at the | 59 | /** |
| 53 | // front the queue in its priority level | 60 | * Add a thread to the scheduling queue of a cpu core. The thread is added at the |
| 61 | * front the queue in its priority level. | ||
| 62 | */ | ||
| 54 | void SchedulePrepend(u32 priority, u32 core, Thread* thread); | 63 | void SchedulePrepend(u32 priority, u32 core, Thread* thread); |
| 55 | 64 | ||
| 56 | // Reschedule an already scheduled thread based on a new priority | 65 | /// Reschedule an already scheduled thread based on a new priority |
| 57 | void Reschedule(u32 priority, u32 core, Thread* thread); | 66 | void Reschedule(u32 priority, u32 core, Thread* thread); |
| 58 | 67 | ||
| 59 | // Unschedule a thread. | 68 | /// Unschedules a thread. |
| 60 | void Unschedule(u32 priority, u32 core, Thread* thread); | 69 | void Unschedule(u32 priority, u32 core, Thread* thread); |
| 61 | 70 | ||
| 62 | // Transfers a thread into an specific core. If the destination_core is -1 | 71 | /** |
| 63 | // it will be unscheduled from its source code and added into its suggested | 72 | * Transfers a thread into an specific core. If the destination_core is -1 |
| 64 | // queue. | 73 | * it will be unscheduled from its source code and added into its suggested |
| 74 | * queue. | ||
| 75 | */ | ||
| 65 | void TransferToCore(u32 priority, s32 destination_core, Thread* thread); | 76 | void TransferToCore(u32 priority, s32 destination_core, Thread* thread); |
| 66 | 77 | ||
| 67 | /* | 78 | /// Selects a core and forces it to unload its current thread's context |
| 68 | * UnloadThread selects a core and forces it to unload its current thread's context | ||
| 69 | */ | ||
| 70 | void UnloadThread(s32 core); | 79 | void UnloadThread(s32 core); |
| 71 | 80 | ||
| 72 | /* | 81 | /** |
| 73 | * SelectThread takes care of selecting the new scheduled thread. | 82 | * Takes care of selecting the new scheduled thread in three steps: |
| 74 | * It does it in 3 steps: | 83 | * |
| 75 | * - First a thread is selected from the top of the priority queue. If no thread | 84 | * 1. First a thread is selected from the top of the priority queue. If no thread |
| 76 | * is obtained then we move to step two, else we are done. | 85 | * is obtained then we move to step two, else we are done. |
| 77 | * - Second we try to get a suggested thread that's not assigned to any core or | 86 | * |
| 78 | * that is not the top thread in that core. | 87 | * 2. Second we try to get a suggested thread that's not assigned to any core or |
| 79 | * - Third is no suggested thread is found, we do a second pass and pick a running | 88 | * that is not the top thread in that core. |
| 80 | * thread in another core and swap it with its current thread. | 89 | * |
| 90 | * 3. Third is no suggested thread is found, we do a second pass and pick a running | ||
| 91 | * thread in another core and swap it with its current thread. | ||
| 81 | */ | 92 | */ |
| 82 | void SelectThread(u32 core); | 93 | void SelectThread(u32 core); |
| 83 | 94 | ||
| @@ -85,33 +96,37 @@ public: | |||
| 85 | return !scheduled_queue[core_id].empty(); | 96 | return !scheduled_queue[core_id].empty(); |
| 86 | } | 97 | } |
| 87 | 98 | ||
| 88 | /* | 99 | /** |
| 89 | * YieldThread takes a thread and moves it to the back of the it's priority list | 100 | * Takes a thread and moves it to the back of the it's priority list. |
| 90 | * This operation can be redundant and no scheduling is changed if marked as so. | 101 | * |
| 102 | * @note This operation can be redundant and no scheduling is changed if marked as so. | ||
| 91 | */ | 103 | */ |
| 92 | bool YieldThread(Thread* thread); | 104 | bool YieldThread(Thread* thread); |
| 93 | 105 | ||
| 94 | /* | 106 | /** |
| 95 | * YieldThreadAndBalanceLoad takes a thread and moves it to the back of the it's priority list. | 107 | * Takes a thread and moves it to the back of the it's priority list. |
| 96 | * Afterwards, tries to pick a suggested thread from the suggested queue that has worse time or | 108 | * Afterwards, tries to pick a suggested thread from the suggested queue that has worse time or |
| 97 | * a better priority than the next thread in the core. | 109 | * a better priority than the next thread in the core. |
| 98 | * This operation can be redundant and no scheduling is changed if marked as so. | 110 | * |
| 111 | * @note This operation can be redundant and no scheduling is changed if marked as so. | ||
| 99 | */ | 112 | */ |
| 100 | bool YieldThreadAndBalanceLoad(Thread* thread); | 113 | bool YieldThreadAndBalanceLoad(Thread* thread); |
| 101 | 114 | ||
| 102 | /* | 115 | /** |
| 103 | * YieldThreadAndWaitForLoadBalancing takes a thread and moves it out of the scheduling queue | 116 | * Takes a thread and moves it out of the scheduling queue. |
| 104 | * and into the suggested queue. If no thread can be squeduled afterwards in that core, | 117 | * and into the suggested queue. If no thread can be scheduled afterwards in that core, |
| 105 | * a suggested thread is obtained instead. | 118 | * a suggested thread is obtained instead. |
| 106 | * This operation can be redundant and no scheduling is changed if marked as so. | 119 | * |
| 120 | * @note This operation can be redundant and no scheduling is changed if marked as so. | ||
| 107 | */ | 121 | */ |
| 108 | bool YieldThreadAndWaitForLoadBalancing(Thread* thread); | 122 | bool YieldThreadAndWaitForLoadBalancing(Thread* thread); |
| 109 | 123 | ||
| 110 | /* | 124 | /** |
| 111 | * PreemptThreads this operation rotates the scheduling queues of threads at | 125 | * Rotates the scheduling queues of threads at a preemption priority and then does |
| 112 | * a preemption priority and then does some core rebalancing. Preemption priorities | 126 | * some core rebalancing. Preemption priorities can be found in the array |
| 113 | * can be found in the array 'preemption_priorities'. This operation happens | 127 | * 'preemption_priorities'. |
| 114 | * every 10ms. | 128 | * |
| 129 | * @note This operation happens every 10ms. | ||
| 115 | */ | 130 | */ |
| 116 | void PreemptThreads(); | 131 | void PreemptThreads(); |
| 117 | 132 | ||
| @@ -130,15 +145,15 @@ public: | |||
| 130 | void Shutdown(); | 145 | void Shutdown(); |
| 131 | 146 | ||
| 132 | private: | 147 | private: |
| 133 | bool AskForReselectionOrMarkRedundant(Thread* current_thread, Thread* winner); | 148 | bool AskForReselectionOrMarkRedundant(Thread* current_thread, const Thread* winner); |
| 134 | 149 | ||
| 135 | static constexpr u32 min_regular_priority = 2; | 150 | static constexpr u32 min_regular_priority = 2; |
| 136 | std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> scheduled_queue; | 151 | std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> scheduled_queue; |
| 137 | std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> suggested_queue; | 152 | std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> suggested_queue; |
| 138 | std::atomic<bool> is_reselection_pending; | 153 | std::atomic<bool> is_reselection_pending{false}; |
| 139 | 154 | ||
| 140 | // `preemption_priorities` are the priority levels at which the global scheduler | 155 | // The priority levels at which the global scheduler preempts threads every 10 ms. They are |
| 141 | // preempts threads every 10 ms. They are ordered from Core 0 to Core 3 | 156 | // ordered from Core 0 to Core 3. |
| 142 | std::array<u32, NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62}; | 157 | std::array<u32, NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62}; |
| 143 | 158 | ||
| 144 | /// Lists all thread ids that aren't deleted/etc. | 159 | /// Lists all thread ids that aren't deleted/etc. |
| @@ -181,10 +196,8 @@ public: | |||
| 181 | 196 | ||
| 182 | private: | 197 | private: |
| 183 | friend class GlobalScheduler; | 198 | friend class GlobalScheduler; |
| 184 | /** | 199 | |
| 185 | * Switches the CPU's active thread context to that of the specified thread | 200 | /// Switches the CPU's active thread context to that of the specified thread |
| 186 | * @param new_thread The thread to switch to | ||
| 187 | */ | ||
| 188 | void SwitchContext(); | 201 | void SwitchContext(); |
| 189 | 202 | ||
| 190 | /** | 203 | /** |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 3a32d5b41..3d8a91d22 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -1073,9 +1073,9 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | |||
| 1073 | {71, nullptr, "RequestToReboot"}, | 1073 | {71, nullptr, "RequestToReboot"}, |
| 1074 | {80, nullptr, "ExitAndRequestToShowThanksMessage"}, | 1074 | {80, nullptr, "ExitAndRequestToShowThanksMessage"}, |
| 1075 | {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"}, | 1075 | {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"}, |
| 1076 | {100, nullptr, "InitializeApplicationCopyrightFrameBuffer"}, | 1076 | {100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"}, |
| 1077 | {101, nullptr, "SetApplicationCopyrightImage"}, | 1077 | {101, &IApplicationFunctions::SetApplicationCopyrightImage, "SetApplicationCopyrightImage"}, |
| 1078 | {102, nullptr, "SetApplicationCopyrightVisibility"}, | 1078 | {102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"}, |
| 1079 | {110, nullptr, "QueryApplicationPlayStatistics"}, | 1079 | {110, nullptr, "QueryApplicationPlayStatistics"}, |
| 1080 | {120, nullptr, "ExecuteProgram"}, | 1080 | {120, nullptr, "ExecuteProgram"}, |
| 1081 | {121, nullptr, "ClearUserChannel"}, | 1081 | {121, nullptr, "ClearUserChannel"}, |
| @@ -1103,6 +1103,31 @@ void IApplicationFunctions::EnableApplicationCrashReport(Kernel::HLERequestConte | |||
| 1103 | rb.Push(RESULT_SUCCESS); | 1103 | rb.Push(RESULT_SUCCESS); |
| 1104 | } | 1104 | } |
| 1105 | 1105 | ||
| 1106 | void IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer( | ||
| 1107 | Kernel::HLERequestContext& ctx) { | ||
| 1108 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 1109 | |||
| 1110 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1111 | rb.Push(RESULT_SUCCESS); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | void IApplicationFunctions::SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx) { | ||
| 1115 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 1116 | |||
| 1117 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1118 | rb.Push(RESULT_SUCCESS); | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | void IApplicationFunctions::SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx) { | ||
| 1122 | IPC::RequestParser rp{ctx}; | ||
| 1123 | const auto is_visible = rp.Pop<bool>(); | ||
| 1124 | |||
| 1125 | LOG_WARNING(Service_AM, "(STUBBED) called, is_visible={}", is_visible); | ||
| 1126 | |||
| 1127 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1128 | rb.Push(RESULT_SUCCESS); | ||
| 1129 | } | ||
| 1130 | |||
| 1106 | void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed( | 1131 | void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed( |
| 1107 | Kernel::HLERequestContext& ctx) { | 1132 | Kernel::HLERequestContext& ctx) { |
| 1108 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 1133 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index ccd053c13..2ae9402a8 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -252,6 +252,9 @@ private: | |||
| 252 | void BeginBlockingHomeButton(Kernel::HLERequestContext& ctx); | 252 | void BeginBlockingHomeButton(Kernel::HLERequestContext& ctx); |
| 253 | void EndBlockingHomeButton(Kernel::HLERequestContext& ctx); | 253 | void EndBlockingHomeButton(Kernel::HLERequestContext& ctx); |
| 254 | void EnableApplicationCrashReport(Kernel::HLERequestContext& ctx); | 254 | void EnableApplicationCrashReport(Kernel::HLERequestContext& ctx); |
| 255 | void InitializeApplicationCopyrightFrameBuffer(Kernel::HLERequestContext& ctx); | ||
| 256 | void SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx); | ||
| 257 | void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx); | ||
| 255 | void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); | 258 | void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); |
| 256 | 259 | ||
| 257 | bool launch_popped_application_specific = false; | 260 | bool launch_popped_application_specific = false; |
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp index a7db26725..eab0d42c9 100644 --- a/src/core/hle/service/am/applets/error.cpp +++ b/src/core/hle/service/am/applets/error.cpp | |||
| @@ -20,9 +20,9 @@ namespace Service::AM::Applets { | |||
| 20 | struct ShowError { | 20 | struct ShowError { |
| 21 | u8 mode; | 21 | u8 mode; |
| 22 | bool jump; | 22 | bool jump; |
| 23 | INSERT_PADDING_BYTES(4); | 23 | INSERT_UNION_PADDING_BYTES(4); |
| 24 | bool use_64bit_error_code; | 24 | bool use_64bit_error_code; |
| 25 | INSERT_PADDING_BYTES(1); | 25 | INSERT_UNION_PADDING_BYTES(1); |
| 26 | u64 error_code_64; | 26 | u64 error_code_64; |
| 27 | u32 error_code_32; | 27 | u32 error_code_32; |
| 28 | }; | 28 | }; |
| @@ -32,7 +32,7 @@ static_assert(sizeof(ShowError) == 0x14, "ShowError has incorrect size."); | |||
| 32 | struct ShowErrorRecord { | 32 | struct ShowErrorRecord { |
| 33 | u8 mode; | 33 | u8 mode; |
| 34 | bool jump; | 34 | bool jump; |
| 35 | INSERT_PADDING_BYTES(6); | 35 | INSERT_UNION_PADDING_BYTES(6); |
| 36 | u64 error_code_64; | 36 | u64 error_code_64; |
| 37 | u64 posix_time; | 37 | u64 posix_time; |
| 38 | }; | 38 | }; |
| @@ -41,7 +41,7 @@ static_assert(sizeof(ShowErrorRecord) == 0x18, "ShowErrorRecord has incorrect si | |||
| 41 | struct SystemErrorArg { | 41 | struct SystemErrorArg { |
| 42 | u8 mode; | 42 | u8 mode; |
| 43 | bool jump; | 43 | bool jump; |
| 44 | INSERT_PADDING_BYTES(6); | 44 | INSERT_UNION_PADDING_BYTES(6); |
| 45 | u64 error_code_64; | 45 | u64 error_code_64; |
| 46 | std::array<char, 8> language_code; | 46 | std::array<char, 8> language_code; |
| 47 | std::array<char, 0x800> main_text; | 47 | std::array<char, 0x800> main_text; |
| @@ -52,7 +52,7 @@ static_assert(sizeof(SystemErrorArg) == 0x1018, "SystemErrorArg has incorrect si | |||
| 52 | struct ApplicationErrorArg { | 52 | struct ApplicationErrorArg { |
| 53 | u8 mode; | 53 | u8 mode; |
| 54 | bool jump; | 54 | bool jump; |
| 55 | INSERT_PADDING_BYTES(6); | 55 | INSERT_UNION_PADDING_BYTES(6); |
| 56 | u32 error_code; | 56 | u32 error_code; |
| 57 | std::array<char, 8> language_code; | 57 | std::array<char, 8> language_code; |
| 58 | std::array<char, 0x800> main_text; | 58 | std::array<char, 0x800> main_text; |
| @@ -65,6 +65,7 @@ union Error::ErrorArguments { | |||
| 65 | ShowErrorRecord error_record; | 65 | ShowErrorRecord error_record; |
| 66 | SystemErrorArg system_error; | 66 | SystemErrorArg system_error; |
| 67 | ApplicationErrorArg application_error; | 67 | ApplicationErrorArg application_error; |
| 68 | std::array<u8, 0x1018> raw{}; | ||
| 68 | }; | 69 | }; |
| 69 | 70 | ||
| 70 | namespace { | 71 | namespace { |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index ba1da4181..ecc130f6c 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -203,13 +203,13 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) { | |||
| 203 | {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, | 203 | {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, |
| 204 | {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, | 204 | {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, |
| 205 | {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, | 205 | {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, |
| 206 | {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"}, | 206 | {123, &Hid::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"}, |
| 207 | {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, | 207 | {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, |
| 208 | {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, | 208 | {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, |
| 209 | {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"}, | 209 | {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"}, |
| 210 | {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"}, | 210 | {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"}, |
| 211 | {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, | 211 | {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, |
| 212 | {129, nullptr, "GetNpadHandheldActivationMode"}, | 212 | {129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"}, |
| 213 | {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, | 213 | {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, |
| 214 | {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"}, | 214 | {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"}, |
| 215 | {132, nullptr, "EnableUnintendedHomeButtonInputProtection"}, | 215 | {132, nullptr, "EnableUnintendedHomeButtonInputProtection"}, |
| @@ -557,10 +557,126 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx | |||
| 557 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id, | 557 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id, |
| 558 | applet_resource_user_id); | 558 | applet_resource_user_id); |
| 559 | 559 | ||
| 560 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 561 | controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single); | ||
| 562 | |||
| 563 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 564 | rb.Push(RESULT_SUCCESS); | ||
| 565 | } | ||
| 566 | |||
| 567 | void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) { | ||
| 568 | // TODO: Check the differences between this and SetNpadJoyAssignmentModeSingleByDefault | ||
| 569 | IPC::RequestParser rp{ctx}; | ||
| 570 | const auto npad_id{rp.Pop<u32>()}; | ||
| 571 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 572 | const auto npad_joy_device_type{rp.Pop<u64>()}; | ||
| 573 | |||
| 574 | LOG_WARNING(Service_HID, | ||
| 575 | "(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | ||
| 576 | npad_id, applet_resource_user_id, npad_joy_device_type); | ||
| 577 | |||
| 578 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 579 | controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single); | ||
| 580 | |||
| 581 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 582 | rb.Push(RESULT_SUCCESS); | ||
| 583 | } | ||
| 584 | |||
| 585 | void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { | ||
| 586 | IPC::RequestParser rp{ctx}; | ||
| 587 | const auto npad_id{rp.Pop<u32>()}; | ||
| 588 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 589 | |||
| 590 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id, | ||
| 591 | applet_resource_user_id); | ||
| 592 | |||
| 593 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 594 | controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual); | ||
| 595 | |||
| 596 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 597 | rb.Push(RESULT_SUCCESS); | ||
| 598 | } | ||
| 599 | |||
| 600 | void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { | ||
| 601 | IPC::RequestParser rp{ctx}; | ||
| 602 | const auto unknown_1{rp.Pop<u32>()}; | ||
| 603 | const auto unknown_2{rp.Pop<u32>()}; | ||
| 604 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 605 | |||
| 606 | LOG_WARNING(Service_HID, | ||
| 607 | "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", | ||
| 608 | unknown_1, unknown_2, applet_resource_user_id); | ||
| 609 | |||
| 610 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 611 | rb.Push(RESULT_SUCCESS); | ||
| 612 | } | ||
| 613 | |||
| 614 | void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { | ||
| 615 | IPC::RequestParser rp{ctx}; | ||
| 616 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 617 | |||
| 618 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 619 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 620 | controller.StartLRAssignmentMode(); | ||
| 621 | |||
| 622 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 623 | rb.Push(RESULT_SUCCESS); | ||
| 624 | } | ||
| 625 | |||
| 626 | void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) { | ||
| 627 | IPC::RequestParser rp{ctx}; | ||
| 628 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 629 | |||
| 630 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 631 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 632 | controller.StopLRAssignmentMode(); | ||
| 633 | |||
| 634 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 635 | rb.Push(RESULT_SUCCESS); | ||
| 636 | } | ||
| 637 | |||
| 638 | void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { | ||
| 639 | IPC::RequestParser rp{ctx}; | ||
| 640 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 641 | const auto mode{rp.Pop<u64>()}; | ||
| 642 | |||
| 643 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}", | ||
| 644 | applet_resource_user_id, mode); | ||
| 645 | |||
| 646 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 647 | rb.Push(RESULT_SUCCESS); | ||
| 648 | } | ||
| 649 | |||
| 650 | void Hid::GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { | ||
| 651 | IPC::RequestParser rp{ctx}; | ||
| 652 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 653 | |||
| 654 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 655 | applet_resource_user_id); | ||
| 656 | |||
| 560 | IPC::ResponseBuilder rb{ctx, 2}; | 657 | IPC::ResponseBuilder rb{ctx, 2}; |
| 561 | rb.Push(RESULT_SUCCESS); | 658 | rb.Push(RESULT_SUCCESS); |
| 562 | } | 659 | } |
| 563 | 660 | ||
| 661 | void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { | ||
| 662 | IPC::RequestParser rp{ctx}; | ||
| 663 | const auto npad_1{rp.Pop<u32>()}; | ||
| 664 | const auto npad_2{rp.Pop<u32>()}; | ||
| 665 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 666 | |||
| 667 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}", | ||
| 668 | applet_resource_user_id, npad_1, npad_2); | ||
| 669 | |||
| 670 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 671 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 672 | if (controller.SwapNpadAssignment(npad_1, npad_2)) { | ||
| 673 | rb.Push(RESULT_SUCCESS); | ||
| 674 | } else { | ||
| 675 | LOG_ERROR(Service_HID, "Npads are not connected!"); | ||
| 676 | rb.Push(ERR_NPAD_NOT_CONNECTED); | ||
| 677 | } | ||
| 678 | } | ||
| 679 | |||
| 564 | void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { | 680 | void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { |
| 565 | IPC::RequestParser rp{ctx}; | 681 | IPC::RequestParser rp{ctx}; |
| 566 | const auto applet_resource_user_id{rp.Pop<u64>()}; | 682 | const auto applet_resource_user_id{rp.Pop<u64>()}; |
| @@ -635,47 +751,6 @@ void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) { | |||
| 635 | applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration()); | 751 | applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration()); |
| 636 | } | 752 | } |
| 637 | 753 | ||
| 638 | void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { | ||
| 639 | IPC::RequestParser rp{ctx}; | ||
| 640 | const auto npad_id{rp.Pop<u32>()}; | ||
| 641 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 642 | |||
| 643 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id, | ||
| 644 | applet_resource_user_id); | ||
| 645 | |||
| 646 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 647 | controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual); | ||
| 648 | |||
| 649 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 650 | rb.Push(RESULT_SUCCESS); | ||
| 651 | } | ||
| 652 | |||
| 653 | void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { | ||
| 654 | IPC::RequestParser rp{ctx}; | ||
| 655 | const auto unknown_1{rp.Pop<u32>()}; | ||
| 656 | const auto unknown_2{rp.Pop<u32>()}; | ||
| 657 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 658 | |||
| 659 | LOG_WARNING(Service_HID, | ||
| 660 | "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", | ||
| 661 | unknown_1, unknown_2, applet_resource_user_id); | ||
| 662 | |||
| 663 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 664 | rb.Push(RESULT_SUCCESS); | ||
| 665 | } | ||
| 666 | |||
| 667 | void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { | ||
| 668 | IPC::RequestParser rp{ctx}; | ||
| 669 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 670 | const auto mode{rp.Pop<u64>()}; | ||
| 671 | |||
| 672 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}", | ||
| 673 | applet_resource_user_id, mode); | ||
| 674 | |||
| 675 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 676 | rb.Push(RESULT_SUCCESS); | ||
| 677 | } | ||
| 678 | |||
| 679 | void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { | 754 | void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { |
| 680 | LOG_DEBUG(Service_HID, "called"); | 755 | LOG_DEBUG(Service_HID, "called"); |
| 681 | 756 | ||
| @@ -769,49 +844,6 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) { | |||
| 769 | rb.Push(RESULT_SUCCESS); | 844 | rb.Push(RESULT_SUCCESS); |
| 770 | } | 845 | } |
| 771 | 846 | ||
| 772 | void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { | ||
| 773 | IPC::RequestParser rp{ctx}; | ||
| 774 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 775 | |||
| 776 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 777 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 778 | controller.StartLRAssignmentMode(); | ||
| 779 | |||
| 780 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 781 | rb.Push(RESULT_SUCCESS); | ||
| 782 | } | ||
| 783 | |||
| 784 | void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) { | ||
| 785 | IPC::RequestParser rp{ctx}; | ||
| 786 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 787 | |||
| 788 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 789 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 790 | controller.StopLRAssignmentMode(); | ||
| 791 | |||
| 792 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 793 | rb.Push(RESULT_SUCCESS); | ||
| 794 | } | ||
| 795 | |||
| 796 | void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { | ||
| 797 | IPC::RequestParser rp{ctx}; | ||
| 798 | const auto npad_1{rp.Pop<u32>()}; | ||
| 799 | const auto npad_2{rp.Pop<u32>()}; | ||
| 800 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 801 | |||
| 802 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}", | ||
| 803 | applet_resource_user_id, npad_1, npad_2); | ||
| 804 | |||
| 805 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 806 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 807 | if (controller.SwapNpadAssignment(npad_1, npad_2)) { | ||
| 808 | rb.Push(RESULT_SUCCESS); | ||
| 809 | } else { | ||
| 810 | LOG_ERROR(Service_HID, "Npads are not connected!"); | ||
| 811 | rb.Push(ERR_NPAD_NOT_CONNECTED); | ||
| 812 | } | ||
| 813 | } | ||
| 814 | |||
| 815 | class HidDbg final : public ServiceFramework<HidDbg> { | 847 | class HidDbg final : public ServiceFramework<HidDbg> { |
| 816 | public: | 848 | public: |
| 817 | explicit HidDbg() : ServiceFramework{"hid:dbg"} { | 849 | explicit HidDbg() : ServiceFramework{"hid:dbg"} { |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 01852e019..f08e036a3 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -106,14 +106,19 @@ private: | |||
| 106 | void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx); | 106 | void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx); |
| 107 | void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx); | 107 | void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx); |
| 108 | void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx); | 108 | void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx); |
| 109 | void SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx); | ||
| 110 | void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx); | ||
| 111 | void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx); | ||
| 112 | void StartLrAssignmentMode(Kernel::HLERequestContext& ctx); | ||
| 113 | void StopLrAssignmentMode(Kernel::HLERequestContext& ctx); | ||
| 114 | void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); | ||
| 115 | void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); | ||
| 116 | void SwapNpadAssignment(Kernel::HLERequestContext& ctx); | ||
| 109 | void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx); | 117 | void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx); |
| 110 | void EndPermitVibrationSession(Kernel::HLERequestContext& ctx); | 118 | void EndPermitVibrationSession(Kernel::HLERequestContext& ctx); |
| 111 | void SendVibrationValue(Kernel::HLERequestContext& ctx); | 119 | void SendVibrationValue(Kernel::HLERequestContext& ctx); |
| 112 | void SendVibrationValues(Kernel::HLERequestContext& ctx); | 120 | void SendVibrationValues(Kernel::HLERequestContext& ctx); |
| 113 | void GetActualVibrationValue(Kernel::HLERequestContext& ctx); | 121 | void GetActualVibrationValue(Kernel::HLERequestContext& ctx); |
| 114 | void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx); | ||
| 115 | void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx); | ||
| 116 | void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); | ||
| 117 | void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); | 122 | void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); |
| 118 | void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx); | 123 | void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx); |
| 119 | void PermitVibration(Kernel::HLERequestContext& ctx); | 124 | void PermitVibration(Kernel::HLERequestContext& ctx); |
| @@ -123,9 +128,6 @@ private: | |||
| 123 | void StopSixAxisSensor(Kernel::HLERequestContext& ctx); | 128 | void StopSixAxisSensor(Kernel::HLERequestContext& ctx); |
| 124 | void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx); | 129 | void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx); |
| 125 | void SetPalmaBoostMode(Kernel::HLERequestContext& ctx); | 130 | void SetPalmaBoostMode(Kernel::HLERequestContext& ctx); |
| 126 | void StartLrAssignmentMode(Kernel::HLERequestContext& ctx); | ||
| 127 | void StopLrAssignmentMode(Kernel::HLERequestContext& ctx); | ||
| 128 | void SwapNpadAssignment(Kernel::HLERequestContext& ctx); | ||
| 129 | 131 | ||
| 130 | std::shared_ptr<IAppletResource> applet_resource; | 132 | std::shared_ptr<IAppletResource> applet_resource; |
| 131 | Core::System& system; | 133 | Core::System& system; |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 199b30635..611cecc20 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -45,7 +45,7 @@ struct DisplayInfo { | |||
| 45 | 45 | ||
| 46 | /// Whether or not the display has a limited number of layers. | 46 | /// Whether or not the display has a limited number of layers. |
| 47 | u8 has_limited_layers{1}; | 47 | u8 has_limited_layers{1}; |
| 48 | INSERT_PADDING_BYTES(7){}; | 48 | INSERT_PADDING_BYTES(7); |
| 49 | 49 | ||
| 50 | /// Indicates the total amount of layers supported by the display. | 50 | /// Indicates the total amount of layers supported by the display. |
| 51 | /// @note This is only valid if has_limited_layers is set. | 51 | /// @note This is only valid if has_limited_layers is set. |
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index cb6eda1b8..c911c6ec4 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -36,6 +36,8 @@ add_library(video_core STATIC | |||
| 36 | memory_manager.h | 36 | memory_manager.h |
| 37 | morton.cpp | 37 | morton.cpp |
| 38 | morton.h | 38 | morton.h |
| 39 | rasterizer_accelerated.cpp | ||
| 40 | rasterizer_accelerated.h | ||
| 39 | rasterizer_cache.cpp | 41 | rasterizer_cache.cpp |
| 40 | rasterizer_cache.h | 42 | rasterizer_cache.h |
| 41 | rasterizer_interface.h | 43 | rasterizer_interface.h |
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 7ff44f06d..85d308e26 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp | |||
| @@ -28,6 +28,13 @@ void Fermi2D::CallMethod(const GPU::MethodCall& method_call) { | |||
| 28 | } | 28 | } |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | std::pair<u32, u32> DelimitLine(u32 src_1, u32 src_2, u32 dst_1, u32 dst_2, u32 src_line) { | ||
| 32 | const u32 line_a = src_2 - src_1; | ||
| 33 | const u32 line_b = dst_2 - dst_1; | ||
| 34 | const u32 excess = std::max<s32>(0, line_a - src_line + src_1); | ||
| 35 | return {line_b - (excess * line_b) / line_a, excess}; | ||
| 36 | } | ||
| 37 | |||
| 31 | void Fermi2D::HandleSurfaceCopy() { | 38 | void Fermi2D::HandleSurfaceCopy() { |
| 32 | LOG_DEBUG(HW_GPU, "Requested a surface copy with operation {}", | 39 | LOG_DEBUG(HW_GPU, "Requested a surface copy with operation {}", |
| 33 | static_cast<u32>(regs.operation)); | 40 | static_cast<u32>(regs.operation)); |
| @@ -47,10 +54,27 @@ void Fermi2D::HandleSurfaceCopy() { | |||
| 47 | src_blit_x2 = static_cast<u32>((regs.blit_src_x >> 32) + regs.blit_dst_width); | 54 | src_blit_x2 = static_cast<u32>((regs.blit_src_x >> 32) + regs.blit_dst_width); |
| 48 | src_blit_y2 = static_cast<u32>((regs.blit_src_y >> 32) + regs.blit_dst_height); | 55 | src_blit_y2 = static_cast<u32>((regs.blit_src_y >> 32) + regs.blit_dst_height); |
| 49 | } | 56 | } |
| 57 | u32 dst_blit_x2 = regs.blit_dst_x + regs.blit_dst_width; | ||
| 58 | u32 dst_blit_y2 = regs.blit_dst_y + regs.blit_dst_height; | ||
| 59 | const auto [new_dst_w, src_excess_x] = | ||
| 60 | DelimitLine(src_blit_x1, src_blit_x2, regs.blit_dst_x, dst_blit_x2, regs.src.width); | ||
| 61 | const auto [new_dst_h, src_excess_y] = | ||
| 62 | DelimitLine(src_blit_y1, src_blit_y2, regs.blit_dst_y, dst_blit_y2, regs.src.height); | ||
| 63 | dst_blit_x2 = new_dst_w + regs.blit_dst_x; | ||
| 64 | src_blit_x2 = src_blit_x2 - src_excess_x; | ||
| 65 | dst_blit_y2 = new_dst_h + regs.blit_dst_y; | ||
| 66 | src_blit_y2 = src_blit_y2 - src_excess_y; | ||
| 67 | const auto [new_src_w, dst_excess_x] = | ||
| 68 | DelimitLine(regs.blit_dst_x, dst_blit_x2, src_blit_x1, src_blit_x2, regs.dst.width); | ||
| 69 | const auto [new_src_h, dst_excess_y] = | ||
| 70 | DelimitLine(regs.blit_dst_y, dst_blit_y2, src_blit_y1, src_blit_y2, regs.dst.height); | ||
| 71 | src_blit_x2 = new_src_w + src_blit_x1; | ||
| 72 | dst_blit_x2 = dst_blit_x2 - dst_excess_x; | ||
| 73 | src_blit_y2 = new_src_h + src_blit_y1; | ||
| 74 | dst_blit_y2 = dst_blit_y2 - dst_excess_y; | ||
| 50 | const Common::Rectangle<u32> src_rect{src_blit_x1, src_blit_y1, src_blit_x2, src_blit_y2}; | 75 | const Common::Rectangle<u32> src_rect{src_blit_x1, src_blit_y1, src_blit_x2, src_blit_y2}; |
| 51 | const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y, | 76 | const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y, dst_blit_x2, |
| 52 | regs.blit_dst_x + regs.blit_dst_width, | 77 | dst_blit_y2}; |
| 53 | regs.blit_dst_y + regs.blit_dst_height}; | ||
| 54 | Config copy_config; | 78 | Config copy_config; |
| 55 | copy_config.operation = regs.operation; | 79 | copy_config.operation = regs.operation; |
| 56 | copy_config.filter = regs.blit_control.filter; | 80 | copy_config.filter = regs.blit_control.filter; |
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 0901cf2fa..dba342c70 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h | |||
| @@ -99,19 +99,19 @@ public: | |||
| 99 | 99 | ||
| 100 | union { | 100 | union { |
| 101 | struct { | 101 | struct { |
| 102 | INSERT_PADDING_WORDS(0x80); | 102 | INSERT_UNION_PADDING_WORDS(0x80); |
| 103 | 103 | ||
| 104 | Surface dst; | 104 | Surface dst; |
| 105 | 105 | ||
| 106 | INSERT_PADDING_WORDS(2); | 106 | INSERT_UNION_PADDING_WORDS(2); |
| 107 | 107 | ||
| 108 | Surface src; | 108 | Surface src; |
| 109 | 109 | ||
| 110 | INSERT_PADDING_WORDS(0x15); | 110 | INSERT_UNION_PADDING_WORDS(0x15); |
| 111 | 111 | ||
| 112 | Operation operation; | 112 | Operation operation; |
| 113 | 113 | ||
| 114 | INSERT_PADDING_WORDS(0x177); | 114 | INSERT_UNION_PADDING_WORDS(0x177); |
| 115 | 115 | ||
| 116 | union { | 116 | union { |
| 117 | u32 raw; | 117 | u32 raw; |
| @@ -119,7 +119,7 @@ public: | |||
| 119 | BitField<4, 1, Filter> filter; | 119 | BitField<4, 1, Filter> filter; |
| 120 | } blit_control; | 120 | } blit_control; |
| 121 | 121 | ||
| 122 | INSERT_PADDING_WORDS(0x8); | 122 | INSERT_UNION_PADDING_WORDS(0x8); |
| 123 | 123 | ||
| 124 | u32 blit_dst_x; | 124 | u32 blit_dst_x; |
| 125 | u32 blit_dst_y; | 125 | u32 blit_dst_y; |
| @@ -130,7 +130,7 @@ public: | |||
| 130 | u64 blit_src_x; | 130 | u64 blit_src_x; |
| 131 | u64 blit_src_y; | 131 | u64 blit_src_y; |
| 132 | 132 | ||
| 133 | INSERT_PADDING_WORDS(0x21); | 133 | INSERT_UNION_PADDING_WORDS(0x21); |
| 134 | }; | 134 | }; |
| 135 | std::array<u32, NUM_REGS> reg_array; | 135 | std::array<u32, NUM_REGS> reg_array; |
| 136 | }; | 136 | }; |
diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h index b185c98c7..5259d92bd 100644 --- a/src/video_core/engines/kepler_compute.h +++ b/src/video_core/engines/kepler_compute.h | |||
| @@ -51,7 +51,7 @@ public: | |||
| 51 | 51 | ||
| 52 | union { | 52 | union { |
| 53 | struct { | 53 | struct { |
| 54 | INSERT_PADDING_WORDS(0x60); | 54 | INSERT_UNION_PADDING_WORDS(0x60); |
| 55 | 55 | ||
| 56 | Upload::Registers upload; | 56 | Upload::Registers upload; |
| 57 | 57 | ||
| @@ -63,7 +63,7 @@ public: | |||
| 63 | 63 | ||
| 64 | u32 data_upload; | 64 | u32 data_upload; |
| 65 | 65 | ||
| 66 | INSERT_PADDING_WORDS(0x3F); | 66 | INSERT_UNION_PADDING_WORDS(0x3F); |
| 67 | 67 | ||
| 68 | struct { | 68 | struct { |
| 69 | u32 address; | 69 | u32 address; |
| @@ -72,11 +72,11 @@ public: | |||
| 72 | } | 72 | } |
| 73 | } launch_desc_loc; | 73 | } launch_desc_loc; |
| 74 | 74 | ||
| 75 | INSERT_PADDING_WORDS(0x1); | 75 | INSERT_UNION_PADDING_WORDS(0x1); |
| 76 | 76 | ||
| 77 | u32 launch; | 77 | u32 launch; |
| 78 | 78 | ||
| 79 | INSERT_PADDING_WORDS(0x4A7); | 79 | INSERT_UNION_PADDING_WORDS(0x4A7); |
| 80 | 80 | ||
| 81 | struct { | 81 | struct { |
| 82 | u32 address_high; | 82 | u32 address_high; |
| @@ -88,7 +88,7 @@ public: | |||
| 88 | } | 88 | } |
| 89 | } tsc; | 89 | } tsc; |
| 90 | 90 | ||
| 91 | INSERT_PADDING_WORDS(0x3); | 91 | INSERT_UNION_PADDING_WORDS(0x3); |
| 92 | 92 | ||
| 93 | struct { | 93 | struct { |
| 94 | u32 address_high; | 94 | u32 address_high; |
| @@ -100,7 +100,7 @@ public: | |||
| 100 | } | 100 | } |
| 101 | } tic; | 101 | } tic; |
| 102 | 102 | ||
| 103 | INSERT_PADDING_WORDS(0x22); | 103 | INSERT_UNION_PADDING_WORDS(0x22); |
| 104 | 104 | ||
| 105 | struct { | 105 | struct { |
| 106 | u32 address_high; | 106 | u32 address_high; |
| @@ -111,11 +111,11 @@ public: | |||
| 111 | } | 111 | } |
| 112 | } code_loc; | 112 | } code_loc; |
| 113 | 113 | ||
| 114 | INSERT_PADDING_WORDS(0x3FE); | 114 | INSERT_UNION_PADDING_WORDS(0x3FE); |
| 115 | 115 | ||
| 116 | u32 tex_cb_index; | 116 | u32 tex_cb_index; |
| 117 | 117 | ||
| 118 | INSERT_PADDING_WORDS(0x374); | 118 | INSERT_UNION_PADDING_WORDS(0x374); |
| 119 | }; | 119 | }; |
| 120 | std::array<u32, NUM_REGS> reg_array; | 120 | std::array<u32, NUM_REGS> reg_array; |
| 121 | }; | 121 | }; |
| @@ -179,7 +179,7 @@ public: | |||
| 179 | }; | 179 | }; |
| 180 | 180 | ||
| 181 | INSERT_PADDING_WORDS(0x11); | 181 | INSERT_PADDING_WORDS(0x11); |
| 182 | } launch_description; | 182 | } launch_description{}; |
| 183 | 183 | ||
| 184 | struct { | 184 | struct { |
| 185 | u32 write_offset = 0; | 185 | u32 write_offset = 0; |
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h index e0e25c321..396fb6e86 100644 --- a/src/video_core/engines/kepler_memory.h +++ b/src/video_core/engines/kepler_memory.h | |||
| @@ -45,7 +45,7 @@ public: | |||
| 45 | 45 | ||
| 46 | union { | 46 | union { |
| 47 | struct { | 47 | struct { |
| 48 | INSERT_PADDING_WORDS(0x60); | 48 | INSERT_UNION_PADDING_WORDS(0x60); |
| 49 | 49 | ||
| 50 | Upload::Registers upload; | 50 | Upload::Registers upload; |
| 51 | 51 | ||
| @@ -57,7 +57,7 @@ public: | |||
| 57 | 57 | ||
| 58 | u32 data; | 58 | u32 data; |
| 59 | 59 | ||
| 60 | INSERT_PADDING_WORDS(0x11); | 60 | INSERT_UNION_PADDING_WORDS(0x11); |
| 61 | }; | 61 | }; |
| 62 | std::array<u32, NUM_REGS> reg_array; | 62 | std::array<u32, NUM_REGS> reg_array; |
| 63 | }; | 63 | }; |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 8cc842684..1aa7c274f 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -496,7 +496,7 @@ public: | |||
| 496 | Equation equation_a; | 496 | Equation equation_a; |
| 497 | Factor factor_source_a; | 497 | Factor factor_source_a; |
| 498 | Factor factor_dest_a; | 498 | Factor factor_dest_a; |
| 499 | INSERT_PADDING_WORDS(1); | 499 | INSERT_UNION_PADDING_WORDS(1); |
| 500 | }; | 500 | }; |
| 501 | 501 | ||
| 502 | struct RenderTargetConfig { | 502 | struct RenderTargetConfig { |
| @@ -517,7 +517,7 @@ public: | |||
| 517 | }; | 517 | }; |
| 518 | u32 layer_stride; | 518 | u32 layer_stride; |
| 519 | u32 base_layer; | 519 | u32 base_layer; |
| 520 | INSERT_PADDING_WORDS(7); | 520 | INSERT_UNION_PADDING_WORDS(7); |
| 521 | 521 | ||
| 522 | GPUVAddr Address() const { | 522 | GPUVAddr Address() const { |
| 523 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | 523 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| @@ -542,7 +542,7 @@ public: | |||
| 542 | f32 translate_x; | 542 | f32 translate_x; |
| 543 | f32 translate_y; | 543 | f32 translate_y; |
| 544 | f32 translate_z; | 544 | f32 translate_z; |
| 545 | INSERT_PADDING_WORDS(2); | 545 | INSERT_UNION_PADDING_WORDS(2); |
| 546 | 546 | ||
| 547 | Common::Rectangle<s32> GetRect() const { | 547 | Common::Rectangle<s32> GetRect() const { |
| 548 | return { | 548 | return { |
| @@ -606,7 +606,7 @@ public: | |||
| 606 | 606 | ||
| 607 | union { | 607 | union { |
| 608 | struct { | 608 | struct { |
| 609 | INSERT_PADDING_WORDS(0x45); | 609 | INSERT_UNION_PADDING_WORDS(0x45); |
| 610 | 610 | ||
| 611 | struct { | 611 | struct { |
| 612 | u32 upload_address; | 612 | u32 upload_address; |
| @@ -615,7 +615,7 @@ public: | |||
| 615 | u32 bind; | 615 | u32 bind; |
| 616 | } macros; | 616 | } macros; |
| 617 | 617 | ||
| 618 | INSERT_PADDING_WORDS(0x17); | 618 | INSERT_UNION_PADDING_WORDS(0x17); |
| 619 | 619 | ||
| 620 | Upload::Registers upload; | 620 | Upload::Registers upload; |
| 621 | struct { | 621 | struct { |
| @@ -626,7 +626,7 @@ public: | |||
| 626 | 626 | ||
| 627 | u32 data_upload; | 627 | u32 data_upload; |
| 628 | 628 | ||
| 629 | INSERT_PADDING_WORDS(0x44); | 629 | INSERT_UNION_PADDING_WORDS(0x44); |
| 630 | 630 | ||
| 631 | struct { | 631 | struct { |
| 632 | union { | 632 | union { |
| @@ -636,11 +636,11 @@ public: | |||
| 636 | }; | 636 | }; |
| 637 | } sync_info; | 637 | } sync_info; |
| 638 | 638 | ||
| 639 | INSERT_PADDING_WORDS(0x11E); | 639 | INSERT_UNION_PADDING_WORDS(0x11E); |
| 640 | 640 | ||
| 641 | u32 tfb_enabled; | 641 | u32 tfb_enabled; |
| 642 | 642 | ||
| 643 | INSERT_PADDING_WORDS(0x2E); | 643 | INSERT_UNION_PADDING_WORDS(0x2E); |
| 644 | 644 | ||
| 645 | std::array<RenderTargetConfig, NumRenderTargets> rt; | 645 | std::array<RenderTargetConfig, NumRenderTargets> rt; |
| 646 | 646 | ||
| @@ -648,49 +648,49 @@ public: | |||
| 648 | 648 | ||
| 649 | std::array<ViewPort, NumViewports> viewports; | 649 | std::array<ViewPort, NumViewports> viewports; |
| 650 | 650 | ||
| 651 | INSERT_PADDING_WORDS(0x1D); | 651 | INSERT_UNION_PADDING_WORDS(0x1D); |
| 652 | 652 | ||
| 653 | struct { | 653 | struct { |
| 654 | u32 first; | 654 | u32 first; |
| 655 | u32 count; | 655 | u32 count; |
| 656 | } vertex_buffer; | 656 | } vertex_buffer; |
| 657 | 657 | ||
| 658 | INSERT_PADDING_WORDS(1); | 658 | INSERT_UNION_PADDING_WORDS(1); |
| 659 | 659 | ||
| 660 | float clear_color[4]; | 660 | float clear_color[4]; |
| 661 | float clear_depth; | 661 | float clear_depth; |
| 662 | 662 | ||
| 663 | INSERT_PADDING_WORDS(0x3); | 663 | INSERT_UNION_PADDING_WORDS(0x3); |
| 664 | 664 | ||
| 665 | s32 clear_stencil; | 665 | s32 clear_stencil; |
| 666 | 666 | ||
| 667 | INSERT_PADDING_WORDS(0x7); | 667 | INSERT_UNION_PADDING_WORDS(0x7); |
| 668 | 668 | ||
| 669 | u32 polygon_offset_point_enable; | 669 | u32 polygon_offset_point_enable; |
| 670 | u32 polygon_offset_line_enable; | 670 | u32 polygon_offset_line_enable; |
| 671 | u32 polygon_offset_fill_enable; | 671 | u32 polygon_offset_fill_enable; |
| 672 | 672 | ||
| 673 | INSERT_PADDING_WORDS(0xD); | 673 | INSERT_UNION_PADDING_WORDS(0xD); |
| 674 | 674 | ||
| 675 | std::array<ScissorTest, NumViewports> scissor_test; | 675 | std::array<ScissorTest, NumViewports> scissor_test; |
| 676 | 676 | ||
| 677 | INSERT_PADDING_WORDS(0x15); | 677 | INSERT_UNION_PADDING_WORDS(0x15); |
| 678 | 678 | ||
| 679 | s32 stencil_back_func_ref; | 679 | s32 stencil_back_func_ref; |
| 680 | u32 stencil_back_mask; | 680 | u32 stencil_back_mask; |
| 681 | u32 stencil_back_func_mask; | 681 | u32 stencil_back_func_mask; |
| 682 | 682 | ||
| 683 | INSERT_PADDING_WORDS(0xC); | 683 | INSERT_UNION_PADDING_WORDS(0xC); |
| 684 | 684 | ||
| 685 | u32 color_mask_common; | 685 | u32 color_mask_common; |
| 686 | 686 | ||
| 687 | INSERT_PADDING_WORDS(0x6); | 687 | INSERT_UNION_PADDING_WORDS(0x6); |
| 688 | 688 | ||
| 689 | u32 rt_separate_frag_data; | 689 | u32 rt_separate_frag_data; |
| 690 | 690 | ||
| 691 | f32 depth_bounds[2]; | 691 | f32 depth_bounds[2]; |
| 692 | 692 | ||
| 693 | INSERT_PADDING_WORDS(0xA); | 693 | INSERT_UNION_PADDING_WORDS(0xA); |
| 694 | 694 | ||
| 695 | struct { | 695 | struct { |
| 696 | u32 address_high; | 696 | u32 address_high; |
| @@ -710,7 +710,7 @@ public: | |||
| 710 | } | 710 | } |
| 711 | } zeta; | 711 | } zeta; |
| 712 | 712 | ||
| 713 | INSERT_PADDING_WORDS(0x41); | 713 | INSERT_UNION_PADDING_WORDS(0x41); |
| 714 | 714 | ||
| 715 | union { | 715 | union { |
| 716 | BitField<0, 4, u32> stencil; | 716 | BitField<0, 4, u32> stencil; |
| @@ -719,11 +719,11 @@ public: | |||
| 719 | BitField<12, 4, u32> viewport; | 719 | BitField<12, 4, u32> viewport; |
| 720 | } clear_flags; | 720 | } clear_flags; |
| 721 | 721 | ||
| 722 | INSERT_PADDING_WORDS(0x19); | 722 | INSERT_UNION_PADDING_WORDS(0x19); |
| 723 | 723 | ||
| 724 | std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; | 724 | std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; |
| 725 | 725 | ||
| 726 | INSERT_PADDING_WORDS(0xF); | 726 | INSERT_UNION_PADDING_WORDS(0xF); |
| 727 | 727 | ||
| 728 | struct { | 728 | struct { |
| 729 | union { | 729 | union { |
| @@ -746,16 +746,16 @@ public: | |||
| 746 | } | 746 | } |
| 747 | } rt_control; | 747 | } rt_control; |
| 748 | 748 | ||
| 749 | INSERT_PADDING_WORDS(0x2); | 749 | INSERT_UNION_PADDING_WORDS(0x2); |
| 750 | 750 | ||
| 751 | u32 zeta_width; | 751 | u32 zeta_width; |
| 752 | u32 zeta_height; | 752 | u32 zeta_height; |
| 753 | 753 | ||
| 754 | INSERT_PADDING_WORDS(0x27); | 754 | INSERT_UNION_PADDING_WORDS(0x27); |
| 755 | 755 | ||
| 756 | u32 depth_test_enable; | 756 | u32 depth_test_enable; |
| 757 | 757 | ||
| 758 | INSERT_PADDING_WORDS(0x5); | 758 | INSERT_UNION_PADDING_WORDS(0x5); |
| 759 | 759 | ||
| 760 | u32 independent_blend_enable; | 760 | u32 independent_blend_enable; |
| 761 | 761 | ||
| @@ -763,7 +763,7 @@ public: | |||
| 763 | 763 | ||
| 764 | u32 alpha_test_enabled; | 764 | u32 alpha_test_enabled; |
| 765 | 765 | ||
| 766 | INSERT_PADDING_WORDS(0x6); | 766 | INSERT_UNION_PADDING_WORDS(0x6); |
| 767 | 767 | ||
| 768 | u32 d3d_cull_mode; | 768 | u32 d3d_cull_mode; |
| 769 | 769 | ||
| @@ -777,7 +777,7 @@ public: | |||
| 777 | float b; | 777 | float b; |
| 778 | float a; | 778 | float a; |
| 779 | } blend_color; | 779 | } blend_color; |
| 780 | INSERT_PADDING_WORDS(0x4); | 780 | INSERT_UNION_PADDING_WORDS(0x4); |
| 781 | 781 | ||
| 782 | struct { | 782 | struct { |
| 783 | u32 separate_alpha; | 783 | u32 separate_alpha; |
| @@ -786,7 +786,7 @@ public: | |||
| 786 | Blend::Factor factor_dest_rgb; | 786 | Blend::Factor factor_dest_rgb; |
| 787 | Blend::Equation equation_a; | 787 | Blend::Equation equation_a; |
| 788 | Blend::Factor factor_source_a; | 788 | Blend::Factor factor_source_a; |
| 789 | INSERT_PADDING_WORDS(1); | 789 | INSERT_UNION_PADDING_WORDS(1); |
| 790 | Blend::Factor factor_dest_a; | 790 | Blend::Factor factor_dest_a; |
| 791 | 791 | ||
| 792 | u32 enable_common; | 792 | u32 enable_common; |
| @@ -802,7 +802,7 @@ public: | |||
| 802 | u32 stencil_front_func_mask; | 802 | u32 stencil_front_func_mask; |
| 803 | u32 stencil_front_mask; | 803 | u32 stencil_front_mask; |
| 804 | 804 | ||
| 805 | INSERT_PADDING_WORDS(0x2); | 805 | INSERT_UNION_PADDING_WORDS(0x2); |
| 806 | 806 | ||
| 807 | u32 frag_color_clamp; | 807 | u32 frag_color_clamp; |
| 808 | 808 | ||
| @@ -811,12 +811,12 @@ public: | |||
| 811 | BitField<4, 1, u32> triangle_rast_flip; | 811 | BitField<4, 1, u32> triangle_rast_flip; |
| 812 | } screen_y_control; | 812 | } screen_y_control; |
| 813 | 813 | ||
| 814 | INSERT_PADDING_WORDS(0x21); | 814 | INSERT_UNION_PADDING_WORDS(0x21); |
| 815 | 815 | ||
| 816 | u32 vb_element_base; | 816 | u32 vb_element_base; |
| 817 | u32 vb_base_instance; | 817 | u32 vb_base_instance; |
| 818 | 818 | ||
| 819 | INSERT_PADDING_WORDS(0x35); | 819 | INSERT_UNION_PADDING_WORDS(0x35); |
| 820 | 820 | ||
| 821 | union { | 821 | union { |
| 822 | BitField<0, 1, u32> c0; | 822 | BitField<0, 1, u32> c0; |
| @@ -829,11 +829,11 @@ public: | |||
| 829 | BitField<7, 1, u32> c7; | 829 | BitField<7, 1, u32> c7; |
| 830 | } clip_distance_enabled; | 830 | } clip_distance_enabled; |
| 831 | 831 | ||
| 832 | INSERT_PADDING_WORDS(0x1); | 832 | INSERT_UNION_PADDING_WORDS(0x1); |
| 833 | 833 | ||
| 834 | float point_size; | 834 | float point_size; |
| 835 | 835 | ||
| 836 | INSERT_PADDING_WORDS(0x7); | 836 | INSERT_UNION_PADDING_WORDS(0x7); |
| 837 | 837 | ||
| 838 | u32 zeta_enable; | 838 | u32 zeta_enable; |
| 839 | 839 | ||
| @@ -842,7 +842,7 @@ public: | |||
| 842 | BitField<4, 1, u32> alpha_to_one; | 842 | BitField<4, 1, u32> alpha_to_one; |
| 843 | } multisample_control; | 843 | } multisample_control; |
| 844 | 844 | ||
| 845 | INSERT_PADDING_WORDS(0x4); | 845 | INSERT_UNION_PADDING_WORDS(0x4); |
| 846 | 846 | ||
| 847 | struct { | 847 | struct { |
| 848 | u32 address_high; | 848 | u32 address_high; |
| @@ -866,11 +866,11 @@ public: | |||
| 866 | } | 866 | } |
| 867 | } tsc; | 867 | } tsc; |
| 868 | 868 | ||
| 869 | INSERT_PADDING_WORDS(0x1); | 869 | INSERT_UNION_PADDING_WORDS(0x1); |
| 870 | 870 | ||
| 871 | float polygon_offset_factor; | 871 | float polygon_offset_factor; |
| 872 | 872 | ||
| 873 | INSERT_PADDING_WORDS(0x1); | 873 | INSERT_UNION_PADDING_WORDS(0x1); |
| 874 | 874 | ||
| 875 | struct { | 875 | struct { |
| 876 | u32 tic_address_high; | 876 | u32 tic_address_high; |
| @@ -883,7 +883,7 @@ public: | |||
| 883 | } | 883 | } |
| 884 | } tic; | 884 | } tic; |
| 885 | 885 | ||
| 886 | INSERT_PADDING_WORDS(0x5); | 886 | INSERT_UNION_PADDING_WORDS(0x5); |
| 887 | 887 | ||
| 888 | u32 stencil_two_side_enable; | 888 | u32 stencil_two_side_enable; |
| 889 | StencilOp stencil_back_op_fail; | 889 | StencilOp stencil_back_op_fail; |
| @@ -891,13 +891,13 @@ public: | |||
| 891 | StencilOp stencil_back_op_zpass; | 891 | StencilOp stencil_back_op_zpass; |
| 892 | ComparisonOp stencil_back_func_func; | 892 | ComparisonOp stencil_back_func_func; |
| 893 | 893 | ||
| 894 | INSERT_PADDING_WORDS(0x4); | 894 | INSERT_UNION_PADDING_WORDS(0x4); |
| 895 | 895 | ||
| 896 | u32 framebuffer_srgb; | 896 | u32 framebuffer_srgb; |
| 897 | 897 | ||
| 898 | float polygon_offset_units; | 898 | float polygon_offset_units; |
| 899 | 899 | ||
| 900 | INSERT_PADDING_WORDS(0x11); | 900 | INSERT_UNION_PADDING_WORDS(0x11); |
| 901 | 901 | ||
| 902 | union { | 902 | union { |
| 903 | BitField<2, 1, u32> coord_origin; | 903 | BitField<2, 1, u32> coord_origin; |
| @@ -913,7 +913,7 @@ public: | |||
| 913 | (static_cast<GPUVAddr>(code_address_high) << 32) | code_address_low); | 913 | (static_cast<GPUVAddr>(code_address_high) << 32) | code_address_low); |
| 914 | } | 914 | } |
| 915 | } code_address; | 915 | } code_address; |
| 916 | INSERT_PADDING_WORDS(1); | 916 | INSERT_UNION_PADDING_WORDS(1); |
| 917 | 917 | ||
| 918 | struct { | 918 | struct { |
| 919 | u32 vertex_end_gl; | 919 | u32 vertex_end_gl; |
| @@ -925,14 +925,14 @@ public: | |||
| 925 | }; | 925 | }; |
| 926 | } draw; | 926 | } draw; |
| 927 | 927 | ||
| 928 | INSERT_PADDING_WORDS(0xA); | 928 | INSERT_UNION_PADDING_WORDS(0xA); |
| 929 | 929 | ||
| 930 | struct { | 930 | struct { |
| 931 | u32 enabled; | 931 | u32 enabled; |
| 932 | u32 index; | 932 | u32 index; |
| 933 | } primitive_restart; | 933 | } primitive_restart; |
| 934 | 934 | ||
| 935 | INSERT_PADDING_WORDS(0x5F); | 935 | INSERT_UNION_PADDING_WORDS(0x5F); |
| 936 | 936 | ||
| 937 | struct { | 937 | struct { |
| 938 | u32 start_addr_high; | 938 | u32 start_addr_high; |
| @@ -973,9 +973,9 @@ public: | |||
| 973 | } | 973 | } |
| 974 | } index_array; | 974 | } index_array; |
| 975 | 975 | ||
| 976 | INSERT_PADDING_WORDS(0x7); | 976 | INSERT_UNION_PADDING_WORDS(0x7); |
| 977 | 977 | ||
| 978 | INSERT_PADDING_WORDS(0x1F); | 978 | INSERT_UNION_PADDING_WORDS(0x1F); |
| 979 | 979 | ||
| 980 | float polygon_offset_clamp; | 980 | float polygon_offset_clamp; |
| 981 | 981 | ||
| @@ -989,17 +989,17 @@ public: | |||
| 989 | } | 989 | } |
| 990 | } instanced_arrays; | 990 | } instanced_arrays; |
| 991 | 991 | ||
| 992 | INSERT_PADDING_WORDS(0x6); | 992 | INSERT_UNION_PADDING_WORDS(0x6); |
| 993 | 993 | ||
| 994 | Cull cull; | 994 | Cull cull; |
| 995 | 995 | ||
| 996 | u32 pixel_center_integer; | 996 | u32 pixel_center_integer; |
| 997 | 997 | ||
| 998 | INSERT_PADDING_WORDS(0x1); | 998 | INSERT_UNION_PADDING_WORDS(0x1); |
| 999 | 999 | ||
| 1000 | u32 viewport_transform_enabled; | 1000 | u32 viewport_transform_enabled; |
| 1001 | 1001 | ||
| 1002 | INSERT_PADDING_WORDS(0x3); | 1002 | INSERT_UNION_PADDING_WORDS(0x3); |
| 1003 | 1003 | ||
| 1004 | union { | 1004 | union { |
| 1005 | BitField<0, 1, u32> depth_range_0_1; | 1005 | BitField<0, 1, u32> depth_range_0_1; |
| @@ -1007,13 +1007,13 @@ public: | |||
| 1007 | BitField<4, 1, u32> depth_clamp_far; | 1007 | BitField<4, 1, u32> depth_clamp_far; |
| 1008 | } view_volume_clip_control; | 1008 | } view_volume_clip_control; |
| 1009 | 1009 | ||
| 1010 | INSERT_PADDING_WORDS(0x21); | 1010 | INSERT_UNION_PADDING_WORDS(0x21); |
| 1011 | struct { | 1011 | struct { |
| 1012 | u32 enable; | 1012 | u32 enable; |
| 1013 | LogicOperation operation; | 1013 | LogicOperation operation; |
| 1014 | } logic_op; | 1014 | } logic_op; |
| 1015 | 1015 | ||
| 1016 | INSERT_PADDING_WORDS(0x1); | 1016 | INSERT_UNION_PADDING_WORDS(0x1); |
| 1017 | 1017 | ||
| 1018 | union { | 1018 | union { |
| 1019 | u32 raw; | 1019 | u32 raw; |
| @@ -1026,9 +1026,9 @@ public: | |||
| 1026 | BitField<6, 4, u32> RT; | 1026 | BitField<6, 4, u32> RT; |
| 1027 | BitField<10, 11, u32> layer; | 1027 | BitField<10, 11, u32> layer; |
| 1028 | } clear_buffers; | 1028 | } clear_buffers; |
| 1029 | INSERT_PADDING_WORDS(0xB); | 1029 | INSERT_UNION_PADDING_WORDS(0xB); |
| 1030 | std::array<ColorMask, NumRenderTargets> color_mask; | 1030 | std::array<ColorMask, NumRenderTargets> color_mask; |
| 1031 | INSERT_PADDING_WORDS(0x38); | 1031 | INSERT_UNION_PADDING_WORDS(0x38); |
| 1032 | 1032 | ||
| 1033 | struct { | 1033 | struct { |
| 1034 | u32 query_address_high; | 1034 | u32 query_address_high; |
| @@ -1050,7 +1050,7 @@ public: | |||
| 1050 | } | 1050 | } |
| 1051 | } query; | 1051 | } query; |
| 1052 | 1052 | ||
| 1053 | INSERT_PADDING_WORDS(0x3C); | 1053 | INSERT_UNION_PADDING_WORDS(0x3C); |
| 1054 | 1054 | ||
| 1055 | struct { | 1055 | struct { |
| 1056 | union { | 1056 | union { |
| @@ -1090,10 +1090,10 @@ public: | |||
| 1090 | BitField<4, 4, ShaderProgram> program; | 1090 | BitField<4, 4, ShaderProgram> program; |
| 1091 | }; | 1091 | }; |
| 1092 | u32 offset; | 1092 | u32 offset; |
| 1093 | INSERT_PADDING_WORDS(14); | 1093 | INSERT_UNION_PADDING_WORDS(14); |
| 1094 | } shader_config[MaxShaderProgram]; | 1094 | } shader_config[MaxShaderProgram]; |
| 1095 | 1095 | ||
| 1096 | INSERT_PADDING_WORDS(0x60); | 1096 | INSERT_UNION_PADDING_WORDS(0x60); |
| 1097 | 1097 | ||
| 1098 | u32 firmware[0x20]; | 1098 | u32 firmware[0x20]; |
| 1099 | 1099 | ||
| @@ -1110,7 +1110,7 @@ public: | |||
| 1110 | } | 1110 | } |
| 1111 | } const_buffer; | 1111 | } const_buffer; |
| 1112 | 1112 | ||
| 1113 | INSERT_PADDING_WORDS(0x10); | 1113 | INSERT_UNION_PADDING_WORDS(0x10); |
| 1114 | 1114 | ||
| 1115 | struct { | 1115 | struct { |
| 1116 | union { | 1116 | union { |
| @@ -1118,14 +1118,14 @@ public: | |||
| 1118 | BitField<0, 1, u32> valid; | 1118 | BitField<0, 1, u32> valid; |
| 1119 | BitField<4, 5, u32> index; | 1119 | BitField<4, 5, u32> index; |
| 1120 | }; | 1120 | }; |
| 1121 | INSERT_PADDING_WORDS(7); | 1121 | INSERT_UNION_PADDING_WORDS(7); |
| 1122 | } cb_bind[MaxShaderStage]; | 1122 | } cb_bind[MaxShaderStage]; |
| 1123 | 1123 | ||
| 1124 | INSERT_PADDING_WORDS(0x56); | 1124 | INSERT_UNION_PADDING_WORDS(0x56); |
| 1125 | 1125 | ||
| 1126 | u32 tex_cb_index; | 1126 | u32 tex_cb_index; |
| 1127 | 1127 | ||
| 1128 | INSERT_PADDING_WORDS(0x395); | 1128 | INSERT_UNION_PADDING_WORDS(0x395); |
| 1129 | 1129 | ||
| 1130 | struct { | 1130 | struct { |
| 1131 | /// Compressed address of a buffer that holds information about bound SSBOs. | 1131 | /// Compressed address of a buffer that holds information about bound SSBOs. |
| @@ -1137,14 +1137,14 @@ public: | |||
| 1137 | } | 1137 | } |
| 1138 | } ssbo_info; | 1138 | } ssbo_info; |
| 1139 | 1139 | ||
| 1140 | INSERT_PADDING_WORDS(0x11); | 1140 | INSERT_UNION_PADDING_WORDS(0x11); |
| 1141 | 1141 | ||
| 1142 | struct { | 1142 | struct { |
| 1143 | u32 address[MaxShaderStage]; | 1143 | u32 address[MaxShaderStage]; |
| 1144 | u32 size[MaxShaderStage]; | 1144 | u32 size[MaxShaderStage]; |
| 1145 | } tex_info_buffers; | 1145 | } tex_info_buffers; |
| 1146 | 1146 | ||
| 1147 | INSERT_PADDING_WORDS(0xCC); | 1147 | INSERT_UNION_PADDING_WORDS(0xCC); |
| 1148 | }; | 1148 | }; |
| 1149 | std::array<u32, NUM_REGS> reg_array; | 1149 | std::array<u32, NUM_REGS> reg_array; |
| 1150 | }; | 1150 | }; |
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index 93808a9bb..4f40d1d1f 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h | |||
| @@ -94,7 +94,7 @@ public: | |||
| 94 | 94 | ||
| 95 | union { | 95 | union { |
| 96 | struct { | 96 | struct { |
| 97 | INSERT_PADDING_WORDS(0xC0); | 97 | INSERT_UNION_PADDING_WORDS(0xC0); |
| 98 | 98 | ||
| 99 | struct { | 99 | struct { |
| 100 | union { | 100 | union { |
| @@ -112,7 +112,7 @@ public: | |||
| 112 | }; | 112 | }; |
| 113 | } exec; | 113 | } exec; |
| 114 | 114 | ||
| 115 | INSERT_PADDING_WORDS(0x3F); | 115 | INSERT_UNION_PADDING_WORDS(0x3F); |
| 116 | 116 | ||
| 117 | struct { | 117 | struct { |
| 118 | u32 address_high; | 118 | u32 address_high; |
| @@ -139,7 +139,7 @@ public: | |||
| 139 | u32 x_count; | 139 | u32 x_count; |
| 140 | u32 y_count; | 140 | u32 y_count; |
| 141 | 141 | ||
| 142 | INSERT_PADDING_WORDS(0xB8); | 142 | INSERT_UNION_PADDING_WORDS(0xB8); |
| 143 | 143 | ||
| 144 | u32 const0; | 144 | u32 const0; |
| 145 | u32 const1; | 145 | u32 const1; |
| @@ -162,11 +162,11 @@ public: | |||
| 162 | 162 | ||
| 163 | Parameters dst_params; | 163 | Parameters dst_params; |
| 164 | 164 | ||
| 165 | INSERT_PADDING_WORDS(1); | 165 | INSERT_UNION_PADDING_WORDS(1); |
| 166 | 166 | ||
| 167 | Parameters src_params; | 167 | Parameters src_params; |
| 168 | 168 | ||
| 169 | INSERT_PADDING_WORDS(0x13); | 169 | INSERT_UNION_PADDING_WORDS(0x13); |
| 170 | }; | 170 | }; |
| 171 | std::array<u32, NUM_REGS> reg_array; | 171 | std::array<u32, NUM_REGS> reg_array; |
| 172 | }; | 172 | }; |
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index d3d05a866..8f6bc76eb 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -1238,6 +1238,32 @@ union Instruction { | |||
| 1238 | } tld4; | 1238 | } tld4; |
| 1239 | 1239 | ||
| 1240 | union { | 1240 | union { |
| 1241 | BitField<35, 1, u64> ndv_flag; | ||
| 1242 | BitField<49, 1, u64> nodep_flag; | ||
| 1243 | BitField<50, 1, u64> dc_flag; | ||
| 1244 | BitField<33, 2, u64> info; | ||
| 1245 | BitField<37, 2, u64> component; | ||
| 1246 | |||
| 1247 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 1248 | switch (mode) { | ||
| 1249 | case TextureMiscMode::NDV: | ||
| 1250 | return ndv_flag != 0; | ||
| 1251 | case TextureMiscMode::NODEP: | ||
| 1252 | return nodep_flag != 0; | ||
| 1253 | case TextureMiscMode::DC: | ||
| 1254 | return dc_flag != 0; | ||
| 1255 | case TextureMiscMode::AOFFI: | ||
| 1256 | return info == 1; | ||
| 1257 | case TextureMiscMode::PTP: | ||
| 1258 | return info == 2; | ||
| 1259 | default: | ||
| 1260 | break; | ||
| 1261 | } | ||
| 1262 | return false; | ||
| 1263 | } | ||
| 1264 | } tld4_b; | ||
| 1265 | |||
| 1266 | union { | ||
| 1241 | BitField<49, 1, u64> nodep_flag; | 1267 | BitField<49, 1, u64> nodep_flag; |
| 1242 | BitField<50, 1, u64> dc_flag; | 1268 | BitField<50, 1, u64> dc_flag; |
| 1243 | BitField<51, 1, u64> aoffi_flag; | 1269 | BitField<51, 1, u64> aoffi_flag; |
| @@ -1590,7 +1616,8 @@ public: | |||
| 1590 | TEXS, // Texture Fetch with scalar/non-vec4 source/destinations | 1616 | TEXS, // Texture Fetch with scalar/non-vec4 source/destinations |
| 1591 | TLD, // Texture Load | 1617 | TLD, // Texture Load |
| 1592 | TLDS, // Texture Load with scalar/non-vec4 source/destinations | 1618 | TLDS, // Texture Load with scalar/non-vec4 source/destinations |
| 1593 | TLD4, // Texture Load 4 | 1619 | TLD4, // Texture Gather 4 |
| 1620 | TLD4_B, // Texture Gather 4 Bindless | ||
| 1594 | TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations | 1621 | TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations |
| 1595 | TMML_B, // Texture Mip Map Level | 1622 | TMML_B, // Texture Mip Map Level |
| 1596 | TMML, // Texture Mip Map Level | 1623 | TMML, // Texture Mip Map Level |
| @@ -1881,6 +1908,7 @@ private: | |||
| 1881 | INST("11011100--11----", Id::TLD, Type::Texture, "TLD"), | 1908 | INST("11011100--11----", Id::TLD, Type::Texture, "TLD"), |
| 1882 | INST("1101-01---------", Id::TLDS, Type::Texture, "TLDS"), | 1909 | INST("1101-01---------", Id::TLDS, Type::Texture, "TLDS"), |
| 1883 | INST("110010----111---", Id::TLD4, Type::Texture, "TLD4"), | 1910 | INST("110010----111---", Id::TLD4, Type::Texture, "TLD4"), |
| 1911 | INST("1101111011111---", Id::TLD4_B, Type::Texture, "TLD4_B"), | ||
| 1884 | INST("1101111100------", Id::TLD4S, Type::Texture, "TLD4S"), | 1912 | INST("1101111100------", Id::TLD4S, Type::Texture, "TLD4S"), |
| 1885 | INST("110111110110----", Id::TMML_B, Type::Texture, "TMML_B"), | 1913 | INST("110111110110----", Id::TMML_B, Type::Texture, "TMML_B"), |
| 1886 | INST("1101111101011---", Id::TMML, Type::Texture, "TMML"), | 1914 | INST("1101111101011---", Id::TMML, Type::Texture, "TMML"), |
diff --git a/src/video_core/engines/shader_header.h b/src/video_core/engines/shader_header.h index e86a7f04a..bc80661d8 100644 --- a/src/video_core/engines/shader_header.h +++ b/src/video_core/engines/shader_header.h | |||
| @@ -38,37 +38,37 @@ struct Header { | |||
| 38 | BitField<26, 1, u32> does_load_or_store; | 38 | BitField<26, 1, u32> does_load_or_store; |
| 39 | BitField<27, 1, u32> does_fp64; | 39 | BitField<27, 1, u32> does_fp64; |
| 40 | BitField<28, 4, u32> stream_out_mask; | 40 | BitField<28, 4, u32> stream_out_mask; |
| 41 | } common0; | 41 | } common0{}; |
| 42 | 42 | ||
| 43 | union { | 43 | union { |
| 44 | BitField<0, 24, u32> shader_local_memory_low_size; | 44 | BitField<0, 24, u32> shader_local_memory_low_size; |
| 45 | BitField<24, 8, u32> per_patch_attribute_count; | 45 | BitField<24, 8, u32> per_patch_attribute_count; |
| 46 | } common1; | 46 | } common1{}; |
| 47 | 47 | ||
| 48 | union { | 48 | union { |
| 49 | BitField<0, 24, u32> shader_local_memory_high_size; | 49 | BitField<0, 24, u32> shader_local_memory_high_size; |
| 50 | BitField<24, 8, u32> threads_per_input_primitive; | 50 | BitField<24, 8, u32> threads_per_input_primitive; |
| 51 | } common2; | 51 | } common2{}; |
| 52 | 52 | ||
| 53 | union { | 53 | union { |
| 54 | BitField<0, 24, u32> shader_local_memory_crs_size; | 54 | BitField<0, 24, u32> shader_local_memory_crs_size; |
| 55 | BitField<24, 4, OutputTopology> output_topology; | 55 | BitField<24, 4, OutputTopology> output_topology; |
| 56 | BitField<28, 4, u32> reserved; | 56 | BitField<28, 4, u32> reserved; |
| 57 | } common3; | 57 | } common3{}; |
| 58 | 58 | ||
| 59 | union { | 59 | union { |
| 60 | BitField<0, 12, u32> max_output_vertices; | 60 | BitField<0, 12, u32> max_output_vertices; |
| 61 | BitField<12, 8, u32> store_req_start; // NOTE: not used by geometry shaders. | 61 | BitField<12, 8, u32> store_req_start; // NOTE: not used by geometry shaders. |
| 62 | BitField<24, 4, u32> reserved; | 62 | BitField<24, 4, u32> reserved; |
| 63 | BitField<12, 8, u32> store_req_end; // NOTE: not used by geometry shaders. | 63 | BitField<12, 8, u32> store_req_end; // NOTE: not used by geometry shaders. |
| 64 | } common4; | 64 | } common4{}; |
| 65 | 65 | ||
| 66 | union { | 66 | union { |
| 67 | struct { | 67 | struct { |
| 68 | INSERT_PADDING_BYTES(3); // ImapSystemValuesA | 68 | INSERT_UNION_PADDING_BYTES(3); // ImapSystemValuesA |
| 69 | INSERT_PADDING_BYTES(1); // ImapSystemValuesB | 69 | INSERT_UNION_PADDING_BYTES(1); // ImapSystemValuesB |
| 70 | INSERT_PADDING_BYTES(16); // ImapGenericVector[32] | 70 | INSERT_UNION_PADDING_BYTES(16); // ImapGenericVector[32] |
| 71 | INSERT_PADDING_BYTES(2); // ImapColor | 71 | INSERT_UNION_PADDING_BYTES(2); // ImapColor |
| 72 | union { | 72 | union { |
| 73 | BitField<0, 8, u16> clip_distances; | 73 | BitField<0, 8, u16> clip_distances; |
| 74 | BitField<8, 1, u16> point_sprite_s; | 74 | BitField<8, 1, u16> point_sprite_s; |
| @@ -79,20 +79,20 @@ struct Header { | |||
| 79 | BitField<14, 1, u16> instance_id; | 79 | BitField<14, 1, u16> instance_id; |
| 80 | BitField<15, 1, u16> vertex_id; | 80 | BitField<15, 1, u16> vertex_id; |
| 81 | }; | 81 | }; |
| 82 | INSERT_PADDING_BYTES(5); // ImapFixedFncTexture[10] | 82 | INSERT_UNION_PADDING_BYTES(5); // ImapFixedFncTexture[10] |
| 83 | INSERT_PADDING_BYTES(1); // ImapReserved | 83 | INSERT_UNION_PADDING_BYTES(1); // ImapReserved |
| 84 | INSERT_PADDING_BYTES(3); // OmapSystemValuesA | 84 | INSERT_UNION_PADDING_BYTES(3); // OmapSystemValuesA |
| 85 | INSERT_PADDING_BYTES(1); // OmapSystemValuesB | 85 | INSERT_UNION_PADDING_BYTES(1); // OmapSystemValuesB |
| 86 | INSERT_PADDING_BYTES(16); // OmapGenericVector[32] | 86 | INSERT_UNION_PADDING_BYTES(16); // OmapGenericVector[32] |
| 87 | INSERT_PADDING_BYTES(2); // OmapColor | 87 | INSERT_UNION_PADDING_BYTES(2); // OmapColor |
| 88 | INSERT_PADDING_BYTES(2); // OmapSystemValuesC | 88 | INSERT_UNION_PADDING_BYTES(2); // OmapSystemValuesC |
| 89 | INSERT_PADDING_BYTES(5); // OmapFixedFncTexture[10] | 89 | INSERT_UNION_PADDING_BYTES(5); // OmapFixedFncTexture[10] |
| 90 | INSERT_PADDING_BYTES(1); // OmapReserved | 90 | INSERT_UNION_PADDING_BYTES(1); // OmapReserved |
| 91 | } vtg; | 91 | } vtg; |
| 92 | 92 | ||
| 93 | struct { | 93 | struct { |
| 94 | INSERT_PADDING_BYTES(3); // ImapSystemValuesA | 94 | INSERT_UNION_PADDING_BYTES(3); // ImapSystemValuesA |
| 95 | INSERT_PADDING_BYTES(1); // ImapSystemValuesB | 95 | INSERT_UNION_PADDING_BYTES(1); // ImapSystemValuesB |
| 96 | union { | 96 | union { |
| 97 | BitField<0, 2, AttributeUse> x; | 97 | BitField<0, 2, AttributeUse> x; |
| 98 | BitField<2, 2, AttributeUse> y; | 98 | BitField<2, 2, AttributeUse> y; |
| @@ -100,10 +100,10 @@ struct Header { | |||
| 100 | BitField<6, 2, AttributeUse> z; | 100 | BitField<6, 2, AttributeUse> z; |
| 101 | u8 raw; | 101 | u8 raw; |
| 102 | } imap_generic_vector[32]; | 102 | } imap_generic_vector[32]; |
| 103 | INSERT_PADDING_BYTES(2); // ImapColor | 103 | INSERT_UNION_PADDING_BYTES(2); // ImapColor |
| 104 | INSERT_PADDING_BYTES(2); // ImapSystemValuesC | 104 | INSERT_UNION_PADDING_BYTES(2); // ImapSystemValuesC |
| 105 | INSERT_PADDING_BYTES(10); // ImapFixedFncTexture[10] | 105 | INSERT_UNION_PADDING_BYTES(10); // ImapFixedFncTexture[10] |
| 106 | INSERT_PADDING_BYTES(2); // ImapReserved | 106 | INSERT_UNION_PADDING_BYTES(2); // ImapReserved |
| 107 | struct { | 107 | struct { |
| 108 | u32 target; | 108 | u32 target; |
| 109 | union { | 109 | union { |
| @@ -139,6 +139,8 @@ struct Header { | |||
| 139 | return result; | 139 | return result; |
| 140 | } | 140 | } |
| 141 | } ps; | 141 | } ps; |
| 142 | |||
| 143 | std::array<u32, 0xF> raw{}; | ||
| 142 | }; | 144 | }; |
| 143 | 145 | ||
| 144 | u64 GetLocalMemorySize() const { | 146 | u64 GetLocalMemorySize() const { |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index dbca19f35..ecc338ae9 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -207,7 +207,7 @@ public: | |||
| 207 | 207 | ||
| 208 | union { | 208 | union { |
| 209 | struct { | 209 | struct { |
| 210 | INSERT_PADDING_WORDS(0x4); | 210 | INSERT_UNION_PADDING_WORDS(0x4); |
| 211 | struct { | 211 | struct { |
| 212 | u32 address_high; | 212 | u32 address_high; |
| 213 | u32 address_low; | 213 | u32 address_low; |
| @@ -220,12 +220,12 @@ public: | |||
| 220 | 220 | ||
| 221 | u32 semaphore_sequence; | 221 | u32 semaphore_sequence; |
| 222 | u32 semaphore_trigger; | 222 | u32 semaphore_trigger; |
| 223 | INSERT_PADDING_WORDS(0xC); | 223 | INSERT_UNION_PADDING_WORDS(0xC); |
| 224 | 224 | ||
| 225 | // The puser and the puller share the reference counter, the pusher only has read | 225 | // The puser and the puller share the reference counter, the pusher only has read |
| 226 | // access | 226 | // access |
| 227 | u32 reference_count; | 227 | u32 reference_count; |
| 228 | INSERT_PADDING_WORDS(0x5); | 228 | INSERT_UNION_PADDING_WORDS(0x5); |
| 229 | 229 | ||
| 230 | u32 semaphore_acquire; | 230 | u32 semaphore_acquire; |
| 231 | u32 semaphore_release; | 231 | u32 semaphore_release; |
| @@ -234,7 +234,7 @@ public: | |||
| 234 | BitField<4, 4, u32> operation; | 234 | BitField<4, 4, u32> operation; |
| 235 | BitField<8, 8, u32> id; | 235 | BitField<8, 8, u32> id; |
| 236 | } fence_action; | 236 | } fence_action; |
| 237 | INSERT_PADDING_WORDS(0xE2); | 237 | INSERT_UNION_PADDING_WORDS(0xE2); |
| 238 | 238 | ||
| 239 | // Puller state | 239 | // Puller state |
| 240 | u32 acquire_mode; | 240 | u32 acquire_mode; |
diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp new file mode 100644 index 000000000..b230dcc18 --- /dev/null +++ b/src/video_core/rasterizer_accelerated.cpp | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <mutex> | ||
| 6 | |||
| 7 | #include <boost/icl/interval_map.hpp> | ||
| 8 | |||
| 9 | #include "common/assert.h" | ||
| 10 | #include "common/common_types.h" | ||
| 11 | #include "core/memory.h" | ||
| 12 | #include "video_core/rasterizer_accelerated.h" | ||
| 13 | |||
| 14 | namespace VideoCore { | ||
| 15 | |||
| 16 | namespace { | ||
| 17 | |||
| 18 | template <typename Map, typename Interval> | ||
| 19 | constexpr auto RangeFromInterval(Map& map, const Interval& interval) { | ||
| 20 | return boost::make_iterator_range(map.equal_range(interval)); | ||
| 21 | } | ||
| 22 | |||
| 23 | } // Anonymous namespace | ||
| 24 | |||
| 25 | RasterizerAccelerated::RasterizerAccelerated() = default; | ||
| 26 | |||
| 27 | RasterizerAccelerated::~RasterizerAccelerated() = default; | ||
| 28 | |||
| 29 | void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { | ||
| 30 | std::lock_guard lock{pages_mutex}; | ||
| 31 | const u64 page_start{addr >> Memory::PAGE_BITS}; | ||
| 32 | const u64 page_end{(addr + size + Memory::PAGE_SIZE - 1) >> Memory::PAGE_BITS}; | ||
| 33 | |||
| 34 | // Interval maps will erase segments if count reaches 0, so if delta is negative we have to | ||
| 35 | // subtract after iterating | ||
| 36 | const auto pages_interval = CachedPageMap::interval_type::right_open(page_start, page_end); | ||
| 37 | if (delta > 0) { | ||
| 38 | cached_pages.add({pages_interval, delta}); | ||
| 39 | } | ||
| 40 | |||
| 41 | for (const auto& pair : RangeFromInterval(cached_pages, pages_interval)) { | ||
| 42 | const auto interval = pair.first & pages_interval; | ||
| 43 | const int count = pair.second; | ||
| 44 | |||
| 45 | const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS; | ||
| 46 | const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS; | ||
| 47 | const u64 interval_size = interval_end_addr - interval_start_addr; | ||
| 48 | |||
| 49 | if (delta > 0 && count == delta) { | ||
| 50 | Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, true); | ||
| 51 | } else if (delta < 0 && count == -delta) { | ||
| 52 | Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, false); | ||
| 53 | } else { | ||
| 54 | ASSERT(count >= 0); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | if (delta < 0) { | ||
| 59 | cached_pages.add({pages_interval, delta}); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | } // namespace VideoCore | ||
diff --git a/src/video_core/rasterizer_accelerated.h b/src/video_core/rasterizer_accelerated.h new file mode 100644 index 000000000..8f7e3547e --- /dev/null +++ b/src/video_core/rasterizer_accelerated.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | // Copyright 2019 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <mutex> | ||
| 8 | |||
| 9 | #include <boost/icl/interval_map.hpp> | ||
| 10 | |||
| 11 | #include "common/common_types.h" | ||
| 12 | #include "video_core/rasterizer_interface.h" | ||
| 13 | |||
| 14 | namespace VideoCore { | ||
| 15 | |||
| 16 | /// Implements the shared part in GPU accelerated rasterizers in RasterizerInterface. | ||
| 17 | class RasterizerAccelerated : public RasterizerInterface { | ||
| 18 | public: | ||
| 19 | explicit RasterizerAccelerated(); | ||
| 20 | ~RasterizerAccelerated() override; | ||
| 21 | |||
| 22 | void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override; | ||
| 23 | |||
| 24 | private: | ||
| 25 | using CachedPageMap = boost::icl::interval_map<u64, int>; | ||
| 26 | CachedPageMap cached_pages; | ||
| 27 | |||
| 28 | std::mutex pages_mutex; | ||
| 29 | }; | ||
| 30 | |||
| 31 | } // namespace VideoCore | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 35fc094a8..d1e147db8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -68,8 +68,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind | |||
| 68 | ScreenInfo& info) | 68 | ScreenInfo& info) |
| 69 | : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device}, | 69 | : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device}, |
| 70 | system{system}, screen_info{info}, buffer_cache{*this, system, STREAM_BUFFER_SIZE} { | 70 | system{system}, screen_info{info}, buffer_cache{*this, system, STREAM_BUFFER_SIZE} { |
| 71 | OpenGLState::ApplyDefaultState(); | ||
| 72 | |||
| 73 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); | 71 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); |
| 74 | state.draw.shader_program = 0; | 72 | state.draw.shader_program = 0; |
| 75 | state.Apply(); | 73 | state.Apply(); |
| @@ -342,42 +340,6 @@ std::size_t RasterizerOpenGL::CalculateIndexBufferSize() const { | |||
| 342 | static_cast<std::size_t>(regs.index_array.FormatSizeInBytes()); | 340 | static_cast<std::size_t>(regs.index_array.FormatSizeInBytes()); |
| 343 | } | 341 | } |
| 344 | 342 | ||
| 345 | template <typename Map, typename Interval> | ||
| 346 | static constexpr auto RangeFromInterval(Map& map, const Interval& interval) { | ||
| 347 | return boost::make_iterator_range(map.equal_range(interval)); | ||
| 348 | } | ||
| 349 | |||
| 350 | void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { | ||
| 351 | std::lock_guard lock{pages_mutex}; | ||
| 352 | const u64 page_start{addr >> Memory::PAGE_BITS}; | ||
| 353 | const u64 page_end{(addr + size + Memory::PAGE_SIZE - 1) >> Memory::PAGE_BITS}; | ||
| 354 | |||
| 355 | // Interval maps will erase segments if count reaches 0, so if delta is negative we have to | ||
| 356 | // subtract after iterating | ||
| 357 | const auto pages_interval = CachedPageMap::interval_type::right_open(page_start, page_end); | ||
| 358 | if (delta > 0) | ||
| 359 | cached_pages.add({pages_interval, delta}); | ||
| 360 | |||
| 361 | for (const auto& pair : RangeFromInterval(cached_pages, pages_interval)) { | ||
| 362 | const auto interval = pair.first & pages_interval; | ||
| 363 | const int count = pair.second; | ||
| 364 | |||
| 365 | const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS; | ||
| 366 | const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS; | ||
| 367 | const u64 interval_size = interval_end_addr - interval_start_addr; | ||
| 368 | |||
| 369 | if (delta > 0 && count == delta) | ||
| 370 | Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, true); | ||
| 371 | else if (delta < 0 && count == -delta) | ||
| 372 | Memory::RasterizerMarkRegionCached(interval_start_addr, interval_size, false); | ||
| 373 | else | ||
| 374 | ASSERT(count >= 0); | ||
| 375 | } | ||
| 376 | |||
| 377 | if (delta < 0) | ||
| 378 | cached_pages.add({pages_interval, delta}); | ||
| 379 | } | ||
| 380 | |||
| 381 | void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, | 343 | void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, |
| 382 | const VideoCore::DiskResourceLoadCallback& callback) { | 344 | const VideoCore::DiskResourceLoadCallback& callback) { |
| 383 | shader_cache.LoadDiskCache(stop_loading, callback); | 345 | shader_cache.LoadDiskCache(stop_loading, callback); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index c24a02d71..bd6fe5c3a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -9,17 +9,16 @@ | |||
| 9 | #include <cstddef> | 9 | #include <cstddef> |
| 10 | #include <map> | 10 | #include <map> |
| 11 | #include <memory> | 11 | #include <memory> |
| 12 | #include <mutex> | ||
| 13 | #include <optional> | 12 | #include <optional> |
| 14 | #include <tuple> | 13 | #include <tuple> |
| 15 | #include <utility> | 14 | #include <utility> |
| 16 | 15 | ||
| 17 | #include <boost/icl/interval_map.hpp> | ||
| 18 | #include <glad/glad.h> | 16 | #include <glad/glad.h> |
| 19 | 17 | ||
| 20 | #include "common/common_types.h" | 18 | #include "common/common_types.h" |
| 21 | #include "video_core/engines/const_buffer_info.h" | 19 | #include "video_core/engines/const_buffer_info.h" |
| 22 | #include "video_core/engines/maxwell_3d.h" | 20 | #include "video_core/engines/maxwell_3d.h" |
| 21 | #include "video_core/rasterizer_accelerated.h" | ||
| 23 | #include "video_core/rasterizer_cache.h" | 22 | #include "video_core/rasterizer_cache.h" |
| 24 | #include "video_core/rasterizer_interface.h" | 23 | #include "video_core/rasterizer_interface.h" |
| 25 | #include "video_core/renderer_opengl/gl_buffer_cache.h" | 24 | #include "video_core/renderer_opengl/gl_buffer_cache.h" |
| @@ -52,7 +51,7 @@ namespace OpenGL { | |||
| 52 | struct ScreenInfo; | 51 | struct ScreenInfo; |
| 53 | struct DrawParameters; | 52 | struct DrawParameters; |
| 54 | 53 | ||
| 55 | class RasterizerOpenGL : public VideoCore::RasterizerInterface { | 54 | class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { |
| 56 | public: | 55 | public: |
| 57 | explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, | 56 | explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, |
| 58 | ScreenInfo& info); | 57 | ScreenInfo& info); |
| @@ -73,7 +72,6 @@ public: | |||
| 73 | const Tegra::Engines::Fermi2D::Config& copy_config) override; | 72 | const Tegra::Engines::Fermi2D::Config& copy_config) override; |
| 74 | bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, | 73 | bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, |
| 75 | u32 pixel_stride) override; | 74 | u32 pixel_stride) override; |
| 76 | void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override; | ||
| 77 | void LoadDiskResources(const std::atomic_bool& stop_loading, | 75 | void LoadDiskResources(const std::atomic_bool& stop_loading, |
| 78 | const VideoCore::DiskResourceLoadCallback& callback) override; | 76 | const VideoCore::DiskResourceLoadCallback& callback) override; |
| 79 | 77 | ||
| @@ -228,11 +226,6 @@ private: | |||
| 228 | AccelDraw accelerate_draw = AccelDraw::Disabled; | 226 | AccelDraw accelerate_draw = AccelDraw::Disabled; |
| 229 | 227 | ||
| 230 | OGLFramebuffer clear_framebuffer; | 228 | OGLFramebuffer clear_framebuffer; |
| 231 | |||
| 232 | using CachedPageMap = boost::icl::interval_map<u64, int>; | ||
| 233 | CachedPageMap cached_pages; | ||
| 234 | |||
| 235 | std::mutex pages_mutex; | ||
| 236 | }; | 229 | }; |
| 237 | 230 | ||
| 238 | } // namespace OpenGL | 231 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index bf86b5a0b..f25148362 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 5 | #include <iterator> | 6 | #include <iterator> |
| 6 | #include <glad/glad.h> | 7 | #include <glad/glad.h> |
| 7 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| @@ -69,147 +70,29 @@ void Enable(GLenum cap, GLuint index, bool enable) { | |||
| 69 | } | 70 | } |
| 70 | 71 | ||
| 71 | void Enable(GLenum cap, bool& current_value, bool new_value) { | 72 | void Enable(GLenum cap, bool& current_value, bool new_value) { |
| 72 | if (UpdateValue(current_value, new_value)) | 73 | if (UpdateValue(current_value, new_value)) { |
| 73 | Enable(cap, new_value); | 74 | Enable(cap, new_value); |
| 75 | } | ||
| 74 | } | 76 | } |
| 75 | 77 | ||
| 76 | void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) { | 78 | void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) { |
| 77 | if (UpdateValue(current_value, new_value)) | 79 | if (UpdateValue(current_value, new_value)) { |
| 78 | Enable(cap, index, new_value); | 80 | Enable(cap, index, new_value); |
| 79 | } | ||
| 80 | |||
| 81 | } // namespace | ||
| 82 | |||
| 83 | OpenGLState::OpenGLState() { | ||
| 84 | // These all match default OpenGL values | ||
| 85 | framebuffer_srgb.enabled = false; | ||
| 86 | |||
| 87 | multisample_control.alpha_to_coverage = false; | ||
| 88 | multisample_control.alpha_to_one = false; | ||
| 89 | |||
| 90 | cull.enabled = false; | ||
| 91 | cull.mode = GL_BACK; | ||
| 92 | cull.front_face = GL_CCW; | ||
| 93 | |||
| 94 | depth.test_enabled = false; | ||
| 95 | depth.test_func = GL_LESS; | ||
| 96 | depth.write_mask = GL_TRUE; | ||
| 97 | |||
| 98 | primitive_restart.enabled = false; | ||
| 99 | primitive_restart.index = 0; | ||
| 100 | |||
| 101 | for (auto& item : color_mask) { | ||
| 102 | item.red_enabled = GL_TRUE; | ||
| 103 | item.green_enabled = GL_TRUE; | ||
| 104 | item.blue_enabled = GL_TRUE; | ||
| 105 | item.alpha_enabled = GL_TRUE; | ||
| 106 | } | 81 | } |
| 82 | } | ||
| 107 | 83 | ||
| 108 | const auto ResetStencil = [](auto& config) { | 84 | } // Anonymous namespace |
| 109 | config.test_func = GL_ALWAYS; | ||
| 110 | config.test_ref = 0; | ||
| 111 | config.test_mask = 0xFFFFFFFF; | ||
| 112 | config.write_mask = 0xFFFFFFFF; | ||
| 113 | config.action_depth_fail = GL_KEEP; | ||
| 114 | config.action_depth_pass = GL_KEEP; | ||
| 115 | config.action_stencil_fail = GL_KEEP; | ||
| 116 | }; | ||
| 117 | stencil.test_enabled = false; | ||
| 118 | ResetStencil(stencil.front); | ||
| 119 | ResetStencil(stencil.back); | ||
| 120 | |||
| 121 | for (auto& item : viewports) { | ||
| 122 | item.x = 0; | ||
| 123 | item.y = 0; | ||
| 124 | item.width = 0; | ||
| 125 | item.height = 0; | ||
| 126 | item.depth_range_near = 0.0f; | ||
| 127 | item.depth_range_far = 1.0f; | ||
| 128 | item.scissor.enabled = false; | ||
| 129 | item.scissor.x = 0; | ||
| 130 | item.scissor.y = 0; | ||
| 131 | item.scissor.width = 0; | ||
| 132 | item.scissor.height = 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | for (auto& item : blend) { | ||
| 136 | item.enabled = true; | ||
| 137 | item.rgb_equation = GL_FUNC_ADD; | ||
| 138 | item.a_equation = GL_FUNC_ADD; | ||
| 139 | item.src_rgb_func = GL_ONE; | ||
| 140 | item.dst_rgb_func = GL_ZERO; | ||
| 141 | item.src_a_func = GL_ONE; | ||
| 142 | item.dst_a_func = GL_ZERO; | ||
| 143 | } | ||
| 144 | |||
| 145 | independant_blend.enabled = false; | ||
| 146 | |||
| 147 | blend_color.red = 0.0f; | ||
| 148 | blend_color.green = 0.0f; | ||
| 149 | blend_color.blue = 0.0f; | ||
| 150 | blend_color.alpha = 0.0f; | ||
| 151 | |||
| 152 | logic_op.enabled = false; | ||
| 153 | logic_op.operation = GL_COPY; | ||
| 154 | |||
| 155 | draw.read_framebuffer = 0; | ||
| 156 | draw.draw_framebuffer = 0; | ||
| 157 | draw.vertex_array = 0; | ||
| 158 | draw.shader_program = 0; | ||
| 159 | draw.program_pipeline = 0; | ||
| 160 | |||
| 161 | clip_distance = {}; | ||
| 162 | |||
| 163 | point.size = 1; | ||
| 164 | |||
| 165 | fragment_color_clamp.enabled = false; | ||
| 166 | |||
| 167 | depth_clamp.far_plane = false; | ||
| 168 | depth_clamp.near_plane = false; | ||
| 169 | |||
| 170 | polygon_offset.fill_enable = false; | ||
| 171 | polygon_offset.line_enable = false; | ||
| 172 | polygon_offset.point_enable = false; | ||
| 173 | polygon_offset.factor = 0.0f; | ||
| 174 | polygon_offset.units = 0.0f; | ||
| 175 | polygon_offset.clamp = 0.0f; | ||
| 176 | 85 | ||
| 177 | alpha_test.enabled = false; | 86 | OpenGLState::OpenGLState() = default; |
| 178 | alpha_test.func = GL_ALWAYS; | ||
| 179 | alpha_test.ref = 0.0f; | ||
| 180 | } | ||
| 181 | 87 | ||
| 182 | void OpenGLState::SetDefaultViewports() { | 88 | void OpenGLState::SetDefaultViewports() { |
| 183 | for (auto& item : viewports) { | 89 | viewports.fill(Viewport{}); |
| 184 | item.x = 0; | ||
| 185 | item.y = 0; | ||
| 186 | item.width = 0; | ||
| 187 | item.height = 0; | ||
| 188 | item.depth_range_near = 0.0f; | ||
| 189 | item.depth_range_far = 1.0f; | ||
| 190 | item.scissor.enabled = false; | ||
| 191 | item.scissor.x = 0; | ||
| 192 | item.scissor.y = 0; | ||
| 193 | item.scissor.width = 0; | ||
| 194 | item.scissor.height = 0; | ||
| 195 | } | ||
| 196 | 90 | ||
| 197 | depth_clamp.far_plane = false; | 91 | depth_clamp.far_plane = false; |
| 198 | depth_clamp.near_plane = false; | 92 | depth_clamp.near_plane = false; |
| 199 | } | 93 | } |
| 200 | 94 | ||
| 201 | void OpenGLState::ApplyDefaultState() { | 95 | void OpenGLState::ApplyFramebufferState() { |
| 202 | glEnable(GL_BLEND); | ||
| 203 | glDisable(GL_FRAMEBUFFER_SRGB); | ||
| 204 | glDisable(GL_CULL_FACE); | ||
| 205 | glDisable(GL_DEPTH_TEST); | ||
| 206 | glDisable(GL_PRIMITIVE_RESTART); | ||
| 207 | glDisable(GL_STENCIL_TEST); | ||
| 208 | glDisable(GL_COLOR_LOGIC_OP); | ||
| 209 | glDisable(GL_SCISSOR_TEST); | ||
| 210 | } | ||
| 211 | |||
| 212 | void OpenGLState::ApplyFramebufferState() const { | ||
| 213 | if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) { | 96 | if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) { |
| 214 | glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); | 97 | glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); |
| 215 | } | 98 | } |
| @@ -218,52 +101,52 @@ void OpenGLState::ApplyFramebufferState() const { | |||
| 218 | } | 101 | } |
| 219 | } | 102 | } |
| 220 | 103 | ||
| 221 | void OpenGLState::ApplyVertexArrayState() const { | 104 | void OpenGLState::ApplyVertexArrayState() { |
| 222 | if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) { | 105 | if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) { |
| 223 | glBindVertexArray(draw.vertex_array); | 106 | glBindVertexArray(draw.vertex_array); |
| 224 | } | 107 | } |
| 225 | } | 108 | } |
| 226 | 109 | ||
| 227 | void OpenGLState::ApplyShaderProgram() const { | 110 | void OpenGLState::ApplyShaderProgram() { |
| 228 | if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) { | 111 | if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) { |
| 229 | glUseProgram(draw.shader_program); | 112 | glUseProgram(draw.shader_program); |
| 230 | } | 113 | } |
| 231 | } | 114 | } |
| 232 | 115 | ||
| 233 | void OpenGLState::ApplyProgramPipeline() const { | 116 | void OpenGLState::ApplyProgramPipeline() { |
| 234 | if (UpdateValue(cur_state.draw.program_pipeline, draw.program_pipeline)) { | 117 | if (UpdateValue(cur_state.draw.program_pipeline, draw.program_pipeline)) { |
| 235 | glBindProgramPipeline(draw.program_pipeline); | 118 | glBindProgramPipeline(draw.program_pipeline); |
| 236 | } | 119 | } |
| 237 | } | 120 | } |
| 238 | 121 | ||
| 239 | void OpenGLState::ApplyClipDistances() const { | 122 | void OpenGLState::ApplyClipDistances() { |
| 240 | for (std::size_t i = 0; i < clip_distance.size(); ++i) { | 123 | for (std::size_t i = 0; i < clip_distance.size(); ++i) { |
| 241 | Enable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i), cur_state.clip_distance[i], | 124 | Enable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i), cur_state.clip_distance[i], |
| 242 | clip_distance[i]); | 125 | clip_distance[i]); |
| 243 | } | 126 | } |
| 244 | } | 127 | } |
| 245 | 128 | ||
| 246 | void OpenGLState::ApplyPointSize() const { | 129 | void OpenGLState::ApplyPointSize() { |
| 247 | if (UpdateValue(cur_state.point.size, point.size)) { | 130 | if (UpdateValue(cur_state.point.size, point.size)) { |
| 248 | glPointSize(point.size); | 131 | glPointSize(point.size); |
| 249 | } | 132 | } |
| 250 | } | 133 | } |
| 251 | 134 | ||
| 252 | void OpenGLState::ApplyFragmentColorClamp() const { | 135 | void OpenGLState::ApplyFragmentColorClamp() { |
| 253 | if (UpdateValue(cur_state.fragment_color_clamp.enabled, fragment_color_clamp.enabled)) { | 136 | if (UpdateValue(cur_state.fragment_color_clamp.enabled, fragment_color_clamp.enabled)) { |
| 254 | glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, | 137 | glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, |
| 255 | fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE); | 138 | fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE); |
| 256 | } | 139 | } |
| 257 | } | 140 | } |
| 258 | 141 | ||
| 259 | void OpenGLState::ApplyMultisample() const { | 142 | void OpenGLState::ApplyMultisample() { |
| 260 | Enable(GL_SAMPLE_ALPHA_TO_COVERAGE, cur_state.multisample_control.alpha_to_coverage, | 143 | Enable(GL_SAMPLE_ALPHA_TO_COVERAGE, cur_state.multisample_control.alpha_to_coverage, |
| 261 | multisample_control.alpha_to_coverage); | 144 | multisample_control.alpha_to_coverage); |
| 262 | Enable(GL_SAMPLE_ALPHA_TO_ONE, cur_state.multisample_control.alpha_to_one, | 145 | Enable(GL_SAMPLE_ALPHA_TO_ONE, cur_state.multisample_control.alpha_to_one, |
| 263 | multisample_control.alpha_to_one); | 146 | multisample_control.alpha_to_one); |
| 264 | } | 147 | } |
| 265 | 148 | ||
| 266 | void OpenGLState::ApplyDepthClamp() const { | 149 | void OpenGLState::ApplyDepthClamp() { |
| 267 | if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane && | 150 | if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane && |
| 268 | depth_clamp.near_plane == cur_state.depth_clamp.near_plane) { | 151 | depth_clamp.near_plane == cur_state.depth_clamp.near_plane) { |
| 269 | return; | 152 | return; |
| @@ -276,7 +159,7 @@ void OpenGLState::ApplyDepthClamp() const { | |||
| 276 | Enable(GL_DEPTH_CLAMP, depth_clamp.far_plane || depth_clamp.near_plane); | 159 | Enable(GL_DEPTH_CLAMP, depth_clamp.far_plane || depth_clamp.near_plane); |
| 277 | } | 160 | } |
| 278 | 161 | ||
| 279 | void OpenGLState::ApplySRgb() const { | 162 | void OpenGLState::ApplySRgb() { |
| 280 | if (cur_state.framebuffer_srgb.enabled == framebuffer_srgb.enabled) | 163 | if (cur_state.framebuffer_srgb.enabled == framebuffer_srgb.enabled) |
| 281 | return; | 164 | return; |
| 282 | cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled; | 165 | cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled; |
| @@ -287,7 +170,7 @@ void OpenGLState::ApplySRgb() const { | |||
| 287 | } | 170 | } |
| 288 | } | 171 | } |
| 289 | 172 | ||
| 290 | void OpenGLState::ApplyCulling() const { | 173 | void OpenGLState::ApplyCulling() { |
| 291 | Enable(GL_CULL_FACE, cur_state.cull.enabled, cull.enabled); | 174 | Enable(GL_CULL_FACE, cur_state.cull.enabled, cull.enabled); |
| 292 | 175 | ||
| 293 | if (UpdateValue(cur_state.cull.mode, cull.mode)) { | 176 | if (UpdateValue(cur_state.cull.mode, cull.mode)) { |
| @@ -299,7 +182,12 @@ void OpenGLState::ApplyCulling() const { | |||
| 299 | } | 182 | } |
| 300 | } | 183 | } |
| 301 | 184 | ||
| 302 | void OpenGLState::ApplyColorMask() const { | 185 | void OpenGLState::ApplyColorMask() { |
| 186 | if (!dirty.color_mask) { | ||
| 187 | return; | ||
| 188 | } | ||
| 189 | dirty.color_mask = false; | ||
| 190 | |||
| 303 | for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { | 191 | for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { |
| 304 | const auto& updated = color_mask[i]; | 192 | const auto& updated = color_mask[i]; |
| 305 | auto& current = cur_state.color_mask[i]; | 193 | auto& current = cur_state.color_mask[i]; |
| @@ -314,7 +202,7 @@ void OpenGLState::ApplyColorMask() const { | |||
| 314 | } | 202 | } |
| 315 | } | 203 | } |
| 316 | 204 | ||
| 317 | void OpenGLState::ApplyDepth() const { | 205 | void OpenGLState::ApplyDepth() { |
| 318 | Enable(GL_DEPTH_TEST, cur_state.depth.test_enabled, depth.test_enabled); | 206 | Enable(GL_DEPTH_TEST, cur_state.depth.test_enabled, depth.test_enabled); |
| 319 | 207 | ||
| 320 | if (cur_state.depth.test_func != depth.test_func) { | 208 | if (cur_state.depth.test_func != depth.test_func) { |
| @@ -328,7 +216,7 @@ void OpenGLState::ApplyDepth() const { | |||
| 328 | } | 216 | } |
| 329 | } | 217 | } |
| 330 | 218 | ||
| 331 | void OpenGLState::ApplyPrimitiveRestart() const { | 219 | void OpenGLState::ApplyPrimitiveRestart() { |
| 332 | Enable(GL_PRIMITIVE_RESTART, cur_state.primitive_restart.enabled, primitive_restart.enabled); | 220 | Enable(GL_PRIMITIVE_RESTART, cur_state.primitive_restart.enabled, primitive_restart.enabled); |
| 333 | 221 | ||
| 334 | if (cur_state.primitive_restart.index != primitive_restart.index) { | 222 | if (cur_state.primitive_restart.index != primitive_restart.index) { |
| @@ -337,7 +225,12 @@ void OpenGLState::ApplyPrimitiveRestart() const { | |||
| 337 | } | 225 | } |
| 338 | } | 226 | } |
| 339 | 227 | ||
| 340 | void OpenGLState::ApplyStencilTest() const { | 228 | void OpenGLState::ApplyStencilTest() { |
| 229 | if (!dirty.stencil_state) { | ||
| 230 | return; | ||
| 231 | } | ||
| 232 | dirty.stencil_state = false; | ||
| 233 | |||
| 341 | Enable(GL_STENCIL_TEST, cur_state.stencil.test_enabled, stencil.test_enabled); | 234 | Enable(GL_STENCIL_TEST, cur_state.stencil.test_enabled, stencil.test_enabled); |
| 342 | 235 | ||
| 343 | const auto ConfigStencil = [](GLenum face, const auto& config, auto& current) { | 236 | const auto ConfigStencil = [](GLenum face, const auto& config, auto& current) { |
| @@ -366,7 +259,7 @@ void OpenGLState::ApplyStencilTest() const { | |||
| 366 | ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back); | 259 | ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back); |
| 367 | } | 260 | } |
| 368 | 261 | ||
| 369 | void OpenGLState::ApplyViewport() const { | 262 | void OpenGLState::ApplyViewport() { |
| 370 | for (GLuint i = 0; i < static_cast<GLuint>(Maxwell::NumViewports); ++i) { | 263 | for (GLuint i = 0; i < static_cast<GLuint>(Maxwell::NumViewports); ++i) { |
| 371 | const auto& updated = viewports[i]; | 264 | const auto& updated = viewports[i]; |
| 372 | auto& current = cur_state.viewports[i]; | 265 | auto& current = cur_state.viewports[i]; |
| @@ -403,7 +296,7 @@ void OpenGLState::ApplyViewport() const { | |||
| 403 | } | 296 | } |
| 404 | } | 297 | } |
| 405 | 298 | ||
| 406 | void OpenGLState::ApplyGlobalBlending() const { | 299 | void OpenGLState::ApplyGlobalBlending() { |
| 407 | const Blend& updated = blend[0]; | 300 | const Blend& updated = blend[0]; |
| 408 | Blend& current = cur_state.blend[0]; | 301 | Blend& current = cur_state.blend[0]; |
| 409 | 302 | ||
| @@ -427,7 +320,7 @@ void OpenGLState::ApplyGlobalBlending() const { | |||
| 427 | } | 320 | } |
| 428 | } | 321 | } |
| 429 | 322 | ||
| 430 | void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) const { | 323 | void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) { |
| 431 | const Blend& updated = blend[target]; | 324 | const Blend& updated = blend[target]; |
| 432 | Blend& current = cur_state.blend[target]; | 325 | Blend& current = cur_state.blend[target]; |
| 433 | 326 | ||
| @@ -451,7 +344,12 @@ void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) const { | |||
| 451 | } | 344 | } |
| 452 | } | 345 | } |
| 453 | 346 | ||
| 454 | void OpenGLState::ApplyBlending() const { | 347 | void OpenGLState::ApplyBlending() { |
| 348 | if (!dirty.blend_state) { | ||
| 349 | return; | ||
| 350 | } | ||
| 351 | dirty.blend_state = false; | ||
| 352 | |||
| 455 | if (independant_blend.enabled) { | 353 | if (independant_blend.enabled) { |
| 456 | const bool force = independant_blend.enabled != cur_state.independant_blend.enabled; | 354 | const bool force = independant_blend.enabled != cur_state.independant_blend.enabled; |
| 457 | for (std::size_t target = 0; target < Maxwell::NumRenderTargets; ++target) { | 355 | for (std::size_t target = 0; target < Maxwell::NumRenderTargets; ++target) { |
| @@ -470,7 +368,7 @@ void OpenGLState::ApplyBlending() const { | |||
| 470 | } | 368 | } |
| 471 | } | 369 | } |
| 472 | 370 | ||
| 473 | void OpenGLState::ApplyLogicOp() const { | 371 | void OpenGLState::ApplyLogicOp() { |
| 474 | Enable(GL_COLOR_LOGIC_OP, cur_state.logic_op.enabled, logic_op.enabled); | 372 | Enable(GL_COLOR_LOGIC_OP, cur_state.logic_op.enabled, logic_op.enabled); |
| 475 | 373 | ||
| 476 | if (UpdateValue(cur_state.logic_op.operation, logic_op.operation)) { | 374 | if (UpdateValue(cur_state.logic_op.operation, logic_op.operation)) { |
| @@ -478,7 +376,12 @@ void OpenGLState::ApplyLogicOp() const { | |||
| 478 | } | 376 | } |
| 479 | } | 377 | } |
| 480 | 378 | ||
| 481 | void OpenGLState::ApplyPolygonOffset() const { | 379 | void OpenGLState::ApplyPolygonOffset() { |
| 380 | if (!dirty.polygon_offset) { | ||
| 381 | return; | ||
| 382 | } | ||
| 383 | dirty.polygon_offset = false; | ||
| 384 | |||
| 482 | Enable(GL_POLYGON_OFFSET_FILL, cur_state.polygon_offset.fill_enable, | 385 | Enable(GL_POLYGON_OFFSET_FILL, cur_state.polygon_offset.fill_enable, |
| 483 | polygon_offset.fill_enable); | 386 | polygon_offset.fill_enable); |
| 484 | Enable(GL_POLYGON_OFFSET_LINE, cur_state.polygon_offset.line_enable, | 387 | Enable(GL_POLYGON_OFFSET_LINE, cur_state.polygon_offset.line_enable, |
| @@ -499,7 +402,7 @@ void OpenGLState::ApplyPolygonOffset() const { | |||
| 499 | } | 402 | } |
| 500 | } | 403 | } |
| 501 | 404 | ||
| 502 | void OpenGLState::ApplyAlphaTest() const { | 405 | void OpenGLState::ApplyAlphaTest() { |
| 503 | Enable(GL_ALPHA_TEST, cur_state.alpha_test.enabled, alpha_test.enabled); | 406 | Enable(GL_ALPHA_TEST, cur_state.alpha_test.enabled, alpha_test.enabled); |
| 504 | if (UpdateTie(std::tie(cur_state.alpha_test.func, cur_state.alpha_test.ref), | 407 | if (UpdateTie(std::tie(cur_state.alpha_test.func, cur_state.alpha_test.ref), |
| 505 | std::tie(alpha_test.func, alpha_test.ref))) { | 408 | std::tie(alpha_test.func, alpha_test.ref))) { |
| @@ -507,19 +410,19 @@ void OpenGLState::ApplyAlphaTest() const { | |||
| 507 | } | 410 | } |
| 508 | } | 411 | } |
| 509 | 412 | ||
| 510 | void OpenGLState::ApplyTextures() const { | 413 | void OpenGLState::ApplyTextures() { |
| 511 | if (const auto update = UpdateArray(cur_state.textures, textures)) { | 414 | if (const auto update = UpdateArray(cur_state.textures, textures)) { |
| 512 | glBindTextures(update->first, update->second, textures.data() + update->first); | 415 | glBindTextures(update->first, update->second, textures.data() + update->first); |
| 513 | } | 416 | } |
| 514 | } | 417 | } |
| 515 | 418 | ||
| 516 | void OpenGLState::ApplySamplers() const { | 419 | void OpenGLState::ApplySamplers() { |
| 517 | if (const auto update = UpdateArray(cur_state.samplers, samplers)) { | 420 | if (const auto update = UpdateArray(cur_state.samplers, samplers)) { |
| 518 | glBindSamplers(update->first, update->second, samplers.data() + update->first); | 421 | glBindSamplers(update->first, update->second, samplers.data() + update->first); |
| 519 | } | 422 | } |
| 520 | } | 423 | } |
| 521 | 424 | ||
| 522 | void OpenGLState::ApplyImages() const { | 425 | void OpenGLState::ApplyImages() { |
| 523 | if (const auto update = UpdateArray(cur_state.images, images)) { | 426 | if (const auto update = UpdateArray(cur_state.images, images)) { |
| 524 | glBindImageTextures(update->first, update->second, images.data() + update->first); | 427 | glBindImageTextures(update->first, update->second, images.data() + update->first); |
| 525 | } | 428 | } |
| @@ -535,32 +438,20 @@ void OpenGLState::Apply() { | |||
| 535 | ApplyPointSize(); | 438 | ApplyPointSize(); |
| 536 | ApplyFragmentColorClamp(); | 439 | ApplyFragmentColorClamp(); |
| 537 | ApplyMultisample(); | 440 | ApplyMultisample(); |
| 538 | if (dirty.color_mask) { | 441 | ApplyColorMask(); |
| 539 | ApplyColorMask(); | ||
| 540 | dirty.color_mask = false; | ||
| 541 | } | ||
| 542 | ApplyDepthClamp(); | 442 | ApplyDepthClamp(); |
| 543 | ApplyViewport(); | 443 | ApplyViewport(); |
| 544 | if (dirty.stencil_state) { | 444 | ApplyStencilTest(); |
| 545 | ApplyStencilTest(); | ||
| 546 | dirty.stencil_state = false; | ||
| 547 | } | ||
| 548 | ApplySRgb(); | 445 | ApplySRgb(); |
| 549 | ApplyCulling(); | 446 | ApplyCulling(); |
| 550 | ApplyDepth(); | 447 | ApplyDepth(); |
| 551 | ApplyPrimitiveRestart(); | 448 | ApplyPrimitiveRestart(); |
| 552 | if (dirty.blend_state) { | 449 | ApplyBlending(); |
| 553 | ApplyBlending(); | ||
| 554 | dirty.blend_state = false; | ||
| 555 | } | ||
| 556 | ApplyLogicOp(); | 450 | ApplyLogicOp(); |
| 557 | ApplyTextures(); | 451 | ApplyTextures(); |
| 558 | ApplySamplers(); | 452 | ApplySamplers(); |
| 559 | ApplyImages(); | 453 | ApplyImages(); |
| 560 | if (dirty.polygon_offset) { | 454 | ApplyPolygonOffset(); |
| 561 | ApplyPolygonOffset(); | ||
| 562 | dirty.polygon_offset = false; | ||
| 563 | } | ||
| 564 | ApplyAlphaTest(); | 455 | ApplyAlphaTest(); |
| 565 | } | 456 | } |
| 566 | 457 | ||
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index c358d3b38..cca25206b 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -5,168 +5,146 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <type_traits> | ||
| 8 | #include <glad/glad.h> | 9 | #include <glad/glad.h> |
| 9 | #include "video_core/engines/maxwell_3d.h" | 10 | #include "video_core/engines/maxwell_3d.h" |
| 10 | 11 | ||
| 11 | namespace OpenGL { | 12 | namespace OpenGL { |
| 12 | 13 | ||
| 13 | namespace TextureUnits { | ||
| 14 | |||
| 15 | struct TextureUnit { | ||
| 16 | GLint id; | ||
| 17 | constexpr GLenum Enum() const { | ||
| 18 | return static_cast<GLenum>(GL_TEXTURE0 + id); | ||
| 19 | } | ||
| 20 | }; | ||
| 21 | |||
| 22 | constexpr TextureUnit MaxwellTexture(int unit) { | ||
| 23 | return TextureUnit{unit}; | ||
| 24 | } | ||
| 25 | |||
| 26 | constexpr TextureUnit LightingLUT{3}; | ||
| 27 | constexpr TextureUnit FogLUT{4}; | ||
| 28 | constexpr TextureUnit ProcTexNoiseLUT{5}; | ||
| 29 | constexpr TextureUnit ProcTexColorMap{6}; | ||
| 30 | constexpr TextureUnit ProcTexAlphaMap{7}; | ||
| 31 | constexpr TextureUnit ProcTexLUT{8}; | ||
| 32 | constexpr TextureUnit ProcTexDiffLUT{9}; | ||
| 33 | |||
| 34 | } // namespace TextureUnits | ||
| 35 | |||
| 36 | class OpenGLState { | 14 | class OpenGLState { |
| 37 | public: | 15 | public: |
| 38 | struct { | 16 | struct { |
| 39 | bool enabled; // GL_FRAMEBUFFER_SRGB | 17 | bool enabled = false; // GL_FRAMEBUFFER_SRGB |
| 40 | } framebuffer_srgb; | 18 | } framebuffer_srgb; |
| 41 | 19 | ||
| 42 | struct { | 20 | struct { |
| 43 | bool alpha_to_coverage; // GL_ALPHA_TO_COVERAGE | 21 | bool alpha_to_coverage = false; // GL_ALPHA_TO_COVERAGE |
| 44 | bool alpha_to_one; // GL_ALPHA_TO_ONE | 22 | bool alpha_to_one = false; // GL_ALPHA_TO_ONE |
| 45 | } multisample_control; | 23 | } multisample_control; |
| 46 | 24 | ||
| 47 | struct { | 25 | struct { |
| 48 | bool enabled; // GL_CLAMP_FRAGMENT_COLOR_ARB | 26 | bool enabled = false; // GL_CLAMP_FRAGMENT_COLOR_ARB |
| 49 | } fragment_color_clamp; | 27 | } fragment_color_clamp; |
| 50 | 28 | ||
| 51 | struct { | 29 | struct { |
| 52 | bool far_plane; | 30 | bool far_plane = false; |
| 53 | bool near_plane; | 31 | bool near_plane = false; |
| 54 | } depth_clamp; // GL_DEPTH_CLAMP | 32 | } depth_clamp; // GL_DEPTH_CLAMP |
| 55 | 33 | ||
| 56 | struct { | 34 | struct { |
| 57 | bool enabled; // GL_CULL_FACE | 35 | bool enabled = false; // GL_CULL_FACE |
| 58 | GLenum mode; // GL_CULL_FACE_MODE | 36 | GLenum mode = GL_BACK; // GL_CULL_FACE_MODE |
| 59 | GLenum front_face; // GL_FRONT_FACE | 37 | GLenum front_face = GL_CCW; // GL_FRONT_FACE |
| 60 | } cull; | 38 | } cull; |
| 61 | 39 | ||
| 62 | struct { | 40 | struct { |
| 63 | bool test_enabled; // GL_DEPTH_TEST | 41 | bool test_enabled = false; // GL_DEPTH_TEST |
| 64 | GLenum test_func; // GL_DEPTH_FUNC | 42 | GLboolean write_mask = GL_TRUE; // GL_DEPTH_WRITEMASK |
| 65 | GLboolean write_mask; // GL_DEPTH_WRITEMASK | 43 | GLenum test_func = GL_LESS; // GL_DEPTH_FUNC |
| 66 | } depth; | 44 | } depth; |
| 67 | 45 | ||
| 68 | struct { | 46 | struct { |
| 69 | bool enabled; | 47 | bool enabled = false; |
| 70 | GLuint index; | 48 | GLuint index = 0; |
| 71 | } primitive_restart; // GL_PRIMITIVE_RESTART | 49 | } primitive_restart; // GL_PRIMITIVE_RESTART |
| 72 | 50 | ||
| 73 | struct ColorMask { | 51 | struct ColorMask { |
| 74 | GLboolean red_enabled; | 52 | GLboolean red_enabled = GL_TRUE; |
| 75 | GLboolean green_enabled; | 53 | GLboolean green_enabled = GL_TRUE; |
| 76 | GLboolean blue_enabled; | 54 | GLboolean blue_enabled = GL_TRUE; |
| 77 | GLboolean alpha_enabled; | 55 | GLboolean alpha_enabled = GL_TRUE; |
| 78 | }; | 56 | }; |
| 79 | std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> | 57 | std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> |
| 80 | color_mask; // GL_COLOR_WRITEMASK | 58 | color_mask; // GL_COLOR_WRITEMASK |
| 81 | struct { | 59 | struct { |
| 82 | bool test_enabled; // GL_STENCIL_TEST | 60 | bool test_enabled = false; // GL_STENCIL_TEST |
| 83 | struct { | 61 | struct { |
| 84 | GLenum test_func; // GL_STENCIL_FUNC | 62 | GLenum test_func = GL_ALWAYS; // GL_STENCIL_FUNC |
| 85 | GLint test_ref; // GL_STENCIL_REF | 63 | GLint test_ref = 0; // GL_STENCIL_REF |
| 86 | GLuint test_mask; // GL_STENCIL_VALUE_MASK | 64 | GLuint test_mask = 0xFFFFFFFF; // GL_STENCIL_VALUE_MASK |
| 87 | GLuint write_mask; // GL_STENCIL_WRITEMASK | 65 | GLuint write_mask = 0xFFFFFFFF; // GL_STENCIL_WRITEMASK |
| 88 | GLenum action_stencil_fail; // GL_STENCIL_FAIL | 66 | GLenum action_stencil_fail = GL_KEEP; // GL_STENCIL_FAIL |
| 89 | GLenum action_depth_fail; // GL_STENCIL_PASS_DEPTH_FAIL | 67 | GLenum action_depth_fail = GL_KEEP; // GL_STENCIL_PASS_DEPTH_FAIL |
| 90 | GLenum action_depth_pass; // GL_STENCIL_PASS_DEPTH_PASS | 68 | GLenum action_depth_pass = GL_KEEP; // GL_STENCIL_PASS_DEPTH_PASS |
| 91 | } front, back; | 69 | } front, back; |
| 92 | } stencil; | 70 | } stencil; |
| 93 | 71 | ||
| 94 | struct Blend { | 72 | struct Blend { |
| 95 | bool enabled; // GL_BLEND | 73 | bool enabled = false; // GL_BLEND |
| 96 | GLenum rgb_equation; // GL_BLEND_EQUATION_RGB | 74 | GLenum rgb_equation = GL_FUNC_ADD; // GL_BLEND_EQUATION_RGB |
| 97 | GLenum a_equation; // GL_BLEND_EQUATION_ALPHA | 75 | GLenum a_equation = GL_FUNC_ADD; // GL_BLEND_EQUATION_ALPHA |
| 98 | GLenum src_rgb_func; // GL_BLEND_SRC_RGB | 76 | GLenum src_rgb_func = GL_ONE; // GL_BLEND_SRC_RGB |
| 99 | GLenum dst_rgb_func; // GL_BLEND_DST_RGB | 77 | GLenum dst_rgb_func = GL_ZERO; // GL_BLEND_DST_RGB |
| 100 | GLenum src_a_func; // GL_BLEND_SRC_ALPHA | 78 | GLenum src_a_func = GL_ONE; // GL_BLEND_SRC_ALPHA |
| 101 | GLenum dst_a_func; // GL_BLEND_DST_ALPHA | 79 | GLenum dst_a_func = GL_ZERO; // GL_BLEND_DST_ALPHA |
| 102 | }; | 80 | }; |
| 103 | std::array<Blend, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> blend; | 81 | std::array<Blend, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> blend; |
| 104 | 82 | ||
| 105 | struct { | 83 | struct { |
| 106 | bool enabled; | 84 | bool enabled = false; |
| 107 | } independant_blend; | 85 | } independant_blend; |
| 108 | 86 | ||
| 109 | struct { | 87 | struct { |
| 110 | GLclampf red; | 88 | GLclampf red = 0.0f; |
| 111 | GLclampf green; | 89 | GLclampf green = 0.0f; |
| 112 | GLclampf blue; | 90 | GLclampf blue = 0.0f; |
| 113 | GLclampf alpha; | 91 | GLclampf alpha = 0.0f; |
| 114 | } blend_color; // GL_BLEND_COLOR | 92 | } blend_color; // GL_BLEND_COLOR |
| 115 | 93 | ||
| 116 | struct { | 94 | struct { |
| 117 | bool enabled; // GL_LOGIC_OP_MODE | 95 | bool enabled = false; // GL_LOGIC_OP_MODE |
| 118 | GLenum operation; | 96 | GLenum operation = GL_COPY; |
| 119 | } logic_op; | 97 | } logic_op; |
| 120 | 98 | ||
| 121 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> textures{}; | 99 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> textures = {}; |
| 122 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers{}; | 100 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers = {}; |
| 123 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images{}; | 101 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images = {}; |
| 124 | 102 | ||
| 125 | struct { | 103 | struct { |
| 126 | GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING | 104 | GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING |
| 127 | GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING | 105 | GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING |
| 128 | GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING | 106 | GLuint vertex_array = 0; // GL_VERTEX_ARRAY_BINDING |
| 129 | GLuint shader_program; // GL_CURRENT_PROGRAM | 107 | GLuint shader_program = 0; // GL_CURRENT_PROGRAM |
| 130 | GLuint program_pipeline; // GL_PROGRAM_PIPELINE_BINDING | 108 | GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING |
| 131 | } draw; | 109 | } draw; |
| 132 | 110 | ||
| 133 | struct viewport { | 111 | struct Viewport { |
| 134 | GLint x; | 112 | GLint x = 0; |
| 135 | GLint y; | 113 | GLint y = 0; |
| 136 | GLint width; | 114 | GLint width = 0; |
| 137 | GLint height; | 115 | GLint height = 0; |
| 138 | GLfloat depth_range_near; // GL_DEPTH_RANGE | 116 | GLfloat depth_range_near = 0.0f; // GL_DEPTH_RANGE |
| 139 | GLfloat depth_range_far; // GL_DEPTH_RANGE | 117 | GLfloat depth_range_far = 1.0f; // GL_DEPTH_RANGE |
| 140 | struct { | 118 | struct { |
| 141 | bool enabled; // GL_SCISSOR_TEST | 119 | bool enabled = false; // GL_SCISSOR_TEST |
| 142 | GLint x; | 120 | GLint x = 0; |
| 143 | GLint y; | 121 | GLint y = 0; |
| 144 | GLsizei width; | 122 | GLsizei width = 0; |
| 145 | GLsizei height; | 123 | GLsizei height = 0; |
| 146 | } scissor; | 124 | } scissor; |
| 147 | }; | 125 | }; |
| 148 | std::array<viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports; | 126 | std::array<Viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports; |
| 149 | 127 | ||
| 150 | struct { | 128 | struct { |
| 151 | float size; // GL_POINT_SIZE | 129 | float size = 1.0f; // GL_POINT_SIZE |
| 152 | } point; | 130 | } point; |
| 153 | 131 | ||
| 154 | struct { | 132 | struct { |
| 155 | bool point_enable; | 133 | bool point_enable = false; |
| 156 | bool line_enable; | 134 | bool line_enable = false; |
| 157 | bool fill_enable; | 135 | bool fill_enable = false; |
| 158 | GLfloat units; | 136 | GLfloat units = 0.0f; |
| 159 | GLfloat factor; | 137 | GLfloat factor = 0.0f; |
| 160 | GLfloat clamp; | 138 | GLfloat clamp = 0.0f; |
| 161 | } polygon_offset; | 139 | } polygon_offset; |
| 162 | 140 | ||
| 163 | struct { | 141 | struct { |
| 164 | bool enabled; // GL_ALPHA_TEST | 142 | bool enabled = false; // GL_ALPHA_TEST |
| 165 | GLenum func; // GL_ALPHA_TEST_FUNC | 143 | GLenum func = GL_ALWAYS; // GL_ALPHA_TEST_FUNC |
| 166 | GLfloat ref; // GL_ALPHA_TEST_REF | 144 | GLfloat ref = 0.0f; // GL_ALPHA_TEST_REF |
| 167 | } alpha_test; | 145 | } alpha_test; |
| 168 | 146 | ||
| 169 | std::array<bool, 8> clip_distance; // GL_CLIP_DISTANCE | 147 | std::array<bool, 8> clip_distance = {}; // GL_CLIP_DISTANCE |
| 170 | 148 | ||
| 171 | OpenGLState(); | 149 | OpenGLState(); |
| 172 | 150 | ||
| @@ -179,34 +157,31 @@ public: | |||
| 179 | /// Apply this state as the current OpenGL state | 157 | /// Apply this state as the current OpenGL state |
| 180 | void Apply(); | 158 | void Apply(); |
| 181 | 159 | ||
| 182 | void ApplyFramebufferState() const; | 160 | void ApplyFramebufferState(); |
| 183 | void ApplyVertexArrayState() const; | 161 | void ApplyVertexArrayState(); |
| 184 | void ApplyShaderProgram() const; | 162 | void ApplyShaderProgram(); |
| 185 | void ApplyProgramPipeline() const; | 163 | void ApplyProgramPipeline(); |
| 186 | void ApplyClipDistances() const; | 164 | void ApplyClipDistances(); |
| 187 | void ApplyPointSize() const; | 165 | void ApplyPointSize(); |
| 188 | void ApplyFragmentColorClamp() const; | 166 | void ApplyFragmentColorClamp(); |
| 189 | void ApplyMultisample() const; | 167 | void ApplyMultisample(); |
| 190 | void ApplySRgb() const; | 168 | void ApplySRgb(); |
| 191 | void ApplyCulling() const; | 169 | void ApplyCulling(); |
| 192 | void ApplyColorMask() const; | 170 | void ApplyColorMask(); |
| 193 | void ApplyDepth() const; | 171 | void ApplyDepth(); |
| 194 | void ApplyPrimitiveRestart() const; | 172 | void ApplyPrimitiveRestart(); |
| 195 | void ApplyStencilTest() const; | 173 | void ApplyStencilTest(); |
| 196 | void ApplyViewport() const; | 174 | void ApplyViewport(); |
| 197 | void ApplyTargetBlending(std::size_t target, bool force) const; | 175 | void ApplyTargetBlending(std::size_t target, bool force); |
| 198 | void ApplyGlobalBlending() const; | 176 | void ApplyGlobalBlending(); |
| 199 | void ApplyBlending() const; | 177 | void ApplyBlending(); |
| 200 | void ApplyLogicOp() const; | 178 | void ApplyLogicOp(); |
| 201 | void ApplyTextures() const; | 179 | void ApplyTextures(); |
| 202 | void ApplySamplers() const; | 180 | void ApplySamplers(); |
| 203 | void ApplyImages() const; | 181 | void ApplyImages(); |
| 204 | void ApplyDepthClamp() const; | 182 | void ApplyDepthClamp(); |
| 205 | void ApplyPolygonOffset() const; | 183 | void ApplyPolygonOffset(); |
| 206 | void ApplyAlphaTest() const; | 184 | void ApplyAlphaTest(); |
| 207 | |||
| 208 | /// Set the initial OpenGL state | ||
| 209 | static void ApplyDefaultState(); | ||
| 210 | 185 | ||
| 211 | /// Resets any references to the given resource | 186 | /// Resets any references to the given resource |
| 212 | OpenGLState& UnbindTexture(GLuint handle); | 187 | OpenGLState& UnbindTexture(GLuint handle); |
| @@ -253,5 +228,6 @@ private: | |||
| 253 | bool color_mask; | 228 | bool color_mask; |
| 254 | } dirty{}; | 229 | } dirty{}; |
| 255 | }; | 230 | }; |
| 231 | static_assert(std::is_trivially_copyable_v<OpenGLState>); | ||
| 256 | 232 | ||
| 257 | } // namespace OpenGL | 233 | } // namespace OpenGL |
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 8d3d962c7..ca690b58b 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp | |||
| @@ -96,6 +96,10 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 96 | } | 96 | } |
| 97 | break; | 97 | break; |
| 98 | } | 98 | } |
| 99 | case OpCode::Id::TLD4_B: { | ||
| 100 | is_bindless = true; | ||
| 101 | [[fallthrough]]; | ||
| 102 | } | ||
| 99 | case OpCode::Id::TLD4: { | 103 | case OpCode::Id::TLD4: { |
| 100 | ASSERT(instr.tld4.array == 0); | 104 | ASSERT(instr.tld4.array == 0); |
| 101 | UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(TextureMiscMode::NDV), | 105 | UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(TextureMiscMode::NDV), |
| @@ -108,11 +112,14 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 108 | } | 112 | } |
| 109 | 113 | ||
| 110 | const auto texture_type = instr.tld4.texture_type.Value(); | 114 | const auto texture_type = instr.tld4.texture_type.Value(); |
| 111 | const bool depth_compare = instr.tld4.UsesMiscMode(TextureMiscMode::DC); | 115 | const bool depth_compare = is_bindless ? instr.tld4_b.UsesMiscMode(TextureMiscMode::DC) |
| 116 | : instr.tld4.UsesMiscMode(TextureMiscMode::DC); | ||
| 112 | const bool is_array = instr.tld4.array != 0; | 117 | const bool is_array = instr.tld4.array != 0; |
| 113 | const bool is_aoffi = instr.tld4.UsesMiscMode(TextureMiscMode::AOFFI); | 118 | const bool is_aoffi = is_bindless ? instr.tld4_b.UsesMiscMode(TextureMiscMode::AOFFI) |
| 119 | : instr.tld4.UsesMiscMode(TextureMiscMode::AOFFI); | ||
| 114 | WriteTexInstructionFloat( | 120 | WriteTexInstructionFloat( |
| 115 | bb, instr, GetTld4Code(instr, texture_type, depth_compare, is_array, is_aoffi)); | 121 | bb, instr, |
| 122 | GetTld4Code(instr, texture_type, depth_compare, is_array, is_aoffi, is_bindless)); | ||
| 116 | break; | 123 | break; |
| 117 | } | 124 | } |
| 118 | case OpCode::Id::TLD4S: { | 125 | case OpCode::Id::TLD4S: { |
| @@ -586,7 +593,7 @@ Node4 ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type, | |||
| 586 | } | 593 | } |
| 587 | 594 | ||
| 588 | Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool depth_compare, | 595 | Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool depth_compare, |
| 589 | bool is_array, bool is_aoffi) { | 596 | bool is_array, bool is_aoffi, bool is_bindless) { |
| 590 | const std::size_t coord_count = GetCoordCount(texture_type); | 597 | const std::size_t coord_count = GetCoordCount(texture_type); |
| 591 | 598 | ||
| 592 | // If enabled arrays index is always stored in the gpr8 field | 599 | // If enabled arrays index is always stored in the gpr8 field |
| @@ -600,6 +607,12 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de | |||
| 600 | } | 607 | } |
| 601 | 608 | ||
| 602 | u64 parameter_register = instr.gpr20.Value(); | 609 | u64 parameter_register = instr.gpr20.Value(); |
| 610 | |||
| 611 | const auto& sampler = | ||
| 612 | is_bindless | ||
| 613 | ? GetBindlessSampler(parameter_register++, {{texture_type, is_array, depth_compare}}) | ||
| 614 | : GetSampler(instr.sampler, {{texture_type, is_array, depth_compare}}); | ||
| 615 | |||
| 603 | std::vector<Node> aoffi; | 616 | std::vector<Node> aoffi; |
| 604 | if (is_aoffi) { | 617 | if (is_aoffi) { |
| 605 | aoffi = GetAoffiCoordinates(GetRegister(parameter_register++), coord_count, true); | 618 | aoffi = GetAoffiCoordinates(GetRegister(parameter_register++), coord_count, true); |
| @@ -610,12 +623,14 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de | |||
| 610 | dc = GetRegister(parameter_register++); | 623 | dc = GetRegister(parameter_register++); |
| 611 | } | 624 | } |
| 612 | 625 | ||
| 613 | const auto& sampler = GetSampler(instr.sampler, {{texture_type, is_array, depth_compare}}); | 626 | const Node component = is_bindless ? Immediate(static_cast<u32>(instr.tld4_b.component)) |
| 627 | : Immediate(static_cast<u32>(instr.tld4.component)); | ||
| 614 | 628 | ||
| 615 | Node4 values; | 629 | Node4 values; |
| 616 | for (u32 element = 0; element < values.size(); ++element) { | 630 | for (u32 element = 0; element < values.size(); ++element) { |
| 617 | auto coords_copy = coords; | 631 | auto coords_copy = coords; |
| 618 | MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, element}; | 632 | MetaTexture meta{sampler, GetRegister(array_register), dc, aoffi, {}, {}, component, |
| 633 | element}; | ||
| 619 | values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); | 634 | values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); |
| 620 | } | 635 | } |
| 621 | 636 | ||
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 5243644e8..26c8fde22 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -341,7 +341,7 @@ private: | |||
| 341 | bool is_array); | 341 | bool is_array); |
| 342 | 342 | ||
| 343 | Node4 GetTld4Code(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type, | 343 | Node4 GetTld4Code(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type, |
| 344 | bool depth_compare, bool is_array, bool is_aoffi); | 344 | bool depth_compare, bool is_array, bool is_aoffi, bool is_bindless); |
| 345 | 345 | ||
| 346 | Node4 GetTldCode(Tegra::Shader::Instruction instr); | 346 | Node4 GetTldCode(Tegra::Shader::Instruction instr); |
| 347 | 347 | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index d6bb18d24..160613ee1 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1839,6 +1839,10 @@ void GMainWindow::OnLoadAmiibo() { | |||
| 1839 | return; | 1839 | return; |
| 1840 | } | 1840 | } |
| 1841 | 1841 | ||
| 1842 | LoadAmiibo(filename); | ||
| 1843 | } | ||
| 1844 | |||
| 1845 | void GMainWindow::LoadAmiibo(const QString& filename) { | ||
| 1842 | Core::System& system{Core::System::GetInstance()}; | 1846 | Core::System& system{Core::System::GetInstance()}; |
| 1843 | Service::SM::ServiceManager& sm = system.ServiceManager(); | 1847 | Service::SM::ServiceManager& sm = system.ServiceManager(); |
| 1844 | auto nfc = sm.GetService<Service::NFP::Module::Interface>("nfp:user"); | 1848 | auto nfc = sm.GetService<Service::NFP::Module::Interface>("nfp:user"); |
| @@ -2189,10 +2193,19 @@ static bool IsSingleFileDropEvent(QDropEvent* event) { | |||
| 2189 | } | 2193 | } |
| 2190 | 2194 | ||
| 2191 | void GMainWindow::dropEvent(QDropEvent* event) { | 2195 | void GMainWindow::dropEvent(QDropEvent* event) { |
| 2192 | if (IsSingleFileDropEvent(event) && ConfirmChangeGame()) { | 2196 | if (!IsSingleFileDropEvent(event)) { |
| 2193 | const QMimeData* mimeData = event->mimeData(); | 2197 | return; |
| 2194 | QString filename = mimeData->urls().at(0).toLocalFile(); | 2198 | } |
| 2195 | BootGame(filename); | 2199 | |
| 2200 | const QMimeData* mime_data = event->mimeData(); | ||
| 2201 | const QString filename = mime_data->urls().at(0).toLocalFile(); | ||
| 2202 | |||
| 2203 | if (emulation_running && QFileInfo(filename).suffix() == QStringLiteral("bin")) { | ||
| 2204 | LoadAmiibo(filename); | ||
| 2205 | } else { | ||
| 2206 | if (ConfirmChangeGame()) { | ||
| 2207 | BootGame(filename); | ||
| 2208 | } | ||
| 2196 | } | 2209 | } |
| 2197 | } | 2210 | } |
| 2198 | 2211 | ||
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index fd4b9ccf5..7f46bea2b 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -142,6 +142,7 @@ private: | |||
| 142 | 142 | ||
| 143 | void ShowTelemetryCallout(); | 143 | void ShowTelemetryCallout(); |
| 144 | void SetDiscordEnabled(bool state); | 144 | void SetDiscordEnabled(bool state); |
| 145 | void LoadAmiibo(const QString& filename); | ||
| 145 | 146 | ||
| 146 | void SelectAndSetCurrentUser(); | 147 | void SelectAndSetCurrentUser(); |
| 147 | 148 | ||