Compare commits
501 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a86a3d2fee | |||
| a917f55ef8 | |||
| 21b535b5c5 | |||
| af9e217fa4 | |||
| 9a51f22265 | |||
| 144b185802 | |||
| 3c0f6a2919 | |||
| 22c33d4fb4 | |||
| e9cdb248a0 | |||
| e8274d5a59 | |||
| 6952be5ce4 | |||
| 4317291827 | |||
| bd40430d2b | |||
| ebc4a0188a | |||
| bfa4fcf584 | |||
| 48f70fbf10 | |||
| 019d2d5dcf | |||
| 17f7f329a8 | |||
| 933737e8f0 | |||
| 47b545282e | |||
| 190822c2b2 | |||
| d000d648b0 | |||
| d257ba5156 | |||
| 9828d6146b | |||
| 9e4bec8cec | |||
| 65ead08880 | |||
| f6c6c04648 | |||
| 794378d5e9 | |||
| a5ac5a9861 | |||
| faaf28b41d | |||
| 700c540434 | |||
| c177bf7480 | |||
| bccfb1cda7 | |||
| c099bb817f | |||
| 7fe98d8d66 | |||
| d356e0d1e7 | |||
| 3ce7fd7894 | |||
| 6f42297b58 | |||
| c5aebe4564 | |||
| 841b8fad38 | |||
| ab0df0a0f5 | |||
| 27e3317449 | |||
| edc09e22b4 | |||
| b487c09d34 | |||
| 4a40ef6a19 | |||
| bcddbc15f0 | |||
| 2a19d0a579 | |||
| 9af66e22da | |||
| 715f4f0669 | |||
| e6e753f37f | |||
| e958c3cc6a | |||
| 19500ac9ad | |||
| 25dee4a78e | |||
| ee953f7953 | |||
| acee590733 | |||
| cd94d9849d | |||
| c3709fa744 | |||
| 853e2b90a3 | |||
| 995cb8125e | |||
| 01d3585bf3 | |||
| a11afe05bf | |||
| 9e4f43f4d1 | |||
| 8cdfe5952a | |||
| 0f8ca1f7c5 | |||
| fd2607ad52 | |||
| 7e1b24224d | |||
| 56c63170b9 | |||
| b41349546c | |||
| 6850533b50 | |||
| 4ce2ad54a8 | |||
| 0c85d4c0d0 | |||
| 57471f8c94 | |||
| 7e11855330 | |||
| f188589685 | |||
| 96428a7555 | |||
| d3585e1f80 | |||
| c0c86521a2 | |||
| 22f5e7a9be | |||
| 06c42bba5d | |||
| ada6db2df4 | |||
| eee5e812f7 | |||
| eb5ae94c24 | |||
| 7109fe9889 | |||
| 17557df9f4 | |||
| fab1f7d939 | |||
| 815d6f4223 | |||
| 25d73f5a70 | |||
| d633a266c1 | |||
| 938bf8624c | |||
| 2cdb46b167 | |||
| 8799eebfe1 | |||
| 70fb5712e5 | |||
| 6a51c27fde | |||
| 17f965c171 | |||
| bd21930d1a | |||
| 4df933275b | |||
| 107129f95a | |||
| e11734f971 | |||
| 3bba9708d9 | |||
| dd497625a5 | |||
| f6764767f6 | |||
| e52dd9dc6f | |||
| 03ae1481fb | |||
| 82068cf802 | |||
| ebf832214e | |||
| 4315363f4b | |||
| f073ff8fe8 | |||
| 47040be3ad | |||
| d0bb9d2b62 | |||
| cb6e536fbd | |||
| f820a7a205 | |||
| 16212854b4 | |||
| 1c6003acd5 | |||
| ef3e8d26ce | |||
| 21a1072117 | |||
| 2ce49e3674 | |||
| e58e1ebfd9 | |||
| 609182b131 | |||
| 7898ae6fe6 | |||
| a9d0ffcac1 | |||
| 824be77bba | |||
| 74c8a44d84 | |||
| 9f829b375a | |||
| da44d5f10d | |||
| be4b71b805 | |||
| b0c7ca6d1f | |||
| 4d8de282f9 | |||
| c5d39ace2b | |||
| de80a4b6c7 | |||
| 917069e31a | |||
| 3354c800d7 | |||
| bb3ac62126 | |||
| 6e25fea16a | |||
| 5e7c6853c2 | |||
| f76a011ba0 | |||
| d854a39500 | |||
| a00ebacef3 | |||
| c2f4244c4d | |||
| 7437c324c6 | |||
| 54b87b6dbb | |||
| a029a94c73 | |||
| 3157a10428 | |||
| f8d2d8ca11 | |||
| 0d8152cd4e | |||
| c37bc3c55c | |||
| 6cc0fe4221 | |||
| af1ceb1151 | |||
| c1a80b8146 | |||
| 268bcd1c7b | |||
| 42a9ac9e6c | |||
| 182b20c33d | |||
| 58e2465369 | |||
| 07a44d0ff9 | |||
| d00f882c23 | |||
| e70e534bfa | |||
| d345916241 | |||
| fe8bcac270 | |||
| 60f05fdbf3 | |||
| ad0f12c742 | |||
| 2f2a03b37b | |||
| 881e8e4723 | |||
| e1af6dc4af | |||
| 4d9533ea54 | |||
| d6623e0f22 | |||
| ab3d36f0f3 | |||
| 632af8d723 | |||
| 282b00674a | |||
| 235d12aa6b | |||
| 5d1fc546a8 | |||
| eb993781ef | |||
| 0756fd9c7e | |||
| a3e79fc105 | |||
| 84470c34db | |||
| f8dbfa1d1e | |||
| d9750e8f9f | |||
| e09c4b72c8 | |||
| 53b95fea19 | |||
| e2fd4e46f7 | |||
| 20d6664dc1 | |||
| 8ee953ef8e | |||
| 5b7ee43352 | |||
| 8add57f8e9 | |||
| bb0aaea92d | |||
| 987ede2e6c | |||
| 5fae1b3637 | |||
| cb08c53f2f | |||
| 171e4fafed | |||
| 8d2ce2815c | |||
| d91551c277 | |||
| 332f9cae77 | |||
| dc25a3fa2a | |||
| c98ec4d014 | |||
| 05dc6ad610 | |||
| 3fe8499956 | |||
| f1b1c9053c | |||
| ea4cc0b395 | |||
| be8980fc23 | |||
| e4a9c177e6 | |||
| 99be645fcc | |||
| f8920edb2e | |||
| acf51f0ead | |||
| ddd202b5ff | |||
| 78eb7e73bc | |||
| 72337f2678 | |||
| 14200c1a1f | |||
| c495ef10b0 | |||
| 3bdce6050b | |||
| c9c0d7361d | |||
| d7ffc8b4ac | |||
| b5f01372ee | |||
| bec6bde919 | |||
| 1f25924384 | |||
| 36cf5dca82 | |||
| eea12bad07 | |||
| 6a9fe8e3c4 | |||
| 55e907385b | |||
| bd14429f20 | |||
| 5867b3b72e | |||
| 45e1a8756f | |||
| 6742fad753 | |||
| c6190fa95d | |||
| 372eff2d8f | |||
| 98eb0cd3f2 | |||
| 541e20cbec | |||
| ef203f6bcb | |||
| a5368d766a | |||
| cf2e2a0511 | |||
| e5bb5f02e0 | |||
| 3a17eefde7 | |||
| 7d2ecbf29a | |||
| c72a6f8e6f | |||
| 6a486d3402 | |||
| e43db24b2c | |||
| 3ea33763bc | |||
| 695cfead16 | |||
| 12dded403f | |||
| a7a5034958 | |||
| fa81146b79 | |||
| 5269b69bc5 | |||
| d9e3f0ccfa | |||
| 2483cc6f8d | |||
| 97717defa5 | |||
| 5e29bdbe22 | |||
| b437794e92 | |||
| 9fcbad326a | |||
| 2c93fecd8b | |||
| 20fcc6530f | |||
| 11e75853a6 | |||
| 9cb4402c16 | |||
| f29589e5cf | |||
| d7842b7de2 | |||
| 5a8eb9d3d7 | |||
| ab4c40c988 | |||
| 5ea6535fd5 | |||
| 76faaf43f7 | |||
| 9679ae68cb | |||
| 7d3389d548 | |||
| ab9cdc70ad | |||
| e45d37073a | |||
| e353ad3557 | |||
| abec850379 | |||
| 431e0eb30c | |||
| 628cb1c779 | |||
| a14e0a0104 | |||
| f3637cdfdb | |||
| c6a9a5d5d7 | |||
| 7e3ece7d9f | |||
| 7f917c8ba5 | |||
| e992cbe01b | |||
| 1974911a71 | |||
| 8659994b2c | |||
| 5affc459a2 | |||
| cd4ed11700 | |||
| c4fe418f66 | |||
| 7d9d58f38f | |||
| b212f29cf2 | |||
| fd2cd84555 | |||
| bf978ac8ca | |||
| d3c6472c0f | |||
| 1c7a318413 | |||
| 591624b96c | |||
| 2323cd2a2d | |||
| cc5c89539b | |||
| a7ee059419 | |||
| 7d5c8fe553 | |||
| fd048a75da | |||
| 5c1ce6350b | |||
| d86c9a2549 | |||
| 249686708c | |||
| 3ee1d8aed1 | |||
| 5c6dae498b | |||
| 2086e7f2e8 | |||
| 4092e3e95f | |||
| c764925b4d | |||
| 83d818d96f | |||
| 3d3c91d654 | |||
| 0ad4e91001 | |||
| 731d4330fe | |||
| 5777a1d426 | |||
| 5fda9a4efb | |||
| c15b5f1eca | |||
| 314dc4c5de | |||
| a0f0f58fc5 | |||
| 92b7c56f29 | |||
| 8d8fb4a2e4 | |||
| 717e851a99 | |||
| 2e737ad483 | |||
| 88a0e0fe2d | |||
| e2248332ae | |||
| 3663a8ab4d | |||
| 5430892052 | |||
| ff04cd6d69 | |||
| aa4fdff82c | |||
| 5bc4f9df0d | |||
| 5d0066029f | |||
| 56962a58da | |||
| 746615a937 | |||
| e485c9c79c | |||
| bd6fdf3f2d | |||
| e1f8573c68 | |||
| 4bc157881d | |||
| f0d526411c | |||
| e1183f6919 | |||
| f4ec28d932 | |||
| ce587f43a0 | |||
| 6892399699 | |||
| 22b1cc765a | |||
| b9cb181691 | |||
| 4a03f06175 | |||
| 768bb8d31f | |||
| 0bf8f2a527 | |||
| 2dca8d84e1 | |||
| 1668900fb8 | |||
| 66f1cbfb34 | |||
| b75af69cf9 | |||
| c36c425fb9 | |||
| f75b26d1c9 | |||
| bfee541540 | |||
| 3d7c38ff9d | |||
| 5d27f1c732 | |||
| 3b8e7d0967 | |||
| ebbf329b6a | |||
| 87cc937d4e | |||
| dcf5c06d6d | |||
| 8357523ec0 | |||
| 39149fd84d | |||
| 289c594187 | |||
| d47d597b34 | |||
| 69c2150fbd | |||
| 334d0bbc86 | |||
| 1cb4fb9c50 | |||
| 413f87b737 | |||
| 8a8edb1b62 | |||
| caa1324457 | |||
| 776c2ada6a | |||
| 41eb6d4461 | |||
| 0315781306 | |||
| 437f374bae | |||
| 9657b3f1d4 | |||
| 650152e05f | |||
| 73fe9b51de | |||
| 26b2e4253d | |||
| b353bf6c56 | |||
| c601374b1f | |||
| 66d13da2ac | |||
| 938ca90a02 | |||
| 2d2ed7efd0 | |||
| 1507a59786 | |||
| 675fde69aa | |||
| 99895471ae | |||
| 3e2aede85c | |||
| 377ad9887c | |||
| c9a978a03e | |||
| 59d44cd1cc | |||
| 542a6aed51 | |||
| 1677618c75 | |||
| 3df83e03a9 | |||
| a199c71a55 | |||
| 3d20ce70f5 | |||
| f0cdd8ace6 | |||
| 8e9d2fa70e | |||
| abf9a08ee3 | |||
| 9d02231074 | |||
| f56b362769 | |||
| 865180e63e | |||
| 3265772ae4 | |||
| 224a0e4b1a | |||
| bd41a108d8 | |||
| 695b6e8f46 | |||
| ab6942d974 | |||
| 6efc735728 | |||
| 3048bb1a75 | |||
| b8f86eb78d | |||
| 68bee397eb | |||
| a703f6febb | |||
| 81749f4353 | |||
| 2d1d36678d | |||
| 0e6abd66ca | |||
| 7080305d82 | |||
| 7c3166a0c6 | |||
| 4405f46aec | |||
| 81684919f5 | |||
| 1a8fb61373 | |||
| c47d04fd2f | |||
| 91ee480e56 | |||
| 3d320aea2c | |||
| 703841e251 | |||
| 1fffffad7a | |||
| 72fedccaba | |||
| ae519200ed | |||
| 201d54ee08 | |||
| 2591d99db1 | |||
| a2327de3cb | |||
| 581176fb1a | |||
| 377e2ce3e8 | |||
| a2653532ef | |||
| 37df3c6f96 | |||
| a8bca8b2ed | |||
| b0d3c4d75e | |||
| 3db2f23e02 | |||
| 661636efef | |||
| 99f5145aab | |||
| 8a0425570c | |||
| eecb22e749 | |||
| 3ad12cf5f8 | |||
| d4333788e2 | |||
| 308cdfac35 | |||
| db4414ca87 | |||
| b5dbb2eb36 | |||
| 67b002f586 | |||
| e186ef9490 | |||
| cccc5bc18d | |||
| 7824419bbf | |||
| c22d778143 | |||
| 61f43d78df | |||
| 54dd9f4eae | |||
| 91d06a9729 | |||
| 310f367fb1 | |||
| b1fb5b6239 | |||
| 20d8d38e53 | |||
| 78ac2a86bb | |||
| cc723ed45c | |||
| ed82288c1b | |||
| 7680466e0d | |||
| 9266507e4c | |||
| 8cca113ef4 | |||
| 7ff25588f4 | |||
| 93122196d9 | |||
| 5c4c8f4539 | |||
| 118bfbbe98 | |||
| 12f0278808 | |||
| b38580bf32 | |||
| 525453794f | |||
| eb5ec211c2 | |||
| 69ea573b0d | |||
| dd9397473a | |||
| 86cf8a1717 | |||
| 6374a9f19b | |||
| f95b81574f | |||
| d67e77899f | |||
| dd5c54290c | |||
| b6e8560532 | |||
| 5dc8b05275 | |||
| 48ecc00368 | |||
| 04ead3cba4 | |||
| 79e2a87bc5 | |||
| bd61347b21 | |||
| 09797c3584 | |||
| 14969cd8d0 | |||
| 79c54aeba9 | |||
| a1b6415c5a | |||
| 8e2b2bc179 | |||
| e1042bc631 | |||
| a6025df7de | |||
| 5c4b8e8dee | |||
| f95bf01c78 | |||
| d4606cfdb9 | |||
| 907adc817e | |||
| a6f0b1b532 | |||
| 1bd6cb2105 | |||
| 142a1da0e0 | |||
| fb3d5827f0 | |||
| a3f25bc7c7 | |||
| a0f63a31e3 | |||
| f72385b00c | |||
| 4f7c020e63 | |||
| 9a4c26dc8c | |||
| edde748519 | |||
| 37ce7056ac | |||
| b84b8f4db4 | |||
| 72bef8dd7f | |||
| 0e6937a359 | |||
| b18dcd7660 | |||
| 2b69a68ef6 | |||
| fc68c508c8 | |||
| cda8b3a59e | |||
| 31035608ee | |||
| f6200ba635 | |||
| c1bd154bcd | |||
| a568c958af | |||
| 2de6a9bc44 |
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
ccache -s # debug
|
||||
|
||||
# Pull all the submodules except llvm
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
|
||||
# XXX Drop after Travis upgrades FreeBSD to 12.2 (see also .ci/install-freebsd.sh)
|
||||
case $(${CXX:-c++} --version) in
|
||||
*version\ 8.0.*)
|
||||
fetch https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/libcxx-10.0.0.src.tar.xz
|
||||
tar xf libcxx-10.0.0.src.tar.xz
|
||||
export CC=clang10 CXX=clang++10
|
||||
export CXXFLAGS="$CXXFLAGS -nostdinc++ -isystem $PWD/libcxx-10.0.0.src/include"
|
||||
;;
|
||||
esac
|
||||
|
||||
CONFIGURE_ARGS="
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
-DWITH_LLVM=OFF
|
||||
-DUSE_PRECOMPILED_HEADERS=OFF
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF
|
||||
-DUSE_SYSTEM_FFMPEG=ON
|
||||
-DUSE_SYSTEM_CURL=ON
|
||||
-DUSE_SYSTEM_LIBPNG=ON
|
||||
"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
cmake -B build -G Ninja $CONFIGURE_ARGS
|
||||
cmake --build build
|
||||
|
||||
ccache -s # debug
|
||||
+2
-2
@@ -25,8 +25,8 @@ if [ "$COMPILER" = "gcc" ]; then
|
||||
export CXX=${GXX_BINARY}
|
||||
export LINKER=gold
|
||||
# We need to set the following variables for LTO to link properly
|
||||
export AR=/usr/bin/gcc-ar-9
|
||||
export RANLIB=/usr/bin/gcc-ranlib-9
|
||||
export AR=/usr/bin/gcc-ar-$GCCVER
|
||||
export RANLIB=/usr/bin/gcc-ranlib-$GCCVER
|
||||
export CFLAGS="-fuse-linker-plugin"
|
||||
else
|
||||
export CC=${CLANG_BINARY}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
curl -L -o "./llvm.lock" "https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win/llvmlibs_mt.7z.sha256"
|
||||
curl -L -o "./glslang.lock" "https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z.sha256"
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
ARTIFACT_DIR="$BUILD_ARTIFACTSTAGINGDIRECTORY"
|
||||
generate_post_data()
|
||||
{
|
||||
body=$(cat GitHubReleaseMessage.txt)
|
||||
cat <<EOF
|
||||
{
|
||||
"tag_name": "build-${BUILD_SOURCEVERSION}",
|
||||
"target_commitish": "7d09e3be30805911226241afbb14f8cdc2eb054e",
|
||||
"name": "${AVVER}",
|
||||
"body": "$body",
|
||||
"draft": false,
|
||||
"prerelease": false
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
repo_full_name="RPCS3/rpcs3-binaries-win"
|
||||
|
||||
curl -s \
|
||||
-H "Authorization: token ${RPCS3_TOKEN}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--data "$(generate_post_data)" "https://api.github.com/repos/$repo_full_name/releases" >> release.json
|
||||
|
||||
cat release.json
|
||||
id=$(grep '"id"' release.json | cut -d ':' -f2 | head -n1 | awk '{$1=$1;print}')
|
||||
id=${id%?}
|
||||
echo ${id:?}
|
||||
|
||||
upload_file()
|
||||
{
|
||||
curl -s \
|
||||
-H "Authorization: token ${RPCS3_TOKEN}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary @"$2"/"$3" \
|
||||
"https://uploads.github.com/repos/$repo_full_name/releases/$1/assets?name=$3"
|
||||
}
|
||||
|
||||
for file in "$ARTIFACT_DIR"/*; do
|
||||
name=$(basename "$file")
|
||||
upload_file "$id" "$ARTIFACT_DIR" "$name"
|
||||
done
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env -S su -m root -ex
|
||||
# NOTE: this script is run under root permissions
|
||||
# shellcheck shell=sh disable=SC2096
|
||||
|
||||
# RPCS3 often needs recent Qt5 and Vulkan-Headers
|
||||
sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf
|
||||
|
||||
export ASSUME_ALWAYS_YES=true
|
||||
pkg info # debug
|
||||
|
||||
# XXX Drop after Travis upgrades FreeBSD to 12.2 (see also .ci/build-freebsd.sh)
|
||||
case $(${CXX:-c++} --version) in
|
||||
*version\ 8.0.*)
|
||||
pkg install llvm10
|
||||
;;
|
||||
esac
|
||||
|
||||
# Mandatory dependencies (qt5-dbus and qt5-gui are pulled via qt5-widgets)
|
||||
pkg install git ccache cmake ninja qt5-qmake qt5-buildtools qt5-widgets qt5-concurrent glew openal-soft ffmpeg
|
||||
|
||||
# Optional dependencies (libevdev is pulled by qt5-gui)
|
||||
pkg install pkgconf alsa-lib pulseaudio sdl2 evdev-proto vulkan-headers vulkan-loader
|
||||
@@ -7,8 +7,8 @@ PR_NUMBER="$SYSTEM_PULLREQUEST_PULLREQUESTID"
|
||||
|
||||
# Resource/dependency URLs
|
||||
# Qt mirrors can be volatile and slow, so we list 2
|
||||
#QT_HOST="http://mirrors.ocf.berkeley.edu/qt/"
|
||||
QT_HOST="http://qt.mirror.constant.com/"
|
||||
QT_HOST="http://mirrors.ocf.berkeley.edu/qt/"
|
||||
#QT_HOST="http://qt.mirror.constant.com/"
|
||||
QT_URL_VER=$(echo "$QT_VER" | sed "s/\.//g")
|
||||
QT_PREFIX="online/qtsdkrepository/windows_x86/desktop/qt5_${QT_URL_VER}/qt.qt5.${QT_URL_VER}.win64_msvc2017_64/${QT_VER}-0-${QT_DATE}"
|
||||
QT_SUFFIX="-Windows-Windows_10-MSVC2017-Windows-Windows_10-X86_64.7z"
|
||||
@@ -17,8 +17,9 @@ QT_WINE_URL="${QT_HOST}${QT_PREFIX}qtwinextras${QT_SUFFIX}"
|
||||
QT_DECL_URL="${QT_HOST}${QT_PREFIX}qtdeclarative${QT_SUFFIX}"
|
||||
QT_TOOL_URL="${QT_HOST}${QT_PREFIX}qttools${QT_SUFFIX}"
|
||||
LLVMLIBS_URL='https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win/llvmlibs_mt.7z'
|
||||
GLSLANG_URL='https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z'
|
||||
VULKAN_SDK_URL="https://sdk.lunarg.com/sdk/download/${VULKAN_VER}/windows/VulkanSDK-${VULKAN_VER}-Installer.exe"
|
||||
#GLSLANG_URL='https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z' <- Temporarily disabled auto-builds
|
||||
GLSLANG_URL='https://www.dropbox.com/s/cg48qr4zmnn066v/glslanglibs_mt.7z'
|
||||
VULKAN_SDK_URL="https://www.dropbox.com/s/adanclixregbp2x/VulkanSDK-${VULKAN_VER}-Installer.exe"
|
||||
|
||||
DEP_URLS=" \
|
||||
$QT_BASE_URL \
|
||||
@@ -35,7 +36,7 @@ DEP_URLS=" \
|
||||
# Pull all the submodules except llvm, since it is built separately and we just download that build
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
git submodule -q update --init --depth 1 $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
|
||||
# Git bash doesn't have rev, so here it is
|
||||
rev()
|
||||
@@ -75,7 +76,8 @@ for url in $DEP_URLS; do
|
||||
case "$url" in
|
||||
*qt*) checksum=$(curl -L "${url}.sha1"); algo="sha1"; outDir='C:\Qt\' ;;
|
||||
*llvm*) checksum=$(curl -L "${url}.sha256"); algo="sha256"; outDir="." ;;
|
||||
*glslang*) checksum=$(curl -L "${url}.sha256"); algo="sha256"; outDir="./lib/Release - LLVM-x64" ;;
|
||||
#*glslang*) checksum=$(curl -L "${url}.sha256"); algo="sha256"; outDir="./lib/Release - LLVM-x64" ;; <- Temporarily disabled auto-build
|
||||
*glslang*) checksum=$(curl -L 'https://www.dropbox.com/s/hwnatk68n70jap0/glslanglibs_mt.7z.sha256'); algo="sha256"; outDir="./lib/Release - LLVM-x64" ;;
|
||||
*Vulkan*)
|
||||
# Vulkan setup needs to be run in batch environment
|
||||
# Need to subshell this or else it doesn't wait
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
env:
|
||||
CIRRUS_CLONE_DEPTH: 0 # Unshallow clone to obtain proper GIT_VERSION
|
||||
|
||||
freebsd_task:
|
||||
matrix:
|
||||
- name: FreeBSD 12.2 (snapshot)
|
||||
freebsd_instance:
|
||||
image_family: freebsd-12-1-snap
|
||||
cpu: 8
|
||||
memory: 8G
|
||||
env:
|
||||
CCACHE_MAXSIZE: 300M # 3x clean build, rounded
|
||||
CCACHE_DIR: /tmp/ccache_dir
|
||||
ccache_cache:
|
||||
folder: /tmp/ccache_dir
|
||||
packages_cache:
|
||||
folder: /var/cache/pkg
|
||||
install_script: "sh -ex ./.ci/install-freebsd.sh"
|
||||
script: "./.ci/build-freebsd.sh"
|
||||
@@ -1,28 +1,62 @@
|
||||
---
|
||||
name: Regression report
|
||||
about: If something worked before, but now it doesn't
|
||||
about: If something used to work before, but now it doesn't
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!---
|
||||
Please do not ask for help or report compatibility regressions here, use RPCS3 Discord server or forums instead.
|
||||
|
||||
Please read Contributing guide under Helpful resources on the right. →
|
||||
--->
|
||||
## Please do not ask for help or report compatibility regressions here, use [RPCS3 Discord server](https://discord.me/RPCS3) or [forums](https://forums.rpcs3.net/) instead.
|
||||
|
||||
## Quick summary
|
||||
Please describe what exactly has stopped working correctly
|
||||
Please briefly describe what has stopped working correctly.
|
||||
|
||||
## Details
|
||||
Please provide _exact_ build (or commit) information that introduced the regression you're reporting.
|
||||
Please see How to find the build that caused a regression in wiki: https://wiki.rpcs3.net/index.php?title=Help:Using_different_versions_of_RPCS3#How_to_find_the_build_that_caused_a_regression.3F
|
||||
You can find old builds here: https://rpcs3.net/compatibility?b
|
||||
Please describe the regression as accurately as possible.
|
||||
|
||||
Please remember to attach TWO logs: one for the build that exhibits regression, and one for the previous build that works as expected.
|
||||
#### 1. Please provide _exact_ build (or commit) information that introduced the regression you're reporting.
|
||||
* Please see [How to find the build that caused a regression](https://wiki.rpcs3.net/index.php?title=Help:Using_different_versions_of_RPCS3#How_to_find_the_build_that_caused_a_regression.3F) in our wiki.
|
||||
* You can find [History of RPCS3 builds](https://rpcs3.net/compatibility?b) here.
|
||||
|
||||
If the regression caused a graphical issue, please provide RSX capture and a Renderdoc capture that demonstrate the issue.
|
||||
To create an RSX capture, enable Debugger view (View → Show Debugger) and use the RSX Capture button. Captues will be stored in RPCS3 folder → captures.
|
||||
To create Renderdoc capture, please refer to Renderdoc documentation https://renderdoc.org/docs/how/how_capture_frame.html
|
||||
#### 2. Please attach TWO logs:
|
||||
* One for the build with regression.
|
||||
* One for the build that works as expected.
|
||||
|
||||
##### How to obtain RPCS3's log:
|
||||
* Run the game until you find the regression.
|
||||
* Completely close RPCS3, or move to the next step in case it has crashed.
|
||||
* Locate RPCS3's log file:
|
||||
+ ```RPCS3.log``` (It can show up as just RPCS3 and have a notepad icon)
|
||||
or
|
||||
+ ```RPCS3.log.gz``` (It can show up as RPCS3.log and have a zip or rar icon)
|
||||

|
||||
On Linux it will be in ```~/.cache/rpcs3/```.
|
||||
On Windows it will be near the executable.
|
||||
* Attach the log:
|
||||
+ Drag and drop your log file into the issue.
|
||||
+ Or upload it to the cloud, such as Dropbox, Mega etc.
|
||||
|
||||
#### 3. If you describe graphical regression, please provide an RSX capture and a RenderDoc capture that demonstrate it.
|
||||
* To create an RSX capture, use _Create_ _RSX_ _Capture_ under _Utilities_.
|
||||
Captures will be stored in RPCS3 folder → captures.
|
||||
+ Compress your capture with 7z, Rar etc.
|
||||
And drag and drop it into the issue.
|
||||
+ Or upload it to the cloud, such as Dropbox, Mega etc.
|
||||
* To create a RenderDoc capture, please refer to [RenderDoc's documentation](https://renderdoc.org/docs/how/how_capture_frame.html).
|
||||
|
||||
#### 4. Please attach screenshots of your problem.
|
||||
* Enable performance overlay with at least medium level of detail.
|
||||
You can find it in _Emulator_ tab in _Settings_.
|
||||
|
||||
#### 5. Please provide comparison with real PS3.
|
||||
|
||||
#### 6. Please provide your system configuration:
|
||||
* OS
|
||||
* CPU
|
||||
* GPU
|
||||
* Driver version
|
||||
* etc.
|
||||
|
||||
#### Please include.
|
||||
* Anything else you deem to be important
|
||||
@@ -7,20 +7,49 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!---
|
||||
Please do not ask for help or general inquiry here, use RPCS3 Discord server instead.
|
||||
|
||||
Please read Contributing guide under Helpful resources on the right. →
|
||||
--->
|
||||
## Please do not ask for help or report compatibility regressions here, use [RPCS3 Discord server](https://discord.me/RPCS3) or [forums](https://forums.rpcs3.net/) instead.
|
||||
|
||||
## Quick summary
|
||||
Please summarize the issue here
|
||||
Please briefly describe what is not working correctly.
|
||||
|
||||
## Details
|
||||
Please provide as much detail as you can here, including
|
||||
- expected (real hw) and observed (emulator) behavior
|
||||
- full logs (not from UI)
|
||||
- back traces (for hard crashes)
|
||||
- screenshots, Renderdoc, and RSX captures (for visual issues)
|
||||
- your system configuration (OS, CPU, GPU, driver versions, etc)
|
||||
- anything else you deem to be important
|
||||
|
||||
Please describe the problem as accurately as possible.
|
||||
|
||||
#### 1. Please attach RPCS3's log.
|
||||
* Run the game until you find the issue.
|
||||
* Completely close RPCS3, or move to the next step in case it has crashed.
|
||||
* Locate RPCS3's log file:
|
||||
+ ```RPCS3.log``` (It can show up as just RPCS3 and have a notepad icon)
|
||||
or
|
||||
+ ```RPCS3.log.gz``` (It can show up as RPCS3.log and have a zip or rar icon)
|
||||

|
||||
On Linux it will be in ```~/.cache/rpcs3/```.
|
||||
On Windows it will be near the executable.
|
||||
* Attach the log:
|
||||
+ Drag and drop your log file into the issue.
|
||||
+ Or upload it to the cloud, such as Dropbox, Mega etc.
|
||||
|
||||
#### 2. If you describe graphical issue, please provide an RSX capture and a RenderDoc capture that demonstrate it.
|
||||
* To create an RSX capture, use _Create_ _RSX_ _Capture_ under _Utilities_.
|
||||
Captures will be stored in RPCS3 folder → captures.
|
||||
+ Compress your capture with 7z, Rar etc.
|
||||
And drag and drop it into the issue.
|
||||
+ Or upload it to the cloud, such as Dropbox, Mega etc.
|
||||
* To create a RenderDoc capture, please refer to [RenderDoc's documentation](https://renderdoc.org/docs/how/how_capture_frame.html).
|
||||
|
||||
#### 3. Please attach screenshots of your problem.
|
||||
* Enable performance overlay with at least medium level of detail.
|
||||
You can find it in _Emulator_ tab in _Settings_.
|
||||
|
||||
#### 4. Please provide comparison with real PS3.
|
||||
|
||||
#### 5. Please provide your system configuration:
|
||||
* OS
|
||||
* CPU
|
||||
* GPU
|
||||
* Driver version
|
||||
* etc.
|
||||
|
||||
#### Please include.
|
||||
* Anything else you deem to be important
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: If RPCS3 lacks a feature you would like to see
|
||||
title: '[Feature Request] Enter Feature Title Here'
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Please do not ask for help or report compatibility regressions here, use [RPCS3 Discord server](https://discord.me/RPCS3) or [forums](https://forums.rpcs3.net/) instead.
|
||||
|
||||
## Quick summary
|
||||
Please briefly describe what feature you would like RPCS3 to have.
|
||||
|
||||
## Details
|
||||
|
||||
Please describe the feature as accurately as possible.
|
||||
|
||||
#### 1. Please describe, what part of RPCS3 would be affected by your feature:
|
||||
* Gameplay
|
||||
* Debugging
|
||||
* UI
|
||||
* Patches
|
||||
* Installation
|
||||
* Github
|
||||
* CI
|
||||
* etc.
|
||||
|
||||
#### 2. Please tell us, why your feature is important to RPCS3.
|
||||
|
||||
#### 3. Please attach screenshots of the feature implemented in other projects.
|
||||
|
||||
#### 4. Please provide your system configuration:
|
||||
* OS
|
||||
* CPU
|
||||
* GPU
|
||||
* Driver version
|
||||
* etc.
|
||||
|
||||
#### Please include.
|
||||
* Anything else you deem to be important
|
||||
@@ -40,6 +40,7 @@
|
||||
/3rdparty/llvm_build
|
||||
/Vulkan/Vulkan-build
|
||||
/Vulkan/glslang-build
|
||||
/Vulkan/spirv-tools-build
|
||||
|
||||
!/bin
|
||||
/bin/*
|
||||
|
||||
+12
-1
@@ -14,6 +14,14 @@
|
||||
path = Vulkan/glslang
|
||||
url = https://github.com/KhronosGroup/glslang.git
|
||||
ignore = dirty
|
||||
[submodule "Vulkan/spirv-tools"]
|
||||
path = Vulkan/spirv-tools
|
||||
url = https://github.com/KhronosGroup/SPIRV-Tools.git
|
||||
ignore = dirty
|
||||
[submodule "Vulkan/spirv-headers"]
|
||||
path = Vulkan/spirv-headers
|
||||
url = https://github.com/KhronosGroup/SPIRV-Headers.git
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/cereal"]
|
||||
path = 3rdparty/cereal
|
||||
url = https://github.com/RPCS3/cereal.git
|
||||
@@ -63,4 +71,7 @@
|
||||
path = 3rdparty/wolfssl
|
||||
url = https://github.com/RipleyTom/wolfssl.git
|
||||
ignore = dirty
|
||||
|
||||
[submodule "3rdparty/flatbuffers"]
|
||||
path = 3rdparty/flatbuffers
|
||||
url = https://github.com/google/flatbuffers.git
|
||||
ignore = dirty
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"userBlacklist": ["AlexAltea", "tambry", "DHrpcs3"]
|
||||
}
|
||||
+9
-4
@@ -10,8 +10,8 @@ jobs:
|
||||
services: docker
|
||||
cache: ccache
|
||||
compiler: gcc
|
||||
install: "docker pull rpcs3/rpcs3-travis-xenial:1.2"
|
||||
script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .ci/travis.env rpcs3/rpcs3-travis-xenial:1.2 /rpcs3/.ci/build-linux.sh'
|
||||
install: "docker pull rpcs3/rpcs3-travis-xenial:1.5"
|
||||
script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .ci/travis.env rpcs3/rpcs3-travis-xenial:1.5 /rpcs3/.ci/build-linux.sh'
|
||||
- os: linux
|
||||
dist: xenial
|
||||
env:
|
||||
@@ -20,8 +20,13 @@ jobs:
|
||||
services: docker
|
||||
cache: ccache
|
||||
compiler: clang
|
||||
install: "docker pull rpcs3/rpcs3-travis-xenial:1.2"
|
||||
script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .ci/travis.env rpcs3/rpcs3-travis-xenial:1.2 /rpcs3/.ci/build-linux.sh'
|
||||
install: "docker pull rpcs3/rpcs3-travis-xenial:1.5"
|
||||
script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .ci/travis.env rpcs3/rpcs3-travis-xenial:1.5 /rpcs3/.ci/build-linux.sh'
|
||||
# - os: freebsd
|
||||
# compiler: clang
|
||||
# cache: ccache
|
||||
# install: "./.ci/install-freebsd.sh"
|
||||
# script: "./.ci/build-freebsd.sh"
|
||||
# - os: osx
|
||||
# osx_image: xcode11.3
|
||||
# addons:
|
||||
|
||||
Vendored
+3
@@ -111,6 +111,9 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
|
||||
Vendored
+8
-3
@@ -74,6 +74,9 @@ else()
|
||||
add_library(3rdparty_7z INTERFACE)
|
||||
endif()
|
||||
|
||||
add_library(3rdparty_flatbuffers INTERFACE)
|
||||
target_include_directories(3rdparty_flatbuffers INTERFACE flatbuffers/include)
|
||||
|
||||
# libPNG
|
||||
# Select the version of libpng to use, default is builtin
|
||||
if (NOT USE_SYSTEM_LIBPNG)
|
||||
@@ -297,7 +300,7 @@ if(USE_VULKAN)
|
||||
if(VULKAN_FOUND)
|
||||
add_library(3rdparty_vulkan INTERFACE)
|
||||
target_compile_definitions(3rdparty_vulkan INTERFACE -DHAVE_VULKAN)
|
||||
target_link_libraries(3rdparty_vulkan INTERFACE SPIRV Vulkan::Vulkan)
|
||||
target_link_libraries(3rdparty_vulkan INTERFACE SPIRV SPIRV-Tools-opt Vulkan::Vulkan)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(Wayland)
|
||||
@@ -413,16 +416,17 @@ endif()
|
||||
# LLVM
|
||||
include(llvm.cmake)
|
||||
|
||||
# WOLFSSL
|
||||
add_subdirectory(wolfssl EXCLUDE_FROM_ALL)
|
||||
|
||||
# CURL
|
||||
if(USE_SYSTEM_CURL)
|
||||
message("-- RPCS3: using shared libcurl")
|
||||
find_package(CURL REQUIRED)
|
||||
add_library(wolfssl-3-static INTERFACE)
|
||||
add_library(libcurl INTERFACE)
|
||||
target_link_libraries(libcurl INTERFACE CURL::libcurl)
|
||||
else()
|
||||
message("-- RPCS3: building libcurl + wolfssl submodules")
|
||||
add_subdirectory(wolfssl EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(curl EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
@@ -430,6 +434,7 @@ endif()
|
||||
add_library(3rdparty::libusb ALIAS usb-1.0-static)
|
||||
add_library(3rdparty::zlib ALIAS 3rdparty_zlib)
|
||||
add_library(3rdparty::7z ALIAS 3rdparty_7z)
|
||||
add_library(3rdparty::flatbuffers ALIAS 3rdparty_flatbuffers)
|
||||
add_library(3rdparty::pugixml ALIAS pugixml)
|
||||
add_library(3rdparty::yaml-cpp ALIAS yaml-cpp)
|
||||
add_library(3rdparty::xxhash ALIAS xxhash)
|
||||
|
||||
Vendored
+383
-77
@@ -1,12 +1,12 @@
|
||||
#ifndef __glext_h_
|
||||
#define __glext_h_ 1
|
||||
#ifndef __gl_glext_h_
|
||||
#define __gl_glext_h_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013-2017 The Khronos Group Inc.
|
||||
** Copyright (c) 2013-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
@@ -51,7 +51,9 @@ extern "C" {
|
||||
#define GLAPI extern
|
||||
#endif
|
||||
|
||||
#define GL_GLEXT_VERSION 20180114
|
||||
#define GL_GLEXT_VERSION 20200423
|
||||
|
||||
#include "khrplatform.h"
|
||||
|
||||
/* Generated C header for:
|
||||
* API: gl
|
||||
@@ -464,9 +466,8 @@ GLAPI void APIENTRY glBlendEquation (GLenum mode);
|
||||
|
||||
#ifndef GL_VERSION_1_5
|
||||
#define GL_VERSION_1_5 1
|
||||
#include <stddef.h>
|
||||
typedef ptrdiff_t GLsizeiptr;
|
||||
typedef ptrdiff_t GLintptr;
|
||||
typedef khronos_ssize_t GLsizeiptr;
|
||||
typedef khronos_intptr_t GLintptr;
|
||||
#define GL_BUFFER_SIZE 0x8764
|
||||
#define GL_BUFFER_USAGE 0x8765
|
||||
#define GL_QUERY_COUNTER_BITS 0x8864
|
||||
@@ -879,7 +880,7 @@ GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboole
|
||||
|
||||
#ifndef GL_VERSION_3_0
|
||||
#define GL_VERSION_3_0 1
|
||||
typedef unsigned short GLhalf;
|
||||
typedef khronos_uint16_t GLhalf;
|
||||
#define GL_COMPARE_REF_TO_TEXTURE 0x884E
|
||||
#define GL_CLIP_DISTANCE0 0x3000
|
||||
#define GL_CLIP_DISTANCE1 0x3001
|
||||
@@ -1383,45 +1384,8 @@ GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIn
|
||||
#ifndef GL_VERSION_3_2
|
||||
#define GL_VERSION_3_2 1
|
||||
typedef struct __GLsync *GLsync;
|
||||
#ifndef GLEXT_64_TYPES_DEFINED
|
||||
/* This code block is duplicated in glxext.h, so must be protected */
|
||||
#define GLEXT_64_TYPES_DEFINED
|
||||
/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
|
||||
/* (as used in the GL_EXT_timer_query extension). */
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
#include <inttypes.h>
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
#include <inttypes.h>
|
||||
#if defined(__STDC__)
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int int64_t;
|
||||
typedef unsigned long int uint64_t;
|
||||
#else
|
||||
typedef long long int int64_t;
|
||||
typedef unsigned long long int uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#endif /* __STDC__ */
|
||||
#elif defined( __VMS ) || defined(__sgi)
|
||||
#include <inttypes.h>
|
||||
#elif defined(__SCO__) || defined(__USLC__)
|
||||
#include <stdint.h>
|
||||
#elif defined(__UNIXOS2__) || defined(__SOL64__)
|
||||
typedef long int int32_t;
|
||||
typedef long long int int64_t;
|
||||
typedef unsigned long long int uint64_t;
|
||||
#elif defined(_WIN32) && defined(__GNUC__)
|
||||
#include <stdint.h>
|
||||
#elif defined(_WIN32)
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
/* Fallback if nothing above works */
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
typedef uint64_t GLuint64;
|
||||
typedef int64_t GLint64;
|
||||
typedef khronos_uint64_t GLuint64;
|
||||
typedef khronos_int64_t GLint64;
|
||||
#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
|
||||
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
|
||||
#define GL_LINES_ADJACENCY 0x000A
|
||||
@@ -1497,7 +1461,7 @@ typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
|
||||
typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
|
||||
typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
|
||||
typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data);
|
||||
typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
|
||||
typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values);
|
||||
typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
|
||||
typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
|
||||
@@ -1517,7 +1481,7 @@ GLAPI void APIENTRY glDeleteSync (GLsync sync);
|
||||
GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
|
||||
GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
|
||||
GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *data);
|
||||
GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
|
||||
GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values);
|
||||
GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);
|
||||
GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);
|
||||
GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level);
|
||||
@@ -1773,8 +1737,8 @@ typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location,
|
||||
typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name);
|
||||
typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);
|
||||
typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices);
|
||||
typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params);
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values);
|
||||
@@ -1820,8 +1784,8 @@ GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *pa
|
||||
GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name);
|
||||
GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name);
|
||||
GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);
|
||||
GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
|
||||
GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
|
||||
GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
|
||||
GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
|
||||
GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices);
|
||||
GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params);
|
||||
GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values);
|
||||
@@ -2175,7 +2139,7 @@ GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data)
|
||||
typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
|
||||
typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
|
||||
typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
|
||||
typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
|
||||
typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
|
||||
@@ -2188,7 +2152,7 @@ typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum m
|
||||
GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
|
||||
GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
|
||||
GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
|
||||
GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
|
||||
GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params);
|
||||
GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params);
|
||||
GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
|
||||
GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers);
|
||||
@@ -2469,7 +2433,7 @@ typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect);
|
||||
typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
|
||||
typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params);
|
||||
typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64 *params);
|
||||
typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
|
||||
typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level);
|
||||
typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
|
||||
@@ -2481,7 +2445,7 @@ typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params);
|
||||
typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params);
|
||||
typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name);
|
||||
typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
|
||||
@@ -2513,7 +2477,7 @@ GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect);
|
||||
GLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
|
||||
GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param);
|
||||
GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params);
|
||||
GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params);
|
||||
GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64 *params);
|
||||
GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
|
||||
GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level);
|
||||
GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length);
|
||||
@@ -2525,7 +2489,7 @@ GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const
|
||||
GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params);
|
||||
GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name);
|
||||
GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
|
||||
GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params);
|
||||
GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name);
|
||||
GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name);
|
||||
GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
|
||||
@@ -2936,7 +2900,7 @@ GLAPI void APIENTRY glPrimitiveBoundingBoxARB (GLfloat minX, GLfloat minY, GLflo
|
||||
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
#define GL_ARB_bindless_texture 1
|
||||
typedef uint64_t GLuint64EXT;
|
||||
typedef khronos_uint64_t GLuint64EXT;
|
||||
#define GL_UNSIGNED_INT64_ARB 0x140F
|
||||
typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture);
|
||||
typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler);
|
||||
@@ -3496,7 +3460,7 @@ GLAPI void APIENTRY glProgramUniform4ui64vARB (GLuint program, GLint location, G
|
||||
|
||||
#ifndef GL_ARB_half_float_pixel
|
||||
#define GL_ARB_half_float_pixel 1
|
||||
typedef unsigned short GLhalfARB;
|
||||
typedef khronos_uint16_t GLhalfARB;
|
||||
#define GL_HALF_FLOAT_ARB 0x140B
|
||||
#endif /* GL_ARB_half_float_pixel */
|
||||
|
||||
@@ -3666,6 +3630,25 @@ GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor);
|
||||
#ifndef GL_ARB_internalformat_query2
|
||||
#define GL_ARB_internalformat_query2 1
|
||||
#define GL_SRGB_DECODE_ARB 0x8299
|
||||
#define GL_VIEW_CLASS_EAC_R11 0x9383
|
||||
#define GL_VIEW_CLASS_EAC_RG11 0x9384
|
||||
#define GL_VIEW_CLASS_ETC2_RGB 0x9385
|
||||
#define GL_VIEW_CLASS_ETC2_RGBA 0x9386
|
||||
#define GL_VIEW_CLASS_ETC2_EAC_RGBA 0x9387
|
||||
#define GL_VIEW_CLASS_ASTC_4x4_RGBA 0x9388
|
||||
#define GL_VIEW_CLASS_ASTC_5x4_RGBA 0x9389
|
||||
#define GL_VIEW_CLASS_ASTC_5x5_RGBA 0x938A
|
||||
#define GL_VIEW_CLASS_ASTC_6x5_RGBA 0x938B
|
||||
#define GL_VIEW_CLASS_ASTC_6x6_RGBA 0x938C
|
||||
#define GL_VIEW_CLASS_ASTC_8x5_RGBA 0x938D
|
||||
#define GL_VIEW_CLASS_ASTC_8x6_RGBA 0x938E
|
||||
#define GL_VIEW_CLASS_ASTC_8x8_RGBA 0x938F
|
||||
#define GL_VIEW_CLASS_ASTC_10x5_RGBA 0x9390
|
||||
#define GL_VIEW_CLASS_ASTC_10x6_RGBA 0x9391
|
||||
#define GL_VIEW_CLASS_ASTC_10x8_RGBA 0x9392
|
||||
#define GL_VIEW_CLASS_ASTC_10x10_RGBA 0x9393
|
||||
#define GL_VIEW_CLASS_ASTC_12x10_RGBA 0x9394
|
||||
#define GL_VIEW_CLASS_ASTC_12x12_RGBA 0x9395
|
||||
#endif /* GL_ARB_internalformat_query2 */
|
||||
|
||||
#ifndef GL_ARB_invalidate_subdata
|
||||
@@ -4713,8 +4696,8 @@ GLAPI void APIENTRY glVertexBlendARB (GLint count);
|
||||
|
||||
#ifndef GL_ARB_vertex_buffer_object
|
||||
#define GL_ARB_vertex_buffer_object 1
|
||||
typedef ptrdiff_t GLsizeiptrARB;
|
||||
typedef ptrdiff_t GLintptrARB;
|
||||
typedef khronos_ssize_t GLsizeiptrARB;
|
||||
typedef khronos_intptr_t GLintptrARB;
|
||||
#define GL_BUFFER_SIZE_ARB 0x8764
|
||||
#define GL_BUFFER_USAGE_ARB 0x8765
|
||||
#define GL_ARRAY_BUFFER_ARB 0x8892
|
||||
@@ -4909,6 +4892,12 @@ GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcha
|
||||
|
||||
#ifndef GL_ARB_viewport_array
|
||||
#define GL_ARB_viewport_array 1
|
||||
typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYDVNVPROC) (GLuint first, GLsizei count, const GLdouble *v);
|
||||
typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDDNVPROC) (GLuint index, GLdouble n, GLdouble f);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glDepthRangeArraydvNV (GLuint first, GLsizei count, const GLdouble *v);
|
||||
GLAPI void APIENTRY glDepthRangeIndexeddNV (GLuint index, GLdouble n, GLdouble f);
|
||||
#endif
|
||||
#endif /* GL_ARB_viewport_array */
|
||||
|
||||
#ifndef GL_ARB_window_pos
|
||||
@@ -5009,6 +4998,22 @@ GLAPI void APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count);
|
||||
#define GL_CONTEXT_ROBUST_ACCESS 0x90F3
|
||||
#endif /* GL_KHR_robustness */
|
||||
|
||||
#ifndef GL_KHR_shader_subgroup
|
||||
#define GL_KHR_shader_subgroup 1
|
||||
#define GL_SUBGROUP_SIZE_KHR 0x9532
|
||||
#define GL_SUBGROUP_SUPPORTED_STAGES_KHR 0x9533
|
||||
#define GL_SUBGROUP_SUPPORTED_FEATURES_KHR 0x9534
|
||||
#define GL_SUBGROUP_QUAD_ALL_STAGES_KHR 0x9535
|
||||
#define GL_SUBGROUP_FEATURE_BASIC_BIT_KHR 0x00000001
|
||||
#define GL_SUBGROUP_FEATURE_VOTE_BIT_KHR 0x00000002
|
||||
#define GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR 0x00000004
|
||||
#define GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR 0x00000008
|
||||
#define GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR 0x00000010
|
||||
#define GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR 0x00000020
|
||||
#define GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR 0x00000040
|
||||
#define GL_SUBGROUP_FEATURE_QUAD_BIT_KHR 0x00000080
|
||||
#endif /* GL_KHR_shader_subgroup */
|
||||
|
||||
#ifndef GL_KHR_texture_compression_astc_hdr
|
||||
#define GL_KHR_texture_compression_astc_hdr 1
|
||||
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
|
||||
@@ -5115,7 +5120,7 @@ GLAPI void APIENTRY glVertex4bvOES (const GLbyte *coords);
|
||||
|
||||
#ifndef GL_OES_fixed_point
|
||||
#define GL_OES_fixed_point 1
|
||||
typedef GLint GLfixed;
|
||||
typedef khronos_int32_t GLfixed;
|
||||
#define GL_FIXED_OES 0x140C
|
||||
typedef void (APIENTRYP PFNGLALPHAFUNCXOESPROC) (GLenum func, GLfixed ref);
|
||||
typedef void (APIENTRYP PFNGLCLEARCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
|
||||
@@ -5411,12 +5416,12 @@ typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severi
|
||||
typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
|
||||
typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf);
|
||||
typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam);
|
||||
typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
|
||||
typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufSize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
|
||||
GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf);
|
||||
GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, void *userParam);
|
||||
GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
|
||||
GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufSize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
|
||||
#endif
|
||||
#endif /* GL_AMD_debug_output */
|
||||
|
||||
@@ -5440,6 +5445,22 @@ GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRG
|
||||
#endif
|
||||
#endif /* GL_AMD_draw_buffers_blend */
|
||||
|
||||
#ifndef GL_AMD_framebuffer_multisample_advanced
|
||||
#define GL_AMD_framebuffer_multisample_advanced 1
|
||||
#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2
|
||||
#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3
|
||||
#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4
|
||||
#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5
|
||||
#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6
|
||||
#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7
|
||||
typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glRenderbufferStorageMultisampleAdvancedAMD (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleAdvancedAMD (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
#endif
|
||||
#endif /* GL_AMD_framebuffer_multisample_advanced */
|
||||
|
||||
#ifndef GL_AMD_framebuffer_sample_positions
|
||||
#define GL_AMD_framebuffer_sample_positions 1
|
||||
#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F
|
||||
@@ -5485,7 +5506,7 @@ GLAPI void APIENTRY glGetNamedFramebufferParameterfvAMD (GLuint framebuffer, GLe
|
||||
|
||||
#ifndef GL_AMD_gpu_shader_int64
|
||||
#define GL_AMD_gpu_shader_int64 1
|
||||
typedef int64_t GLint64EXT;
|
||||
typedef khronos_int64_t GLint64EXT;
|
||||
#define GL_INT64_NV 0x140E
|
||||
#define GL_UNSIGNED_INT64_NV 0x140F
|
||||
#define GL_INT8_NV 0x8FE0
|
||||
@@ -5704,6 +5725,10 @@ GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLf
|
||||
#define GL_AMD_shader_explicit_vertex_parameter 1
|
||||
#endif /* GL_AMD_shader_explicit_vertex_parameter */
|
||||
|
||||
#ifndef GL_AMD_shader_gpu_shader_half_float_fetch
|
||||
#define GL_AMD_shader_gpu_shader_half_float_fetch 1
|
||||
#endif /* GL_AMD_shader_gpu_shader_half_float_fetch */
|
||||
|
||||
#ifndef GL_AMD_shader_image_load_store_lod
|
||||
#define GL_AMD_shader_image_load_store_lod 1
|
||||
#endif /* GL_AMD_shader_image_load_store_lod */
|
||||
@@ -6451,6 +6476,21 @@ GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param);
|
||||
#define GL_422_REV_AVERAGE_EXT 0x80CF
|
||||
#endif /* GL_EXT_422_pixels */
|
||||
|
||||
#ifndef GL_EXT_EGL_image_storage
|
||||
#define GL_EXT_EGL_image_storage 1
|
||||
typedef void *GLeglImageOES;
|
||||
typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) (GLenum target, GLeglImageOES image, const GLint* attrib_list);
|
||||
typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) (GLuint texture, GLeglImageOES image, const GLint* attrib_list);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glEGLImageTargetTexStorageEXT (GLenum target, GLeglImageOES image, const GLint* attrib_list);
|
||||
GLAPI void APIENTRY glEGLImageTargetTextureStorageEXT (GLuint texture, GLeglImageOES image, const GLint* attrib_list);
|
||||
#endif
|
||||
#endif /* GL_EXT_EGL_image_storage */
|
||||
|
||||
#ifndef GL_EXT_EGL_sync
|
||||
#define GL_EXT_EGL_sync 1
|
||||
#endif /* GL_EXT_EGL_sync */
|
||||
|
||||
#ifndef GL_EXT_abgr
|
||||
#define GL_EXT_abgr 1
|
||||
#define GL_ABGR_EXT 0x8000
|
||||
@@ -7780,6 +7820,18 @@ GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern);
|
||||
#endif
|
||||
#endif /* GL_EXT_multisample */
|
||||
|
||||
#ifndef GL_EXT_multiview_tessellation_geometry_shader
|
||||
#define GL_EXT_multiview_tessellation_geometry_shader 1
|
||||
#endif /* GL_EXT_multiview_tessellation_geometry_shader */
|
||||
|
||||
#ifndef GL_EXT_multiview_texture_multisample
|
||||
#define GL_EXT_multiview_texture_multisample 1
|
||||
#endif /* GL_EXT_multiview_texture_multisample */
|
||||
|
||||
#ifndef GL_EXT_multiview_timer_query
|
||||
#define GL_EXT_multiview_timer_query 1
|
||||
#endif /* GL_EXT_multiview_timer_query */
|
||||
|
||||
#ifndef GL_EXT_packed_depth_stencil
|
||||
#define GL_EXT_packed_depth_stencil 1
|
||||
#define GL_DEPTH_STENCIL_EXT 0x84F9
|
||||
@@ -8049,6 +8101,19 @@ GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *strin
|
||||
#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
|
||||
#endif /* GL_EXT_separate_specular_color */
|
||||
|
||||
#ifndef GL_EXT_shader_framebuffer_fetch
|
||||
#define GL_EXT_shader_framebuffer_fetch 1
|
||||
#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
|
||||
#endif /* GL_EXT_shader_framebuffer_fetch */
|
||||
|
||||
#ifndef GL_EXT_shader_framebuffer_fetch_non_coherent
|
||||
#define GL_EXT_shader_framebuffer_fetch_non_coherent 1
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) (void);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glFramebufferFetchBarrierEXT (void);
|
||||
#endif
|
||||
#endif /* GL_EXT_shader_framebuffer_fetch_non_coherent */
|
||||
|
||||
#ifndef GL_EXT_shader_image_load_formatted
|
||||
#define GL_EXT_shader_image_load_formatted 1
|
||||
#endif /* GL_EXT_shader_image_load_formatted */
|
||||
@@ -8485,6 +8550,11 @@ GLAPI void APIENTRY glTextureNormalEXT (GLenum mode);
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
|
||||
#endif /* GL_EXT_texture_sRGB */
|
||||
|
||||
#ifndef GL_EXT_texture_sRGB_R8
|
||||
#define GL_EXT_texture_sRGB_R8 1
|
||||
#define GL_SR8_EXT 0x8FBD
|
||||
#endif /* GL_EXT_texture_sRGB_R8 */
|
||||
|
||||
#ifndef GL_EXT_texture_sRGB_decode
|
||||
#define GL_EXT_texture_sRGB_decode 1
|
||||
#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
|
||||
@@ -8492,6 +8562,10 @@ GLAPI void APIENTRY glTextureNormalEXT (GLenum mode);
|
||||
#define GL_SKIP_DECODE_EXT 0x8A4A
|
||||
#endif /* GL_EXT_texture_sRGB_decode */
|
||||
|
||||
#ifndef GL_EXT_texture_shadow_lod
|
||||
#define GL_EXT_texture_shadow_lod 1
|
||||
#endif /* GL_EXT_texture_shadow_lod */
|
||||
|
||||
#ifndef GL_EXT_texture_shared_exponent
|
||||
#define GL_EXT_texture_shared_exponent 1
|
||||
#define GL_RGB9_E5_EXT 0x8C3D
|
||||
@@ -9098,6 +9172,11 @@ GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRG
|
||||
#define GL_INTERLACE_READ_INGR 0x8568
|
||||
#endif /* GL_INGR_interlace_read */
|
||||
|
||||
#ifndef GL_INTEL_blackhole_render
|
||||
#define GL_INTEL_blackhole_render 1
|
||||
#define GL_BLACKHOLE_RENDER_INTEL 0x83FC
|
||||
#endif /* GL_INTEL_blackhole_render */
|
||||
|
||||
#ifndef GL_INTEL_conservative_rasterization
|
||||
#define GL_INTEL_conservative_rasterization 1
|
||||
#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE
|
||||
@@ -9206,6 +9285,27 @@ GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLen
|
||||
#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E
|
||||
#endif /* GL_MESAX_texture_stack */
|
||||
|
||||
#ifndef GL_MESA_framebuffer_flip_x
|
||||
#define GL_MESA_framebuffer_flip_x 1
|
||||
#define GL_FRAMEBUFFER_FLIP_X_MESA 0x8BBC
|
||||
#endif /* GL_MESA_framebuffer_flip_x */
|
||||
|
||||
#ifndef GL_MESA_framebuffer_flip_y
|
||||
#define GL_MESA_framebuffer_flip_y 1
|
||||
#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIMESAPROC) (GLenum target, GLenum pname, GLint param);
|
||||
typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC) (GLenum target, GLenum pname, GLint *params);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glFramebufferParameteriMESA (GLenum target, GLenum pname, GLint param);
|
||||
GLAPI void APIENTRY glGetFramebufferParameterivMESA (GLenum target, GLenum pname, GLint *params);
|
||||
#endif
|
||||
#endif /* GL_MESA_framebuffer_flip_y */
|
||||
|
||||
#ifndef GL_MESA_framebuffer_swap_xy
|
||||
#define GL_MESA_framebuffer_swap_xy 1
|
||||
#define GL_FRAMEBUFFER_SWAP_XY_MESA 0x8BBD
|
||||
#endif /* GL_MESA_framebuffer_swap_xy */
|
||||
|
||||
#ifndef GL_MESA_pack_invert
|
||||
#define GL_MESA_pack_invert 1
|
||||
#define GL_PACK_INVERT_MESA 0x8758
|
||||
@@ -9319,6 +9419,25 @@ GLAPI void APIENTRY glEndConditionalRenderNVX (void);
|
||||
#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
|
||||
#endif /* GL_NVX_gpu_memory_info */
|
||||
|
||||
#ifndef GL_NVX_gpu_multicast2
|
||||
#define GL_NVX_gpu_multicast2 1
|
||||
#define GL_UPLOAD_GPU_MASK_NVX 0x954A
|
||||
typedef void (APIENTRYP PFNGLUPLOADGPUMASKNVXPROC) (GLbitfield mask);
|
||||
typedef void (APIENTRYP PFNGLMULTICASTVIEWPORTARRAYVNVXPROC) (GLuint gpu, GLuint first, GLsizei count, const GLfloat *v);
|
||||
typedef void (APIENTRYP PFNGLMULTICASTVIEWPORTPOSITIONWSCALENVXPROC) (GLuint gpu, GLuint index, GLfloat xcoeff, GLfloat ycoeff);
|
||||
typedef void (APIENTRYP PFNGLMULTICASTSCISSORARRAYVNVXPROC) (GLuint gpu, GLuint first, GLsizei count, const GLint *v);
|
||||
typedef GLuint (APIENTRYP PFNGLASYNCCOPYBUFFERSUBDATANVXPROC) (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *fenceValueArray, GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray);
|
||||
typedef GLuint (APIENTRYP PFNGLASYNCCOPYIMAGESUBDATANVXPROC) (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *waitValueArray, GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glUploadGpuMaskNVX (GLbitfield mask);
|
||||
GLAPI void APIENTRY glMulticastViewportArrayvNVX (GLuint gpu, GLuint first, GLsizei count, const GLfloat *v);
|
||||
GLAPI void APIENTRY glMulticastViewportPositionWScaleNVX (GLuint gpu, GLuint index, GLfloat xcoeff, GLfloat ycoeff);
|
||||
GLAPI void APIENTRY glMulticastScissorArrayvNVX (GLuint gpu, GLuint first, GLsizei count, const GLint *v);
|
||||
GLAPI GLuint APIENTRY glAsyncCopyBufferSubDataNVX (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *fenceValueArray, GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray);
|
||||
GLAPI GLuint APIENTRY glAsyncCopyImageSubDataNVX (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *waitValueArray, GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray);
|
||||
#endif
|
||||
#endif /* GL_NVX_gpu_multicast2 */
|
||||
|
||||
#ifndef GL_NVX_linked_gpu_multicast
|
||||
#define GL_NVX_linked_gpu_multicast 1
|
||||
#define GL_LGPU_SEPARATE_STORAGE_BIT_NVX 0x0800
|
||||
@@ -9333,6 +9452,20 @@ GLAPI void APIENTRY glLGPUInterlockNVX (void);
|
||||
#endif
|
||||
#endif /* GL_NVX_linked_gpu_multicast */
|
||||
|
||||
#ifndef GL_NVX_progress_fence
|
||||
#define GL_NVX_progress_fence 1
|
||||
typedef GLuint (APIENTRYP PFNGLCREATEPROGRESSFENCENVXPROC) (void);
|
||||
typedef void (APIENTRYP PFNGLSIGNALSEMAPHOREUI64NVXPROC) (GLuint signalGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray);
|
||||
typedef void (APIENTRYP PFNGLWAITSEMAPHOREUI64NVXPROC) (GLuint waitGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray);
|
||||
typedef void (APIENTRYP PFNGLCLIENTWAITSEMAPHOREUI64NVXPROC) (GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI GLuint APIENTRY glCreateProgressFenceNVX (void);
|
||||
GLAPI void APIENTRY glSignalSemaphoreui64NVX (GLuint signalGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray);
|
||||
GLAPI void APIENTRY glWaitSemaphoreui64NVX (GLuint waitGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray);
|
||||
GLAPI void APIENTRY glClientWaitSemaphoreui64NVX (GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray);
|
||||
#endif
|
||||
#endif /* GL_NVX_progress_fence */
|
||||
|
||||
#ifndef GL_NV_alpha_to_coverage_dither_control
|
||||
#define GL_NV_alpha_to_coverage_dither_control 1
|
||||
#define GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV 0x934D
|
||||
@@ -9545,6 +9678,10 @@ GLAPI void APIENTRY glCallCommandListNV (GLuint list);
|
||||
#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC
|
||||
#endif /* GL_NV_compute_program5 */
|
||||
|
||||
#ifndef GL_NV_compute_shader_derivatives
|
||||
#define GL_NV_compute_shader_derivatives 1
|
||||
#endif /* GL_NV_compute_shader_derivatives */
|
||||
|
||||
#ifndef GL_NV_conditional_render
|
||||
#define GL_NV_conditional_render 1
|
||||
#define GL_QUERY_WAIT_NV 0x8E13
|
||||
@@ -9843,6 +9980,10 @@ GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, cons
|
||||
#define GL_NV_fragment_program_option 1
|
||||
#endif /* GL_NV_fragment_program_option */
|
||||
|
||||
#ifndef GL_NV_fragment_shader_barycentric
|
||||
#define GL_NV_fragment_shader_barycentric 1
|
||||
#endif /* GL_NV_fragment_shader_barycentric */
|
||||
|
||||
#ifndef GL_NV_fragment_shader_interlock
|
||||
#define GL_NV_fragment_shader_interlock 1
|
||||
#endif /* GL_NV_fragment_shader_interlock */
|
||||
@@ -9858,11 +9999,11 @@ GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, cons
|
||||
#define GL_COVERAGE_MODULATION_NV 0x9332
|
||||
#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333
|
||||
typedef void (APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v);
|
||||
typedef void (APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufsize, GLfloat *v);
|
||||
typedef void (APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufSize, GLfloat *v);
|
||||
typedef void (APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v);
|
||||
GLAPI void APIENTRY glGetCoverageModulationTableNV (GLsizei bufsize, GLfloat *v);
|
||||
GLAPI void APIENTRY glGetCoverageModulationTableNV (GLsizei bufSize, GLfloat *v);
|
||||
GLAPI void APIENTRY glCoverageModulationNV (GLenum components);
|
||||
#endif
|
||||
#endif /* GL_NV_framebuffer_mixed_samples */
|
||||
@@ -10115,9 +10256,9 @@ GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfN
|
||||
#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372
|
||||
#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373
|
||||
#define GL_CONFORMANT_NV 0x9374
|
||||
typedef void (APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params);
|
||||
GLAPI void APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params);
|
||||
#endif
|
||||
#endif /* GL_NV_internalformat_sample_query */
|
||||
|
||||
@@ -10127,6 +10268,96 @@ GLAPI void APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum interna
|
||||
#define GL_MAX_SPOT_EXPONENT_NV 0x8505
|
||||
#endif /* GL_NV_light_max_exponent */
|
||||
|
||||
#ifndef GL_NV_memory_attachment
|
||||
#define GL_NV_memory_attachment 1
|
||||
#define GL_ATTACHED_MEMORY_OBJECT_NV 0x95A4
|
||||
#define GL_ATTACHED_MEMORY_OFFSET_NV 0x95A5
|
||||
#define GL_MEMORY_ATTACHABLE_ALIGNMENT_NV 0x95A6
|
||||
#define GL_MEMORY_ATTACHABLE_SIZE_NV 0x95A7
|
||||
#define GL_MEMORY_ATTACHABLE_NV 0x95A8
|
||||
#define GL_DETACHED_MEMORY_INCARNATION_NV 0x95A9
|
||||
#define GL_DETACHED_TEXTURES_NV 0x95AA
|
||||
#define GL_DETACHED_BUFFERS_NV 0x95AB
|
||||
#define GL_MAX_DETACHED_TEXTURES_NV 0x95AC
|
||||
#define GL_MAX_DETACHED_BUFFERS_NV 0x95AD
|
||||
typedef void (APIENTRYP PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC) (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params);
|
||||
typedef void (APIENTRYP PFNGLRESETMEMORYOBJECTPARAMETERNVPROC) (GLuint memory, GLenum pname);
|
||||
typedef void (APIENTRYP PFNGLTEXATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset);
|
||||
typedef void (APIENTRYP PFNGLBUFFERATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset);
|
||||
typedef void (APIENTRYP PFNGLTEXTUREATTACHMEMORYNVPROC) (GLuint texture, GLuint memory, GLuint64 offset);
|
||||
typedef void (APIENTRYP PFNGLNAMEDBUFFERATTACHMEMORYNVPROC) (GLuint buffer, GLuint memory, GLuint64 offset);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glGetMemoryObjectDetachedResourcesuivNV (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params);
|
||||
GLAPI void APIENTRY glResetMemoryObjectParameterNV (GLuint memory, GLenum pname);
|
||||
GLAPI void APIENTRY glTexAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset);
|
||||
GLAPI void APIENTRY glBufferAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset);
|
||||
GLAPI void APIENTRY glTextureAttachMemoryNV (GLuint texture, GLuint memory, GLuint64 offset);
|
||||
GLAPI void APIENTRY glNamedBufferAttachMemoryNV (GLuint buffer, GLuint memory, GLuint64 offset);
|
||||
#endif
|
||||
#endif /* GL_NV_memory_attachment */
|
||||
|
||||
#ifndef GL_NV_mesh_shader
|
||||
#define GL_NV_mesh_shader 1
|
||||
#define GL_MESH_SHADER_NV 0x9559
|
||||
#define GL_TASK_SHADER_NV 0x955A
|
||||
#define GL_MAX_MESH_UNIFORM_BLOCKS_NV 0x8E60
|
||||
#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV 0x8E61
|
||||
#define GL_MAX_MESH_IMAGE_UNIFORMS_NV 0x8E62
|
||||
#define GL_MAX_MESH_UNIFORM_COMPONENTS_NV 0x8E63
|
||||
#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV 0x8E64
|
||||
#define GL_MAX_MESH_ATOMIC_COUNTERS_NV 0x8E65
|
||||
#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV 0x8E66
|
||||
#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV 0x8E67
|
||||
#define GL_MAX_TASK_UNIFORM_BLOCKS_NV 0x8E68
|
||||
#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV 0x8E69
|
||||
#define GL_MAX_TASK_IMAGE_UNIFORMS_NV 0x8E6A
|
||||
#define GL_MAX_TASK_UNIFORM_COMPONENTS_NV 0x8E6B
|
||||
#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV 0x8E6C
|
||||
#define GL_MAX_TASK_ATOMIC_COUNTERS_NV 0x8E6D
|
||||
#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV 0x8E6E
|
||||
#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV 0x8E6F
|
||||
#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV 0x95A2
|
||||
#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV 0x95A3
|
||||
#define GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV 0x9536
|
||||
#define GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV 0x9537
|
||||
#define GL_MAX_MESH_OUTPUT_VERTICES_NV 0x9538
|
||||
#define GL_MAX_MESH_OUTPUT_PRIMITIVES_NV 0x9539
|
||||
#define GL_MAX_TASK_OUTPUT_COUNT_NV 0x953A
|
||||
#define GL_MAX_DRAW_MESH_TASKS_COUNT_NV 0x953D
|
||||
#define GL_MAX_MESH_VIEWS_NV 0x9557
|
||||
#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV 0x92DF
|
||||
#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV 0x9543
|
||||
#define GL_MAX_MESH_WORK_GROUP_SIZE_NV 0x953B
|
||||
#define GL_MAX_TASK_WORK_GROUP_SIZE_NV 0x953C
|
||||
#define GL_MESH_WORK_GROUP_SIZE_NV 0x953E
|
||||
#define GL_TASK_WORK_GROUP_SIZE_NV 0x953F
|
||||
#define GL_MESH_VERTICES_OUT_NV 0x9579
|
||||
#define GL_MESH_PRIMITIVES_OUT_NV 0x957A
|
||||
#define GL_MESH_OUTPUT_TYPE_NV 0x957B
|
||||
#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV 0x959C
|
||||
#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV 0x959D
|
||||
#define GL_REFERENCED_BY_MESH_SHADER_NV 0x95A0
|
||||
#define GL_REFERENCED_BY_TASK_SHADER_NV 0x95A1
|
||||
#define GL_MESH_SHADER_BIT_NV 0x00000040
|
||||
#define GL_TASK_SHADER_BIT_NV 0x00000080
|
||||
#define GL_MESH_SUBROUTINE_NV 0x957C
|
||||
#define GL_TASK_SUBROUTINE_NV 0x957D
|
||||
#define GL_MESH_SUBROUTINE_UNIFORM_NV 0x957E
|
||||
#define GL_TASK_SUBROUTINE_UNIFORM_NV 0x957F
|
||||
#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV 0x959E
|
||||
#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV 0x959F
|
||||
typedef void (APIENTRYP PFNGLDRAWMESHTASKSNVPROC) (GLuint first, GLuint count);
|
||||
typedef void (APIENTRYP PFNGLDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect);
|
||||
typedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride);
|
||||
typedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glDrawMeshTasksNV (GLuint first, GLuint count);
|
||||
GLAPI void APIENTRY glDrawMeshTasksIndirectNV (GLintptr indirect);
|
||||
GLAPI void APIENTRY glMultiDrawMeshTasksIndirectNV (GLintptr indirect, GLsizei drawcount, GLsizei stride);
|
||||
GLAPI void APIENTRY glMultiDrawMeshTasksIndirectCountNV (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
|
||||
#endif
|
||||
#endif /* GL_NV_mesh_shader */
|
||||
|
||||
#ifndef GL_NV_multisample_coverage
|
||||
#define GL_NV_multisample_coverage 1
|
||||
#endif /* GL_NV_multisample_coverage */
|
||||
@@ -10408,7 +10639,7 @@ typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, co
|
||||
typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
|
||||
typedef GLenum (APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
|
||||
typedef void (APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params);
|
||||
typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs);
|
||||
typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs);
|
||||
typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode);
|
||||
@@ -10473,7 +10704,7 @@ GLAPI GLenum APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fo
|
||||
GLAPI GLenum APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
|
||||
GLAPI GLenum APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
|
||||
GLAPI void APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
|
||||
GLAPI void APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
GLAPI void APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params);
|
||||
GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs);
|
||||
GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs);
|
||||
GLAPI void APIENTRY glPathFogGenNV (GLenum genMode);
|
||||
@@ -10562,9 +10793,9 @@ GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index);
|
||||
#define GL_QUERY_RESOURCE_TEXTURE_NV 0x9545
|
||||
#define GL_QUERY_RESOURCE_RENDERBUFFER_NV 0x9546
|
||||
#define GL_QUERY_RESOURCE_BUFFEROBJECT_NV 0x9547
|
||||
typedef GLint (APIENTRYP PFNGLQUERYRESOURCENVPROC) (GLenum queryType, GLint tagId, GLuint bufSize, GLint *buffer);
|
||||
typedef GLint (APIENTRYP PFNGLQUERYRESOURCENVPROC) (GLenum queryType, GLint tagId, GLuint count, GLint *buffer);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI GLint APIENTRY glQueryResourceNV (GLenum queryType, GLint tagId, GLuint bufSize, GLint *buffer);
|
||||
GLAPI GLint APIENTRY glQueryResourceNV (GLenum queryType, GLint tagId, GLuint count, GLint *buffer);
|
||||
#endif
|
||||
#endif /* GL_NV_query_resource */
|
||||
|
||||
@@ -10672,6 +10903,11 @@ GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname,
|
||||
#endif
|
||||
#endif /* GL_NV_register_combiners2 */
|
||||
|
||||
#ifndef GL_NV_representative_fragment_test
|
||||
#define GL_NV_representative_fragment_test 1
|
||||
#define GL_REPRESENTATIVE_FRAGMENT_TEST_NV 0x937F
|
||||
#endif /* GL_NV_representative_fragment_test */
|
||||
|
||||
#ifndef GL_NV_robustness_video_memory_purge
|
||||
#define GL_NV_robustness_video_memory_purge 1
|
||||
#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
|
||||
@@ -10701,6 +10937,18 @@ GLAPI void APIENTRY glResolveDepthValuesNV (void);
|
||||
#define GL_NV_sample_mask_override_coverage 1
|
||||
#endif /* GL_NV_sample_mask_override_coverage */
|
||||
|
||||
#ifndef GL_NV_scissor_exclusive
|
||||
#define GL_NV_scissor_exclusive 1
|
||||
#define GL_SCISSOR_TEST_EXCLUSIVE_NV 0x9555
|
||||
#define GL_SCISSOR_BOX_EXCLUSIVE_NV 0x9556
|
||||
typedef void (APIENTRYP PFNGLSCISSOREXCLUSIVENVPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
typedef void (APIENTRYP PFNGLSCISSOREXCLUSIVEARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glScissorExclusiveNV (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GLAPI void APIENTRY glScissorExclusiveArrayvNV (GLuint first, GLsizei count, const GLint *v);
|
||||
#endif
|
||||
#endif /* GL_NV_scissor_exclusive */
|
||||
|
||||
#ifndef GL_NV_shader_atomic_counters
|
||||
#define GL_NV_shader_atomic_counters 1
|
||||
#endif /* GL_NV_shader_atomic_counters */
|
||||
@@ -10765,6 +11013,15 @@ GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLs
|
||||
#define GL_NV_shader_storage_buffer_object 1
|
||||
#endif /* GL_NV_shader_storage_buffer_object */
|
||||
|
||||
#ifndef GL_NV_shader_subgroup_partitioned
|
||||
#define GL_NV_shader_subgroup_partitioned 1
|
||||
#define GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV 0x00000100
|
||||
#endif /* GL_NV_shader_subgroup_partitioned */
|
||||
|
||||
#ifndef GL_NV_shader_texture_footprint
|
||||
#define GL_NV_shader_texture_footprint 1
|
||||
#endif /* GL_NV_shader_texture_footprint */
|
||||
|
||||
#ifndef GL_NV_shader_thread_group
|
||||
#define GL_NV_shader_thread_group 1
|
||||
#define GL_WARP_SIZE_NV 0x9339
|
||||
@@ -10776,6 +11033,47 @@ GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLs
|
||||
#define GL_NV_shader_thread_shuffle 1
|
||||
#endif /* GL_NV_shader_thread_shuffle */
|
||||
|
||||
#ifndef GL_NV_shading_rate_image
|
||||
#define GL_NV_shading_rate_image 1
|
||||
#define GL_SHADING_RATE_IMAGE_NV 0x9563
|
||||
#define GL_SHADING_RATE_NO_INVOCATIONS_NV 0x9564
|
||||
#define GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV 0x9565
|
||||
#define GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 0x9566
|
||||
#define GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 0x9567
|
||||
#define GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 0x9568
|
||||
#define GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 0x9569
|
||||
#define GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 0x956A
|
||||
#define GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 0x956B
|
||||
#define GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV 0x956C
|
||||
#define GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV 0x956D
|
||||
#define GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV 0x956E
|
||||
#define GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 0x956F
|
||||
#define GL_SHADING_RATE_IMAGE_BINDING_NV 0x955B
|
||||
#define GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV 0x955C
|
||||
#define GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV 0x955D
|
||||
#define GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV 0x955E
|
||||
#define GL_MAX_COARSE_FRAGMENT_SAMPLES_NV 0x955F
|
||||
#define GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV 0x95AE
|
||||
#define GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV 0x95AF
|
||||
#define GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV 0x95B0
|
||||
typedef void (APIENTRYP PFNGLBINDSHADINGRATEIMAGENVPROC) (GLuint texture);
|
||||
typedef void (APIENTRYP PFNGLGETSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint entry, GLenum *rate);
|
||||
typedef void (APIENTRYP PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC) (GLenum rate, GLuint samples, GLuint index, GLint *location);
|
||||
typedef void (APIENTRYP PFNGLSHADINGRATEIMAGEBARRIERNVPROC) (GLboolean synchronize);
|
||||
typedef void (APIENTRYP PFNGLSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates);
|
||||
typedef void (APIENTRYP PFNGLSHADINGRATESAMPLEORDERNVPROC) (GLenum order);
|
||||
typedef void (APIENTRYP PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC) (GLenum rate, GLuint samples, const GLint *locations);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glBindShadingRateImageNV (GLuint texture);
|
||||
GLAPI void APIENTRY glGetShadingRateImagePaletteNV (GLuint viewport, GLuint entry, GLenum *rate);
|
||||
GLAPI void APIENTRY glGetShadingRateSampleLocationivNV (GLenum rate, GLuint samples, GLuint index, GLint *location);
|
||||
GLAPI void APIENTRY glShadingRateImageBarrierNV (GLboolean synchronize);
|
||||
GLAPI void APIENTRY glShadingRateImagePaletteNV (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates);
|
||||
GLAPI void APIENTRY glShadingRateSampleOrderNV (GLenum order);
|
||||
GLAPI void APIENTRY glShadingRateSampleOrderCustomNV (GLenum rate, GLuint samples, const GLint *locations);
|
||||
#endif
|
||||
#endif /* GL_NV_shading_rate_image */
|
||||
|
||||
#ifndef GL_NV_stereo_view_rendering
|
||||
#define GL_NV_stereo_view_rendering 1
|
||||
#endif /* GL_NV_stereo_view_rendering */
|
||||
@@ -11068,7 +11366,7 @@ typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const
|
||||
typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
|
||||
typedef GLboolean (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface);
|
||||
typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface);
|
||||
typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
|
||||
typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei count, GLsizei *length, GLint *values);
|
||||
typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access);
|
||||
typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces);
|
||||
typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces);
|
||||
@@ -11079,13 +11377,21 @@ GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (const void *vdpSu
|
||||
GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
|
||||
GLAPI GLboolean APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface);
|
||||
GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface);
|
||||
GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
|
||||
GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei count, GLsizei *length, GLint *values);
|
||||
GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access);
|
||||
GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces);
|
||||
GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces);
|
||||
#endif
|
||||
#endif /* GL_NV_vdpau_interop */
|
||||
|
||||
#ifndef GL_NV_vdpau_interop2
|
||||
#define GL_NV_vdpau_interop2 1
|
||||
typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACEWITHPICTURESTRUCTURENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames, GLboolean isFrameStructure);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceWithPictureStructureNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames, GLboolean isFrameStructure);
|
||||
#endif
|
||||
#endif /* GL_NV_vdpau_interop2 */
|
||||
|
||||
#ifndef GL_NV_vertex_array_range
|
||||
#define GL_NV_vertex_array_range 1
|
||||
#define GL_VERTEX_ARRAY_RANGE_NV 0x851D
|
||||
|
||||
Vendored
+290
@@ -0,0 +1,290 @@
|
||||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(KHRONOS_STATIC)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef _WIN64
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
||||
+1
Submodule 3rdparty/flatbuffers added at 9e7e8cbe9f
Vendored
+3
@@ -27,6 +27,9 @@
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
|
||||
Vendored
+3
@@ -31,6 +31,9 @@
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
|
||||
Vendored
+4
-1
@@ -28,6 +28,9 @@
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|x64'" Label="PropertySheets">
|
||||
@@ -97,7 +100,7 @@
|
||||
<DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<AdditionalIncludeDirectories>$(ZLibSrcDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
|
||||
<Optimization>Full</Optimization>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
||||
Vendored
+3
@@ -24,6 +24,9 @@
|
||||
<WholeProgramOptimization Condition="'$(Configuration)'=='Release'">true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
|
||||
Vendored
+3
@@ -21,6 +21,9 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\3rdparty\zlib.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/wolfssl updated: f7130a4e43...d0749c6549
Vendored
+3
@@ -28,6 +28,9 @@
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
|
||||
Vendored
+7
-1
@@ -27,6 +27,9 @@
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
@@ -41,7 +44,10 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="xxHash/xxhash.c" />
|
||||
|
||||
Vendored
+4
@@ -22,6 +22,9 @@
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
@@ -40,6 +43,7 @@
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
||||
Vendored
+4
-1
@@ -31,6 +31,9 @@
|
||||
<Import Project="$(SolutionDir)\3rdparty\zlib.props" />
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
@@ -79,7 +82,7 @@
|
||||
<ClCompile>
|
||||
<WarningLevel>$(WarningLevel)</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Full</Optimization>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
|
||||
+5
-5
@@ -9,11 +9,11 @@ Other instructions may be found [here](https://wiki.rpcs3.net/index.php?title=Bu
|
||||
|
||||
* [CMake 3.14.1+](https://www.cmake.org/download/) (add to PATH)
|
||||
* [Python 3.3+](https://www.python.org/downloads/) (add to PATH)
|
||||
* [Qt 5.14+](https://www.qt.io/download-qt-installer)
|
||||
* [Qt 5.14.2](https://www.qt.io/download-qt-installer)
|
||||
* [Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community)
|
||||
* [Vulkan SDK 1.1.126+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html))
|
||||
|
||||
**Either add the** `QTDIR` **environment variable, e.g.** `<QtInstallFolder>\5.14.1\msvc2017_64\` **, or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools-19123)**
|
||||
**Either add the** `QTDIR` **environment variable, e.g.** `<QtInstallFolder>\5.14.2\msvc2017_64\` **, or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools-19123)**
|
||||
|
||||
### Linux
|
||||
|
||||
@@ -21,7 +21,7 @@ These are the essentials tools to build RPCS3 on Linux. Some of them can be inst
|
||||
|
||||
* Clang 9+ or GCC 9+
|
||||
* [CMake 3.14.1+](https://www.cmake.org/download/)
|
||||
* [Qt 5.14+](https://www.qt.io/download-qt-installer)
|
||||
* [Qt 5.14.2](https://www.qt.io/download-qt-installer)
|
||||
* [Vulkan SDK 1.1.126+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html))
|
||||
* [SDL2](https://www.libsdl.org/download-2.0.php) (for the FAudio backend)
|
||||
|
||||
@@ -41,7 +41,7 @@ Ubuntu is usually horrendously out of date, and some packages need to be downloa
|
||||
Ubuntu usually does not have a new enough Qt package to suit rpcs3's needs. There is a PPA available to work around this. Run the following:
|
||||
```
|
||||
ucodename=$(lsb_release -sc)
|
||||
sudo add-apt-repository ppa:beineri/opt-qt-5.14.1-$ucodename
|
||||
sudo add-apt-repository ppa:beineri/opt-qt-5.14.2-$ucodename
|
||||
sudo apt-get update
|
||||
. /opt/qt514/bin/qt514-env.sh >/dev/null 2>&1
|
||||
sudo apt-get install qt514-meta-minimal qt514svg
|
||||
@@ -103,7 +103,7 @@ git submodule update --init
|
||||
#### Configuring the Qt plugin (if used)
|
||||
|
||||
1) Go to the Qt5 menu and edit Qt5 options.
|
||||
2) Add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\5.14.1\msvc2017_64`.
|
||||
2) Add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\5.14.2\msvc2017_64`.
|
||||
3) While selecting the rpcs3qt project, go to Qt5->Project Setting and select the version you added.
|
||||
|
||||
#### Building the projects
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
RPCS3
|
||||
=====
|
||||
|
||||
[](https://travis-ci.org/RPCS3/rpcs3)
|
||||
[](https://dev.azure.com/nekotekina/nekotekina/_build/latest?definitionId=4&branchName=master)
|
||||
[](https://travis-ci.org/RPCS3/rpcs3)
|
||||
[](https://dev.azure.com/nekotekina/nekotekina/_build?definitionId=4&branchName=master)
|
||||
[&logo=cirrus-ci)](https://cirrus-ci.com/github/RPCS3/rpcs3)
|
||||
[](https://discord.me/rpcs3)
|
||||
|
||||
The world's first free and open-source PlayStation 3 emulator/debugger, written in C++ for Windows and Linux.
|
||||
|
||||
|
||||
+51
-7
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
#ifndef BETYPE_H_GUARD
|
||||
#define BETYPE_H_GUARD
|
||||
|
||||
#include "types.h"
|
||||
#include "util/endian.hpp"
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
#if __has_include(<bit>)
|
||||
#include <bit>
|
||||
@@ -13,7 +15,8 @@
|
||||
// 128-bit vector type and also se_storage<> storage type
|
||||
union alignas(16) v128
|
||||
{
|
||||
char _bytes[16];
|
||||
uchar _bytes[16];
|
||||
char _chars[16];
|
||||
|
||||
template <typename T, std::size_t N, std::size_t M>
|
||||
struct masked_array_t // array type accessed as (index ^ M)
|
||||
@@ -312,14 +315,54 @@ union alignas(16) v128
|
||||
return fromV(_mm_cmpeq_epi32(left.vi, right.vi));
|
||||
}
|
||||
|
||||
static inline v128 eq32f(const v128& left, const v128& right)
|
||||
{
|
||||
return fromF(_mm_cmpeq_ps(left.vf, right.vf));
|
||||
}
|
||||
|
||||
static inline v128 eq64f(const v128& left, const v128& right)
|
||||
{
|
||||
return fromD(_mm_cmpeq_pd(left.vd, right.vd));
|
||||
}
|
||||
|
||||
static inline bool use_fma = false;
|
||||
|
||||
static inline v128 fma32f(v128 a, const v128& b, const v128& c)
|
||||
{
|
||||
#ifndef __FMA__
|
||||
if (use_fma) [[likely]]
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
a.vf = _mm_fmadd_ps(a.vf, b.vf, c.vf);
|
||||
return a;
|
||||
#else
|
||||
__asm__("vfmadd213ps %[c], %[b], %[a]"
|
||||
: [a] "+x" (a.vf)
|
||||
: [b] "x" (b.vf)
|
||||
, [c] "x" (c.vf));
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
a._f[i] = std::fmaf(a._f[i], b._f[i], c._f[i]);
|
||||
}
|
||||
return a;
|
||||
#else
|
||||
a.vf = _mm_fmadd_ps(a.vf, b.vf, c.vf);
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool operator==(const v128& right) const
|
||||
{
|
||||
return _u64[0] == right._u64[0] && _u64[1] == right._u64[1];
|
||||
return _mm_movemask_epi8(v128::eq32(*this, right).vi) == 0xffff;
|
||||
}
|
||||
|
||||
bool operator!=(const v128& right) const
|
||||
{
|
||||
return _u64[0] != right._u64[0] || _u64[1] != right._u64[1];
|
||||
return !operator==(right);
|
||||
}
|
||||
|
||||
// result = (~left) & (right)
|
||||
@@ -330,8 +373,7 @@ union alignas(16) v128
|
||||
|
||||
void clear()
|
||||
{
|
||||
_u64[0] = 0;
|
||||
_u64[1] = 0;
|
||||
*this = {};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -362,7 +404,7 @@ inline v128 operator^(const v128& left, const v128& right)
|
||||
|
||||
inline v128 operator~(const v128& other)
|
||||
{
|
||||
return v128::from64(~other._u64[0], ~other._u64[1]);
|
||||
return other ^ v128::from32p(UINT32_MAX); // XOR with ones
|
||||
}
|
||||
|
||||
using stx::se_t;
|
||||
@@ -465,3 +507,5 @@ struct fmt_unveil<se_t<T, Se, Align>, void>
|
||||
return fmt_unveil<T>::get(arg);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BETYPE_H_GUARD
|
||||
|
||||
+10
-1
@@ -65,6 +65,13 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
|
||||
const char* start = &value.front();
|
||||
const char* end = &value.back() + 1;
|
||||
int base = 10;
|
||||
int sign = +1;
|
||||
|
||||
if (start[0] == '-')
|
||||
{
|
||||
sign = -1;
|
||||
start += 1;
|
||||
}
|
||||
|
||||
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
|
||||
{
|
||||
@@ -75,12 +82,14 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
|
||||
|
||||
const auto ret = std::from_chars(start, end, result, base);
|
||||
|
||||
if (ret.ec != std::errc() || ret.ptr != end)
|
||||
if (ret.ec != std::errc() || ret.ptr != end || (start[0] == '-' && sign < 0))
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_int('%s'): invalid integer", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
result *= sign;
|
||||
|
||||
if (result < min || result > max)
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_int('%s'): out of bounds (%d..%d)", value, min, max);
|
||||
|
||||
+1
-1
@@ -384,7 +384,7 @@ namespace cfg
|
||||
using uint64 = uint<0, UINT64_MAX>;
|
||||
|
||||
// Simple string entry with mutex
|
||||
class string final : public _base
|
||||
class string : public _base
|
||||
{
|
||||
const std::string m_name;
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ static fs::error to_error(DWORD e)
|
||||
case ERROR_DIR_NOT_EMPTY: return fs::error::notempty;
|
||||
case ERROR_NOT_READY: return fs::error::noent;
|
||||
case ERROR_FILENAME_EXCED_RANGE: return fs::error::toolong;
|
||||
case ERROR_DISK_FULL: return fs::error::nospace;
|
||||
default: return fs::error::unknown;
|
||||
}
|
||||
}
|
||||
@@ -170,6 +171,7 @@ static fs::error to_error(int e)
|
||||
case ENOTEMPTY: return fs::error::notempty;
|
||||
case EROFS: return fs::error::readonly;
|
||||
case EISDIR: return fs::error::isdir;
|
||||
case ENOSPC: return fs::error::nospace;
|
||||
default: return fs::error::unknown;
|
||||
}
|
||||
}
|
||||
@@ -1818,6 +1820,7 @@ void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
|
||||
case fs::error::readonly: return "Read only";
|
||||
case fs::error::isdir: return "Is a directory";
|
||||
case fs::error::toolong: return "Path too long";
|
||||
case fs::error::nospace: return "Not enough space on the device";
|
||||
case fs::error::unknown: return "Unknown system error";
|
||||
}
|
||||
|
||||
|
||||
@@ -516,6 +516,7 @@ namespace fs
|
||||
readonly,
|
||||
isdir,
|
||||
toolong,
|
||||
nospace,
|
||||
unknown
|
||||
};
|
||||
|
||||
|
||||
+13
-13
@@ -915,10 +915,10 @@ public:
|
||||
|
||||
~ObjectCache() override = default;
|
||||
|
||||
void notifyObjectCompiled(const llvm::Module* module, llvm::MemoryBufferRef obj) override
|
||||
void notifyObjectCompiled(const llvm::Module* _module, llvm::MemoryBufferRef obj) override
|
||||
{
|
||||
std::string name = m_path;
|
||||
name.append(module->getName().data());
|
||||
name.append(_module->getName().data());
|
||||
//fs::file(name, fs::rewrite).write(obj.getBufferStart(), obj.getBufferSize());
|
||||
name.append(".gz");
|
||||
|
||||
@@ -948,14 +948,14 @@ public:
|
||||
}
|
||||
default:
|
||||
{
|
||||
jit_log.error("LLVM: Failed to compress module: %s", module->getName().data());
|
||||
jit_log.error("LLVM: Failed to compress module: %s", _module->getName().data());
|
||||
deflateEnd(&zs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fs::file(name, fs::rewrite).write(zbuf.get(), zsz - zs.avail_out);
|
||||
jit_log.notice("LLVM: Created module: %s", module->getName().data());
|
||||
jit_log.notice("LLVM: Created module: %s", _module->getName().data());
|
||||
}
|
||||
|
||||
static std::unique_ptr<llvm::MemoryBuffer> load(const std::string& path)
|
||||
@@ -1033,14 +1033,14 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* module) override
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* _module) override
|
||||
{
|
||||
std::string path = m_path;
|
||||
path.append(module->getName().data());
|
||||
path.append(_module->getName().data());
|
||||
|
||||
if (auto buf = load(path))
|
||||
{
|
||||
jit_log.notice("LLVM: Loaded module: %s", module->getName().data());
|
||||
jit_log.notice("LLVM: Loaded module: %s", _module->getName().data());
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -1166,13 +1166,13 @@ jit_compiler::~jit_compiler()
|
||||
{
|
||||
}
|
||||
|
||||
void jit_compiler::add(std::unique_ptr<llvm::Module> module, const std::string& path)
|
||||
void jit_compiler::add(std::unique_ptr<llvm::Module> _module, const std::string& path)
|
||||
{
|
||||
ObjectCache cache{path};
|
||||
m_engine->setObjectCache(&cache);
|
||||
|
||||
const auto ptr = module.get();
|
||||
m_engine->addModule(std::move(module));
|
||||
const auto ptr = _module.get();
|
||||
m_engine->addModule(std::move(_module));
|
||||
m_engine->generateCodeForModule(ptr);
|
||||
m_engine->setObjectCache(nullptr);
|
||||
|
||||
@@ -1183,10 +1183,10 @@ void jit_compiler::add(std::unique_ptr<llvm::Module> module, const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
void jit_compiler::add(std::unique_ptr<llvm::Module> module)
|
||||
void jit_compiler::add(std::unique_ptr<llvm::Module> _module)
|
||||
{
|
||||
const auto ptr = module.get();
|
||||
m_engine->addModule(std::move(module));
|
||||
const auto ptr = _module.get();
|
||||
m_engine->addModule(std::move(_module));
|
||||
m_engine->generateCodeForModule(ptr);
|
||||
|
||||
for (auto& func : ptr->functions())
|
||||
|
||||
+2
-2
@@ -163,10 +163,10 @@ public:
|
||||
}
|
||||
|
||||
// Add module (path to obj cache dir)
|
||||
void add(std::unique_ptr<llvm::Module> module, const std::string& path);
|
||||
void add(std::unique_ptr<llvm::Module> _module, const std::string& path);
|
||||
|
||||
// Add module (not cached)
|
||||
void add(std::unique_ptr<llvm::Module> module);
|
||||
void add(std::unique_ptr<llvm::Module> _module);
|
||||
|
||||
// Add object (path to obj file)
|
||||
void add(const std::string& path);
|
||||
|
||||
+54
-33
@@ -1382,6 +1382,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
|
||||
|
||||
if (cpu)
|
||||
{
|
||||
vm::temporary_unlock(*cpu);
|
||||
u32 pf_port_id = 0;
|
||||
|
||||
if (auto pf_entries = g_fxo->get<page_fault_notification_entries>(); true)
|
||||
@@ -1416,7 +1417,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
|
||||
{
|
||||
const auto& spu = static_cast<spu_thread&>(*cpu);
|
||||
|
||||
const u64 type = spu.offset < RAW_SPU_BASE_ADDR ?
|
||||
const u64 type = spu.get_type() == spu_type::threaded ?
|
||||
SYS_MEMORY_PAGE_FAULT_TYPE_SPU_THREAD :
|
||||
SYS_MEMORY_PAGE_FAULT_TYPE_RAW_SPU;
|
||||
|
||||
@@ -1441,13 +1442,19 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
|
||||
}
|
||||
}
|
||||
|
||||
// Deschedule
|
||||
if (cpu->id_type() == 1)
|
||||
{
|
||||
lv2_obj::sleep(*cpu);
|
||||
}
|
||||
|
||||
// Now, place the page fault event onto table so that other functions [sys_mmapper_free_address and pagefault recovery funcs etc]
|
||||
// know that this thread is page faulted and where.
|
||||
|
||||
auto pf_events = g_fxo->get<page_fault_event_entries>();
|
||||
{
|
||||
std::lock_guard pf_lock(pf_events->pf_mutex);
|
||||
pf_events->events.emplace(static_cast<u32>(data2), addr);
|
||||
pf_events->events.emplace(cpu, addr);
|
||||
}
|
||||
|
||||
sig_log.warning("Page_fault %s location 0x%x because of %s memory", is_writing ? "writing" : "reading",
|
||||
@@ -1466,38 +1473,32 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
|
||||
// If we fail due to being busy, wait a bit and try again.
|
||||
while (static_cast<u32>(sending_error) == CELL_EBUSY)
|
||||
{
|
||||
if (cpu->id_type() == 1)
|
||||
if (cpu->is_stopped())
|
||||
{
|
||||
lv2_obj::sleep(*cpu, 1000);
|
||||
sending_error = {};
|
||||
break;
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(1000);
|
||||
sending_error = sys_event_port_send(pf_port_id, data1, data2, data3);
|
||||
}
|
||||
|
||||
if (cpu->id_type() == 1)
|
||||
{
|
||||
// Deschedule
|
||||
lv2_obj::sleep(*cpu);
|
||||
}
|
||||
|
||||
if (sending_error)
|
||||
{
|
||||
vm_log.fatal("Unknown error %x while trying to pass page fault.", +sending_error);
|
||||
cpu->state += cpu_flag::dbg_pause;
|
||||
vm_log.fatal("Unknown error 0x%x while trying to pass page fault.", +sending_error);
|
||||
}
|
||||
|
||||
// Wait until the thread is recovered
|
||||
for (std::shared_lock pf_lock(pf_events->pf_mutex);
|
||||
pf_events->events.count(static_cast<u32>(data2)) && !sending_error;)
|
||||
else
|
||||
{
|
||||
if (cpu->is_stopped())
|
||||
// Wait until the thread is recovered
|
||||
while (!cpu->state.test_and_reset(cpu_flag::signal))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (cpu->is_stopped())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Timeout in case the emulator is stopping
|
||||
pf_events->cond.wait(pf_lock, 10000);
|
||||
thread_ctrl::wait();
|
||||
}
|
||||
}
|
||||
|
||||
// Reschedule, test cpu state and try recovery if stopped
|
||||
@@ -1657,10 +1658,10 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
|
||||
//const auto uw = (u8*)(unwind_base + rtf->UnwindData);
|
||||
}
|
||||
|
||||
for (HMODULE module : modules)
|
||||
for (HMODULE _module : modules)
|
||||
{
|
||||
MODULEINFO info;
|
||||
if (GetModuleInformation(GetCurrentProcess(), module, &info, sizeof(info)))
|
||||
if (GetModuleInformation(GetCurrentProcess(), _module, &info, sizeof(info)))
|
||||
{
|
||||
const DWORD64 base = reinterpret_cast<DWORD64>(info.lpBaseOfDll);
|
||||
|
||||
@@ -1670,7 +1671,7 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
|
||||
for (DWORD size = 15; module_name.size() != size;)
|
||||
{
|
||||
module_name.resize(size);
|
||||
size = GetModuleBaseNameA(GetCurrentProcess(), module, &module_name.front(), size + 1);
|
||||
size = GetModuleBaseNameA(GetCurrentProcess(), _module, &module_name.front(), size + 1);
|
||||
if (!size)
|
||||
{
|
||||
module_name.clear();
|
||||
@@ -1891,6 +1892,7 @@ void thread_base::initialize(void (*error_cb)(), bool(*wait_cb)(const void*))
|
||||
|
||||
void thread_base::notify_abort() noexcept
|
||||
{
|
||||
m_signal.try_inc();
|
||||
atomic_storage_futex::raw_notify(+m_state_notifier);
|
||||
}
|
||||
|
||||
@@ -2154,7 +2156,7 @@ void thread_ctrl::detect_cpu_layout()
|
||||
if (!g_native_core_layout.compare_and_swap_test(native_core_arrangement::undefined, native_core_arrangement::generic))
|
||||
return;
|
||||
|
||||
const auto system_id = utils::get_system_info();
|
||||
const auto system_id = utils::get_cpu_brand();
|
||||
if (system_id.find("Ryzen") != umax)
|
||||
{
|
||||
g_native_core_layout.store(native_core_arrangement::amd_ccx);
|
||||
@@ -2226,7 +2228,7 @@ u64 thread_ctrl::get_affinity_mask(thread_class group)
|
||||
case native_core_arrangement::amd_ccx:
|
||||
{
|
||||
u64 spu_mask, ppu_mask, rsx_mask;
|
||||
const auto system_id = utils::get_system_info();
|
||||
const auto system_id = utils::get_cpu_brand();
|
||||
if (thread_count >= 32)
|
||||
{
|
||||
if (system_id.find("3950X") != umax)
|
||||
@@ -2399,6 +2401,30 @@ void thread_ctrl::set_native_priority(int priority)
|
||||
#endif
|
||||
}
|
||||
|
||||
u64 thread_ctrl::get_process_affinity_mask()
|
||||
{
|
||||
static const u64 mask = []() -> u64
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD_PTR res, _sys;
|
||||
if (!GetProcessAffinityMask(GetCurrentProcess(), &res, &_sys))
|
||||
{
|
||||
sig_log.error("Failed to get process affinity mask.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
#else
|
||||
// Assume it's called from the main thread (this is a bit shaky)
|
||||
return thread_ctrl::get_thread_affinity_mask();
|
||||
#endif
|
||||
}();
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
DECLARE(thread_ctrl::process_affinity_mask) = get_process_affinity_mask();
|
||||
|
||||
void thread_ctrl::set_thread_affinity_mask(u64 mask)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@@ -2441,12 +2467,7 @@ void thread_ctrl::set_thread_affinity_mask(u64 mask)
|
||||
u64 thread_ctrl::get_thread_affinity_mask()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD_PTR res, _sys;
|
||||
if (!GetProcessAffinityMask(GetCurrentProcess(), &res, &_sys))
|
||||
{
|
||||
sig_log.error("Failed to get process affinity mask.");
|
||||
return 0;
|
||||
}
|
||||
const u64 res = get_process_affinity_mask();
|
||||
|
||||
if (DWORD_PTR result = SetThreadAffinityMask(GetCurrentThread(), res))
|
||||
{
|
||||
@@ -2470,7 +2491,7 @@ u64 thread_ctrl::get_thread_affinity_mask()
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 result;
|
||||
u64 result = 0;
|
||||
|
||||
for (u32 core = 0; core < 64u; core++)
|
||||
{
|
||||
|
||||
@@ -210,6 +210,12 @@ public:
|
||||
static_cast<thread_base&>(thread).notify();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void raw_notify(named_thread<T>& thread)
|
||||
{
|
||||
static_cast<thread_base&>(thread).notify_abort();
|
||||
}
|
||||
|
||||
// Read current state
|
||||
static inline thread_state state()
|
||||
{
|
||||
@@ -249,8 +255,15 @@ public:
|
||||
// Sets the preferred affinity mask for this thread
|
||||
static void set_thread_affinity_mask(u64 mask);
|
||||
|
||||
// Get process affinity mask
|
||||
static u64 get_process_affinity_mask();
|
||||
|
||||
// Miscellaneous
|
||||
static u64 get_thread_affinity_mask();
|
||||
|
||||
private:
|
||||
// Miscellaneous
|
||||
static const u64 process_affinity_mask;
|
||||
};
|
||||
|
||||
// Derived from the callable object Context, possibly a lambda
|
||||
|
||||
@@ -63,6 +63,17 @@ namespace utils
|
||||
#ifdef _WIN32
|
||||
return ::VirtualAlloc(use_addr, size, MEM_RESERVE, PAGE_NOACCESS);
|
||||
#else
|
||||
if (use_addr && reinterpret_cast<uptr>(use_addr) % 0x10000)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!use_addr)
|
||||
{
|
||||
// Hack: Ensure aligned 64k allocations
|
||||
size += 0x10000;
|
||||
}
|
||||
|
||||
auto ptr = ::mmap(use_addr, size, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
|
||||
if (ptr == reinterpret_cast<void*>(-1))
|
||||
@@ -76,6 +87,20 @@ namespace utils
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!use_addr && ptr)
|
||||
{
|
||||
// Continuation of the hack above
|
||||
const auto misalign = reinterpret_cast<uptr>(ptr) % 0x10000;
|
||||
::munmap(ptr, 0x10000 - misalign);
|
||||
|
||||
if (misalign)
|
||||
{
|
||||
::munmap(static_cast<u8*>(ptr) + size - misalign, misalign);
|
||||
}
|
||||
|
||||
ptr = static_cast<u8*>(ptr) + (0x10000 - misalign);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
+1116
-193
File diff suppressed because it is too large
Load Diff
+121
-12
@@ -1,12 +1,30 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include "BEType.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "util/yaml.hpp"
|
||||
|
||||
namespace patch_key
|
||||
{
|
||||
static const std::string all = "All";
|
||||
static const std::string anchors = "Anchors";
|
||||
static const std::string author = "Author";
|
||||
static const std::string games = "Games";
|
||||
static const std::string group = "Group";
|
||||
static const std::string notes = "Notes";
|
||||
static const std::string patch = "Patch";
|
||||
static const std::string patch_version = "Patch Version";
|
||||
static const std::string version = "Version";
|
||||
}
|
||||
|
||||
static const std::string patch_engine_version = "1.2";
|
||||
|
||||
enum class patch_type
|
||||
{
|
||||
invalid,
|
||||
load,
|
||||
byte,
|
||||
le16,
|
||||
@@ -23,22 +41,113 @@ enum class patch_type
|
||||
|
||||
class patch_engine
|
||||
{
|
||||
struct patch
|
||||
public:
|
||||
struct patch_data
|
||||
{
|
||||
patch_type type;
|
||||
u32 offset;
|
||||
u64 value;
|
||||
patch_type type = patch_type::load;
|
||||
u32 offset = 0;
|
||||
std::string original_value; // Used for import consistency (avoid rounding etc.)
|
||||
union
|
||||
{
|
||||
u64 long_value;
|
||||
f64 double_value;
|
||||
} value { 0 };
|
||||
};
|
||||
|
||||
using patch_app_versions = std::unordered_map<std::string /*app_version*/, bool /*enabled*/>;
|
||||
using patch_serials = std::unordered_map<std::string /*serial*/, patch_app_versions>;
|
||||
using patch_titles = std::unordered_map<std::string /*serial*/, patch_serials>;
|
||||
|
||||
struct patch_info
|
||||
{
|
||||
// Patch information
|
||||
std::vector<patch_data> data_list;
|
||||
patch_titles titles;
|
||||
std::string description;
|
||||
std::string patch_version;
|
||||
std::string patch_group;
|
||||
std::string author;
|
||||
std::string notes;
|
||||
std::string source_path;
|
||||
|
||||
// Redundant information for accessibility (see patch_container)
|
||||
std::string hash;
|
||||
std::string version;
|
||||
bool is_legacy = false;
|
||||
bool is_enabled = false; // only for legacy patches
|
||||
};
|
||||
|
||||
// Database
|
||||
std::unordered_map<std::string, std::vector<patch>> m_map;
|
||||
struct patch_container
|
||||
{
|
||||
std::unordered_map<std::string /*description*/, patch_info> patch_info_map;
|
||||
std::string hash;
|
||||
std::string version;
|
||||
bool is_legacy = false;
|
||||
};
|
||||
|
||||
public:
|
||||
// Load from file
|
||||
void append(const std::string& path);
|
||||
using patch_map = std::unordered_map<std::string /*hash*/, patch_container>;
|
||||
|
||||
patch_engine();
|
||||
|
||||
// Returns the directory in which patch_config.yml is located
|
||||
static std::string get_patch_config_path();
|
||||
|
||||
// Returns the directory in which patches are located
|
||||
static std::string get_patches_path();
|
||||
|
||||
// Returns the filepath for the imported_patch.yml
|
||||
static std::string get_imported_patch_path();
|
||||
|
||||
// Load from file and append to specified patches map
|
||||
static bool load(patch_map& patches, const std::string& path, bool importing = false, std::stringstream* log_messages = nullptr);
|
||||
|
||||
// Read and add a patch node to the patch info
|
||||
static bool read_patch_node(patch_info& info, YAML::Node node, const YAML::Node& root, std::stringstream* log_messages = nullptr);
|
||||
|
||||
// Get the patch type of a patch node
|
||||
static patch_type get_patch_type(YAML::Node node);
|
||||
|
||||
// Add the data of a patch node
|
||||
static bool add_patch_data(YAML::Node node, patch_info& info, u32 modifier, const YAML::Node& root, std::stringstream* log_messages = nullptr);
|
||||
|
||||
// Save to patch_config.yml
|
||||
static void save_config(const patch_map& patches_map, bool enable_legacy_patches);
|
||||
|
||||
// Save a patch file
|
||||
static bool save_patches(const patch_map& patches, const std::string& path, std::stringstream* log_messages = nullptr);
|
||||
|
||||
// Create or append patches to a file
|
||||
static bool import_patches(const patch_map& patches, const std::string& path, size_t& count, size_t& total, std::stringstream* log_messages = nullptr);
|
||||
|
||||
// Remove a patch from a file
|
||||
static bool remove_patch(const patch_info& info);
|
||||
|
||||
// Load patch_config.yml
|
||||
static patch_map load_config(bool& enable_legacy_patches);
|
||||
|
||||
// Load from file and append to member patches map
|
||||
void append_global_patches();
|
||||
|
||||
// Load from title relevant files and append to member patches map
|
||||
void append_title_patches(const std::string& title_id);
|
||||
|
||||
// Apply patch (returns the number of entries applied)
|
||||
std::size_t apply(const std::string& name, u8* dst) const;
|
||||
std::size_t apply(const std::string& name, u8* dst);
|
||||
|
||||
// Apply patch with a check that the address exists in SPU local storage
|
||||
std::size_t apply_with_ls_check(const std::string&name, u8*dst, u32 filesz, u32 ls_addr) const;
|
||||
std::size_t apply_with_ls_check(const std::string& name, u8* dst, u32 filesz, u32 ls_addr);
|
||||
|
||||
private:
|
||||
// Load from file and append to member patches map
|
||||
void append(const std::string& path);
|
||||
|
||||
// Internal: Apply patch (returns the number of entries applied)
|
||||
template <bool check_local_storage>
|
||||
std::size_t apply_patch(const std::string& name, u8* dst, u32 filesz, u32 ls_addr);
|
||||
|
||||
// Database
|
||||
patch_map m_map;
|
||||
|
||||
// Only one patch per patch group can be applied
|
||||
std::set<std::string> m_applied_groups;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "stdafx.h"
|
||||
#include "cheat_info.h"
|
||||
#include "Config.h"
|
||||
#include "StrUtil.h"
|
||||
|
||||
LOG_CHANNEL(log_cheat, "Cheat");
|
||||
|
||||
bool cheat_info::from_str(const std::string& cheat_line)
|
||||
{
|
||||
auto cheat_vec = fmt::split(cheat_line, {"@@@"}, false);
|
||||
|
||||
s64 val64 = 0;
|
||||
if (cheat_vec.size() != 5 || !cfg::try_to_int64(&val64, cheat_vec[2], 0, cheat_type_max - 1))
|
||||
{
|
||||
log_cheat.fatal("Failed to parse cheat line");
|
||||
return false;
|
||||
}
|
||||
|
||||
game = cheat_vec[0];
|
||||
description = cheat_vec[1];
|
||||
type = cheat_type{::narrow<u8>(val64)};
|
||||
offset = std::stoul(cheat_vec[3]);
|
||||
red_script = cheat_vec[4];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string cheat_info::to_str() const
|
||||
{
|
||||
std::string cheat_str = game + "@@@" + description + "@@@" + std::to_string(static_cast<u8>(type)) + "@@@" + std::to_string(offset) + "@@@" + red_script + "@@@";
|
||||
return cheat_str;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
enum class cheat_type : u8
|
||||
{
|
||||
unsigned_8_cheat,
|
||||
unsigned_16_cheat,
|
||||
unsigned_32_cheat,
|
||||
unsigned_64_cheat,
|
||||
signed_8_cheat,
|
||||
signed_16_cheat,
|
||||
signed_32_cheat,
|
||||
signed_64_cheat,
|
||||
max
|
||||
};
|
||||
|
||||
constexpr u8 cheat_type_max = static_cast<u8>(cheat_type::max);
|
||||
|
||||
struct cheat_info
|
||||
{
|
||||
std::string game;
|
||||
std::string description;
|
||||
cheat_type type = cheat_type::max;
|
||||
u32 offset{};
|
||||
std::string red_script;
|
||||
|
||||
bool from_str(const std::string& cheat_line);
|
||||
std::string to_str() const;
|
||||
};
|
||||
+16
-5
@@ -64,6 +64,13 @@ bool utils::has_avx512()
|
||||
return g_value;
|
||||
}
|
||||
|
||||
bool utils::has_avx512_icl()
|
||||
{
|
||||
// Check AVX512IFMA, AVX512VBMI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG, AVX512VNNI, AVX512VPCLMULQDQ, AVX512GFNI, AVX512VAES (Icelake-client level support)
|
||||
static const bool g_value = has_avx512() && (get_cpuid(7, 0)[1] & 0x00200000) == 0x00200000 && (get_cpuid(7, 0)[2] & 0x00005f42) == 0x00005f42;
|
||||
return g_value;
|
||||
}
|
||||
|
||||
bool utils::has_xop()
|
||||
{
|
||||
static const bool g_value = has_avx() && get_cpuid(0x80000001, 0)[2] & 0x800;
|
||||
@@ -145,12 +152,16 @@ std::string utils::get_system_info()
|
||||
{
|
||||
result += " | AVX";
|
||||
|
||||
if (has_avx2())
|
||||
{
|
||||
result += '+';
|
||||
}
|
||||
|
||||
if (has_avx512())
|
||||
{
|
||||
result += "-512";
|
||||
|
||||
if (has_avx512_icl())
|
||||
{
|
||||
result += '+';
|
||||
}
|
||||
}
|
||||
else if (has_avx2())
|
||||
{
|
||||
result += '+';
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ namespace utils
|
||||
|
||||
bool has_avx512();
|
||||
|
||||
bool has_avx512_icl();
|
||||
|
||||
bool has_xop();
|
||||
|
||||
bool has_clwb();
|
||||
|
||||
+60
-8
@@ -18,7 +18,7 @@
|
||||
#include <array>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef __cpp_lib_bitops
|
||||
#if !defined(__cpp_lib_bitops) && _MSC_VER < 1928
|
||||
#define __cpp_lib_bitops
|
||||
#endif
|
||||
#endif
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define ASSUME(...) __assume(__VA_ARGS__) // MSVC __assume ignores side-effects
|
||||
#define ASSUME(...) ((__VA_ARGS__) ? void() : __assume(0)) // MSVC __assume ignores side-effects
|
||||
#define SAFE_BUFFERS __declspec(safebuffers)
|
||||
#define NEVER_INLINE __declspec(noinline)
|
||||
#define FORCE_INLINE __forceinline
|
||||
@@ -40,13 +40,12 @@
|
||||
|
||||
#ifdef __clang__
|
||||
#if defined(__has_builtin) && __has_builtin(__builtin_assume)
|
||||
#pragma clang diagnostic ignored "-Wassume" // ignore the clang "side-effects ignored" warning
|
||||
#define ASSUME(...) __builtin_assume(!!(__VA_ARGS__)) // __builtin_assume (supported by modern clang) ignores side-effects
|
||||
#define ASSUME(...) ((__VA_ARGS__) ? void() : __builtin_assume(0)) // __builtin_assume (supported by modern clang) ignores side-effects
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ASSUME // gcc and old clang
|
||||
#define ASSUME(...) do { if (!(__VA_ARGS__)) __builtin_unreachable(); } while (0) // note: the compiler will generate code to evaluate "cond" if the expression is opaque
|
||||
#define ASSUME(...) ((__VA_ARGS__) ? void() : __builtin_unreachable()) // note: the compiler will generate code to evaluate "cond" if the expression is opaque
|
||||
#endif
|
||||
|
||||
#define SAFE_BUFFERS __attribute__((no_stack_protector))
|
||||
@@ -77,7 +76,7 @@
|
||||
#define STR_CASE(...) case __VA_ARGS__: return #__VA_ARGS__
|
||||
|
||||
|
||||
#define ASSERT(...) do { if(!(__VA_ARGS__)) fmt::raw_error("Assertion failed: " STRINGIZE(__VA_ARGS__) HERE); } while(0)
|
||||
#define ASSERT(...) ((__VA_ARGS__) ? void() : fmt::raw_error("Assertion failed: " STRINGIZE(__VA_ARGS__) HERE))
|
||||
|
||||
#if defined(_DEBUG) || defined(_AUDIT)
|
||||
#define AUDIT(...) ASSERT(__VA_ARGS__)
|
||||
@@ -95,6 +94,11 @@ namespace std
|
||||
{
|
||||
static_assert(sizeof(To) == sizeof(From), "std::bit_cast<>: incompatible type size");
|
||||
|
||||
if constexpr ((std::is_same_v<std::remove_const_t<To>, std::remove_const_t<From>> && std::is_constructible_v<To, From>) || (std::is_integral_v<From> && std::is_integral_v<To>))
|
||||
{
|
||||
return static_cast<To>(from);
|
||||
}
|
||||
|
||||
To result{};
|
||||
std::memcpy(&result, &from, sizeof(From));
|
||||
return result;
|
||||
@@ -126,6 +130,53 @@ using s16 = std::int16_t;
|
||||
using s32 = std::int32_t;
|
||||
using s64 = std::int64_t;
|
||||
|
||||
#if __APPLE__
|
||||
namespace std
|
||||
{
|
||||
template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
|
||||
constexpr int countr_zero(T x) noexcept
|
||||
{
|
||||
if (x == 0)
|
||||
return sizeof(T) * 8;
|
||||
if constexpr (sizeof(T) <= sizeof(uint))
|
||||
return __builtin_ctz(x);
|
||||
else if constexpr (sizeof(T) <= sizeof(ulong))
|
||||
return __builtin_ctzl(x);
|
||||
else if constexpr (sizeof(T) <= sizeof(ullong))
|
||||
return __builtin_ctzll(x);
|
||||
else
|
||||
static_assert(sizeof(T) <= sizeof(ullong));
|
||||
}
|
||||
|
||||
template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
|
||||
constexpr int countr_one(T x) noexcept
|
||||
{
|
||||
return countr_zero<T>(~x);
|
||||
}
|
||||
|
||||
template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
|
||||
constexpr int countl_zero(T x) noexcept
|
||||
{
|
||||
if (x == 0)
|
||||
return sizeof(T) * 8;
|
||||
if constexpr (sizeof(T) <= sizeof(uint))
|
||||
return __builtin_clz(x) - (sizeof(uint) - sizeof(T)) * 8;
|
||||
else if constexpr (sizeof(T) <= sizeof(ulong))
|
||||
return __builtin_clzl(x) - (sizeof(ulong) - sizeof(T)) * 8;
|
||||
else if constexpr (sizeof(T) <= sizeof(ullong))
|
||||
return __builtin_clzll(x) - (sizeof(ullong) - sizeof(T)) * 8;
|
||||
else
|
||||
static_assert(sizeof(T) <= sizeof(ullong));
|
||||
}
|
||||
|
||||
template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
|
||||
constexpr int countl_one(T x) noexcept
|
||||
{
|
||||
return countl_zero<T>(~x);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
using steady_clock = std::conditional<
|
||||
std::chrono::high_resolution_clock::is_steady,
|
||||
std::chrono::high_resolution_clock, std::chrono::steady_clock>::type;
|
||||
@@ -911,11 +962,12 @@ struct cmd64 : any64
|
||||
static_assert(sizeof(cmd64) == 8 && std::is_trivially_copyable_v<cmd64>, "Incorrect cmd64 type");
|
||||
|
||||
// Error code type (return type), implements error reporting. Could be a template.
|
||||
struct error_code
|
||||
class error_code
|
||||
{
|
||||
// Use fixed s32 type for now
|
||||
s32 value;
|
||||
|
||||
public:
|
||||
error_code() = default;
|
||||
|
||||
// Implementation must be provided specially
|
||||
@@ -1005,4 +1057,4 @@ inline constexpr uintmax_t ceil2(T value)
|
||||
return i + std::min<uintmax_t>(ispow2, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <regex>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
std::string to_string(version_type type)
|
||||
@@ -48,4 +50,51 @@ namespace utils
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
// Based on https://www.geeksforgeeks.org/compare-two-version-numbers/
|
||||
int compare_versions(const std::string& v1, const std::string& v2, bool& ok)
|
||||
{
|
||||
// Check if both version strings are valid
|
||||
ok = std::regex_match(v1, std::regex("[0-9.]*")) && std::regex_match(v2, std::regex("[0-9.]*"));
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// vnum stores each numeric part of version
|
||||
int vnum1 = 0;
|
||||
int vnum2 = 0;
|
||||
|
||||
// Loop until both strings are processed
|
||||
for (size_t i = 0, j = 0; (i < v1.length() || j < v2.length());)
|
||||
{
|
||||
// Storing numeric part of version 1 in vnum1
|
||||
while (i < v1.length() && v1[i] != '.')
|
||||
{
|
||||
vnum1 = vnum1 * 10 + (v1[i] - '0');
|
||||
i++;
|
||||
}
|
||||
|
||||
// Storing numeric part of version 2 in vnum2
|
||||
while (j < v2.length() && v2[j] != '.')
|
||||
{
|
||||
vnum2 = vnum2 * 10 + (v2[j] - '0');
|
||||
j++;
|
||||
}
|
||||
|
||||
if (vnum1 > vnum2)
|
||||
return 1;
|
||||
|
||||
if (vnum2 > vnum1)
|
||||
return -1;
|
||||
|
||||
// If equal, reset variables and go for next numeric part
|
||||
vnum1 = vnum2 = 0;
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,4 +69,7 @@ namespace utils
|
||||
uint to_hex() const;
|
||||
std::string to_string() const;
|
||||
};
|
||||
|
||||
// Generic version comparison (e.g. 0.0.5 vs 1.3)
|
||||
int compare_versions(const std::string& v1, const std::string& v2, bool& ok);
|
||||
}
|
||||
|
||||
@@ -6,3 +6,7 @@ set(ENABLE_HLSL OFF CACHE BOOL "Enables HLSL input support" FORCE)
|
||||
set(ENABLE_OPT OFF CACHE BOOL "Enables spirv-opt capability if present" FORCE)
|
||||
set(ENABLE_CTEST OFF CACHE BOOL "Enables testing" FORCE)
|
||||
add_subdirectory(glslang)
|
||||
|
||||
set(SKIP_SPIRV_TOOLS_INSTALL ON CACHE BOOL "Skip spirv-tools install" FORCE)
|
||||
set(SPIRV-Headers_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/spirv-headers" CACHE STRING "spirv-headers path" FORCE)
|
||||
add_subdirectory(spirv-tools)
|
||||
|
||||
+1
-1
Submodule Vulkan/glslang updated: ae59435606...3ee5f2f1d3
@@ -38,29 +38,24 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<CmakeGenerator>"Visual Studio $(VisualStudioVersion.Substring(0,2))"</CmakeGenerator>
|
||||
<CmakeCLI>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang</CmakeCLI>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang
|
||||
<NMakeBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang
|
||||
<NMakeReBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang
|
||||
<NMakeCleanCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang
|
||||
<NMakeBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang
|
||||
<NMakeReBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang
|
||||
<NMakeCleanCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
|
||||
Submodule
+1
Submodule Vulkan/spirv-headers added at 3fdabd0da2
Submodule
+1
Submodule Vulkan/spirv-tools added at 895927bd3f
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}</ProjectGuid>
|
||||
<Keyword>MakeFileProj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\..\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<CmakeGenerator>"Visual Studio $(VisualStudioVersion.Substring(0,2))"</CmakeGenerator>
|
||||
<CmakeCLI>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DSPIRV-Headers_SOURCE_DIR=$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../spirv-headers')) ../spirv-tools</CmakeCLI>
|
||||
<PropsAbsPath>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\common_default.props'))</PropsAbsPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakeBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<NMakeBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(PropsAbsPath) /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||
@@ -96,6 +96,9 @@
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
@@ -125,6 +128,7 @@
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PreprocessorDefinitions>ASMJIT_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
+30
-22
@@ -31,27 +31,28 @@ jobs:
|
||||
displayName: ccache
|
||||
|
||||
- bash: |
|
||||
docker pull --quiet rpcs3/rpcs3-travis-xenial:1.2
|
||||
docker pull --quiet rpcs3/rpcs3-travis-xenial:1.5
|
||||
docker run \
|
||||
-v $(pwd):/rpcs3 \
|
||||
--env-file .ci/travis.env \
|
||||
-v $CCACHE_DIR:/root/.ccache \
|
||||
-v $BUILD_ARTIFACTSTAGINGDIRECTORY:/root/artifacts \
|
||||
rpcs3/rpcs3-travis-xenial:1.2 \
|
||||
rpcs3/rpcs3-travis-xenial:1.5 \
|
||||
/rpcs3/.ci/build-linux.sh
|
||||
displayName: Docker setup and build
|
||||
|
||||
- publish: $(Build.ArtifactStagingDirectory)
|
||||
condition: eq(variables['COMPILER'], 'gcc')
|
||||
condition: and(succeeded(), eq(variables['COMPILER'], 'gcc'))
|
||||
artifact: RPCS3 for Linux
|
||||
|
||||
- job: Windows_Build
|
||||
variables:
|
||||
COMPILER: msvc
|
||||
QT_VER: '5.14.1'
|
||||
QT_DATE: '202001240957'
|
||||
QT_VER: '5.14.2'
|
||||
QT_DATE: '202003291224'
|
||||
QTDIR: C:\Qt\$(QT_VER)\msvc2017_64
|
||||
VULKAN_VER: '1.1.126.0'
|
||||
VULKAN_SDK_SHA: 'ee86f25580b550390ce46508415e744d62e87e9c0de6cd299998058253a2a4ba'
|
||||
VULKAN_VER: '1.2.148.1'
|
||||
VULKAN_SDK_SHA: '5dbeafbc75c334811720fb50bd6ed7c9afd42afd31cad6be0b84cd8383aa9472'
|
||||
VULKAN_SDK: C:\VulkanSDK\$(VULKAN_VER)
|
||||
CACHE_DIR: ./cache
|
||||
|
||||
@@ -59,10 +60,15 @@ jobs:
|
||||
vmImage: "windows-latest"
|
||||
|
||||
steps:
|
||||
- bash: .ci/get_keys-windows.sh
|
||||
displayName: Get Cache Keys
|
||||
|
||||
- task: Cache@2
|
||||
inputs:
|
||||
key: $(Agent.OS) | $(COMPILER)
|
||||
key: $(Agent.OS) | $(COMPILER) | "$(QT_VER)" | $(VULKAN_SDK_SHA) | llvm.lock | glslang.lock
|
||||
path: $(CACHE_DIR)
|
||||
restoreKeys: |
|
||||
$(Agent.OS) | $(COMPILER)
|
||||
displayName: Cache
|
||||
|
||||
- bash: .ci/setup-windows.sh
|
||||
@@ -71,30 +77,32 @@ jobs:
|
||||
- bash: .ci/export-azure-vars.sh
|
||||
displayName: Export Variables
|
||||
|
||||
- task: MSBuild@1
|
||||
inputs:
|
||||
solution: './Vulkan/spirv-tools-build/spirv-tools-build.vcxproj'
|
||||
maximumCpuCount: true
|
||||
platform: x64
|
||||
configuration: 'Release'
|
||||
displayName: Compile SPIRV-Tools
|
||||
|
||||
- task: VSBuild@1
|
||||
inputs:
|
||||
solution: 'rpcs3.sln'
|
||||
msbuildArgs: '/m'
|
||||
maximumCpuCount: true
|
||||
platform: x64
|
||||
configuration: 'Release - LLVM'
|
||||
msbuildArgs: '/p:VCToolsVersion=14.25.28610'
|
||||
displayName: Compile RPCS3
|
||||
|
||||
- bash: .ci/deploy-windows.sh
|
||||
displayName: Pack up build artifacts
|
||||
|
||||
- publish: $(Build.ArtifactStagingDirectory)
|
||||
artifact: Windows App Bundle
|
||||
condition: succeeded()
|
||||
artifact: RPCS3 for Windows
|
||||
|
||||
- task: GitHubRelease@1
|
||||
condition: eq(variables['Build.SourceBranch'], 'refs/heads/master')
|
||||
inputs:
|
||||
gitHubConnection: 'RPCS3-Token'
|
||||
repositoryName: 'RPCS3/rpcs3-binaries-win'
|
||||
releaseNotesFilePath: 'GitHubReleaseMessage.txt'
|
||||
action: 'create'
|
||||
target: '7d09e3be30805911226241afbb14f8cdc2eb054e'
|
||||
tagSource: 'userSpecifiedTag'
|
||||
tag: 'build-$(Build.SourceVersion)'
|
||||
title: $(AVVER)
|
||||
addChangeLog: false
|
||||
- bash: .ci/github-upload-windows.sh
|
||||
condition: and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.Repository.Name'], 'RPCS3/rpcs3'), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
|
||||
displayName: Push build to GitHub
|
||||
env:
|
||||
RPCS3_TOKEN: $(RPCS3-Token)
|
||||
|
||||
Executable
+465
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
Nekotekina Theme for RPCS3 by GooseWing
|
||||
v1.0
|
||||
|
||||
Based on YoRHa Theme for RPCS3
|
||||
by Ani @ https://github.com/AniLeo
|
||||
r1 (2018.02.27)
|
||||
sorry for stealing
|
||||
*/
|
||||
|
||||
/*
|
||||
Color Scheme
|
||||
|
||||
- Kot Programs
|
||||
8c806a
|
||||
bd9d86
|
||||
c1b398
|
||||
eadfb1
|
||||
ebe4d2
|
||||
|
||||
- Light
|
||||
ffd785
|
||||
bfa163
|
||||
|
||||
- Dark
|
||||
705722
|
||||
5c471c
|
||||
4d4940
|
||||
*/
|
||||
|
||||
|
||||
/* Every widget */
|
||||
QWidget {
|
||||
font-family: SCE-PS3 Rodin LATIN;
|
||||
font-size: 9.00pt;
|
||||
|
||||
color: #ffd785;
|
||||
background: transparent;
|
||||
alternate-background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
/* Debugger: Sets font-family to default (any invalid value could be provided) */
|
||||
#debugger QListWidget, #debugger QTextEdit {
|
||||
font-family: none;
|
||||
}
|
||||
|
||||
|
||||
/* Log+TTY: Use flat dark color background with default font for better readability */
|
||||
#log_frame, #tty_frame {
|
||||
background: rgba(52, 49, 40, 0.9);
|
||||
font-size: 8.50pt;
|
||||
font-family: none;
|
||||
}
|
||||
|
||||
|
||||
/* Debugger: Restore original font size */
|
||||
#debugger QListWidget, #debugger QTextEdit {
|
||||
font-size: 9.50pt;
|
||||
}
|
||||
|
||||
|
||||
/* LLE: Style QListWidget checkboxes (QListWidget) */
|
||||
#lleList::indicator {
|
||||
border: 0.05em solid #4d4940;
|
||||
}
|
||||
#lleList::indicator::unchecked {
|
||||
background-color: #b3ac98;
|
||||
}
|
||||
#lleList::indicator::checked {
|
||||
background-color: #4d4940;
|
||||
}
|
||||
#lleList::indicator::disabled {
|
||||
background-color: #828790;
|
||||
}
|
||||
#lleList::item::selected {
|
||||
color: #4d4940;
|
||||
}
|
||||
|
||||
|
||||
/* Mouse Tooltips */
|
||||
QToolTip {
|
||||
background-color: #705722;
|
||||
color: #ffd785;
|
||||
border: 0.10em solid #705722;
|
||||
}
|
||||
|
||||
|
||||
/* CG Disasm and Trophy Manager: background-image doesn't work, use static color */
|
||||
QWidget#cg_disasm, QWidget#trophy_manager {
|
||||
background: #6e695c;
|
||||
}
|
||||
|
||||
|
||||
/* Main Window and Dialogs */
|
||||
QDialog, QMainWindow#main_window {
|
||||
border-image: url("GuiConfigs/kot-bg.jpg");
|
||||
}
|
||||
|
||||
|
||||
/* Table headers */
|
||||
QHeaderView::section {
|
||||
text-transform: uppercase;
|
||||
background: #bfa163;
|
||||
color: #4d4940;
|
||||
padding-left: 0.15em;
|
||||
padding-top: 0.15em;
|
||||
padding-bottom: 0.10em;
|
||||
text-transform: uppercase;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
/* All other Tabs */
|
||||
QTabBar {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
QTabBar::tab {
|
||||
background: transparent;
|
||||
padding-left: 0.50em;
|
||||
padding-right: 0.50em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
QTabBar::tab::selected {
|
||||
background: #705722;
|
||||
color: #ffd785;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
|
||||
/* Settings Dialog: Tabs */
|
||||
QTabBar#tab_bar_settings {
|
||||
border-bottom: 0.05em solid #705722;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
QTabBar::tab#tab_bar_settings {
|
||||
background: transparent;
|
||||
width: 5.20em;
|
||||
padding-left: 0.50em;
|
||||
padding-right: 0.50em;
|
||||
padding-top: 0.65em;
|
||||
padding-bottom: 0.65em;
|
||||
margin-right: 0.25em;
|
||||
font-size: 10.5pt;
|
||||
font-weight: 550;
|
||||
}
|
||||
QTabBar::tab:last#tab_bar_settings {
|
||||
margin-right: 0em;
|
||||
}
|
||||
QTabBar::tab:!selected:hover#tab_bar_settings {
|
||||
background: transparent;
|
||||
color: #705722;
|
||||
}
|
||||
QTabBar::tab::selected#tab_bar_settings {
|
||||
background: #bfa163;
|
||||
color: #705722;
|
||||
border-bottom-style: solid;
|
||||
margin-top: 0.15em;
|
||||
}
|
||||
|
||||
|
||||
/* Checkboxes */
|
||||
QCheckBox::indicator {
|
||||
border-radius: 0.1em;
|
||||
border: 0.05em solid #5c471c;
|
||||
margin-top: 0.05em;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
}
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: #ffd785; /* Light */
|
||||
}
|
||||
QCheckBox::indicator:unchecked {
|
||||
background-color: #705722; /* Dark */
|
||||
}
|
||||
QCheckBox::indicator::disabled {
|
||||
background-color: #828790; /* Gray */
|
||||
}
|
||||
|
||||
|
||||
/* Radio Buttons */
|
||||
QRadioButton::indicator {
|
||||
border-radius: 0.4em;
|
||||
border: 0.05em solid #5c471c;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
}
|
||||
QRadioButton::indicator:checked {
|
||||
background-color: #ffd785; /* Light */
|
||||
}
|
||||
QRadioButton::indicator:unchecked {
|
||||
background-color: #705722; /* Dark */
|
||||
}
|
||||
QRadioButton::indicator::disabled {
|
||||
background-color: #828790; /* Gray */
|
||||
}
|
||||
|
||||
|
||||
/* Combo Boxes */
|
||||
QComboBox {
|
||||
background: transparent;
|
||||
color: #ffd785;
|
||||
border: 0.05em solid #ffd785;
|
||||
border-radius: 0.15em;
|
||||
padding-bottom: 0.2em;
|
||||
padding-left: 0.4em;
|
||||
}
|
||||
QComboBox QAbstractItemView {
|
||||
background: #bfa163;
|
||||
color: #4d4940;
|
||||
}
|
||||
QComboBox::disabled {
|
||||
background: #828790;
|
||||
color: #4d4940;
|
||||
}
|
||||
|
||||
|
||||
/* Group Boxes (Settings Dialog) */
|
||||
QGroupBox {
|
||||
margin-top: 1em;
|
||||
border: 0.05em solid #ffd785;
|
||||
text-transform: uppercase;
|
||||
font-size: 9.25pt;
|
||||
background-color: rgba(41,41,41,120);
|
||||
}
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top;
|
||||
padding: 0.3em 0.5em 0.3em 0.5em;
|
||||
color: #ffd785;
|
||||
}
|
||||
|
||||
|
||||
/* Buttons */
|
||||
QPushButton {
|
||||
background: #b89754;
|
||||
color: #292929;
|
||||
}
|
||||
QPushButton::disabled {
|
||||
background: #828790;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
|
||||
/* QSpinBox (Settings -> Emulator -> width/height) */
|
||||
/* QDoubleSpinBox (Pads -> Mouse Acceleration -> x/y) */
|
||||
QSpinBox, QDoubleSpinBox {
|
||||
background: transparent;
|
||||
/*background-color: #bfa163;*/
|
||||
border: 0.05em solid #4d4940;
|
||||
border-radius: 0.10em;
|
||||
color: #ffd785;
|
||||
}
|
||||
|
||||
|
||||
/* Styles Sliders */
|
||||
QSlider::groove:horizontal {
|
||||
border: 0.10em solid #ffd785;
|
||||
border-radius: 0.10em;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
background: #ffd785;
|
||||
width: 0.50em;
|
||||
}
|
||||
|
||||
QSlider#sizeSlider::groove:horizontal {
|
||||
border: 0.10em solid #ffd785;
|
||||
border-radius: 0.10em;
|
||||
height: 1.5em;
|
||||
}
|
||||
|
||||
/* Log and Debugger borders */
|
||||
QTextEdit {
|
||||
border: 0.05em solid #4d4940;
|
||||
}
|
||||
|
||||
|
||||
/* For dock buttons to be visible */
|
||||
QDockWidget {
|
||||
background: transparent;
|
||||
text-transform: uppercase;
|
||||
color: #4d4940;
|
||||
font-weight: 500;
|
||||
}
|
||||
[floating="true"] {
|
||||
border-image: url("GuiConfigs/kot-bg.jpg");
|
||||
}
|
||||
QDockWidget::title {
|
||||
background: #bfa163;
|
||||
padding-top: 0.2em;
|
||||
}
|
||||
QDockWidget::close-button, QDockWidget::float-button {
|
||||
background-color: #bfa163;
|
||||
}
|
||||
|
||||
|
||||
/* Disable ugly borders */
|
||||
QTabWidget::pane {
|
||||
border: 0em solid #4d4940;
|
||||
}
|
||||
|
||||
|
||||
/* Top menu bar */
|
||||
QMenuBar {
|
||||
height:1.50em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
QMenuBar::item {
|
||||
margin-right: 0.20em;
|
||||
margin-left: 0.20em;
|
||||
padding-left: 1.20em;
|
||||
padding-right: 1.20em;
|
||||
}
|
||||
QMenuBar::item:selected {
|
||||
background: #4d4940;
|
||||
color: #aea993;
|
||||
}
|
||||
|
||||
|
||||
QMenu {
|
||||
background: #bfa163;
|
||||
color: #4d4940;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
QMenu::item {
|
||||
padding-left: 1.5em;
|
||||
padding-right: 0.75em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
|
||||
}
|
||||
QMenu::item:selected {
|
||||
background: #4d4940;
|
||||
color: #aea993;
|
||||
border: 0.05em solid #4d4940;
|
||||
}
|
||||
QMenu::item:disabled {
|
||||
background-color: #828790;
|
||||
color: #4d4940;
|
||||
}
|
||||
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
color: #ffd785;
|
||||
}
|
||||
|
||||
|
||||
/* Game Grid Font */
|
||||
QTableWidget#game_grid {
|
||||
font-weight: 600;
|
||||
color: #4d4940;
|
||||
text-transform: uppercase;
|
||||
selection-color: #aea993;
|
||||
}
|
||||
QTableWidget#game_grid::item:selected:active {
|
||||
selection-background-color: #4d4940;
|
||||
}
|
||||
QTableWidget#game_grid::item:selected:!active {
|
||||
selection-background-color: #615c51;
|
||||
}
|
||||
|
||||
|
||||
/* Debug UI Settings buttons */
|
||||
QLabel#color_button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
|
||||
/* Search bar on main Toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
margin-left: 0.7em;
|
||||
color: #4d4940;
|
||||
font-size: 10.25pt;
|
||||
}
|
||||
|
||||
|
||||
/* Uniform colors in Toolbar */
|
||||
QToolButton {
|
||||
background: transparent;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
QToolButton::hover {
|
||||
background-color: #b3ac98;
|
||||
}
|
||||
|
||||
|
||||
/* Set Theme UI colors */
|
||||
QLabel#gamelist_icon_background_color {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
|
||||
/* Set Windows Taskbar Thumbnail colors */
|
||||
QLabel#thumbnail_icon_color {
|
||||
color: #4d4940;
|
||||
}
|
||||
|
||||
|
||||
QLabel#log_level_always {
|
||||
color: #00ffff; /* Cyan */
|
||||
}
|
||||
QLabel#log_level_fatal {
|
||||
color: #ff00ff; /* Fuchsia */
|
||||
}
|
||||
QLabel#log_level_error {
|
||||
color: #ff0000; /* Red */
|
||||
}
|
||||
QLabel#log_level_todo {
|
||||
color: #ff6000; /* Orange */
|
||||
}
|
||||
QLabel#log_level_success {
|
||||
color: #00ff00; /* Green */
|
||||
}
|
||||
QLabel#log_level_warning {
|
||||
color: #ffff00; /* Yellow */
|
||||
}
|
||||
QLabel#log_level_notice {
|
||||
color: #ffffff; /* White */
|
||||
}
|
||||
QLabel#log_level_trace {
|
||||
color: #808080; /* Gray */
|
||||
}
|
||||
QLabel#log_stack {
|
||||
color: #b3ac98; /* Light */
|
||||
}
|
||||
|
||||
/* Set TTY colors */
|
||||
#tty_frame {
|
||||
color: #b3ac98; /* Light */
|
||||
}
|
||||
|
||||
|
||||
/* Memory Viewer */
|
||||
QLabel#memory_viewer_address_panel {
|
||||
color: #0000ff; /* Font Color: Blue */
|
||||
}
|
||||
QLabel#memory_viewer_hex_panel {
|
||||
color: #4d4940; /* Font Color: Grey */
|
||||
}
|
||||
QLabel#memory_viewer_ascii_panel {
|
||||
color: #4d4940; /* Font Color: Grey */
|
||||
}
|
||||
|
||||
|
||||
/* Debugger colors */
|
||||
QLabel#debugger_frame_breakpoint {
|
||||
color: #000000; /* Font Color: Black */
|
||||
background-color: #ffff00; /* Yellow */
|
||||
}
|
||||
QLabel#debugger_frame_pc {
|
||||
color: #000000; /* Font Color: Black */
|
||||
background-color: #00ff00; /* Green */
|
||||
}
|
||||
|
||||
|
||||
/* Trophy Notification Popup */
|
||||
QWidget#trophy_notification_frame {
|
||||
background-color: #b3ac98;
|
||||
color: #4d4940;
|
||||
}
|
||||
@@ -460,10 +460,6 @@ QSpinBox:hover, QDoubleSpinBox:hover {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
QSpinBox::up-button, QSpinBox::down-button, QDoubleSpinBox::up-button, QDoubleSpinBox::down-button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QSpinBox:disabled, QDoubleSpinBox:disabled {
|
||||
color: #455971;
|
||||
background: #26293b;
|
||||
|
||||
@@ -482,10 +482,6 @@ QSpinBox:hover, QDoubleSpinBox:hover {
|
||||
color: #455971;
|
||||
}
|
||||
|
||||
QSpinBox::up-button, QSpinBox::down-button, QDoubleSpinBox::up-button, QDoubleSpinBox::down-button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QSpinBox:disabled, QDoubleSpinBox:disabled {
|
||||
background-color: #b3b3b3;
|
||||
color: #455971;
|
||||
|
||||
@@ -71,6 +71,22 @@ QWidget {
|
||||
color: #4d4940;
|
||||
}
|
||||
|
||||
/* Style QTreeWidget checkboxes */
|
||||
QTreeWidget::indicator {
|
||||
border: 0.05em solid #4d4940;
|
||||
}
|
||||
QTreeWidget::indicator::unchecked {
|
||||
background-color: #b3ac98;
|
||||
}
|
||||
QTreeWidget::indicator::checked {
|
||||
background-color: #4d4940;
|
||||
}
|
||||
QTreeWidget::indicator::disabled {
|
||||
background-color: #828790;
|
||||
}
|
||||
QTreeWidget::item::selected {
|
||||
color: #4d4940;
|
||||
}
|
||||
|
||||
/* Mouse Tooltips */
|
||||
QToolTip {
|
||||
@@ -80,14 +96,8 @@ QToolTip {
|
||||
}
|
||||
|
||||
|
||||
/* CG Disasm and Trophy Manager: background-image doesn't work, use static color */
|
||||
QWidget#cg_disasm, QWidget#trophy_manager {
|
||||
background: #b3ac98;
|
||||
}
|
||||
|
||||
|
||||
/* Main Window and Dialogs */
|
||||
QDialog, QMainWindow#main_window {
|
||||
/* Main Window, Dialogs and some Dialogs that are actually widgets */
|
||||
QDialog, QWidget#trophy_manager, QWidget#cg_disasm, QMainWindow#main_window {
|
||||
border-image: url("GuiConfigs/YoRHa-background.jpg");
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
Regular → Executable
Regular → Executable
@@ -26,6 +26,9 @@
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
@@ -41,31 +44,25 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<NMakePreprocessorDefinitions>
|
||||
</NMakePreprocessorDefinitions>
|
||||
<NMakeBuildCommandLine>
|
||||
$(CmakeCLI)
|
||||
<NMakeBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
$(CmakeCLI)
|
||||
<NMakeReBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
$(CmakeCLI)
|
||||
<NMakeCleanCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakePreprocessorDefinitions />
|
||||
<NMakeBuildCommandLine>
|
||||
$(CmakeCLI)
|
||||
<NMakeBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
$(CmakeCLI)
|
||||
<NMakeReBuildCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
$(CmakeCLI)
|
||||
<NMakeCleanCommandLine>$(CmakeCLI)
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /p:ForceImportBeforeCppTargets=$(SolutionDir)common_default.props /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -93,6 +93,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "3rdparty\libcurl
|
||||
{73973223-5EE8-41CA-8E88-1D60E89A237B} = {73973223-5EE8-41CA-8E88-1D60E89A237B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spirv-tools-build", "Vulkan\spirv-tools-build\spirv-tools-build.vcxproj", "{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug - LLVM|x64 = Debug - LLVM|x64
|
||||
@@ -281,6 +283,11 @@ Global
|
||||
{DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.Release - LLVM|x64.Build.0 = Release - LLVM|x64
|
||||
{DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.Release|x64.ActiveCfg = Release|x64
|
||||
{DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.Release|x64.Build.0 = Release|x64
|
||||
{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}.Debug - LLVM|x64.ActiveCfg = Debug|x64
|
||||
{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
|
||||
{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}.Release - LLVM|x64.ActiveCfg = Release|x64
|
||||
{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}.Release|x64.ActiveCfg = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -304,6 +311,7 @@ Global
|
||||
{5B146DEA-9ACE-4D32-A7FD-3F42464DD69C} = {CB3DD03E-074E-4FA5-B253-51A3372D1768}
|
||||
{73973223-5EE8-41CA-8E88-1D60E89A237B} = {6DA34724-E5B2-4306-906D-1A2340637047}
|
||||
{DA6F56B4-06A4-441D-AD70-AC5A7D51FADB} = {BE02DA0B-BEE1-4214-AFA9-3617982F2FEA}
|
||||
{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1} = {B0AC29FD-7B01-4B5E-9C8D-0A081E4C5668}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {06CC7920-E085-4B81-9582-8DE8AAD42510}
|
||||
|
||||
@@ -83,7 +83,7 @@ set_target_properties(rpcs3
|
||||
AUTOUIC ON)
|
||||
|
||||
target_link_libraries(rpcs3 rpcs3_emu rpcs3_ui)
|
||||
target_link_libraries(rpcs3 3rdparty::discord-rpc 3rdparty::qt5 3rdparty::hidapi 3rdparty::libusb)
|
||||
target_link_libraries(rpcs3 3rdparty::discord-rpc 3rdparty::qt5 3rdparty::hidapi 3rdparty::libusb 3rdparty::wolfssl)
|
||||
target_link_libraries(rpcs3 ${ADDITIONAL_LIBS})
|
||||
|
||||
# Win resource file
|
||||
|
||||
+57
-75
@@ -2,10 +2,14 @@
|
||||
#include "key_vault.h"
|
||||
#include "unedat.h"
|
||||
|
||||
#include "Utilities/mutex.h"
|
||||
#include <cmath>
|
||||
|
||||
LOG_CHANNEL(edat_log, "EDAT");
|
||||
|
||||
// Static variables are being modified concurrently in ec.cpp, for now use a mutex
|
||||
static shared_mutex ec_mtx;
|
||||
|
||||
void generate_key(int crypto_mode, int version, unsigned char *key_final, unsigned char *iv_final, unsigned char *key, unsigned char *iv)
|
||||
{
|
||||
int mode = crypto_mode & 0xF0000000;
|
||||
@@ -131,15 +135,15 @@ std::tuple<u64, s32, s32> dec_section(unsigned char* metadata)
|
||||
return std::make_tuple(offset, length, compression_end);
|
||||
}
|
||||
|
||||
std::array<u8, 0x10> get_block_key(int block, NPD_HEADER *npd)
|
||||
v128 get_block_key(int block, NPD_HEADER *npd)
|
||||
{
|
||||
unsigned char empty_key[0x10] = {};
|
||||
unsigned char *src_key = (npd->version <= 1) ? empty_key : npd->dev_hash;
|
||||
std::array<u8, 0x10> dest_key{};
|
||||
memcpy(dest_key.data(), src_key, 0xC);
|
||||
v128 dest_key{};
|
||||
memcpy(dest_key._bytes, src_key, 0xC);
|
||||
|
||||
s32 swappedBlock = swap32(block);
|
||||
memcpy(&dest_key[0xC], &swappedBlock, sizeof(swappedBlock));
|
||||
memcpy(&dest_key._bytes[0xC], &swappedBlock, sizeof(swappedBlock));
|
||||
return dest_key;
|
||||
}
|
||||
|
||||
@@ -241,10 +245,10 @@ s64 decrypt_block(const fs::file* in, u8* out, EDAT_HEADER *edat, NPD_HEADER *np
|
||||
in->read(enc_data.get(), length);
|
||||
|
||||
// Generate a key for the current block.
|
||||
std::array<u8, 0x10> b_key = get_block_key(block_num, npd);
|
||||
auto b_key = get_block_key(block_num, npd);
|
||||
|
||||
// Encrypt the block key with the crypto key.
|
||||
aesecb128_encrypt(crypt_key, b_key.data(), key_result);
|
||||
aesecb128_encrypt(crypt_key, b_key._bytes, key_result);
|
||||
if ((edat->flags & EDAT_FLAG_0x10) != 0)
|
||||
aesecb128_encrypt(crypt_key, key_result, hash); // If FLAG 0x10 is set, encrypt again to get the final hash.
|
||||
else
|
||||
@@ -468,6 +472,8 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
|
||||
unsigned char signature_s[0x15] = { 0 };
|
||||
unsigned char zero_buf[0x15] = { 0 };
|
||||
|
||||
std::lock_guard lock(ec_mtx);
|
||||
|
||||
// Setup ECDSA curve and public key.
|
||||
ecdsa_set_curve(VSH_CURVE_P, VSH_CURVE_A, VSH_CURVE_B, VSH_CURVE_N, VSH_CURVE_GX, VSH_CURVE_GY);
|
||||
ecdsa_set_pub(VSH_PUB);
|
||||
@@ -518,10 +524,10 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
|
||||
{
|
||||
// Setup header signature hash.
|
||||
memset(signature_hash, 0, 20);
|
||||
std::unique_ptr<u8[]> header_buf(new u8[0xD8]);
|
||||
u8 header_buf[0xD8];
|
||||
f->seek(file_offset);
|
||||
f->read(header_buf.get(), 0xD8);
|
||||
sha1(header_buf.get(), 0xD8, signature_hash );
|
||||
f->read(header_buf, 0xD8);
|
||||
sha1(header_buf, 0xD8, signature_hash);
|
||||
|
||||
if (!ecdsa_verify(signature_hash, signature_r, signature_s))
|
||||
edat_log.warning("EDAT: Header signature is invalid!");
|
||||
@@ -534,7 +540,6 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
|
||||
int validate_dev_klic(const u8* klicensee, NPD_HEADER *npd)
|
||||
{
|
||||
unsigned char dev[0x60] = { 0 };
|
||||
unsigned char key[0x10] = { 0 };
|
||||
|
||||
// Build the dev buffer (first 0x60 bytes of NPD header in big-endian).
|
||||
memcpy(dev, npd, 0x60);
|
||||
@@ -548,17 +553,9 @@ int validate_dev_klic(const u8* klicensee, NPD_HEADER *npd)
|
||||
memcpy(dev + 0xC, &type, 4);
|
||||
|
||||
// Check for an empty dev_hash (can't validate if devklic is NULL);
|
||||
bool isDevklicEmpty = true;
|
||||
for (int i = 0; i < 0x10; i++)
|
||||
{
|
||||
if (klicensee[i] != 0)
|
||||
{
|
||||
isDevklicEmpty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto klic = v128::loadu(klicensee);
|
||||
|
||||
if (isDevklicEmpty)
|
||||
if (klic == v128{})
|
||||
{
|
||||
// Allow empty dev hash.
|
||||
return 1;
|
||||
@@ -566,10 +563,10 @@ int validate_dev_klic(const u8* klicensee, NPD_HEADER *npd)
|
||||
else
|
||||
{
|
||||
// Generate klicensee xor key.
|
||||
xor_key(key, klicensee, NP_OMAC_KEY_2);
|
||||
auto key = klic ^ std::bit_cast<v128>(NP_OMAC_KEY_2);
|
||||
|
||||
// Hash with generated key and compare with dev_hash.
|
||||
return cmac_hash_compare(key, 0x10, dev, 0x60, npd->dev_hash, 0x10);
|
||||
return cmac_hash_compare(key._bytes, 0x10, dev, 0x60, npd->dev_hash, 0x10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -650,7 +647,7 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char*
|
||||
}
|
||||
|
||||
// Set decryption key.
|
||||
u8 key[0x10] = { 0 };
|
||||
v128 key{};
|
||||
|
||||
// Check EDAT/SDAT flag.
|
||||
if ((EDAT.flags & SDAT_FLAG) == SDAT_FLAG)
|
||||
@@ -664,7 +661,7 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char*
|
||||
}
|
||||
|
||||
// Generate SDAT key.
|
||||
xor_key(key, NPD.dev_hash, SDAT_KEY);
|
||||
key = std::bit_cast<v128>(NPD.dev_hash) ^ std::bit_cast<v128>(SDAT_KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -691,23 +688,13 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char*
|
||||
|
||||
// Select EDAT key.
|
||||
if ((NPD.license & 0x3) == 0x3) // Type 3: Use supplied devklic.
|
||||
memcpy(key, devklic, 0x10);
|
||||
memcpy(&key, devklic, 0x10);
|
||||
else if ((NPD.license & 0x2) == 0x2) // Type 2: Use key from RAP file (RIF key).
|
||||
{
|
||||
memcpy(key, rifkey, 0x10);
|
||||
memcpy(&key, rifkey, 0x10);
|
||||
|
||||
// Make sure we don't have an empty RIF key.
|
||||
int i, test = 0;
|
||||
for (i = 0; i < 0x10; i++)
|
||||
{
|
||||
if (key[i] != 0)
|
||||
{
|
||||
test = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!test)
|
||||
if (key == v128{})
|
||||
{
|
||||
edat_log.error("EDAT: A valid RAP file is needed for this EDAT file!");
|
||||
return 1;
|
||||
@@ -721,34 +708,29 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char*
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
int i;
|
||||
edat_log.notice("DEVKLIC: ");
|
||||
for (i = 0; i < 0x10; i++)
|
||||
edat_log.notice("%02X", devklic[i]);
|
||||
be_t<v128> data;
|
||||
|
||||
edat_log.notice("RIF KEY: ");
|
||||
for (i = 0; i < 0x10; i++)
|
||||
edat_log.notice("%02X", rifkey[i]);
|
||||
std::memcpy(&data, devklic, sizeof(data));
|
||||
edat_log.notice("DEVKLIC: %s", data);
|
||||
std::memcpy(&data, rifkey, sizeof(data));
|
||||
edat_log.notice("RIF KEY: %s", data);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
int i;
|
||||
edat_log.notice("DECRYPTION KEY: ");
|
||||
for (i = 0; i < 0x10; i++)
|
||||
edat_log.notice("%02X", key[i]);
|
||||
edat_log.notice("DECRYPTION KEY: %s", std::bit_cast<be_t<v128>>(key));
|
||||
}
|
||||
|
||||
input->seek(0);
|
||||
if (check_data(key, &EDAT, &NPD, input, verbose))
|
||||
if (check_data(key._bytes, &EDAT, &NPD, input, verbose))
|
||||
{
|
||||
edat_log.error("EDAT: Data parsing failed!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
input->seek(0);
|
||||
if (decrypt_data(input, output, &EDAT, &NPD, key, verbose))
|
||||
if (decrypt_data(input, output, &EDAT, &NPD, key._bytes, verbose))
|
||||
{
|
||||
edat_log.error("EDAT: Data decryption failed!");
|
||||
return 1;
|
||||
@@ -757,19 +739,19 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char*
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::array<u8, 0x10> GetEdatRifKeyFromRapFile(const fs::file& rap_file)
|
||||
v128 GetEdatRifKeyFromRapFile(const fs::file& rap_file)
|
||||
{
|
||||
std::array<u8, 0x10> rapkey{ 0 };
|
||||
std::array<u8, 0x10> rifkey{ 0 };
|
||||
v128 rapkey{};
|
||||
v128 rifkey{};
|
||||
|
||||
rap_file.read<std::array<u8, 0x10>>(rapkey);
|
||||
rap_file.read<v128>(rapkey);
|
||||
|
||||
rap_to_rif(rapkey.data(), rifkey.data());
|
||||
rap_to_rif(rapkey._bytes, rifkey._bytes);
|
||||
|
||||
return rifkey;
|
||||
}
|
||||
|
||||
bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const std::array<u8, 0x10>& custom_klic, std::string* contentID)
|
||||
bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const u8* custom_klic, std::string* contentID)
|
||||
{
|
||||
// Setup NPD and EDAT/SDAT structs.
|
||||
NPD_HEADER NPD;
|
||||
@@ -794,7 +776,7 @@ bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& inpu
|
||||
// Perform header validation (EDAT only).
|
||||
char real_file_name[MAX_PATH];
|
||||
extract_file_name(input_file_name.c_str(), real_file_name);
|
||||
if (!validate_npd_hashes(real_file_name, custom_klic.data(), &NPD, false))
|
||||
if (!validate_npd_hashes(real_file_name, custom_klic, &NPD, false))
|
||||
{
|
||||
// Ignore header validation in DEBUG data.
|
||||
if ((EDAT.flags & EDAT_DEBUG_DATA_FLAG) != EDAT_DEBUG_DATA_FLAG)
|
||||
@@ -815,8 +797,8 @@ fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name,
|
||||
input.seek(0);
|
||||
|
||||
// Set keys (RIF and DEVKLIC).
|
||||
std::array<u8, 0x10> rifKey{ 0 };
|
||||
unsigned char devklic[0x10] = { 0 };
|
||||
v128 rifKey{};
|
||||
v128 devklic{};
|
||||
|
||||
// Select the EDAT key mode.
|
||||
switch (mode)
|
||||
@@ -824,30 +806,30 @@ fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name,
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
memcpy(devklic, NP_KLIC_FREE, 0x10);
|
||||
memcpy(&devklic, NP_KLIC_FREE, 0x10);
|
||||
break;
|
||||
case 2:
|
||||
memcpy(devklic, NP_OMAC_KEY_2, 0x10);
|
||||
memcpy(&devklic, NP_OMAC_KEY_2, 0x10);
|
||||
break;
|
||||
case 3:
|
||||
memcpy(devklic, NP_OMAC_KEY_3, 0x10);
|
||||
memcpy(&devklic, NP_OMAC_KEY_3, 0x10);
|
||||
break;
|
||||
case 4:
|
||||
memcpy(devklic, NP_KLIC_KEY, 0x10);
|
||||
memcpy(&devklic, NP_KLIC_KEY, 0x10);
|
||||
break;
|
||||
case 5:
|
||||
memcpy(devklic, NP_PSX_KEY, 0x10);
|
||||
memcpy(&devklic, NP_PSX_KEY, 0x10);
|
||||
break;
|
||||
case 6:
|
||||
memcpy(devklic, NP_PSP_KEY_1, 0x10);
|
||||
memcpy(&devklic, NP_PSP_KEY_1, 0x10);
|
||||
break;
|
||||
case 7:
|
||||
memcpy(devklic, NP_PSP_KEY_2, 0x10);
|
||||
memcpy(&devklic, NP_PSP_KEY_2, 0x10);
|
||||
break;
|
||||
case 8:
|
||||
{
|
||||
if (custom_klic != NULL)
|
||||
memcpy(devklic, custom_klic, 0x10);
|
||||
memcpy(&devklic, custom_klic, 0x10);
|
||||
else
|
||||
{
|
||||
edat_log.error("EDAT: Invalid custom klic!");
|
||||
@@ -870,7 +852,7 @@ fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name,
|
||||
|
||||
// Delete the bad output file if any errors arise.
|
||||
fs::file output = fs::make_stream<std::vector<u8>>();
|
||||
if (extract_all_data(&input, &output, input_file_name.c_str(), devklic, rifKey.data(), verbose))
|
||||
if (extract_all_data(&input, &output, input_file_name.c_str(), devklic._bytes, rifKey._bytes, verbose))
|
||||
{
|
||||
output.release();
|
||||
return fs::file{};
|
||||
@@ -896,12 +878,12 @@ bool EDATADecrypter::ReadHeader()
|
||||
if ((edatHeader.flags & SDAT_FLAG) == SDAT_FLAG)
|
||||
{
|
||||
// Generate SDAT key.
|
||||
xor_key(dec_key.data(), npdHeader.dev_hash, SDAT_KEY);
|
||||
dec_key = std::bit_cast<v128>(npdHeader.dev_hash) ^ std::bit_cast<v128>(SDAT_KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// verify key
|
||||
if (validate_dev_klic(dev_key.data(), &npdHeader) == 0)
|
||||
if (validate_dev_klic(dev_key._bytes, &npdHeader) == 0)
|
||||
{
|
||||
edat_log.error("EDAT: Failed validating klic");
|
||||
return false;
|
||||
@@ -914,7 +896,7 @@ bool EDATADecrypter::ReadHeader()
|
||||
{
|
||||
dec_key = std::move(rif_key);
|
||||
|
||||
if (dec_key == std::array<u8, 0x10>{0})
|
||||
if (dec_key == v128{})
|
||||
{
|
||||
edat_log.warning("EDAT: Empty Dec key!");
|
||||
}
|
||||
@@ -931,13 +913,13 @@ bool EDATADecrypter::ReadHeader()
|
||||
// k the ecdsa_verify function in this check_data function takes a ridiculous amount of time
|
||||
// like it slows down load time by a factor of x20, at least, so its ignored for now
|
||||
|
||||
/*if (check_data(dec_key.data(), &edatHeader, &npdHeader, &sdata_file, false))
|
||||
/*if (check_data(dec_key._bytes, &edatHeader, &npdHeader, &sdata_file, false))
|
||||
{
|
||||
return false;
|
||||
}*/
|
||||
|
||||
file_size = edatHeader.file_size;
|
||||
total_blocks = static_cast<u32>((edatHeader.file_size + edatHeader.block_size - 1) / edatHeader.block_size);
|
||||
total_blocks = ::aligned_div(edatHeader.file_size, edatHeader.block_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -950,7 +932,7 @@ u64 EDATADecrypter::ReadData(u64 pos, u8* data, u64 size)
|
||||
// now we need to offset things to account for the actual 'range' requested
|
||||
const u64 startOffset = pos % edatHeader.block_size;
|
||||
|
||||
const u32 num_blocks = static_cast<u32>(std::ceil((startOffset + size) / (0. + edatHeader.block_size)));
|
||||
const u32 num_blocks = static_cast<u32>(::aligned_div(startOffset + size, edatHeader.block_size));
|
||||
const u64 bufSize = num_blocks*edatHeader.block_size;
|
||||
if (data_buf_size < (bufSize))
|
||||
{
|
||||
@@ -965,7 +947,7 @@ u64 EDATADecrypter::ReadData(u64 pos, u8* data, u64 size)
|
||||
for (u32 i = starting_block; i < ending_block; ++i)
|
||||
{
|
||||
edata_file.seek(0);
|
||||
u64 res = decrypt_block(&edata_file, &data_buf[writeOffset], &edatHeader, &npdHeader, dec_key.data(), i, total_blocks, edatHeader.file_size);
|
||||
u64 res = decrypt_block(&edata_file, &data_buf[writeOffset], &edatHeader, &npdHeader, dec_key._bytes, i, total_blocks, edatHeader.file_size);
|
||||
if (res == umax)
|
||||
{
|
||||
edat_log.error("Error Decrypting data");
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "Utilities/BEType.h"
|
||||
#include "Utilities/File.h"
|
||||
|
||||
constexpr u32 SDAT_FLAG = 0x01000000;
|
||||
@@ -16,8 +17,8 @@ constexpr u32 EDAT_DEBUG_DATA_FLAG = 0x80000000;
|
||||
|
||||
struct loaded_npdrm_keys
|
||||
{
|
||||
std::array<u8, 0x10> devKlic{};
|
||||
std::array<u8, 0x10> rifKey{};
|
||||
atomic_t<v128> devKlic{};
|
||||
atomic_t<v128> rifKey{};
|
||||
atomic_t<u32> npdrm_fds{0};
|
||||
};
|
||||
|
||||
@@ -45,9 +46,9 @@ struct EDAT_HEADER
|
||||
// Decrypts full file, or null/empty file
|
||||
extern fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name, int mode, const std::string& rap_file_name, u8 *custom_klic, bool verbose);
|
||||
|
||||
extern bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const std::array<u8,0x10>& custom_klic, std::string* contentID);
|
||||
extern bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const u8* custom_klic, std::string* contentID);
|
||||
|
||||
extern std::array<u8, 0x10> GetEdatRifKeyFromRapFile(const fs::file& rap_file);
|
||||
v128 GetEdatRifKeyFromRapFile(const fs::file& rap_file);
|
||||
|
||||
struct EDATADecrypter final : fs::file_base
|
||||
{
|
||||
@@ -64,17 +65,17 @@ struct EDATADecrypter final : fs::file_base
|
||||
std::unique_ptr<u8[]> data_buf;
|
||||
u64 data_buf_size{0};
|
||||
|
||||
std::array<u8, 0x10> dec_key{};
|
||||
v128 dec_key{};
|
||||
|
||||
// edat usage
|
||||
std::array<u8, 0x10> rif_key{};
|
||||
std::array<u8, 0x10> dev_key{};
|
||||
v128 rif_key{};
|
||||
v128 dev_key{};
|
||||
public:
|
||||
// SdataByFd usage
|
||||
EDATADecrypter(fs::file&& input)
|
||||
: edata_file(std::move(input)) {}
|
||||
// Edat usage
|
||||
EDATADecrypter(fs::file&& input, const std::array<u8, 0x10>& dev_key, const std::array<u8, 0x10>& rif_key)
|
||||
EDATADecrypter(fs::file&& input, const v128& dev_key, const v128& rif_key)
|
||||
: edata_file(std::move(input)), rif_key(rif_key), dev_key(dev_key) {}
|
||||
|
||||
~EDATADecrypter() override {}
|
||||
|
||||
+40
-9
@@ -535,7 +535,7 @@ package_error package_reader::check_target_app_version()
|
||||
const auto category = psf::get_string(psf, "CATEGORY", "");
|
||||
const auto title_id = psf::get_string(psf, "TITLE_ID", "");
|
||||
const auto app_ver = psf::get_string(psf, "APP_VER", "");
|
||||
auto target_app_ver = psf::get_string(psf, "TARGET_APP_VER", "");
|
||||
const auto target_app_ver = psf::get_string(psf, "TARGET_APP_VER", "");
|
||||
|
||||
if (category != "GD")
|
||||
{
|
||||
@@ -561,7 +561,7 @@ package_error package_reader::check_target_app_version()
|
||||
return package_error::no_error;
|
||||
}
|
||||
|
||||
const fs::file installed_sfo_file(Emu.GetHddDir() + "game/" + title_id + "/PARAM.SFO");
|
||||
const fs::file installed_sfo_file(Emu.GetHddDir() + "game/" + std::string(title_id) + "/PARAM.SFO");
|
||||
if (!installed_sfo_file)
|
||||
{
|
||||
if (!target_app_ver.empty())
|
||||
@@ -587,9 +587,9 @@ package_error package_reader::check_target_app_version()
|
||||
}
|
||||
|
||||
std::add_pointer_t<char> ev0, ev1;
|
||||
const double old_version = std::strtod(installed_app_ver.c_str(), &ev0);
|
||||
const double old_version = std::strtod(installed_app_ver.data(), &ev0);
|
||||
|
||||
if (installed_app_ver.c_str() + installed_app_ver.size() != ev0)
|
||||
if (installed_app_ver.data() + installed_app_ver.size() != ev0)
|
||||
{
|
||||
pkg_log.error("Failed to convert the installed app version to double (%s)", installed_app_ver);
|
||||
return package_error::other;
|
||||
@@ -599,9 +599,9 @@ package_error package_reader::check_target_app_version()
|
||||
{
|
||||
// This is most likely the first patch. Let's make sure its version is high enough for the installed game.
|
||||
|
||||
const double new_version = std::strtod(app_ver.c_str(), &ev1);
|
||||
const double new_version = std::strtod(app_ver.data(), &ev1);
|
||||
|
||||
if (app_ver.c_str() + app_ver.size() != ev1)
|
||||
if (app_ver.data() + app_ver.size() != ev1)
|
||||
{
|
||||
pkg_log.error("Failed to convert the package's app version to double (%s)", app_ver);
|
||||
return package_error::other;
|
||||
@@ -619,9 +619,9 @@ package_error package_reader::check_target_app_version()
|
||||
|
||||
// Check if the installed app version matches the target app version
|
||||
|
||||
const double target_version = std::strtod(target_app_ver.c_str(), &ev1);
|
||||
const double target_version = std::strtod(target_app_ver.data(), &ev1);
|
||||
|
||||
if (target_app_ver.c_str() + target_app_ver.size() != ev1)
|
||||
if (target_app_ver.data() + target_app_ver.size() != ev1)
|
||||
{
|
||||
pkg_log.error("Failed to convert the package's target app version to double (%s)", target_app_ver);
|
||||
return package_error::other;
|
||||
@@ -652,7 +652,36 @@ bool package_reader::extract_data(atomic_t<double>& sync)
|
||||
}
|
||||
|
||||
// Get full path and create the directory
|
||||
const std::string dir = Emulator::GetHddDir() + "game/" + install_dir + '/';
|
||||
std::string dir = Emulator::GetHddDir();
|
||||
|
||||
// Based on https://www.psdevwiki.com/ps3/PKG_files#ContentType
|
||||
switch (metadata.content_type)
|
||||
{
|
||||
case PKG_CONTENT_TYPE_THEME:
|
||||
dir += "theme/";
|
||||
break;
|
||||
case PKG_CONTENT_TYPE_WIDGET:
|
||||
dir += "widget/";
|
||||
break;
|
||||
case PKG_CONTENT_TYPE_LICENSE:
|
||||
dir += "home/" + Emu.GetUsr() + "/exdata/";
|
||||
break;
|
||||
case PKG_CONTENT_TYPE_VSH_MODULE:
|
||||
dir += "vsh/modules/";
|
||||
break;
|
||||
case PKG_CONTENT_TYPE_PSN_AVATAR:
|
||||
dir += "home/" + Emu.GetUsr() + "/psn_avatar/";
|
||||
break;
|
||||
case PKG_CONTENT_TYPE_VMC:
|
||||
dir += "tmp/vmc/";
|
||||
break;
|
||||
// TODO: Find out if other content types are installed elsewhere
|
||||
default:
|
||||
dir += "game/";
|
||||
break;
|
||||
}
|
||||
|
||||
dir += install_dir + '/';
|
||||
|
||||
// If false, an existing directory is being overwritten: cannot cancel the operation
|
||||
const bool was_null = !fs::is_dir(dir);
|
||||
@@ -843,6 +872,8 @@ void package_reader::archive_seek(const s64 new_offset, const fs::seek_mode damo
|
||||
|
||||
u64 package_reader::archive_read(void* data_ptr, const u64 num_bytes)
|
||||
{
|
||||
ASSERT(filelist.size() > cur_file && filelist[cur_file]);
|
||||
|
||||
const u64 num_bytes_left = filelist[cur_file].size() - cur_file_offset;
|
||||
|
||||
// check if it continues in another file
|
||||
|
||||
@@ -34,6 +34,41 @@ enum : u32
|
||||
PKG_FILE_ENTRY_PSP = 0x10000000,
|
||||
};
|
||||
|
||||
enum : u32
|
||||
{
|
||||
PKG_CONTENT_TYPE_UNKNOWN_1 = 0x01, // ?
|
||||
PKG_CONTENT_TYPE_UNKNOWN_2 = 0x02, // ?
|
||||
PKG_CONTENT_TYPE_UNKNOWN_3 = 0x03, // ?
|
||||
PKG_CONTENT_TYPE_GAME_DATA = 0x04, // GameData (also patches)
|
||||
PKG_CONTENT_TYPE_GAME_EXEC = 0x05, // GameExec
|
||||
PKG_CONTENT_TYPE_PS1_EMU = 0x06, // PS1emu
|
||||
PKG_CONTENT_TYPE_PC_ENGINE = 0x07, // PSP & PCEngine
|
||||
PKG_CONTENT_TYPE_UNKNOWN_4 = 0x08, // ?
|
||||
PKG_CONTENT_TYPE_THEME = 0x09, // Theme
|
||||
PKG_CONTENT_TYPE_WIDGET = 0x0A, // Widget
|
||||
PKG_CONTENT_TYPE_LICENSE = 0x0B, // License
|
||||
PKG_CONTENT_TYPE_VSH_MODULE = 0x0C, // VSHModule
|
||||
PKG_CONTENT_TYPE_PSN_AVATAR = 0x0D, // PSN Avatar
|
||||
PKG_CONTENT_TYPE_PSP_GO = 0x0E, // PSPgo
|
||||
PKG_CONTENT_TYPE_MINIS = 0x0F, // Minis
|
||||
PKG_CONTENT_TYPE_NEOGEO = 0x10, // NEOGEO
|
||||
PKG_CONTENT_TYPE_VMC = 0x11, // VMC
|
||||
PKG_CONTENT_TYPE_PS2_CLASSIC = 0x12, // ?PS2Classic? Seen on PS2 classic
|
||||
PKG_CONTENT_TYPE_UNKNOWN_5 = 0x13, // ?
|
||||
PKG_CONTENT_TYPE_PSP_REMASTERED = 0x14, // ?
|
||||
PKG_CONTENT_TYPE_PSP2_GD = 0x15, // PSVita Game Data
|
||||
PKG_CONTENT_TYPE_PSP2_AC = 0x16, // PSVita Additional Content
|
||||
PKG_CONTENT_TYPE_PSP2_LA = 0x17, // PSVita LiveArea
|
||||
PKG_CONTENT_TYPE_PSM_1 = 0x18, // PSVita PSM ?
|
||||
PKG_CONTENT_TYPE_WT = 0x19, // Web TV ?
|
||||
PKG_CONTENT_TYPE_UNKNOWN_6 = 0x1A, // ?
|
||||
PKG_CONTENT_TYPE_UNKNOWN_7 = 0x1B, // ?
|
||||
PKG_CONTENT_TYPE_UNKNOWN_8 = 0x1C, // ?
|
||||
PKG_CONTENT_TYPE_PSM_2 = 0x1D, // PSVita PSM ?
|
||||
PKG_CONTENT_TYPE_UNKNOWN_9 = 0x1E, // ?
|
||||
PKG_CONTENT_TYPE_PSP2_THEME = 0x1F, // PSVita Theme
|
||||
};
|
||||
|
||||
// Structs
|
||||
struct PKGHeader
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "sha1.h"
|
||||
#include "utils.h"
|
||||
#include "unself.h"
|
||||
#include "Utilities/BEType.h"
|
||||
#include "Emu/VFS.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
@@ -1483,9 +1484,7 @@ bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::array<u8, 0x10> get_default_self_klic()
|
||||
v128 get_default_self_klic()
|
||||
{
|
||||
std::array<u8, 0x10> key;
|
||||
std::copy(std::begin(NP_KLIC_FREE), std::end(NP_KLIC_FREE), std::begin(key));
|
||||
return key;
|
||||
return std::bit_cast<v128>(NP_KLIC_FREE);
|
||||
}
|
||||
|
||||
@@ -508,4 +508,6 @@ private:
|
||||
|
||||
fs::file decrypt_self(fs::file elf_or_self, u8* klic_key = nullptr, SelfAdditionalInfo* additional_info = nullptr);
|
||||
bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key = nullptr);
|
||||
std::array<u8, 0x10> get_default_self_klic();
|
||||
|
||||
union v128;
|
||||
v128 get_default_self_klic();
|
||||
|
||||
@@ -15,14 +15,6 @@
|
||||
|
||||
// Auxiliary functions (endian swap, xor).
|
||||
|
||||
void xor_key(unsigned char *dest, const u8* src1, const u8* src2)
|
||||
{
|
||||
for(int i = 0; i < 0x10; i++)
|
||||
{
|
||||
dest[i] = src1[i] ^ src2[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Hex string conversion auxiliary functions.
|
||||
u64 hex_to_u64(const char* hex_str)
|
||||
{
|
||||
@@ -67,22 +59,6 @@ void hex_to_bytes(unsigned char* data, const char* hex_str, unsigned int str_len
|
||||
}
|
||||
}
|
||||
|
||||
bool is_hex(const char* hex_str, unsigned int str_length)
|
||||
{
|
||||
static const char hex_chars[] = "0123456789abcdefABCDEF";
|
||||
|
||||
if (hex_str == NULL)
|
||||
return false;
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < str_length; i++)
|
||||
{
|
||||
if (strchr(hex_chars, hex_str[i]) == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Crypto functions (AES128-CBC, AES128-ECB, SHA1-HMAC and AES-CMAC).
|
||||
void aescbc128_decrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, int len)
|
||||
|
||||
@@ -42,19 +42,11 @@ inline u64 swap64(u64 i)
|
||||
#endif
|
||||
}
|
||||
|
||||
void xor_key(unsigned char *dest, const u8* src1, const u8* src2);
|
||||
inline void xor_key_sse(u8* dest, const u8* src1, const u8* src2)
|
||||
{
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i*>(dest),
|
||||
_mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src1)), _mm_loadu_si128(reinterpret_cast<const __m128i*>(src2))));
|
||||
}
|
||||
|
||||
char* extract_file_name(const char* file_path, char real_file_name[MAX_PATH]);
|
||||
|
||||
// Hex string conversion auxiliary functions.
|
||||
u64 hex_to_u64(const char* hex_str);
|
||||
void hex_to_bytes(unsigned char *data, const char *hex_str, unsigned int str_length);
|
||||
bool is_hex(const char* hex_str, unsigned int str_length);
|
||||
|
||||
// Crypto functions (AES128-CBC, AES128-ECB, SHA1-HMAC and AES-CMAC).
|
||||
void aescbc128_decrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, int len);
|
||||
|
||||
@@ -12,8 +12,7 @@ LOG_CHANNEL(OpenAL);
|
||||
#define checkForAlcError(sit) do { ALCenum g_last_alc_error = alcGetError(m_device); if(g_last_alc_error != ALC_NO_ERROR) { OpenAL.error("%s: OpenALC error 0x%04x", sit, g_last_alc_error); return; }} while(0)
|
||||
|
||||
OpenALBackend::OpenALBackend()
|
||||
: m_sampling_rate(get_sampling_rate())
|
||||
, m_sample_size(get_sample_size())
|
||||
: AudioBackend()
|
||||
{
|
||||
ALCdevice* m_device = alcOpenDevice(nullptr);
|
||||
checkForAlcError("alcOpenDevice");
|
||||
@@ -24,13 +23,17 @@ OpenALBackend::OpenALBackend()
|
||||
alcMakeContextCurrent(m_context);
|
||||
checkForAlcError("alcMakeContextCurrent");
|
||||
|
||||
if (get_channels() == 2)
|
||||
switch (m_channels)
|
||||
{
|
||||
case 2:
|
||||
m_format = (m_sample_size == 2) ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO_FLOAT32;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
case 6:
|
||||
m_format = (m_sample_size == 2) ? AL_FORMAT_51CHN16 : AL_FORMAT_51CHN32;
|
||||
break;
|
||||
default:
|
||||
m_format = (m_sample_size == 2) ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@ private:
|
||||
u32 m_next_buffer = 0;
|
||||
u32 m_num_unqueued = 0;
|
||||
|
||||
const u32 m_sampling_rate;
|
||||
const u32 m_sample_size;
|
||||
|
||||
void unqueue_processed();
|
||||
|
||||
public:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef HAVE_ALSA
|
||||
#ifndef HAVE_ALSA
|
||||
#error "ALSA support disabled but still being built."
|
||||
#endif
|
||||
|
||||
@@ -26,6 +26,7 @@ static bool check(int err, const char* reason)
|
||||
}
|
||||
|
||||
ALSABackend::ALSABackend()
|
||||
: AudioBackend()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -51,14 +52,14 @@ void ALSABackend::Open(u32 num_buffers)
|
||||
if (!check(snd_pcm_hw_params_set_access(tls_handle, tls_hw_params, SND_PCM_ACCESS_RW_INTERLEAVED), "snd_pcm_hw_params_set_access"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_format(tls_handle, tls_hw_params, g_cfg.audio.convert_to_u16 ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_FLOAT_LE), "snd_pcm_hw_params_set_format"))
|
||||
if (!check(snd_pcm_hw_params_set_format(tls_handle, tls_hw_params, m_convert_to_u16 ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_FLOAT_LE), "snd_pcm_hw_params_set_format"))
|
||||
return;
|
||||
|
||||
uint rate = get_sampling_rate();
|
||||
uint rate = m_sampling_rate;
|
||||
if (!check(snd_pcm_hw_params_set_rate_near(tls_handle, tls_hw_params, &rate, nullptr), "snd_pcm_hw_params_set_rate_near"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_channels(tls_handle, tls_hw_params, get_channels()), "snd_pcm_hw_params_set_channels"))
|
||||
if (!check(snd_pcm_hw_params_set_channels(tls_handle, tls_hw_params, m_channels), "snd_pcm_hw_params_set_channels"))
|
||||
return;
|
||||
|
||||
//uint period = 5333;
|
||||
@@ -92,7 +93,7 @@ void ALSABackend::Open(u32 num_buffers)
|
||||
if (!check(snd_pcm_sw_params_current(tls_handle, tls_sw_params), "snd_pcm_sw_params_current"))
|
||||
return;
|
||||
|
||||
period_frames *= g_cfg.audio.startt;
|
||||
period_frames *= m_start_threshold;
|
||||
|
||||
if (!check(snd_pcm_sw_params_set_start_threshold(tls_handle, tls_sw_params, period_frames + 1), "snd_pcm_sw_params_set_start_threshold"))
|
||||
return;
|
||||
@@ -132,7 +133,7 @@ void ALSABackend::Close()
|
||||
|
||||
bool ALSABackend::AddData(const void* src, u32 num_samples)
|
||||
{
|
||||
u32 num_frames = num_samples / get_channels();
|
||||
u32 num_frames = num_samples / m_channels;
|
||||
|
||||
int res = snd_pcm_writei(tls_handle, src, num_frames);
|
||||
|
||||
|
||||
@@ -2,29 +2,67 @@
|
||||
#include "AudioBackend.h"
|
||||
#include "Emu/system_config.h"
|
||||
|
||||
/*
|
||||
* Helper methods
|
||||
*/
|
||||
u32 AudioBackend::get_sampling_rate()
|
||||
AudioBackend::AudioBackend()
|
||||
{
|
||||
m_convert_to_u16 = static_cast<bool>(g_cfg.audio.convert_to_u16);
|
||||
m_sample_size = m_convert_to_u16 ? sizeof(u16) : sizeof(float);
|
||||
m_start_threshold = g_cfg.audio.start_threshold;
|
||||
|
||||
const u32 sampling_period_multiplier_u32 = g_cfg.audio.sampling_period_multiplier;
|
||||
|
||||
if (sampling_period_multiplier_u32 == 100)
|
||||
return DEFAULT_AUDIO_SAMPLING_RATE;
|
||||
{
|
||||
m_sampling_rate = DEFAULT_AUDIO_SAMPLING_RATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
const f32 sampling_period_multiplier = sampling_period_multiplier_u32 / 100.0f;
|
||||
const f32 sampling_rate_multiplier = 1.0f / sampling_period_multiplier;
|
||||
m_sampling_rate = static_cast<u32>(f32{ DEFAULT_AUDIO_SAMPLING_RATE } *sampling_rate_multiplier);
|
||||
}
|
||||
|
||||
const f32 sampling_period_multiplier = sampling_period_multiplier_u32 / 100.0f;
|
||||
const f32 sampling_rate_multiplier = 1.0f / sampling_period_multiplier;
|
||||
return static_cast<u32>(f32{DEFAULT_AUDIO_SAMPLING_RATE} * sampling_rate_multiplier);
|
||||
const audio_downmix downmix = g_cfg.audio.audio_channel_downmix.get();
|
||||
|
||||
switch (downmix)
|
||||
{
|
||||
case audio_downmix::no_downmix:
|
||||
m_channels = 8;
|
||||
break;
|
||||
case audio_downmix::downmix_to_stereo:
|
||||
m_channels = 2;
|
||||
break;
|
||||
case audio_downmix::downmix_to_5_1:
|
||||
m_channels = 6;
|
||||
break;
|
||||
case audio_downmix::use_application_settings:
|
||||
m_channels = 2; // TODO
|
||||
break;
|
||||
default:
|
||||
fmt::throw_exception("Unknown audio channel mode %s (%d)", downmix, static_cast<int>(downmix));
|
||||
}
|
||||
}
|
||||
|
||||
u32 AudioBackend::get_sample_size()
|
||||
/*
|
||||
* Helper methods
|
||||
*/
|
||||
u32 AudioBackend::get_sampling_rate() const
|
||||
{
|
||||
return g_cfg.audio.convert_to_u16 ? sizeof(u16) : sizeof(float);
|
||||
return m_sampling_rate;
|
||||
}
|
||||
|
||||
u32 AudioBackend::get_channels()
|
||||
u32 AudioBackend::get_sample_size() const
|
||||
{
|
||||
return g_cfg.audio.downmix_to_2ch ? 2 : 8;
|
||||
return m_sample_size;
|
||||
}
|
||||
|
||||
u32 AudioBackend::get_channels() const
|
||||
{
|
||||
return m_channels;
|
||||
}
|
||||
|
||||
bool AudioBackend::get_convert_to_u16() const
|
||||
{
|
||||
return m_convert_to_u16;
|
||||
}
|
||||
|
||||
bool AudioBackend::has_capability(u32 cap) const
|
||||
|
||||
@@ -20,6 +20,8 @@ public:
|
||||
SET_FREQUENCY_RATIO = 0x8, // Implements SetFrequencyRatio
|
||||
};
|
||||
|
||||
AudioBackend();
|
||||
|
||||
virtual ~AudioBackend() = default;
|
||||
|
||||
/*
|
||||
@@ -94,13 +96,22 @@ public:
|
||||
/*
|
||||
* Helper methods
|
||||
*/
|
||||
static u32 get_sampling_rate();
|
||||
u32 get_sampling_rate() const;
|
||||
|
||||
static u32 get_sample_size();
|
||||
u32 get_sample_size() const;
|
||||
|
||||
static u32 get_channels();
|
||||
u32 get_channels() const;
|
||||
|
||||
bool get_convert_to_u16() const;
|
||||
|
||||
bool has_capability(u32 cap) const;
|
||||
|
||||
void dump_capabilities(std::string& out) const;
|
||||
|
||||
protected:
|
||||
bool m_convert_to_u16 = false;
|
||||
u32 m_sample_size = sizeof(float);
|
||||
u32 m_sampling_rate = DEFAULT_AUDIO_SAMPLING_RATE;
|
||||
u32 m_channels = 0;
|
||||
u32 m_start_threshold = 1;
|
||||
};
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
#include "stdafx.h"
|
||||
#include "AudioDumper.h"
|
||||
|
||||
#include "Utilities/date_time.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
AudioDumper::AudioDumper(u16 ch)
|
||||
: m_header(ch)
|
||||
{
|
||||
if (GetCh())
|
||||
{
|
||||
m_output.open(fs::get_cache_dir() + "audio.wav", fs::rewrite);
|
||||
std::string path = fs::get_cache_dir() + "audio_";
|
||||
if (const std::string id = Emu.GetTitleID(); !id.empty())
|
||||
{
|
||||
path += id + "_";
|
||||
};
|
||||
path += date_time::current_time_narrow<'_'>() + ".wav";
|
||||
m_output.open(path, fs::rewrite);
|
||||
m_output.write(m_header); // write initial file header
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef HAVE_FAUDIO
|
||||
#ifndef HAVE_FAUDIO
|
||||
#error "FAudio support disabled but still being built."
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
LOG_CHANNEL(FAudio_, "FAudio");
|
||||
|
||||
FAudioBackend::FAudioBackend()
|
||||
: AudioBackend()
|
||||
{
|
||||
u32 res;
|
||||
|
||||
@@ -20,7 +21,7 @@ FAudioBackend::FAudioBackend()
|
||||
return;
|
||||
}
|
||||
|
||||
res = FAudio_CreateMasteringVoice(m_instance, &m_master_voice, g_cfg.audio.downmix_to_2ch ? 2 : 8, 48000, 0, 0, nullptr);
|
||||
res = FAudio_CreateMasteringVoice(m_instance, &m_master_voice, m_channels, 48000, 0, 0, nullptr);
|
||||
if (res)
|
||||
{
|
||||
FAudio_.fatal("FAudio_CreateMasteringVoice() failed(0x%08x)", res);
|
||||
@@ -102,17 +103,13 @@ void FAudioBackend::Close()
|
||||
|
||||
void FAudioBackend::Open(u32 /* num_buffers */)
|
||||
{
|
||||
const u32 sample_size = AudioBackend::get_sample_size();
|
||||
const u32 channels = AudioBackend::get_channels();
|
||||
const u32 sampling_rate = AudioBackend::get_sampling_rate();
|
||||
|
||||
FAudioWaveFormatEx waveformatex;
|
||||
waveformatex.wFormatTag = g_cfg.audio.convert_to_u16 ? FAUDIO_FORMAT_PCM : FAUDIO_FORMAT_IEEE_FLOAT;
|
||||
waveformatex.nChannels = channels;
|
||||
waveformatex.nSamplesPerSec = sampling_rate;
|
||||
waveformatex.nAvgBytesPerSec = static_cast<u32>(sampling_rate * channels * sample_size);
|
||||
waveformatex.nBlockAlign = channels * sample_size;
|
||||
waveformatex.wBitsPerSample = sample_size * 8;
|
||||
waveformatex.wFormatTag = m_convert_to_u16 ? FAUDIO_FORMAT_PCM : FAUDIO_FORMAT_IEEE_FLOAT;
|
||||
waveformatex.nChannels = m_channels;
|
||||
waveformatex.nSamplesPerSec = m_sampling_rate;
|
||||
waveformatex.nAvgBytesPerSec = static_cast<u32>(m_sampling_rate * m_channels * m_sample_size);
|
||||
waveformatex.nBlockAlign = m_channels * m_sample_size;
|
||||
waveformatex.wBitsPerSample = m_sample_size * 8;
|
||||
waveformatex.cbSize = 0;
|
||||
|
||||
u32 res = FAudio_CreateSourceVoice(m_instance, &m_source_voice, &waveformatex, 0, FAUDIO_DEFAULT_FREQ_RATIO, nullptr, nullptr, nullptr);
|
||||
@@ -123,7 +120,7 @@ void FAudioBackend::Open(u32 /* num_buffers */)
|
||||
}
|
||||
|
||||
AUDIT(m_source_voice != nullptr);
|
||||
FAudioVoice_SetVolume(m_source_voice, channels == 2 ? 1.0f : 4.0f, FAUDIO_COMMIT_NOW);
|
||||
FAudioVoice_SetVolume(m_source_voice, 1.0f, FAUDIO_COMMIT_NOW);
|
||||
}
|
||||
|
||||
bool FAudioBackend::AddData(const void* src, u32 num_samples)
|
||||
@@ -140,7 +137,7 @@ bool FAudioBackend::AddData(const void* src, u32 num_samples)
|
||||
}
|
||||
|
||||
FAudioBuffer buffer;
|
||||
buffer.AudioBytes = num_samples * AudioBackend::get_sample_size();
|
||||
buffer.AudioBytes = num_samples * m_sample_size;
|
||||
buffer.Flags = 0;
|
||||
buffer.LoopBegin = FAUDIO_NO_LOOP_REGION;
|
||||
buffer.LoopCount = 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef HAVE_PULSE
|
||||
#ifndef HAVE_PULSE
|
||||
#error "PulseAudio support disabled but still being built."
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <pulse/error.h>
|
||||
|
||||
PulseBackend::PulseBackend()
|
||||
: AudioBackend()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -19,7 +20,8 @@ PulseBackend::~PulseBackend()
|
||||
|
||||
void PulseBackend::Close()
|
||||
{
|
||||
if(this->connection) {
|
||||
if (this->connection)
|
||||
{
|
||||
pa_simple_free(this->connection);
|
||||
this->connection = nullptr;
|
||||
}
|
||||
@@ -28,20 +30,30 @@ void PulseBackend::Close()
|
||||
void PulseBackend::Open(u32 /* num_buffers */)
|
||||
{
|
||||
pa_sample_spec ss;
|
||||
ss.format = (get_sample_size() == 2) ? PA_SAMPLE_S16LE : PA_SAMPLE_FLOAT32LE;
|
||||
ss.rate = get_sampling_rate();
|
||||
ss.format = (m_sample_size == 2) ? PA_SAMPLE_S16LE : PA_SAMPLE_FLOAT32LE;
|
||||
ss.rate = m_sampling_rate;
|
||||
|
||||
pa_channel_map channel_map;
|
||||
|
||||
if (get_channels() == 2)
|
||||
if (m_channels == 2)
|
||||
{
|
||||
channel_map.channels = 2;
|
||||
channel_map.channels = 2;
|
||||
channel_map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
|
||||
channel_map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
|
||||
}
|
||||
else if (m_channels == 6)
|
||||
{
|
||||
channel_map.channels = 6;
|
||||
channel_map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
|
||||
channel_map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
|
||||
channel_map.map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
|
||||
channel_map.map[3] = PA_CHANNEL_POSITION_LFE;
|
||||
channel_map.map[4] = PA_CHANNEL_POSITION_REAR_LEFT;
|
||||
channel_map.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel_map.channels = 8;
|
||||
channel_map.channels = 8;
|
||||
channel_map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
|
||||
channel_map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
|
||||
channel_map.map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
|
||||
@@ -55,7 +67,8 @@ void PulseBackend::Open(u32 /* num_buffers */)
|
||||
|
||||
int err;
|
||||
this->connection = pa_simple_new(NULL, "RPCS3", PA_STREAM_PLAYBACK, NULL, "Game", &ss, &channel_map, NULL, &err);
|
||||
if(!this->connection) {
|
||||
if (!this->connection)
|
||||
{
|
||||
fprintf(stderr, "PulseAudio: Failed to initialize audio: %s\n", pa_strerror(err));
|
||||
}
|
||||
}
|
||||
@@ -65,10 +78,11 @@ bool PulseBackend::AddData(const void* src, u32 num_samples)
|
||||
AUDIT(this->connection);
|
||||
|
||||
int err;
|
||||
if(pa_simple_write(this->connection, src, num_samples * get_sample_size(), &err) < 0) {
|
||||
if (pa_simple_write(this->connection, src, num_samples * m_sample_size, &err) < 0)
|
||||
{
|
||||
fprintf(stderr, "PulseAudio: Failed to write audio stream: %s\n", pa_strerror(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,26 +9,32 @@
|
||||
|
||||
#include "XAudio2Backend.h"
|
||||
#include <Windows.h>
|
||||
#include <system_error>
|
||||
|
||||
#pragma comment(lib, "xaudio2_9redist.lib")
|
||||
|
||||
LOG_CHANNEL(XAudio);
|
||||
|
||||
XAudio2Backend::XAudio2Backend()
|
||||
: AudioBackend()
|
||||
{
|
||||
Microsoft::WRL::ComPtr<IXAudio2> instance;
|
||||
|
||||
// In order to prevent errors on CreateMasteringVoice, apparently we need CoInitializeEx according to:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/xaudio2fx/nf-xaudio2fx-xaudio2createvolumemeter
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
|
||||
HRESULT hr = XAudio2Create(instance.GetAddressOf(), 0, XAUDIO2_DEFAULT_PROCESSOR);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
XAudio.error("XAudio2Create() failed(0x%08x)", (u32)hr);
|
||||
XAudio.error("XAudio2Create() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
return;
|
||||
}
|
||||
|
||||
hr = instance->CreateMasteringVoice(&m_master_voice, g_cfg.audio.downmix_to_2ch ? 2 : 8, 48000);
|
||||
hr = instance->CreateMasteringVoice(&m_master_voice, m_channels, 48000);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
XAudio.error("CreateMasteringVoice() failed(0x%08x)", (u32)hr);
|
||||
XAudio.error("CreateMasteringVoice() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -62,7 +68,7 @@ void XAudio2Backend::Play()
|
||||
HRESULT hr = m_source_voice->Start();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
XAudio.error("Start() failed(0x%08x)", (u32)hr);
|
||||
XAudio.error("Start() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
Emu.Pause();
|
||||
}
|
||||
}
|
||||
@@ -80,7 +86,7 @@ void XAudio2Backend::Pause()
|
||||
HRESULT hr = m_source_voice->Stop();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
XAudio.error("Stop() failed(0x%08x)", (u32)hr);
|
||||
XAudio.error("Stop() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
Emu.Pause();
|
||||
}
|
||||
}
|
||||
@@ -89,29 +95,25 @@ void XAudio2Backend::Open(u32 /* num_buffers */)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
const u32 sample_size = AudioBackend::get_sample_size();
|
||||
const u32 channels = AudioBackend::get_channels();
|
||||
const u32 sampling_rate = AudioBackend::get_sampling_rate();
|
||||
|
||||
WAVEFORMATEX waveformatex;
|
||||
waveformatex.wFormatTag = g_cfg.audio.convert_to_u16 ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
|
||||
waveformatex.nChannels = channels;
|
||||
waveformatex.nSamplesPerSec = sampling_rate;
|
||||
waveformatex.nAvgBytesPerSec = static_cast<DWORD>(sampling_rate * channels * sample_size);
|
||||
waveformatex.nBlockAlign = channels * sample_size;
|
||||
waveformatex.wBitsPerSample = sample_size * 8;
|
||||
waveformatex.wFormatTag = m_convert_to_u16 ? WAVE_FORMAT_PCM : WAVE_FORMAT_IEEE_FLOAT;
|
||||
waveformatex.nChannels = m_channels;
|
||||
waveformatex.nSamplesPerSec = m_sampling_rate;
|
||||
waveformatex.nAvgBytesPerSec = static_cast<DWORD>(m_sampling_rate * m_channels * m_sample_size);
|
||||
waveformatex.nBlockAlign = m_channels * m_sample_size;
|
||||
waveformatex.wBitsPerSample = m_sample_size * 8;
|
||||
waveformatex.cbSize = 0;
|
||||
|
||||
hr = m_xaudio2_instance->CreateSourceVoice(&m_source_voice, &waveformatex, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
XAudio.error("CreateSourceVoice() failed(0x%08x)", (u32)hr);
|
||||
XAudio.error("CreateSourceVoice() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
Emu.Pause();
|
||||
return;
|
||||
}
|
||||
|
||||
AUDIT(m_source_voice != nullptr);
|
||||
m_source_voice->SetVolume(channels == 2 ? 1.0f : 4.0f);
|
||||
m_source_voice->SetVolume(1.0f);
|
||||
}
|
||||
|
||||
bool XAudio2Backend::IsPlaying()
|
||||
@@ -139,7 +141,7 @@ bool XAudio2Backend::AddData(const void* src, u32 num_samples)
|
||||
|
||||
XAUDIO2_BUFFER buffer;
|
||||
|
||||
buffer.AudioBytes = num_samples * AudioBackend::get_sample_size();
|
||||
buffer.AudioBytes = num_samples * m_sample_size;
|
||||
buffer.Flags = 0;
|
||||
buffer.LoopBegin = XAUDIO2_NO_LOOP_REGION;
|
||||
buffer.LoopCount = 0;
|
||||
@@ -152,7 +154,7 @@ bool XAudio2Backend::AddData(const void* src, u32 num_samples)
|
||||
HRESULT hr = m_source_voice->SubmitSourceBuffer(&buffer);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
XAudio.error("AddData() failed(0x%08x)", (u32)hr);
|
||||
XAudio.error("AddData() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
Emu.Pause();
|
||||
return false;
|
||||
}
|
||||
@@ -167,7 +169,7 @@ void XAudio2Backend::Flush()
|
||||
HRESULT hr = m_source_voice->FlushSourceBuffers();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
XAudio.error("FlushSourceBuffers() failed(0x%08x)", (u32)hr);
|
||||
XAudio.error("FlushSourceBuffers() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
Emu.Pause();
|
||||
}
|
||||
}
|
||||
@@ -190,7 +192,7 @@ f32 XAudio2Backend::SetFrequencyRatio(f32 new_ratio)
|
||||
HRESULT hr = m_source_voice->SetFrequencyRatio(new_ratio);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
XAudio.error("SetFrequencyRatio() failed(0x%08x)", (u32)hr);
|
||||
XAudio.error("SetFrequencyRatio() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
Emu.Pause();
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ target_link_libraries(rpcs3_emu
|
||||
PRIVATE
|
||||
3rdparty::zlib 3rdparty::yaml-cpp
|
||||
PUBLIC
|
||||
3rdparty::libevdev)
|
||||
3rdparty::libevdev 3rdparty::flatbuffers)
|
||||
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
@@ -35,6 +35,7 @@ target_sources(rpcs3_emu PRIVATE
|
||||
../util/yaml.cpp
|
||||
../util/cereal.cpp
|
||||
../../Utilities/bin_patch.cpp
|
||||
../../Utilities/cheat_info.cpp
|
||||
../../Utilities/cond.cpp
|
||||
../../Utilities/Config.cpp
|
||||
../../Utilities/dynamic_library.cpp
|
||||
@@ -361,7 +362,11 @@ target_sources(rpcs3_emu PRIVATE
|
||||
|
||||
# Np
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
NP/fb_helpers.cpp
|
||||
NP/np_handler.cpp
|
||||
NP/np_structs_extra.cpp
|
||||
NP/rpcn_client.cpp
|
||||
NP/rpcn_config.cpp
|
||||
)
|
||||
|
||||
# Memory
|
||||
@@ -451,7 +456,7 @@ target_link_libraries(rpcs3_emu
|
||||
3rdparty::ffmpeg 3rdparty::cereal
|
||||
3rdparty::opengl 3rdparty::stblib
|
||||
3rdparty::vulkan 3rdparty::glew
|
||||
3rdparty::libusb
|
||||
3rdparty::libusb 3rdparty::wolfssl
|
||||
PRIVATE
|
||||
3rdparty::span 3rdparty::xxhash
|
||||
)
|
||||
|
||||
@@ -56,7 +56,23 @@ protected:
|
||||
|
||||
virtual u32 DisAsmBranchTarget(const s32 imm) = 0;
|
||||
|
||||
std::string FixOp(std::string op)
|
||||
// TODO: Add builtin fmt helpper for best performance
|
||||
template <typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
|
||||
static std::string SignedHex(T value)
|
||||
{
|
||||
const auto v = static_cast<std::make_signed_t<T>>(value);
|
||||
const auto av = std::abs(v);
|
||||
|
||||
if (av < 10)
|
||||
{
|
||||
// Does not need hex
|
||||
return fmt::format("%d", v);
|
||||
}
|
||||
|
||||
return fmt::format("%s%s", v < 0 ? "-" : "", av);
|
||||
}
|
||||
|
||||
static std::string FixOp(std::string op)
|
||||
{
|
||||
op.resize(std::max<std::size_t>(op.length(), 10), ' ');
|
||||
return op;
|
||||
|
||||
+68
-60
@@ -332,14 +332,13 @@ void cpu_thread::operator()()
|
||||
{
|
||||
thread_ctrl::set_thread_affinity_mask(thread_ctrl::get_affinity_mask(id_type() == 1 ? thread_class::ppu : thread_class::spu));
|
||||
}
|
||||
|
||||
if (g_cfg.core.lower_spu_priority && id_type() == 2)
|
||||
{
|
||||
thread_ctrl::set_native_priority(-1);
|
||||
}
|
||||
|
||||
if (id_type() == 2)
|
||||
{
|
||||
if (g_cfg.core.lower_spu_priority)
|
||||
{
|
||||
thread_ctrl::set_native_priority(-1);
|
||||
}
|
||||
|
||||
// force input/output denormals to zero for SPU threads (FTZ/DAZ)
|
||||
_mm_setcsr( _mm_getcsr() | 0x8040 );
|
||||
|
||||
@@ -434,11 +433,21 @@ void cpu_thread::operator()()
|
||||
if (!(state & cpu_flag::stop))
|
||||
{
|
||||
cpu_task();
|
||||
state -= cpu_flag::ret;
|
||||
|
||||
if (state & cpu_flag::ret && state.test_and_reset(cpu_flag::ret))
|
||||
{
|
||||
cpu_return();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
thread_ctrl::wait();
|
||||
|
||||
if (state & cpu_flag::ret && state.test_and_reset(cpu_flag::ret))
|
||||
{
|
||||
cpu_return();
|
||||
}
|
||||
}
|
||||
|
||||
// Complete cleanup gracefully
|
||||
@@ -465,63 +474,71 @@ bool cpu_thread::check_state() noexcept
|
||||
}
|
||||
|
||||
bool cpu_sleep_called = false;
|
||||
bool cpu_flag_memory = false;
|
||||
|
||||
if (!(state & cpu_flag::wait))
|
||||
{
|
||||
state += cpu_flag::wait;
|
||||
}
|
||||
bool escape, retval;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (state & cpu_flag::memory)
|
||||
// Process all flags in a single atomic op
|
||||
const auto state0 = state.fetch_op([&](bs_t<cpu_flag>& flags)
|
||||
{
|
||||
if (auto& ptr = vm::g_tls_locked)
|
||||
bool store = false;
|
||||
|
||||
if (flags & cpu_flag::signal)
|
||||
{
|
||||
ptr->compare_and_swap(this, nullptr);
|
||||
ptr = nullptr;
|
||||
flags -= cpu_flag::signal;
|
||||
cpu_sleep_called = false;
|
||||
store = true;
|
||||
}
|
||||
|
||||
cpu_flag_memory = true;
|
||||
state -= cpu_flag::memory;
|
||||
}
|
||||
|
||||
if (state & (cpu_flag::exit + cpu_flag::dbg_global_stop))
|
||||
{
|
||||
state += cpu_flag::wait;
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto [state0, escape] = state.fetch_op([&](bs_t<cpu_flag>& flags)
|
||||
{
|
||||
// Atomically clean wait flag and escape
|
||||
if (!(flags & (cpu_flag::exit + cpu_flag::dbg_global_stop + cpu_flag::ret + cpu_flag::stop)))
|
||||
{
|
||||
// Check pause flags which hold thread inside check_state
|
||||
if (flags & (cpu_flag::pause + cpu_flag::suspend + cpu_flag::dbg_global_pause + cpu_flag::dbg_pause))
|
||||
if (flags & (cpu_flag::pause + cpu_flag::suspend + cpu_flag::dbg_global_pause + cpu_flag::dbg_pause + cpu_flag::memory))
|
||||
{
|
||||
return false;
|
||||
if (!(flags & cpu_flag::wait))
|
||||
{
|
||||
flags += cpu_flag::wait;
|
||||
store = true;
|
||||
}
|
||||
|
||||
escape = false;
|
||||
return store;
|
||||
}
|
||||
|
||||
flags -= cpu_flag::wait;
|
||||
if (flags & cpu_flag::wait)
|
||||
{
|
||||
flags -= cpu_flag::wait;
|
||||
store = true;
|
||||
}
|
||||
|
||||
retval = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(flags & cpu_flag::wait))
|
||||
{
|
||||
flags += cpu_flag::wait;
|
||||
store = true;
|
||||
}
|
||||
|
||||
retval = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
if (flags & cpu_flag::dbg_step)
|
||||
{
|
||||
flags += cpu_flag::dbg_pause;
|
||||
flags -= cpu_flag::dbg_step;
|
||||
store = true;
|
||||
}
|
||||
|
||||
if (state & cpu_flag::signal && state.test_and_reset(cpu_flag::signal))
|
||||
{
|
||||
cpu_sleep_called = false;
|
||||
}
|
||||
escape = true;
|
||||
return store;
|
||||
}).first;
|
||||
|
||||
if (escape)
|
||||
{
|
||||
if (cpu_flag_memory)
|
||||
{
|
||||
cpu_mem();
|
||||
}
|
||||
|
||||
break;
|
||||
return retval;
|
||||
}
|
||||
else if (!cpu_sleep_called && state0 & cpu_flag::suspend)
|
||||
{
|
||||
@@ -536,25 +553,16 @@ bool cpu_thread::check_state() noexcept
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state0 & cpu_flag::memory)
|
||||
{
|
||||
vm::passive_lock(*this);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If only cpu_flag::pause was set, notification won't arrive
|
||||
g_fxo->get<cpu_counter>()->cpu_suspend_lock.lock_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
const auto state_ = state.load();
|
||||
|
||||
if (state_ & (cpu_flag::ret + cpu_flag::stop))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (state_ & cpu_flag::dbg_step)
|
||||
{
|
||||
state += cpu_flag::dbg_pause;
|
||||
state -= cpu_flag::dbg_step;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void cpu_thread::notify()
|
||||
@@ -623,7 +631,7 @@ std::string cpu_thread::dump_callstack() const
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<u32> cpu_thread::dump_callstack_list() const
|
||||
std::vector<std::pair<u32, u32>> cpu_thread::dump_callstack_list() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
virtual std::string dump_callstack() const;
|
||||
|
||||
// Get CPU call stack list
|
||||
virtual std::vector<u32> dump_callstack_list() const;
|
||||
virtual std::vector<std::pair<u32, u32>> dump_callstack_list() const;
|
||||
|
||||
// Get CPU dump of misc information
|
||||
virtual std::string dump_misc() const;
|
||||
@@ -120,6 +120,9 @@ public:
|
||||
// Callback for vm::temporary_unlock
|
||||
virtual void cpu_unmem() {}
|
||||
|
||||
// Callback for cpu_flag::ret
|
||||
virtual void cpu_return() {}
|
||||
|
||||
// Thread locker
|
||||
class suspend_all
|
||||
{
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
llvm::LLVMContext g_llvm_ctx;
|
||||
|
||||
cpu_translator::cpu_translator(llvm::Module* module, bool is_be)
|
||||
cpu_translator::cpu_translator(llvm::Module* _module, bool is_be)
|
||||
: m_context(g_llvm_ctx)
|
||||
, m_module(module)
|
||||
, m_module(_module)
|
||||
, m_is_be(is_be)
|
||||
{
|
||||
}
|
||||
@@ -57,6 +57,15 @@ void cpu_translator::initialize(llvm::LLVMContext& context, llvm::ExecutionEngin
|
||||
{
|
||||
m_use_fma = true;
|
||||
}
|
||||
|
||||
// Test AVX-512_icelake features (TODO)
|
||||
if (cpu == "icelake" ||
|
||||
cpu == "icelake-client" ||
|
||||
cpu == "icelake-server" ||
|
||||
cpu == "tigerlake")
|
||||
{
|
||||
m_use_avx512_icl = true;
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value* cpu_translator::bitcast(llvm::Value* val, llvm::Type* type)
|
||||
@@ -83,12 +92,31 @@ llvm::Value* cpu_translator::bitcast(llvm::Value* val, llvm::Type* type)
|
||||
}
|
||||
|
||||
template <>
|
||||
v128 cpu_translator::get_const_vector<v128>(llvm::Constant* c, u32 a, u32 b)
|
||||
std::pair<bool, v128> cpu_translator::get_const_vector<v128>(llvm::Value* c, u32 a, u32 b)
|
||||
{
|
||||
v128 result{};
|
||||
|
||||
if (!llvm::isa<llvm::Constant>(c))
|
||||
{
|
||||
return {false, result};
|
||||
}
|
||||
|
||||
const auto t = c->getType();
|
||||
|
||||
if (!t->isVectorTy())
|
||||
{
|
||||
if (const auto ci = llvm::dyn_cast<llvm::ConstantInt>(c); ci && ci->getBitWidth() == 128)
|
||||
{
|
||||
auto cv = ci->getValue();
|
||||
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
result._bit[i] = cv[i];
|
||||
}
|
||||
|
||||
return {true, result};
|
||||
}
|
||||
|
||||
fmt::throw_exception("[0x%x, %u] Not a vector" HERE, a, b);
|
||||
}
|
||||
|
||||
@@ -106,13 +134,17 @@ v128 cpu_translator::get_const_vector<v128>(llvm::Constant* c, u32 a, u32 b)
|
||||
return {};
|
||||
}
|
||||
|
||||
if (llvm::isa<llvm::ConstantExpr>(c))
|
||||
{
|
||||
// Sorry, if we cannot evaluate it we cannot use it
|
||||
fmt::throw_exception("[0x%x, %u] Constant Expression!" HERE, a, b);
|
||||
}
|
||||
|
||||
fmt::throw_exception("[0x%x, %u] Unexpected constant type" HERE, a, b);
|
||||
}
|
||||
|
||||
const auto sct = t->getScalarType();
|
||||
|
||||
v128 result;
|
||||
|
||||
if (sct->isIntegerTy(8))
|
||||
{
|
||||
for (u32 i = 0; i < 16; i++)
|
||||
@@ -160,12 +192,17 @@ v128 cpu_translator::get_const_vector<v128>(llvm::Constant* c, u32 a, u32 b)
|
||||
fmt::throw_exception("[0x%x, %u] Unexpected vector element type" HERE, a, b);
|
||||
}
|
||||
|
||||
return result;
|
||||
return {true, result};
|
||||
}
|
||||
|
||||
template <>
|
||||
llvm::Constant* cpu_translator::make_const_vector<v128>(v128 v, llvm::Type* t)
|
||||
{
|
||||
if (const auto ct = llvm::dyn_cast<llvm::IntegerType>(t); ct && ct->getBitWidth() == 128)
|
||||
{
|
||||
return llvm::ConstantInt::get(t, llvm::APInt(128, llvm::makeArrayRef(reinterpret_cast<const u64*>(v._bytes), 2)));
|
||||
}
|
||||
|
||||
verify(HERE), t->isVectorTy() && llvm::cast<llvm::VectorType>(t)->getBitWidth() == 128;
|
||||
|
||||
const auto sct = t->getScalarType();
|
||||
|
||||
+100
-20
@@ -828,7 +828,7 @@ struct llvm_neg
|
||||
|
||||
static_assert(llvm_value_t<T>::is_sint || llvm_value_t<T>::is_uint || llvm_value_t<T>::is_float, "llvm_neg<>: invalid type");
|
||||
|
||||
static constexpr auto opc = llvm_value_t<T>::is_float ? llvm::Instruction::FSub : llvm::Instruction::Sub;
|
||||
static constexpr auto opc = llvm_value_t<T>::is_float ? llvm::Instruction::FNeg : llvm::Instruction::Sub;
|
||||
|
||||
llvm::Value* eval(llvm::IRBuilder<>* ir) const
|
||||
{
|
||||
@@ -849,6 +849,19 @@ struct llvm_neg
|
||||
{
|
||||
llvm::Value* v1 = {};
|
||||
|
||||
if constexpr (llvm_value_t<T>::is_float)
|
||||
{
|
||||
if (auto i = llvm::dyn_cast_or_null<llvm::UnaryOperator>(value); i && i->getOpcode() == opc)
|
||||
{
|
||||
v1 = i->getOperand(0);
|
||||
|
||||
if (auto r1 = a1.match(v1); v1)
|
||||
{
|
||||
return r1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto i = llvm::dyn_cast_or_null<llvm::BinaryOperator>(value); i && i->getOpcode() == opc)
|
||||
{
|
||||
v1 = i->getOperand(1);
|
||||
@@ -996,8 +1009,8 @@ struct llvm_fshl
|
||||
|
||||
static llvm::Function* get_fshl(llvm::IRBuilder<>* ir)
|
||||
{
|
||||
const auto module = ir->GetInsertBlock()->getParent()->getParent();
|
||||
return llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::fshl, {llvm_value_t<T>::get_type(ir->getContext())});
|
||||
const auto _module = ir->GetInsertBlock()->getParent()->getParent();
|
||||
return llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::fshl, {llvm_value_t<T>::get_type(ir->getContext())});
|
||||
}
|
||||
|
||||
static llvm::Value* fold(llvm::IRBuilder<>* ir, llvm::Value* v1, llvm::Value* v2, llvm::Value* v3)
|
||||
@@ -1068,8 +1081,8 @@ struct llvm_fshr
|
||||
|
||||
static llvm::Function* get_fshr(llvm::IRBuilder<>* ir)
|
||||
{
|
||||
const auto module = ir->GetInsertBlock()->getParent()->getParent();
|
||||
return llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::fshr, {llvm_value_t<T>::get_type(ir->getContext())});
|
||||
const auto _module = ir->GetInsertBlock()->getParent()->getParent();
|
||||
return llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::fshr, {llvm_value_t<T>::get_type(ir->getContext())});
|
||||
}
|
||||
|
||||
static llvm::Value* fold(llvm::IRBuilder<>* ir, llvm::Value* v1, llvm::Value* v2, llvm::Value* v3)
|
||||
@@ -1629,7 +1642,7 @@ struct llvm_bitcast
|
||||
using type = U;
|
||||
|
||||
llvm_expr_t<A1> a1;
|
||||
llvm::Module* module;
|
||||
llvm::Module* _module;
|
||||
|
||||
static constexpr uint bitsize0 = llvm_value_t<T>::is_vector ? llvm_value_t<T>::is_vector * llvm_value_t<T>::esize : llvm_value_t<T>::esize;
|
||||
static constexpr uint bitsize1 = llvm_value_t<U>::is_vector ? llvm_value_t<U>::is_vector * llvm_value_t<U>::esize : llvm_value_t<U>::esize;
|
||||
@@ -1655,7 +1668,7 @@ struct llvm_bitcast
|
||||
|
||||
if (const auto c1 = llvm::dyn_cast<llvm::Constant>(v1))
|
||||
{
|
||||
const auto result = llvm::ConstantFoldCastOperand(llvm::Instruction::BitCast, c1, rt, module->getDataLayout());
|
||||
const auto result = llvm::ConstantFoldCastOperand(llvm::Instruction::BitCast, c1, rt, _module->getDataLayout());
|
||||
|
||||
if (result)
|
||||
{
|
||||
@@ -1701,7 +1714,7 @@ struct llvm_bitcast
|
||||
const auto target = llvm_value_t<T>::get_type(c->getContext());
|
||||
|
||||
// Reverse bitcast on a constant
|
||||
if (llvm::Value* cv = llvm::ConstantFoldCastOperand(llvm::Instruction::BitCast, c, target, module->getDataLayout()))
|
||||
if (llvm::Value* cv = llvm::ConstantFoldCastOperand(llvm::Instruction::BitCast, c, target, _module->getDataLayout()))
|
||||
{
|
||||
if (auto r1 = a1.match(cv); cv)
|
||||
{
|
||||
@@ -2016,8 +2029,8 @@ struct llvm_add_sat
|
||||
|
||||
static llvm::Function* get_add_sat(llvm::IRBuilder<>* ir)
|
||||
{
|
||||
const auto module = ir->GetInsertBlock()->getParent()->getParent();
|
||||
return llvm::Intrinsic::getDeclaration(module, intr, {llvm_value_t<T>::get_type(ir->getContext())});
|
||||
const auto _module = ir->GetInsertBlock()->getParent()->getParent();
|
||||
return llvm::Intrinsic::getDeclaration(_module, intr, {llvm_value_t<T>::get_type(ir->getContext())});
|
||||
}
|
||||
|
||||
llvm::Value* eval(llvm::IRBuilder<>* ir) const
|
||||
@@ -2087,8 +2100,8 @@ struct llvm_sub_sat
|
||||
|
||||
static llvm::Function* get_sub_sat(llvm::IRBuilder<>* ir)
|
||||
{
|
||||
const auto module = ir->GetInsertBlock()->getParent()->getParent();
|
||||
return llvm::Intrinsic::getDeclaration(module, intr, {llvm_value_t<T>::get_type(ir->getContext())});
|
||||
const auto _module = ir->GetInsertBlock()->getParent()->getParent();
|
||||
return llvm::Intrinsic::getDeclaration(_module, intr, {llvm_value_t<T>::get_type(ir->getContext())});
|
||||
}
|
||||
|
||||
llvm::Value* eval(llvm::IRBuilder<>* ir) const
|
||||
@@ -2390,7 +2403,7 @@ struct llvm_shuffle2
|
||||
class cpu_translator
|
||||
{
|
||||
protected:
|
||||
cpu_translator(llvm::Module* module, bool is_be);
|
||||
cpu_translator(llvm::Module* _module, bool is_be);
|
||||
|
||||
// LLVM context
|
||||
std::reference_wrapper<llvm::LLVMContext> m_context;
|
||||
@@ -2410,6 +2423,9 @@ protected:
|
||||
// Allow FMA
|
||||
bool m_use_fma = false;
|
||||
|
||||
// Allow Icelake tier AVX-512
|
||||
bool m_use_avx512_icl = false;
|
||||
|
||||
// IR builder
|
||||
llvm::IRBuilder<>* m_ir;
|
||||
|
||||
@@ -2682,8 +2698,8 @@ public:
|
||||
template <typename... Types>
|
||||
llvm::Function* get_intrinsic(llvm::Intrinsic::ID id)
|
||||
{
|
||||
const auto module = m_ir->GetInsertBlock()->getParent()->getParent();
|
||||
return llvm::Intrinsic::getDeclaration(module, id, {get_type<Types>()...});
|
||||
const auto _module = m_ir->GetInsertBlock()->getParent()->getParent();
|
||||
return llvm::Intrinsic::getDeclaration(_module, id, {get_type<Types>()...});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -2731,22 +2747,86 @@ public:
|
||||
}
|
||||
|
||||
// TODO: Support doubles
|
||||
auto fre(value_t<f32[4]> a)
|
||||
template <typename T, typename = std::enable_if_t<llvm_value_t<typename T::type>::esize == 32u && llvm_value_t<typename T::type>::is_float>>
|
||||
auto fre(T a)
|
||||
{
|
||||
decltype(a) result;
|
||||
value_t<typename T::type> result;
|
||||
const auto av = a.eval(m_ir);
|
||||
result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.rcp.ps", av->getType(), av->getType()).getCallee(), {av});
|
||||
return result;
|
||||
}
|
||||
|
||||
auto frsqe(value_t<f32[4]> a)
|
||||
template <typename T, typename = std::enable_if_t<llvm_value_t<typename T::type>::esize == 32u && llvm_value_t<typename T::type>::is_float>>
|
||||
auto frsqe(T a)
|
||||
{
|
||||
decltype(a) result;
|
||||
value_t<typename T::type> result;
|
||||
const auto av = a.eval(m_ir);
|
||||
result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.rsqrt.ps", av->getType(), av->getType()).getCallee(), {av});
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, typename U, typename = std::enable_if_t<std::is_same_v<typename T::type, typename U::type> && llvm_value_t<typename T::type>::esize == 32u && llvm_value_t<typename T::type>::is_float>>
|
||||
auto fmax(T a, U b)
|
||||
{
|
||||
value_t<typename T::type> result;
|
||||
const auto av = a.eval(m_ir);
|
||||
const auto bv = b.eval(m_ir);
|
||||
result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.max.ps", av->getType(), av->getType(), av->getType()).getCallee(), {av, bv});
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, typename U, typename = std::enable_if_t<std::is_same_v<typename T::type, typename U::type> && llvm_value_t<typename T::type>::esize == 32u && llvm_value_t<typename T::type>::is_float>>
|
||||
auto fmin(T a, U b)
|
||||
{
|
||||
value_t<typename T::type> result;
|
||||
const auto av = a.eval(m_ir);
|
||||
const auto bv = b.eval(m_ir);
|
||||
result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.min.ps", av->getType(), av->getType(), av->getType()).getCallee(), {av, bv});
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
value_t<u8[16]> gf2p8affineqb(T1 a, T2 b, u8 c)
|
||||
{
|
||||
value_t<u8[16]> result;
|
||||
|
||||
const auto data0 = a.eval(m_ir);
|
||||
const auto data1 = b.eval(m_ir);
|
||||
|
||||
const auto immediate = (llvm_const_int<u8>{c});
|
||||
const auto imm8 = immediate.eval(m_ir);
|
||||
|
||||
result.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::x86_vgf2p8affineqb_128), {data0, data1, imm8});
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
value_t<u8[16]> vperm2b(T1 a, T2 b, T3 c)
|
||||
{
|
||||
value_t<u8[16]> result;
|
||||
|
||||
const auto data0 = a.eval(m_ir);
|
||||
const auto data1 = b.eval(m_ir);
|
||||
const auto index = c.eval(m_ir);
|
||||
const auto zeros = llvm::ConstantAggregateZero::get(get_type<u8[16]>());
|
||||
|
||||
if (auto c = llvm::dyn_cast<llvm::Constant>(index))
|
||||
{
|
||||
// Convert VPERM2B index back to LLVM vector shuffle mask
|
||||
const auto cv = llvm::dyn_cast<llvm::ConstantDataVector>(c);
|
||||
|
||||
if (cv || llvm::isa<llvm::ConstantAggregateZero>(c))
|
||||
{
|
||||
result.value = m_ir->CreateZExt(cv, get_type<u32[16]>());
|
||||
result.value = m_ir->CreateShuffleVector(data0, data1, result.value);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::x86_avx512_vpermi2var_qi_128), {data0, index, data1});
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
value_t<u8[16]> pshufb(T1 a, T2 b)
|
||||
{
|
||||
@@ -2824,7 +2904,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename R = v128>
|
||||
R get_const_vector(llvm::Constant*, u32 a, u32 b);
|
||||
std::pair<bool, R> get_const_vector(llvm::Value*, u32 a, u32 b);
|
||||
|
||||
template <typename T = v128>
|
||||
llvm::Constant* make_const_vector(T, llvm::Type*);
|
||||
|
||||
@@ -45,6 +45,12 @@ void fmt_class_string<MFC>::format(std::string& out, u64 arg)
|
||||
case MFC_EIEIO_CMD: return "EIEIO";
|
||||
case MFC_SYNC_CMD: return "SYNC";
|
||||
|
||||
case MFC_SDCRT_CMD: return "SDCRT";
|
||||
case MFC_SDCRTST_CMD: return "SDCRTST";
|
||||
case MFC_SDCRZ_CMD: return "SDCRZ";
|
||||
case MFC_SDCRS_CMD: return "SDCRS";
|
||||
case MFC_SDCRF_CMD: return "SDCRF";
|
||||
|
||||
case MFC_BARRIER_MASK:
|
||||
case MFC_FENCE_MASK:
|
||||
case MFC_LIST_MASK:
|
||||
|
||||
@@ -27,10 +27,16 @@ enum MFC : u8
|
||||
MFC_LIST_MASK = 0x04,
|
||||
MFC_START_MASK = 0x08,
|
||||
MFC_RESULT_MASK = 0x10, // ???
|
||||
|
||||
MFC_SDCRT_CMD = 0x80,
|
||||
MFC_SDCRTST_CMD = 0x81,
|
||||
MFC_SDCRZ_CMD = 0x89,
|
||||
MFC_SDCRS_CMD = 0x8D,
|
||||
MFC_SDCRF_CMD = 0x8F,
|
||||
};
|
||||
|
||||
// Atomic Status Update
|
||||
enum : u32
|
||||
enum mfc_atomic_status : u32
|
||||
{
|
||||
MFC_PUTLLC_SUCCESS = 0,
|
||||
MFC_PUTLLC_FAILURE = 1, // reservation was lost
|
||||
@@ -39,7 +45,7 @@ enum : u32
|
||||
};
|
||||
|
||||
// MFC Write Tag Status Update Request Channel (ch23) operations
|
||||
enum : u32
|
||||
enum mfc_tag_update : u32
|
||||
{
|
||||
MFC_TAG_UPDATE_IMMEDIATE = 0,
|
||||
MFC_TAG_UPDATE_ANY = 1,
|
||||
|
||||
@@ -83,7 +83,7 @@ bool statichle_handler::load_patterns()
|
||||
dapat.crc16_length = ::narrow<u8>(char_to_u8(pattern[1][0], pattern[1][1]), HERE);
|
||||
dapat.crc16 = (char_to_u8(pattern[2][0], pattern[2][1]) << 8) | char_to_u8(pattern[2][2], pattern[2][3]);
|
||||
dapat.total_length = (char_to_u8(pattern[3][0], pattern[3][1]) << 8) | char_to_u8(pattern[3][2], pattern[3][3]);
|
||||
dapat.module = pattern[4];
|
||||
dapat._module = pattern[4];
|
||||
dapat.name = pattern[5];
|
||||
|
||||
dapat.fnid = ppu_generate_id(dapat.name.c_str());
|
||||
@@ -153,11 +153,11 @@ bool statichle_handler::check_against_patterns(vm::cptr<u8>& data, u32 size, u32
|
||||
static_hle.success("Found function %s at 0x%x", pat.name, addr);
|
||||
|
||||
// patch the code
|
||||
const auto smodule = ppu_module_manager::get_module(pat.module);
|
||||
const auto smodule = ppu_module_manager::get_module(pat._module);
|
||||
|
||||
if (smodule == nullptr)
|
||||
{
|
||||
static_hle.error("Couldn't find module: %s", pat.module);
|
||||
static_hle.error("Couldn't find module: %s", pat._module);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ struct shle_pattern
|
||||
u8 crc16_length;
|
||||
u16 crc16;
|
||||
u16 total_length;
|
||||
std::string module;
|
||||
std::string _module;
|
||||
std::string name;
|
||||
|
||||
u32 fnid;
|
||||
|
||||
@@ -44,8 +44,43 @@ void fmt_class_string<CellAudioError>::format(std::string& out, u64 arg)
|
||||
|
||||
cell_audio_config::cell_audio_config()
|
||||
{
|
||||
raw = audio::get_raw_config();
|
||||
reset();
|
||||
}
|
||||
|
||||
void cell_audio_config::reset()
|
||||
{
|
||||
backend.reset();
|
||||
backend = Emu.GetCallbacks().get_audio();
|
||||
|
||||
audio_channels = backend->get_channels();
|
||||
audio_sampling_rate = backend->get_sampling_rate();
|
||||
audio_block_period = AUDIO_BUFFER_SAMPLES * 1000000 / audio_sampling_rate;
|
||||
|
||||
audio_buffer_length = AUDIO_BUFFER_SAMPLES * audio_channels;
|
||||
audio_buffer_size = audio_buffer_length * backend->get_sample_size();
|
||||
|
||||
desired_buffer_duration = raw.desired_buffer_duration * 1000llu;
|
||||
|
||||
buffering_enabled = raw.buffering_enabled && backend->has_capability(AudioBackend::PLAY_PAUSE_FLUSH | AudioBackend::IS_PLAYING);;
|
||||
|
||||
minimum_block_period = audio_block_period / 2;
|
||||
maximum_block_period = (6 * audio_block_period) / 5;
|
||||
|
||||
desired_full_buffers = buffering_enabled ? static_cast<u32>(desired_buffer_duration / audio_block_period) + 3 : 2;
|
||||
num_allocated_buffers = desired_full_buffers + EXTRA_AUDIO_BUFFERS;
|
||||
|
||||
fully_untouched_timeout = static_cast<u64>(audio_block_period) * 2;
|
||||
partially_untouched_timeout = static_cast<u64>(audio_block_period) * 4;
|
||||
|
||||
const bool raw_time_stretching_enabled = buffering_enabled && raw.enable_time_stretching && (raw.time_stretching_threshold > 0);
|
||||
|
||||
time_stretching_enabled = raw_time_stretching_enabled && backend->has_capability(AudioBackend::SET_FREQUENCY_RATIO);
|
||||
|
||||
time_stretching_threshold = raw.time_stretching_threshold / 100.0f;
|
||||
|
||||
// Warn if audio backend does not support all requested features
|
||||
if (raw_buffering_enabled && !buffering_enabled)
|
||||
if (raw.buffering_enabled && !buffering_enabled)
|
||||
{
|
||||
cellAudio.error("Audio backend %s does not support buffering, this option will be ignored.", backend->GetName());
|
||||
}
|
||||
@@ -142,7 +177,7 @@ void audio_ringbuffer::enqueue(const float* in_buffer)
|
||||
}
|
||||
|
||||
// Enqueue audio
|
||||
bool success = backend->AddData(buf, AUDIO_BUFFER_SAMPLES * cfg.audio_channels);
|
||||
const bool success = backend->AddData(buf, AUDIO_BUFFER_SAMPLES * cfg.audio_channels);
|
||||
if (!success)
|
||||
{
|
||||
cellAudio.error("Could not enqueue buffer onto audio backend. Attempting to recover...");
|
||||
@@ -311,8 +346,8 @@ void audio_port::tag(s32 offset)
|
||||
// We use -0.0f in case games check if the buffer is empty. -0.0f == 0.0f evaluates to true, but std::signbit can be used to distinguish them
|
||||
const f32 tag = -0.0f;
|
||||
|
||||
const u32 tag_first_pos = num_channels == 2 ? PORT_BUFFER_TAG_FIRST_2CH : PORT_BUFFER_TAG_FIRST_8CH;
|
||||
const u32 tag_delta = num_channels == 2 ? PORT_BUFFER_TAG_DELTA_2CH : PORT_BUFFER_TAG_DELTA_8CH;
|
||||
const u32 tag_first_pos = num_channels == 2 ? PORT_BUFFER_TAG_FIRST_2CH : num_channels == 6 ? PORT_BUFFER_TAG_FIRST_6CH : PORT_BUFFER_TAG_FIRST_8CH;
|
||||
const u32 tag_delta = num_channels == 2 ? PORT_BUFFER_TAG_DELTA_2CH : num_channels == 6 ? PORT_BUFFER_TAG_DELTA_6CH : PORT_BUFFER_TAG_DELTA_8CH;
|
||||
|
||||
for (u32 tag_pos = tag_first_pos, tag_nr = 0; tag_nr < PORT_BUFFER_TAG_COUNT; tag_pos += tag_delta, tag_nr++)
|
||||
{
|
||||
@@ -341,8 +376,8 @@ std::tuple<u32, u32, u32, u32> cell_audio_thread::count_port_buffer_tags()
|
||||
u32 port_pos = port.position();
|
||||
|
||||
// Find the last tag that has been touched
|
||||
const u32 tag_first_pos = port.num_channels == 2 ? PORT_BUFFER_TAG_FIRST_2CH : PORT_BUFFER_TAG_FIRST_8CH;
|
||||
const u32 tag_delta = port.num_channels == 2 ? PORT_BUFFER_TAG_DELTA_2CH : PORT_BUFFER_TAG_DELTA_8CH;
|
||||
const u32 tag_first_pos = port.num_channels == 2 ? PORT_BUFFER_TAG_FIRST_2CH : port.num_channels == 6 ? PORT_BUFFER_TAG_FIRST_6CH : PORT_BUFFER_TAG_FIRST_8CH;
|
||||
const u32 tag_delta = port.num_channels == 2 ? PORT_BUFFER_TAG_DELTA_2CH : port.num_channels == 6 ? PORT_BUFFER_TAG_DELTA_6CH : PORT_BUFFER_TAG_DELTA_8CH;
|
||||
|
||||
u32 last_touched_tag_nr = port.prev_touched_tag_nr;
|
||||
bool retouched = false;
|
||||
@@ -460,13 +495,13 @@ void cell_audio_thread::advance(u64 timestamp, bool reset)
|
||||
|
||||
for (const auto& key_inf : keys)
|
||||
{
|
||||
if (const auto queue = lv2_event_queue::find(key_inf.key))
|
||||
if (key_inf.flags & CELL_AUDIO_EVENTFLAG_NOMIX)
|
||||
{
|
||||
if (key_inf.flags & CELL_AUDIO_EVENTFLAG_NOMIX)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((queues[queue_count] = key_inf.port.lock()))
|
||||
{
|
||||
u32 periods = 1;
|
||||
|
||||
if (key_inf.flags & CELL_AUDIO_EVENTFLAG_DECIMATE_2)
|
||||
@@ -483,11 +518,12 @@ void cell_audio_thread::advance(u64 timestamp, bool reset)
|
||||
if ((event_period ^ key_inf.start_period) & (periods - 1))
|
||||
{
|
||||
// The time has not come for this key to receive event
|
||||
queues[queue_count].reset();
|
||||
continue;
|
||||
}
|
||||
|
||||
event_sources[queue_count] = key_inf.source;
|
||||
queues[queue_count++] = queue;
|
||||
queue_count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,6 +535,63 @@ void cell_audio_thread::advance(u64 timestamp, bool reset)
|
||||
}
|
||||
}
|
||||
|
||||
namespace audio
|
||||
{
|
||||
cell_audio_config::raw_config get_raw_config()
|
||||
{
|
||||
return
|
||||
{
|
||||
.buffering_enabled = static_cast<bool>(g_cfg.audio.enable_buffering),
|
||||
.desired_buffer_duration = g_cfg.audio.desired_buffer_duration,
|
||||
.enable_time_stretching = static_cast<bool>(g_cfg.audio.enable_time_stretching),
|
||||
.time_stretching_threshold = g_cfg.audio.time_stretching_threshold,
|
||||
.convert_to_u16 = static_cast<bool>(g_cfg.audio.convert_to_u16),
|
||||
.start_threshold = static_cast<u32>(g_cfg.audio.start_threshold),
|
||||
.sampling_period_multiplier = static_cast<u32>(g_cfg.audio.sampling_period_multiplier),
|
||||
.downmix = g_cfg.audio.audio_channel_downmix,
|
||||
.renderer = g_cfg.audio.renderer
|
||||
};
|
||||
}
|
||||
|
||||
void configure_audio()
|
||||
{
|
||||
if (const auto g_audio = g_fxo->get<cell_audio>())
|
||||
{
|
||||
// Only reboot the audio renderer if a relevant setting changed
|
||||
const auto new_raw = get_raw_config();
|
||||
|
||||
if (const auto raw = g_audio->cfg.raw;
|
||||
raw.desired_buffer_duration != new_raw.desired_buffer_duration ||
|
||||
raw.buffering_enabled != new_raw.buffering_enabled ||
|
||||
raw.time_stretching_threshold != new_raw.time_stretching_threshold ||
|
||||
raw.enable_time_stretching != new_raw.enable_time_stretching ||
|
||||
raw.convert_to_u16 != new_raw.convert_to_u16 ||
|
||||
raw.start_threshold != new_raw.start_threshold ||
|
||||
raw.sampling_period_multiplier != new_raw.sampling_period_multiplier ||
|
||||
raw.downmix != new_raw.downmix ||
|
||||
raw.renderer != new_raw.renderer)
|
||||
{
|
||||
g_audio->cfg.raw = new_raw;
|
||||
g_audio->m_update_configuration = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cell_audio_thread::update_config()
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
// Clear ringbuffer
|
||||
ringbuffer.reset();
|
||||
|
||||
// Reload config
|
||||
cfg.reset();
|
||||
|
||||
// Allocate ringbuffer
|
||||
ringbuffer.reset(new audio_ringbuffer(cfg));
|
||||
}
|
||||
|
||||
void cell_audio_thread::operator()()
|
||||
{
|
||||
thread_ctrl::set_native_priority(1);
|
||||
@@ -518,6 +611,12 @@ void cell_audio_thread::operator()()
|
||||
// Main cellAudio loop
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
if (m_update_configuration)
|
||||
{
|
||||
update_config();
|
||||
m_update_configuration = false;
|
||||
}
|
||||
|
||||
const u64 timestamp = ringbuffer->update();
|
||||
|
||||
if (Emu.IsPaused())
|
||||
@@ -741,16 +840,19 @@ void cell_audio_thread::operator()()
|
||||
|
||||
// Mix
|
||||
float *buf = ringbuffer->get_current_buffer();
|
||||
if (cfg.audio_channels == 2)
|
||||
{
|
||||
mix<true>(buf);
|
||||
}
|
||||
else if (cfg.audio_channels == 8)
|
||||
{
|
||||
mix<false>(buf);
|
||||
}
|
||||
else
|
||||
|
||||
switch (cfg.audio_channels)
|
||||
{
|
||||
case 2:
|
||||
mix<audio_downmix::downmix_to_stereo>(buf);
|
||||
break;
|
||||
case 6:
|
||||
mix<audio_downmix::downmix_to_5_1>(buf);
|
||||
break;
|
||||
case 8:
|
||||
mix<audio_downmix::no_downmix>(buf);
|
||||
break;
|
||||
default:
|
||||
fmt::throw_exception("Unsupported number of audio channels: %u", cfg.audio_channels);
|
||||
}
|
||||
|
||||
@@ -765,16 +867,18 @@ void cell_audio_thread::operator()()
|
||||
ringbuffer.reset();
|
||||
}
|
||||
|
||||
template <bool DownmixToStereo>
|
||||
template <audio_downmix downmix>
|
||||
void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||
{
|
||||
AUDIT(out_buffer != nullptr);
|
||||
|
||||
constexpr u32 channels = DownmixToStereo ? 2 : 8;
|
||||
constexpr u32 channels = downmix == audio_downmix::no_downmix ? 8 : downmix == audio_downmix::downmix_to_5_1 ? 6 : 2;
|
||||
constexpr u32 out_buffer_sz = channels * AUDIO_BUFFER_SAMPLES;
|
||||
|
||||
bool first_mix = true;
|
||||
|
||||
const float master_volume = g_cfg.audio.volume / 100.0f;
|
||||
|
||||
// mixing
|
||||
for (auto& port : ports)
|
||||
{
|
||||
@@ -782,13 +886,12 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||
|
||||
auto buf = port.get_vm_ptr(offset);
|
||||
static const float k = 1.f;
|
||||
static const float minus_3db = 0.707f; /* value taken from
|
||||
https://www.dolby.com/us/en/technologies/a-guide-to-dolby-metadata.pdf */
|
||||
float& m = port.level;
|
||||
static constexpr float minus_3db = 0.707f; // value taken from https://www.dolby.com/us/en/technologies/a-guide-to-dolby-metadata.pdf
|
||||
float m = master_volume;
|
||||
|
||||
// part of cellAudioSetPortLevel functionality
|
||||
// spread port volume changes over 13ms
|
||||
auto step_volume = [](audio_port& port)
|
||||
auto step_volume = [master_volume, &m](audio_port& port)
|
||||
{
|
||||
const auto param = port.level_set.load();
|
||||
|
||||
@@ -803,6 +906,8 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||
port.level_set.compare_and_swap(param, { param.value, 0.0f });
|
||||
}
|
||||
}
|
||||
|
||||
m = port.level * master_volume;
|
||||
};
|
||||
|
||||
if (port.num_channels == 2)
|
||||
@@ -819,14 +924,18 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||
out_buffer[out + 0] = left;
|
||||
out_buffer[out + 1] = right;
|
||||
|
||||
if constexpr (!DownmixToStereo)
|
||||
if constexpr (downmix != audio_downmix::downmix_to_stereo)
|
||||
{
|
||||
out_buffer[out + 2] = 0.0f;
|
||||
out_buffer[out + 3] = 0.0f;
|
||||
out_buffer[out + 4] = 0.0f;
|
||||
out_buffer[out + 5] = 0.0f;
|
||||
out_buffer[out + 6] = 0.0f;
|
||||
out_buffer[out + 7] = 0.0f;
|
||||
|
||||
if constexpr (downmix != audio_downmix::downmix_to_5_1)
|
||||
{
|
||||
out_buffer[out + 6] = 0.0f;
|
||||
out_buffer[out + 7] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
first_mix = false;
|
||||
@@ -862,12 +971,21 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||
const float side_left = buf[in + 6] * m;
|
||||
const float side_right = buf[in + 7] * m;
|
||||
|
||||
if constexpr (DownmixToStereo)
|
||||
if constexpr (downmix == audio_downmix::downmix_to_stereo)
|
||||
{
|
||||
const float mid = center * minus_3db; /* don't mix in the lfe as per
|
||||
dolby specification */
|
||||
out_buffer[out + 0] = (left + rear_left + (side_left * minus_3db) + mid) * k;
|
||||
out_buffer[out + 1] = (right + rear_right + (side_right * minus_3db) + mid) * k;
|
||||
// Don't mix in the lfe as per dolby specification and based on documentation
|
||||
const float mid = center * 0.5f;
|
||||
out_buffer[out + 0] = left * minus_3db + mid + side_left * 0.5f + rear_left * 0.5f;
|
||||
out_buffer[out + 1] = right * minus_3db + mid + side_right * 0.5f + rear_right * 0.5f;
|
||||
}
|
||||
else if constexpr (downmix == audio_downmix::downmix_to_5_1)
|
||||
{
|
||||
out_buffer[out + 0] = left;
|
||||
out_buffer[out + 1] = right;
|
||||
out_buffer[out + 2] = center;
|
||||
out_buffer[out + 3] = low_freq;
|
||||
out_buffer[out + 4] = side_left + rear_left;
|
||||
out_buffer[out + 5] = side_right + rear_right;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -898,11 +1016,21 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||
const float side_left = buf[in + 6] * m;
|
||||
const float side_right = buf[in + 7] * m;
|
||||
|
||||
if constexpr (DownmixToStereo)
|
||||
if constexpr (downmix == audio_downmix::downmix_to_stereo)
|
||||
{
|
||||
const float mid = center * minus_3db;
|
||||
out_buffer[out + 0] += (left + rear_left + (side_left * minus_3db) + mid) * k;
|
||||
out_buffer[out + 1] += (right + rear_right + (side_right * minus_3db) + mid) * k;
|
||||
// Don't mix in the lfe as per dolby specification and based on documentation
|
||||
const float mid = center * 0.5f;
|
||||
out_buffer[out + 0] += left * minus_3db + mid + side_left * 0.5f + rear_left * 0.5f;
|
||||
out_buffer[out + 1] += right * minus_3db + mid + side_right * 0.5f + rear_right * 0.5f;
|
||||
}
|
||||
else if constexpr (downmix == audio_downmix::downmix_to_5_1)
|
||||
{
|
||||
out_buffer[out + 0] += left;
|
||||
out_buffer[out + 1] += right;
|
||||
out_buffer[out + 2] += center;
|
||||
out_buffer[out + 3] += low_freq;
|
||||
out_buffer[out + 4] += side_left + rear_left;
|
||||
out_buffer[out + 5] += side_right + rear_right;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -929,7 +1057,7 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||
{
|
||||
std::memset(out_buffer, 0, out_buffer_sz * sizeof(float));
|
||||
}
|
||||
else if (g_cfg.audio.convert_to_u16)
|
||||
else if (cfg.backend->get_convert_to_u16())
|
||||
{
|
||||
// convert the data from float to u16 with clipping:
|
||||
// 2x MULPS
|
||||
@@ -1037,16 +1165,16 @@ error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32
|
||||
// check attributes
|
||||
if (num_channels != CELL_AUDIO_PORT_2CH &&
|
||||
num_channels != CELL_AUDIO_PORT_8CH &&
|
||||
num_channels)
|
||||
num_channels != 0)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
if (num_blocks != CELL_AUDIO_BLOCK_8 &&
|
||||
num_blocks != CELL_AUDIO_BLOCK_16 &&
|
||||
num_blocks != 2 &&
|
||||
if (num_blocks != 2 &&
|
||||
num_blocks != 4 &&
|
||||
num_blocks != 32)
|
||||
num_blocks != CELL_AUDIO_BLOCK_8 &&
|
||||
num_blocks != CELL_AUDIO_BLOCK_16 &&
|
||||
num_blocks != CELL_AUDIO_BLOCK_32)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
@@ -1092,6 +1220,9 @@ error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PORT_FULL;
|
||||
}
|
||||
|
||||
// TODO: is this necessary in any way? (Based on libaudio.prx)
|
||||
//const u64 num_channels_non_0 = std::max<u64>(1, num_channels);
|
||||
|
||||
port->num_channels = ::narrow<u32>(num_channels);
|
||||
port->num_blocks = ::narrow<u32>(num_blocks);
|
||||
@@ -1104,15 +1235,20 @@ error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32
|
||||
|
||||
if (attr & CELL_AUDIO_PORTATTR_INITLEVEL)
|
||||
{
|
||||
port->level = audioParam->level * g_cfg.audio.volume / 100.0f;
|
||||
port->level = audioParam->level;
|
||||
}
|
||||
else
|
||||
{
|
||||
port->level = g_cfg.audio.volume / 100.0f;
|
||||
port->level = 1.0f;
|
||||
}
|
||||
|
||||
port->level_set.store({ port->level, 0.0f });
|
||||
|
||||
if (port->level <= -1.0f)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PORT_OPEN;
|
||||
}
|
||||
|
||||
*portNum = port->number;
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -1141,10 +1277,18 @@ error_code cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> port
|
||||
|
||||
switch (auto state = port.state.load())
|
||||
{
|
||||
case audio_port_state::closed: portConfig->status = CELL_AUDIO_STATUS_CLOSE; break;
|
||||
case audio_port_state::opened: portConfig->status = CELL_AUDIO_STATUS_READY; break;
|
||||
case audio_port_state::started: portConfig->status = CELL_AUDIO_STATUS_RUN; break;
|
||||
default: fmt::throw_exception("Invalid port state (%d: %d)", portNum, static_cast<u32>(state));
|
||||
case audio_port_state::closed:
|
||||
portConfig->status = CELL_AUDIO_STATUS_CLOSE;
|
||||
break;
|
||||
case audio_port_state::opened:
|
||||
portConfig->status = CELL_AUDIO_STATUS_READY;
|
||||
break;
|
||||
case audio_port_state::started:
|
||||
portConfig->status = CELL_AUDIO_STATUS_RUN;
|
||||
break;
|
||||
default:
|
||||
cellAudio.error("Invalid port state (%d: %d)", portNum, static_cast<u32>(state));
|
||||
return CELL_AUDIO_ERROR_AUDIOSYSTEM;
|
||||
}
|
||||
|
||||
portConfig->nChannel = port.num_channels;
|
||||
@@ -1262,12 +1406,13 @@ error_code cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
|
||||
|
||||
if (port.global_counter < tag)
|
||||
{
|
||||
cellAudio.error("cellAudioGetPortTimestamp(portNum=%d, tag=0x%llx, stamp=*0x%x) -> CELL_AUDIO_ERROR_TAG_NOT_FOUND", portNum, tag, stamp);
|
||||
return CELL_AUDIO_ERROR_TAG_NOT_FOUND;
|
||||
}
|
||||
|
||||
u64 delta_tag = port.global_counter - tag;
|
||||
u64 delta_tag_stamp = delta_tag * g_audio->cfg.audio_block_period;
|
||||
const u64 delta_tag = port.global_counter - tag;
|
||||
const u64 delta_tag_stamp = delta_tag * g_audio->cfg.audio_block_period;
|
||||
|
||||
// Apparently no error is returned if stamp is null
|
||||
*stamp = port.timestamp - delta_tag_stamp;
|
||||
|
||||
return CELL_OK;
|
||||
@@ -1303,6 +1448,7 @@ error_code cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// Apparently no error is returned if tag is null
|
||||
*tag = port.global_counter + blockNo - port.cur_pos;
|
||||
|
||||
return CELL_OK;
|
||||
@@ -1333,8 +1479,6 @@ error_code cellAudioSetPortLevel(u32 portNum, float level)
|
||||
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||
}
|
||||
|
||||
level *= g_cfg.audio.volume / 100.0f;
|
||||
|
||||
if (level >= 0.0f)
|
||||
{
|
||||
port.level_set.exchange({ level, (port.level - level) / 624.0f });
|
||||
@@ -1411,21 +1555,35 @@ error_code AudioSetNotifyEventQueue(u64 key, u32 iFlags)
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
if (!lv2_event_queue::find(key))
|
||||
auto q = lv2_event_queue::find(key);
|
||||
|
||||
if (!q)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_TRANS_EVENT;
|
||||
}
|
||||
|
||||
for (const auto& k : g_audio->keys) // check for duplicates
|
||||
for (auto i = g_audio->keys.cbegin(); i != g_audio->keys.cend();) // check for duplicates
|
||||
{
|
||||
if (k.key == key)
|
||||
auto port = i->port.lock();
|
||||
|
||||
if (port == q)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_TRANS_EVENT;
|
||||
}
|
||||
|
||||
if (!lv2_event_queue::check(port))
|
||||
{
|
||||
// Cleanup, avoid cases where there are multiple ports with the same key
|
||||
i = g_audio->keys.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Set unique source associated with the key
|
||||
g_audio->keys.push_back({g_audio->event_period, iFlags, ((process_getpid() + u64{}) << 32) + lv2_event_port::id_base + (g_audio->key_count++ * lv2_event_port::id_step), key});
|
||||
g_audio->keys.push_back({g_audio->event_period, iFlags, ((process_getpid() + u64{}) << 32) + lv2_event_port::id_base + (g_audio->key_count++ * lv2_event_port::id_step), std::move(q)});
|
||||
g_audio->key_count %= lv2_event_port::id_count;
|
||||
|
||||
return CELL_OK;
|
||||
@@ -1463,7 +1621,7 @@ error_code AudioRemoveNotifyEventQueue(u64 key, u32 iFlags)
|
||||
|
||||
for (auto i = g_audio->keys.cbegin(); i != g_audio->keys.cend(); i++)
|
||||
{
|
||||
if (i->key == key)
|
||||
if ([&](auto port){ return lv2_event_queue::check(port) && port->key == key; }(i->port.lock()))
|
||||
{
|
||||
if (i->flags != iFlags)
|
||||
{
|
||||
@@ -1511,18 +1669,11 @@ error_code cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
if (portNum >= AUDIO_PORT_COUNT || !src || !src.aligned())
|
||||
if (portNum >= AUDIO_PORT_COUNT || !src || !src.aligned() || samples != CELL_AUDIO_BLOCK_SAMPLES)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
if (samples != 256)
|
||||
{
|
||||
// despite the docs, seems that only fixed value is supported
|
||||
cellAudio.error("cellAudioAddData(): invalid samples value (%d)", samples);
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
const audio_port& port = g_audio->ports[portNum];
|
||||
|
||||
const auto dst = port.get_vm_ptr();
|
||||
@@ -1552,18 +1703,11 @@ error_code cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, flo
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
if (portNum >= AUDIO_PORT_COUNT || !src || !src.aligned())
|
||||
if (portNum >= AUDIO_PORT_COUNT || !src || !src.aligned() || samples != CELL_AUDIO_BLOCK_SAMPLES)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
if (samples != 256)
|
||||
{
|
||||
// despite the docs, seems that only fixed value is supported
|
||||
cellAudio.error("cellAudioAdd2chData(): invalid samples value (%d)", samples);
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
const audio_port& port = g_audio->ports[portNum];
|
||||
|
||||
const auto dst = port.get_vm_ptr();
|
||||
@@ -1642,7 +1786,7 @@ error_code cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
|
||||
|
||||
if (port.num_channels == 6)
|
||||
{
|
||||
for (u32 i = 0; i < 256; i++)
|
||||
for (u32 i = 0; i < CELL_AUDIO_BLOCK_SAMPLES; i++)
|
||||
{
|
||||
dst[i * 6 + 0] += src[i * 6 + 0] * volume; // mix L ch
|
||||
dst[i * 6 + 1] += src[i * 6 + 1] * volume; // mix R ch
|
||||
@@ -1654,7 +1798,7 @@ error_code cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
|
||||
}
|
||||
else if (port.num_channels == 8)
|
||||
{
|
||||
for (u32 i = 0; i < 256; i++)
|
||||
for (u32 i = 0; i < CELL_AUDIO_BLOCK_SAMPLES; i++)
|
||||
{
|
||||
dst[i * 8 + 0] += src[i * 6 + 0] * volume; // mix L ch
|
||||
dst[i * 8 + 1] += src[i * 6 + 1] * volume; // mix R ch
|
||||
@@ -1677,6 +1821,18 @@ error_code cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
|
||||
error_code cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
|
||||
{
|
||||
cellAudio.todo("cellAudioMiscSetAccessoryVolume(devNum=%d, volume=%f)", devNum, volume);
|
||||
|
||||
const auto g_audio = g_fxo->get<cell_audio>();
|
||||
|
||||
std::unique_lock lock(g_audio->mutex);
|
||||
|
||||
if (!g_audio->init)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -1689,12 +1845,47 @@ error_code cellAudioSendAck(u64 data3)
|
||||
error_code cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice)
|
||||
{
|
||||
cellAudio.todo("cellAudioSetPersonalDevice(iPersonalStream=%d, iDevice=%d)", iPersonalStream, iDevice);
|
||||
|
||||
const auto g_audio = g_fxo->get<cell_audio>();
|
||||
|
||||
std::unique_lock lock(g_audio->mutex);
|
||||
|
||||
if (!g_audio->init)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
if (iPersonalStream < 0 || iPersonalStream >= 4 ||
|
||||
(iDevice != CELL_AUDIO_PERSONAL_DEVICE_PRIMARY && (iDevice < 0 || iDevice >= 5)))
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellAudioUnsetPersonalDevice(s32 iPersonalStream)
|
||||
{
|
||||
cellAudio.todo("cellAudioUnsetPersonalDevice(iPersonalStream=%d)", iPersonalStream);
|
||||
|
||||
const auto g_audio = g_fxo->get<cell_audio>();
|
||||
|
||||
std::unique_lock lock(g_audio->mutex);
|
||||
|
||||
if (!g_audio->init)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
if (iPersonalStream < 0 || iPersonalStream >= 4)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "Emu/Audio/AudioBackend.h"
|
||||
#include "Emu/Audio/AudioDumper.h"
|
||||
|
||||
struct lv2_event_queue;
|
||||
|
||||
// Error codes
|
||||
enum CellAudioError : u32
|
||||
{
|
||||
@@ -29,23 +31,31 @@ enum CellAudioError : u32
|
||||
// constants
|
||||
enum
|
||||
{
|
||||
CELL_AUDIO_BLOCK_16 = 16,
|
||||
CELL_AUDIO_BLOCK_8 = 8,
|
||||
CELL_AUDIO_BLOCK_16 = 16,
|
||||
CELL_AUDIO_BLOCK_32 = 32,
|
||||
CELL_AUDIO_BLOCK_SAMPLES = 256,
|
||||
|
||||
CELL_AUDIO_CREATEEVENTFLAG_SPU = 0x00000001,
|
||||
CELL_AUDIO_EVENT_HEADPHONE = 1,
|
||||
|
||||
CELL_AUDIO_EVENT_MIX = 0,
|
||||
CELL_AUDIO_EVENT_HEADPHONE = 1,
|
||||
|
||||
CELL_AUDIO_EVENTFLAG_BEFOREMIX = 0x80000000,
|
||||
CELL_AUDIO_EVENTFLAG_DECIMATE_2 = 0x08000000,
|
||||
CELL_AUDIO_EVENTFLAG_DECIMATE_4 = 0x10000000,
|
||||
CELL_AUDIO_EVENTFLAG_HEADPHONE = 0x20000000,
|
||||
CELL_AUDIO_EVENTFLAG_NOMIX = 0x40000000,
|
||||
|
||||
CELL_AUDIO_MAX_PORT = 4,
|
||||
CELL_AUDIO_MAX_PORT_2 = 8,
|
||||
|
||||
CELL_AUDIO_MISC_ACCVOL_ALLDEVICE = 0x0000ffffUL,
|
||||
CELL_AUDIO_PERSONAL_DEVICE_PRIMARY = 0x8000,
|
||||
|
||||
CELL_AUDIO_PORT_2CH = 2,
|
||||
CELL_AUDIO_PORT_8CH = 8,
|
||||
|
||||
CELL_AUDIO_PORTATTR_BGM = 0x0000000000000010ULL,
|
||||
CELL_AUDIO_PORTATTR_INITLEVEL = 0x0000000000001000ULL,
|
||||
CELL_AUDIO_PORTATTR_OUT_NO_ROUTE = 0x0000000000100000ULL,
|
||||
@@ -54,6 +64,7 @@ enum
|
||||
CELL_AUDIO_PORTATTR_OUT_PERSONAL_2 = 0x0000000004000000ULL,
|
||||
CELL_AUDIO_PORTATTR_OUT_PERSONAL_3 = 0x0000000008000000ULL,
|
||||
CELL_AUDIO_PORTATTR_OUT_SECONDARY = 0x0000000000000001ULL,
|
||||
|
||||
CELL_AUDIO_STATUS_CLOSE = 0x1010,
|
||||
CELL_AUDIO_STATUS_READY = 1,
|
||||
CELL_AUDIO_STATUS_RUN = 2,
|
||||
@@ -89,6 +100,7 @@ enum : u32
|
||||
MAX_AUDIO_EVENT_QUEUES = 64,
|
||||
|
||||
AUDIO_BLOCK_SIZE_2CH = 2 * AUDIO_BUFFER_SAMPLES,
|
||||
AUDIO_BLOCK_SIZE_6CH = 6 * AUDIO_BUFFER_SAMPLES,
|
||||
AUDIO_BLOCK_SIZE_8CH = 8 * AUDIO_BUFFER_SAMPLES,
|
||||
|
||||
PORT_BUFFER_TAG_COUNT = 6,
|
||||
@@ -97,6 +109,10 @@ enum : u32
|
||||
PORT_BUFFER_TAG_DELTA_2CH = PORT_BUFFER_TAG_LAST_2CH / (PORT_BUFFER_TAG_COUNT - 1),
|
||||
PORT_BUFFER_TAG_FIRST_2CH = PORT_BUFFER_TAG_LAST_2CH % (PORT_BUFFER_TAG_COUNT - 1),
|
||||
|
||||
PORT_BUFFER_TAG_LAST_6CH = AUDIO_BLOCK_SIZE_6CH - 1,
|
||||
PORT_BUFFER_TAG_DELTA_6CH = PORT_BUFFER_TAG_LAST_6CH / (PORT_BUFFER_TAG_COUNT - 1),
|
||||
PORT_BUFFER_TAG_FIRST_6CH = PORT_BUFFER_TAG_LAST_6CH % (PORT_BUFFER_TAG_COUNT - 1),
|
||||
|
||||
PORT_BUFFER_TAG_LAST_8CH = AUDIO_BLOCK_SIZE_8CH - 1,
|
||||
PORT_BUFFER_TAG_DELTA_8CH = PORT_BUFFER_TAG_LAST_8CH / (PORT_BUFFER_TAG_COUNT - 1),
|
||||
PORT_BUFFER_TAG_FIRST_8CH = PORT_BUFFER_TAG_LAST_8CH % (PORT_BUFFER_TAG_COUNT - 1),
|
||||
@@ -171,49 +187,59 @@ struct audio_port
|
||||
|
||||
struct cell_audio_config
|
||||
{
|
||||
const std::shared_ptr<AudioBackend> backend = Emu.GetCallbacks().get_audio();
|
||||
struct raw_config
|
||||
{
|
||||
bool buffering_enabled = false;
|
||||
s64 desired_buffer_duration = 0;
|
||||
bool enable_time_stretching = false;
|
||||
s64 time_stretching_threshold = 0;
|
||||
bool convert_to_u16 = false;
|
||||
u32 start_threshold = 0;
|
||||
u32 sampling_period_multiplier = 0;
|
||||
audio_downmix downmix = audio_downmix::downmix_to_stereo;
|
||||
audio_renderer renderer = audio_renderer::null;
|
||||
} raw;
|
||||
|
||||
const u32 audio_channels = AudioBackend::get_channels();
|
||||
const u32 audio_sampling_rate = AudioBackend::get_sampling_rate();
|
||||
const u32 audio_block_period = AUDIO_BUFFER_SAMPLES * 1000000 / audio_sampling_rate;
|
||||
std::shared_ptr<AudioBackend> backend = nullptr;
|
||||
|
||||
const u32 audio_buffer_length = AUDIO_BUFFER_SAMPLES * audio_channels;
|
||||
const u32 audio_buffer_size = audio_buffer_length * AudioBackend::get_sample_size();
|
||||
u32 audio_channels = 0;
|
||||
u32 audio_sampling_rate = 0;
|
||||
u32 audio_block_period = 0;
|
||||
|
||||
u32 audio_buffer_length = 0;
|
||||
u32 audio_buffer_size = 0;
|
||||
|
||||
/*
|
||||
* Buffering
|
||||
*/
|
||||
const u64 desired_buffer_duration = g_cfg.audio.desired_buffer_duration * 1000llu;
|
||||
private:
|
||||
const bool raw_buffering_enabled = static_cast<bool>(g_cfg.audio.enable_buffering);
|
||||
public:
|
||||
|
||||
u64 desired_buffer_duration = 0;
|
||||
|
||||
// We need a non-blocking backend (implementing play/pause/flush) to be able to do buffering correctly
|
||||
// We also need to be able to query the current playing state
|
||||
const bool buffering_enabled = raw_buffering_enabled && backend->has_capability(AudioBackend::PLAY_PAUSE_FLUSH | AudioBackend::IS_PLAYING);
|
||||
bool buffering_enabled = false;
|
||||
|
||||
const u64 minimum_block_period = audio_block_period / 2; // the block period will not be dynamically lowered below this value (usecs)
|
||||
const u64 maximum_block_period = (6 * audio_block_period) / 5; // the block period will not be dynamically increased above this value (usecs)
|
||||
u64 minimum_block_period = 0; // the block period will not be dynamically lowered below this value (usecs)
|
||||
u64 maximum_block_period = 0; // the block period will not be dynamically increased above this value (usecs)
|
||||
|
||||
const u32 desired_full_buffers = buffering_enabled ? static_cast<u32>(desired_buffer_duration / audio_block_period) + 3 : 2;
|
||||
const u32 num_allocated_buffers = desired_full_buffers + EXTRA_AUDIO_BUFFERS; // number of ringbuffer buffers
|
||||
u32 desired_full_buffers = 0;
|
||||
u32 num_allocated_buffers = 0; // number of ringbuffer buffers
|
||||
|
||||
const f32 period_average_alpha = 0.02f; // alpha factor for the m_average_period rolling average
|
||||
|
||||
const s64 period_comparison_margin = 250; // when comparing the current period time with the desired period, if it is below this number of usecs we do not wait any longer
|
||||
|
||||
const u64 fully_untouched_timeout = 2 * audio_block_period; // timeout if the game has not touched any audio buffer yet
|
||||
const u64 partially_untouched_timeout = 4 * audio_block_period; // timeout if the game has not touched all audio buffers yet
|
||||
u64 fully_untouched_timeout = 0; // timeout if the game has not touched any audio buffer yet
|
||||
u64 partially_untouched_timeout = 0; // timeout if the game has not touched all audio buffers yet
|
||||
|
||||
/*
|
||||
* Time Stretching
|
||||
*/
|
||||
private:
|
||||
const bool raw_time_stretching_enabled = buffering_enabled && g_cfg.audio.enable_time_stretching && (g_cfg.audio.time_stretching_threshold > 0);
|
||||
public:
|
||||
// We need to be able to set a dynamic frequency ratio to be able to do time stretching
|
||||
const bool time_stretching_enabled = raw_time_stretching_enabled && backend->has_capability(AudioBackend::SET_FREQUENCY_RATIO);
|
||||
|
||||
const f32 time_stretching_threshold = g_cfg.audio.time_stretching_threshold / 100.0f; // we only apply time stretching below this buffer fill rate (adjusted for average period)
|
||||
// We need to be able to set a dynamic frequency ratio to be able to do time stretching
|
||||
bool time_stretching_enabled = false;
|
||||
|
||||
f32 time_stretching_threshold = 0.0f; // we only apply time stretching below this buffer fill rate (adjusted for average period)
|
||||
const f32 time_stretching_step = 0.1f; // will only reduce/increase the frequency ratio in steps of at least this value
|
||||
const f32 time_stretching_scale = 0.9f;
|
||||
|
||||
@@ -221,6 +247,11 @@ public:
|
||||
* Constructor
|
||||
*/
|
||||
cell_audio_config();
|
||||
|
||||
/*
|
||||
* Config changes
|
||||
*/
|
||||
void reset();
|
||||
};
|
||||
|
||||
class audio_ringbuffer
|
||||
@@ -321,12 +352,13 @@ public:
|
||||
|
||||
class cell_audio_thread
|
||||
{
|
||||
private:
|
||||
std::unique_ptr<audio_ringbuffer> ringbuffer;
|
||||
|
||||
void reset_ports(s32 offset = 0);
|
||||
void advance(u64 timestamp, bool reset = true);
|
||||
std::tuple<u32, u32, u32, u32> count_port_buffer_tags();
|
||||
template <bool DownmixToStereo>
|
||||
template <audio_downmix downmix>
|
||||
void mix(float *out_buffer, s32 offset = 0);
|
||||
void finish_port_volume_stepping();
|
||||
|
||||
@@ -335,8 +367,11 @@ class cell_audio_thread
|
||||
return (time_left > 350) ? time_left - 250 : 100;
|
||||
}
|
||||
|
||||
void update_config();
|
||||
|
||||
public:
|
||||
cell_audio_config cfg;
|
||||
atomic_t<bool> m_update_configuration = false;
|
||||
|
||||
shared_mutex mutex;
|
||||
atomic_t<u32> init = 0;
|
||||
@@ -349,7 +384,7 @@ public:
|
||||
u8 start_period; // Starting event_period
|
||||
u32 flags; // iFlags
|
||||
u64 source; // Event source
|
||||
u64 key; // Key
|
||||
std::weak_ptr<lv2_event_queue> port; // Underlying event port
|
||||
};
|
||||
|
||||
std::vector<key_info> keys;
|
||||
@@ -359,7 +394,7 @@ public:
|
||||
u64 m_counter = 0;
|
||||
u64 m_start_time = 0;
|
||||
u64 m_dynamic_period = 0;
|
||||
f32 m_average_playtime;
|
||||
f32 m_average_playtime = 0.0f;
|
||||
|
||||
void operator()();
|
||||
|
||||
@@ -389,3 +424,9 @@ public:
|
||||
};
|
||||
|
||||
using cell_audio = named_thread<cell_audio_thread>;
|
||||
|
||||
namespace audio
|
||||
{
|
||||
cell_audio_config::raw_config get_raw_config();
|
||||
void configure_audio();
|
||||
}
|
||||
|
||||
@@ -1300,7 +1300,7 @@ void camera_context::operator()()
|
||||
data3 = 0; // unused
|
||||
}
|
||||
|
||||
if (queue->send(evt_data.source, CELL_CAMERA_FRAME_UPDATE, data2, data3)) [[likely]]
|
||||
if (queue->send(evt_data.source, CELL_CAMERA_FRAME_UPDATE, data2, data3) == 0) [[likely]]
|
||||
{
|
||||
++frame_num;
|
||||
}
|
||||
@@ -1347,7 +1347,7 @@ void camera_context::send_attach_state(bool attached)
|
||||
|
||||
if (auto queue = lv2_event_queue::find(key))
|
||||
{
|
||||
if (queue->send(evt_data.source, attached ? CELL_CAMERA_ATTACH : CELL_CAMERA_DETACH, 0, 0)) [[likely]]
|
||||
if (queue->send(evt_data.source, attached ? CELL_CAMERA_ATTACH : CELL_CAMERA_DETACH, 0, 0) == 0) [[likely]]
|
||||
{
|
||||
is_attached = attached;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,43 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "cellDaisy.h"
|
||||
|
||||
LOG_CHANNEL(cellDaisy);
|
||||
|
||||
template <>
|
||||
void fmt_class_string<CellDaisyError>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](CellDaisyError value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
STR_CASE(CELL_DAISY_ERROR_NO_BEGIN);
|
||||
STR_CASE(CELL_DAISY_ERROR_INVALID_PORT_ATTACH);
|
||||
STR_CASE(CELL_DAISY_ERROR_NOT_IMPLEMENTED);
|
||||
STR_CASE(CELL_DAISY_ERROR_AGAIN);
|
||||
STR_CASE(CELL_DAISY_ERROR_INVAL);
|
||||
STR_CASE(CELL_DAISY_ERROR_PERM);
|
||||
STR_CASE(CELL_DAISY_ERROR_BUSY);
|
||||
STR_CASE(CELL_DAISY_ERROR_STAT);
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
using LFQueue2 = struct CellDaisyLFQueue2;
|
||||
using Lock = struct CellDaisyLock;
|
||||
using ScatterGatherInterlock = struct CellDaisyScatterGatherInterlock;
|
||||
using AtomicInterlock = volatile struct CellDaisyAtomicInterlock;
|
||||
|
||||
s32 cellDaisyLFQueue2GetPopPointer(vm::ptr<LFQueue2> queue, vm::ptr<s32> pPointer, u32 isBlocking)
|
||||
error_code cellDaisyLFQueue2GetPopPointer(vm::ptr<LFQueue2> queue, vm::ptr<s32> pPointer, u32 isBlocking)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLFQueue2GetPopPointer()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLFQueue2CompletePopPointer(vm::ptr<LFQueue2> queue, s32 pointer, vm::ptr<s32(vm::ptr<void>, u32)> fpSendSignal, u32 isQueueFull)
|
||||
error_code cellDaisyLFQueue2CompletePopPointer(vm::ptr<LFQueue2> queue, s32 pointer, vm::ptr<s32(vm::ptr<void>, u32)> fpSendSignal, u32 isQueueFull)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLFQueue2CompletePopPointer()");
|
||||
return CELL_OK;
|
||||
@@ -27,7 +48,7 @@ void cellDaisyLFQueue2PushOpen(vm::ptr<LFQueue2> queue)
|
||||
cellDaisy.todo("cellDaisyLFQueue2PushOpen()");
|
||||
}
|
||||
|
||||
s32 cellDaisyLFQueue2PushClose(vm::ptr<LFQueue2> queue, vm::ptr<s32(vm::ptr<void>, u32)> fpSendSignal)
|
||||
error_code cellDaisyLFQueue2PushClose(vm::ptr<LFQueue2> queue, vm::ptr<s32(vm::ptr<void>, u32)> fpSendSignal)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLFQueue2PushClose()");
|
||||
return CELL_OK;
|
||||
@@ -38,73 +59,73 @@ void cellDaisyLFQueue2PopOpen(vm::ptr<LFQueue2> queue)
|
||||
cellDaisy.todo("cellDaisyLFQueue2PopOpen()");
|
||||
}
|
||||
|
||||
s32 cellDaisyLFQueue2PopClose(vm::ptr<LFQueue2> queue, vm::ptr<s32(vm::ptr<void>, u32)> fpSendSignal)
|
||||
error_code cellDaisyLFQueue2PopClose(vm::ptr<LFQueue2> queue, vm::ptr<s32(vm::ptr<void>, u32)> fpSendSignal)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLFQueue2PopClose()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLFQueue2HasUnfinishedConsumer(vm::ptr<LFQueue2> queue, u32 isCancelled)
|
||||
error_code cellDaisyLFQueue2HasUnfinishedConsumer(vm::ptr<LFQueue2> queue, u32 isCancelled)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLFQueue2HasUnfinishedConsumer()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisy_snprintf(vm::ptr<char> buffer, u32 count, vm::cptr<char> fmt, ppu_va_args_t fmt_args)
|
||||
error_code cellDaisy_snprintf(vm::ptr<char> buffer, u32 count, vm::cptr<char> fmt, ppu_va_args_t fmt_args)
|
||||
{
|
||||
cellDaisy.todo("cellDaisy_snprintf()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLock_initialize(vm::ptr<Lock> _this, u32 depth)
|
||||
error_code cellDaisyLock_initialize(vm::ptr<Lock> _this, u32 depth)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLock_initialize()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLock_getNextHeadPointer(vm::ptr<Lock> _this)
|
||||
error_code cellDaisyLock_getNextHeadPointer(vm::ptr<Lock> _this)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLock_getNextHeadPointer()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLock_getNextTailPointer(vm::ptr<Lock> _this)
|
||||
error_code cellDaisyLock_getNextTailPointer(vm::ptr<Lock> _this)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLock_getNextTailPointer()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLock_completeConsume(vm::ptr<Lock> _this, u32 pointer)
|
||||
error_code cellDaisyLock_completeConsume(vm::ptr<Lock> _this, u32 pointer)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLock_completeConsume()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLock_completeProduce(vm::ptr<Lock> _this, u32 pointer)
|
||||
error_code cellDaisyLock_completeProduce(vm::ptr<Lock> _this, u32 pointer)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLock_completeProduce()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLock_pushOpen(vm::ptr<Lock> _this)
|
||||
error_code cellDaisyLock_pushOpen(vm::ptr<Lock> _this)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLock_pushOpen()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLock_pushClose(vm::ptr<Lock> _this)
|
||||
error_code cellDaisyLock_pushClose(vm::ptr<Lock> _this)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLock_pushClose()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLock_popOpen(vm::ptr<Lock> _this)
|
||||
error_code cellDaisyLock_popOpen(vm::ptr<Lock> _this)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLock_popOpen()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyLock_popClose(vm::ptr<Lock> _this)
|
||||
error_code cellDaisyLock_popClose(vm::ptr<Lock> _this)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyLock_popClose()");
|
||||
return CELL_OK;
|
||||
@@ -125,13 +146,13 @@ void cellDaisyScatterGatherInterlock_9tor(vm::ptr<ScatterGatherInterlock> _this)
|
||||
cellDaisy.todo("cellDaisyScatterGatherInterlock_9tor()");
|
||||
}
|
||||
|
||||
s32 cellDaisyScatterGatherInterlock_probe(vm::ptr<ScatterGatherInterlock> _this, u32 isBlocking)
|
||||
error_code cellDaisyScatterGatherInterlock_probe(vm::ptr<ScatterGatherInterlock> _this, u32 isBlocking)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyScatterGatherInterlock_probe()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDaisyScatterGatherInterlock_release(vm::ptr<ScatterGatherInterlock> _this)
|
||||
error_code cellDaisyScatterGatherInterlock_release(vm::ptr<ScatterGatherInterlock> _this)
|
||||
{
|
||||
cellDaisy.todo("cellDaisyScatterGatherInterlock_release()");
|
||||
return CELL_OK;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user