Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f85add8776 | |||
| 73bea0cfc6 | |||
| e09ceb4f18 | |||
| 47661ac2ef | |||
| e1461067eb | |||
| 67a4b020fc | |||
| c69d7bc758 | |||
| 3926889c97 | |||
| 34074a9c70 | |||
| 81380a0d60 | |||
| 65878c69be | |||
| 7c4fb183d0 | |||
| 699e1f0516 | |||
| 269d45bfc0 | |||
| f371f8be3e | |||
| a965607f14 | |||
| 59567daea7 | |||
| ef566186be | |||
| 46150322a3 | |||
| 2bb2c748bd | |||
| a5c4951914 | |||
| dfd80d2165 | |||
| 4dbaaafbf1 | |||
| 25c2c601c9 | |||
| 9403d87d84 | |||
| f50d374393 | |||
| eeeb7fb4ab | |||
| 20c9dcd2d6 | |||
| 38ff48595d | |||
| c7c206ecdc | |||
| bfd2adab5e | |||
| 786ac95dc0 | |||
| 1660dc24b3 | |||
| aa50b0fbb9 | |||
| 3df93dcc19 | |||
| 1f0328c5d5 | |||
| 3f635033cc | |||
| 8130babad3 | |||
| 37c4406b23 | |||
| 5d6b8b20c4 | |||
| 396c4bbdd7 | |||
| 16a0ae6a7b | |||
| dd28d100d6 | |||
| 91e22aa4e4 | |||
| cdc78f81f7 | |||
| 91491c7cf3 | |||
| b3492b73ad | |||
| 15791cf94e | |||
| 5417d4854d | |||
| bb1c0a5eee | |||
| 3a65359d59 | |||
| ffa835efac | |||
| f241825c73 | |||
| 2c8c788d81 | |||
| 2ae9753d79 | |||
| 93e6aa6310 | |||
| ae74aa336f | |||
| 64866098e7 | |||
| 20b54f3086 | |||
| aac4fbe941 | |||
| 356b2f5910 | |||
| 4d493bbb80 | |||
| 49729086ac | |||
| 329655a1bf | |||
| b0067e8934 | |||
| 22d9343f2c | |||
| 9c93ec0bc3 | |||
| c6c72d3721 | |||
| 424f9306c4 | |||
| 5d552ca236 | |||
| 28896acb83 | |||
| 6f37be1afd | |||
| 4fd581b812 | |||
| bad6e99258 | |||
| 27359d3d32 | |||
| f8f34787b3 | |||
| d61c2496b6 | |||
| 5569c5c803 | |||
| d0812ee5a8 | |||
| 9634e58f0a | |||
| 9610d45ebf | |||
| 85c813d84c | |||
| ab55500f01 | |||
| af0432a44b | |||
| 2b7161208e | |||
| 5514d7c3d8 | |||
| 823e17288c | |||
| 866daf2059 | |||
| ae38cef7b1 | |||
| e36f55ea41 | |||
| 819d3dc7a6 | |||
| ac99b2036d | |||
| 46cce45b13 | |||
| d685348644 | |||
| d15b7a9955 | |||
| 99db73a34f | |||
| 85e4eff571 | |||
| d8bc2d5c75 | |||
| 4704c03209 | |||
| 70faef3fdb | |||
| 663ff55af9 | |||
| 229c1c38a3 |
@@ -1,9 +1,10 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# Pull all the submodules except llvm, opencv, libpng, sdl and curl
|
||||
# Pull all the submodules except some
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init --depth 1 $(awk '/path/ && !/llvm/ && !/opencv/ && !/libpng/ && !/libsdl-org/ && !/curl/ { print $3 }' .gitmodules)
|
||||
git config --global --add safe.directory .
|
||||
git submodule -q update --init --depth 1 $(awk '/path/ && !/llvm/ && !/opencv/ && !/libpng/ && !/libsdl-org/ && !/curl/ && !/zlib/ && !/libusb/ && !/feralinteractive/ { print $3 }' .gitmodules)
|
||||
|
||||
CONFIGURE_ARGS="
|
||||
-DWITH_LLVM=ON
|
||||
@@ -13,6 +14,7 @@ CONFIGURE_ARGS="
|
||||
-DUSE_SYSTEM_FFMPEG=ON
|
||||
-DUSE_SYSTEM_CURL=ON
|
||||
-DUSE_SYSTEM_LIBPNG=ON
|
||||
-DUSE_SYSTEM_LIBUSB=ON
|
||||
-DUSE_SYSTEM_OPENCV=ON
|
||||
"
|
||||
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
if [ -z "$CIRRUS_CI" ]; then
|
||||
cd rpcs3 || exit 1
|
||||
fi
|
||||
cd rpcs3 || exit 1
|
||||
|
||||
shellcheck .ci/*.sh
|
||||
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
# Pull all the submodules except llvm, opencv, sdl and curl
|
||||
# Pull all the submodules except some
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ && !/opencv/ && !/libsdl-org/ && !/curl/ { print $3 }' .gitmodules)
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ && !/opencv/ && !/libsdl-org/ && !/curl/ && !/zlib/ { print $3 }' .gitmodules)
|
||||
|
||||
mkdir build && cd build || exit 1
|
||||
|
||||
@@ -52,10 +50,6 @@ ninja; build_status=$?;
|
||||
cd ..
|
||||
|
||||
# If it compiled succesfully let's deploy.
|
||||
# Azure and Cirrus publish PRs as artifacts only.
|
||||
{ [ "$CI_HAS_ARTIFACTS" = "true" ];
|
||||
} && SHOULD_DEPLOY="true" || SHOULD_DEPLOY="false"
|
||||
|
||||
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
|
||||
if [ "$build_status" -eq 0 ]; then
|
||||
.ci/deploy-linux.sh "aarch64"
|
||||
fi
|
||||
|
||||
+4
-10
@@ -1,17 +1,15 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
if [ -z "$CIRRUS_CI" ]; then
|
||||
cd rpcs3 || exit 1
|
||||
fi
|
||||
cd rpcs3 || exit 1
|
||||
|
||||
shellcheck .ci/*.sh
|
||||
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
# Pull all the submodules except llvm, opencv, sdl and curl
|
||||
# Pull all the submodules except some
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ && !/opencv/ && !/libsdl-org/ && !/curl/ { print $3 }' .gitmodules)
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ && !/opencv/ && !/libsdl-org/ && !/curl/ && !/zlib/ { print $3 }' .gitmodules)
|
||||
|
||||
mkdir build && cd build || exit 1
|
||||
|
||||
@@ -63,10 +61,6 @@ ninja; build_status=$?;
|
||||
cd ..
|
||||
|
||||
# If it compiled succesfully let's deploy.
|
||||
# Azure and Cirrus publish PRs as artifacts only.
|
||||
{ [ "$CI_HAS_ARTIFACTS" = "true" ];
|
||||
} && SHOULD_DEPLOY="true" || SHOULD_DEPLOY="false"
|
||||
|
||||
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
|
||||
if [ "$build_status" -eq 0 ]; then
|
||||
.ci/deploy-linux.sh "x86_64"
|
||||
fi
|
||||
|
||||
+9
-11
@@ -6,14 +6,14 @@ export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
||||
export HOMEBREW_NO_ENV_HINTS=1
|
||||
export HOMEBREW_NO_INSTALL_CLEANUP=1
|
||||
|
||||
/opt/homebrew/bin/brew install -f --overwrite --quiet nasm ninja p7zip ccache pipenv gnutls freetype #create-dmg
|
||||
/opt/homebrew/bin/brew install -f --overwrite --quiet nasm ninja p7zip ccache pipenv gnutls freetype googletest #create-dmg
|
||||
/opt/homebrew/bin/brew install -f --quiet ffmpeg@5
|
||||
/opt/homebrew/bin/brew install --quiet "llvm@$LLVM_COMPILER_VER" glew cmake sdl3 vulkan-headers coreutils
|
||||
/opt/homebrew/bin/brew link -f --quiet "llvm@$LLVM_COMPILER_VER" ffmpeg@5
|
||||
|
||||
# moltenvk based on commit for 1.3.0 release
|
||||
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/7255441cbcafabaa8950f67c7ec55ff499dbb2d3/Formula/m/molten-vk.rb
|
||||
/opt/homebrew/bin/brew install -f --overwrite --formula --quiet ./molten-vk.rb
|
||||
/opt/homebrew/bin/brew install -f --overwrite --formula --quiet ./molten-vk.rb
|
||||
export CXX=clang++
|
||||
export CC=clang
|
||||
|
||||
@@ -32,7 +32,7 @@ if [ ! -d "/tmp/Qt/$QT_VER" ]; then
|
||||
git clone https://github.com/engnr/qt-downloader.git
|
||||
cd qt-downloader
|
||||
git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597
|
||||
# nested Qt 6.9.0 URL workaround
|
||||
# nested Qt 6.9.1 URL workaround
|
||||
# sed -i '' "s/'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/'qt{0}_{0}{1}{2}'.format(major, minor, patch), 'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/g" qt-downloader
|
||||
# sed -i '' "s/'{}\/{}\/qt{}_{}\/'/'{0}\/{1}\/qt{2}_{3}\/qt{2}_{3}\/'/g" qt-downloader
|
||||
# archived Qt 6.7.3 URL workaround
|
||||
@@ -41,7 +41,7 @@ if [ ! -d "/tmp/Qt/$QT_VER" ]; then
|
||||
arch -arm64 "$BREW_PATH/bin/pipenv" run pip3 uninstall py7zr requests semantic_version lxml
|
||||
arch -arm64 "$BREW_PATH/bin/pipenv" run pip3 install py7zr requests semantic_version lxml --no-cache
|
||||
mkdir -p "$QT_VER/macos" ; ln -s "macos" "$QT_VER/clang_64"
|
||||
# sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader" # Qt 6.9.0 workaround
|
||||
# sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader" # Qt 6.9.1 workaround
|
||||
arch -arm64 "$BREW_PATH/bin/pipenv" run "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats # -o "$QT_VER/clang_64"
|
||||
fi
|
||||
|
||||
@@ -67,7 +67,7 @@ export LLVM_DIR
|
||||
LLVM_DIR="$BREW_PATH/opt/llvm@$LLVM_COMPILER_VER"
|
||||
# exclude ffmpeg, LLVM, opencv, and sdl from submodule update
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/ffmpeg/ && !/llvm/ && !/opencv/ && !/SDL/ { print $3 }' .gitmodules)
|
||||
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/ffmpeg/ && !/llvm/ && !/opencv/ && !/SDL/ && !/feralinteractive/ { print $3 }' .gitmodules)
|
||||
|
||||
# 3rdparty fixes
|
||||
sed -i '' "s/extern const double NSAppKitVersionNumber;/const double NSAppKitVersionNumber = 1343;/g" 3rdparty/hidapi/hidapi/mac/hid.c
|
||||
@@ -77,8 +77,8 @@ mkdir build && cd build || exit 1
|
||||
export MACOSX_DEPLOYMENT_TARGET=14.0
|
||||
|
||||
"$BREW_PATH/bin/cmake" .. \
|
||||
-DBUILD_RPCS3_TESTS=OFF \
|
||||
-DRUN_RPCS3_TESTS=OFF \
|
||||
-DBUILD_RPCS3_TESTS="${RUN_UNIT_TESTS}" \
|
||||
-DRUN_RPCS3_TESTS="${RUN_UNIT_TESTS}" \
|
||||
-DUSE_SDL=ON \
|
||||
-DUSE_DISCORD_RPC=ON \
|
||||
-DUSE_VULKAN=ON \
|
||||
@@ -115,9 +115,7 @@ export MACOSX_DEPLOYMENT_TARGET=14.0
|
||||
|
||||
cd ..
|
||||
|
||||
{ [ "$CI_HAS_ARTIFACTS" = "true" ];
|
||||
} && SHOULD_DEPLOY="true" || SHOULD_DEPLOY="false"
|
||||
|
||||
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
|
||||
# If it compiled succesfully let's deploy.
|
||||
if [ "$build_status" -eq 0 ]; then
|
||||
.ci/deploy-mac-arm64.sh
|
||||
fi
|
||||
|
||||
+5
-7
@@ -36,7 +36,7 @@ if [ ! -d "/tmp/Qt/$QT_VER" ]; then
|
||||
git clone https://github.com/engnr/qt-downloader.git
|
||||
cd qt-downloader
|
||||
git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597
|
||||
# nested Qt 6.9.0 URL workaround
|
||||
# nested Qt 6.9.1 URL workaround
|
||||
# sed -i '' "s/'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/'qt{0}_{0}{1}{2}'.format(major, minor, patch), 'qt{0}_{0}{1}{2}'.format(major, minor, patch)]))/g" qt-downloader
|
||||
# sed -i '' "s/'{}\/{}\/qt{}_{}\/'/'{0}\/{1}\/qt{2}_{3}\/qt{2}_{3}\/'/g" qt-downloader
|
||||
# archived Qt 6.7.3 URL workaround
|
||||
@@ -44,7 +44,7 @@ if [ ! -d "/tmp/Qt/$QT_VER" ]; then
|
||||
cd "/tmp/Qt"
|
||||
arch -x86_64 "$BREW_X64_PATH/bin/pipenv" --python "$BREW_X64_PATH/bin/python3" run pip3 install py7zr requests semantic_version lxml
|
||||
mkdir -p "$QT_VER/macos" ; ln -s "macos" "$QT_VER/clang_64"
|
||||
# sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader" # Qt 6.9.0 workaround
|
||||
# sed -i '' 's/args\.version \/ derive_toolchain_dir(args) \/ //g' "$WORKDIR/qt-downloader/qt-downloader" # Qt 6.9.1 workaround
|
||||
arch -x86_64 "$BREW_X64_PATH/bin/pipenv" --python "$BREW_X64_PATH/bin/python3" run "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats # -o "$QT_VER/clang_64"
|
||||
fi
|
||||
|
||||
@@ -70,7 +70,7 @@ export LLVM_DIR
|
||||
LLVM_DIR="BREW_X64_PATH/opt/llvm@$LLVM_COMPILER_VER"
|
||||
# exclude ffmpeg, LLVM, opencv, and sdl from submodule update
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/ffmpeg/ && !/llvm/ && !/opencv/ && !/SDL/ { print $3 }' .gitmodules)
|
||||
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/ffmpeg/ && !/llvm/ && !/opencv/ && !/SDL/ && !/feralinteractive/ { print $3 }' .gitmodules)
|
||||
|
||||
# 3rdparty fixes
|
||||
sed -i '' "s/extern const double NSAppKitVersionNumber;/const double NSAppKitVersionNumber = 1343;/g" 3rdparty/hidapi/hidapi/mac/hid.c
|
||||
@@ -118,9 +118,7 @@ export MACOSX_DEPLOYMENT_TARGET=14.0
|
||||
|
||||
cd ..
|
||||
|
||||
{ [ "$CI_HAS_ARTIFACTS" = "true" ];
|
||||
} && SHOULD_DEPLOY="true" || SHOULD_DEPLOY="false"
|
||||
|
||||
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
|
||||
# If it compiled succesfully let's deploy.
|
||||
if [ "$build_status" -eq 0 ]; then
|
||||
.ci/deploy-mac.sh
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
# .ci/build-windows-clang-cl.ps1
|
||||
# Enable strict error handling
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
trap {
|
||||
Write-Host "ERROR: $($_.Exception.Message)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Starting RPCS3 build (PowerShell script)"
|
||||
|
||||
# Automatically find clang_rt.builtins-x86_64.lib
|
||||
Write-Host "Searching for clang_rt.builtins-x86_64.lib ..."
|
||||
$clangBuiltinsLibPath = Get-ChildItem -Path "C:/Program Files/LLVM/lib/clang" -Recurse -Filter "clang_rt.builtins-x86_64.lib" -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -match "windows\\clang_rt\.builtins-x86_64\.lib$" } |
|
||||
Select-Object -First 1
|
||||
|
||||
if (-not $clangBuiltinsLibPath) {
|
||||
Write-Error "Could not find clang_rt.builtins-x86_64.lib in LLVM installation."
|
||||
exit 1
|
||||
}
|
||||
|
||||
function Get-ShortPath([string]$path) {
|
||||
$fso = New-Object -ComObject Scripting.FileSystemObject
|
||||
return $fso.GetFolder($path).ShortPath
|
||||
}
|
||||
|
||||
$clangBuiltinsDir = Split-Path -Parent $clangBuiltinsLibPath.FullName
|
||||
$clangBuiltinsDirShort = Get-ShortPath $clangBuiltinsDir
|
||||
$clangBuiltinsLib = Split-Path -Leaf $clangBuiltinsLibPath.FullName
|
||||
$clangPath = "C:/Program Files/LLVM/bin"
|
||||
|
||||
Write-Host "Found Clang builtins library: $clangBuiltinsLib in $clangBuiltinsDir or short $clangBuiltinsDirShort"
|
||||
|
||||
# Get Windows Kits root from registry
|
||||
$kitsRoot = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots" -Name "KitsRoot10"
|
||||
$kitsRootPath = $kitsRoot.KitsRoot10
|
||||
|
||||
# Search for mt.exe in x64 SDK bin directories
|
||||
Write-Host "Searching for mt.exe ..."
|
||||
$mtPath = Get-ChildItem -Path "$kitsRootPath\bin" -Recurse -Filter "mt.exe" -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -match "\\x64\\mt\.exe$" } |
|
||||
Sort-Object FullName -Descending |
|
||||
Select-Object -First 1
|
||||
|
||||
if (-not $mtPath) {
|
||||
Write-Error "Could not find mt.exe in Windows Kits directories."
|
||||
exit 1
|
||||
}
|
||||
|
||||
$mtExePath = $mtPath.FullName
|
||||
|
||||
Write-Host "Found mt.exe at: $mtExePath"
|
||||
|
||||
$VcpkgRoot="$(Get-Location)/vcpkg"
|
||||
$VcpkgTriplet=$env:VCPKG_TRIPLET
|
||||
$VcpkgInstall="$VcpkgRoot/installed/$VcpkgTriplet"
|
||||
$VcpkgInclude="$VcpkgInstall/include"
|
||||
$VcpkgLib="$VcpkgInstall/lib"
|
||||
$VcpkgWindeployqt="$VcpkgInstall/tools/qt6/bin/windeployqt6.exe"
|
||||
|
||||
# Configure git safe directory
|
||||
Write-Host "Configuring git safe directory"
|
||||
& git config --global --add safe.directory '*'
|
||||
|
||||
# Initialize submodules except certain ones
|
||||
Write-Host "Initializing submodules"
|
||||
$excludedSubs = @('llvm','opencv','ffmpeg','FAudio','zlib','libpng','feralinteractive')
|
||||
|
||||
# Get submodule paths excluding those in $excludedSubs
|
||||
$submodules = Select-String -Path .gitmodules -Pattern 'path = (.+)' | ForEach-Object {
|
||||
$_.Matches[0].Groups[1].Value
|
||||
} | Where-Object {
|
||||
$path = $_
|
||||
-not ($excludedSubs | Where-Object { $path -like "*$_*" })
|
||||
}
|
||||
|
||||
Write-Host "Updating submodules: $($submodules -join ', ')"
|
||||
& git submodule update --init --quiet $submodules
|
||||
|
||||
# Create and enter build directory
|
||||
Write-Host "Creating build directory"
|
||||
if (!(Test-Path build)) {
|
||||
New-Item -ItemType Directory -Path build | Out-Null
|
||||
}
|
||||
Set-Location build
|
||||
Write-Host "Changed directory to: $(Get-Location)"
|
||||
|
||||
# Run CMake with Ninja generator and required flags
|
||||
Write-Host "Running CMake configuration"
|
||||
& cmake .. `
|
||||
-G Ninja `
|
||||
-DCMAKE_BUILD_TYPE=Release `
|
||||
-DCMAKE_C_COMPILER="$clangPath/clang-cl.exe" `
|
||||
-DCMAKE_CXX_COMPILER="$clangPath/clang-cl.exe" `
|
||||
-DCMAKE_LINKER="$clangPath/lld-link.exe" `
|
||||
-DCMAKE_INSTALL_PREFIX=/usr `
|
||||
-DCMAKE_TOOLCHAIN_FILE="$VcpkgRoot/scripts/buildsystems/vcpkg.cmake" `
|
||||
-DCMAKE_EXE_LINKER_FLAGS="/LIBPATH:$clangBuiltinsDirShort /defaultlib:$clangBuiltinsLib" `
|
||||
-DCMAKE_MT="$mtExePath" `
|
||||
-DWINDEPLOYQT_EXECUTABLE="$VcpkgWindeployqt" `
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF `
|
||||
-DUSE_PRECOMPILED_HEADERS=OFF `
|
||||
-DVCPKG_TARGET_TRIPLET="$VcpkgTriplet" `
|
||||
-DFFMPEG_INCLUDE_DIR="$VcpkgInclude" `
|
||||
-DFFMPEG_LIBAVCODEC="$VcpkgLib/avcodec.lib" `
|
||||
-DFFMPEG_LIBAVFORMAT="$VcpkgLib/avformat.lib" `
|
||||
-DFFMPEG_LIBAVUTIL="$VcpkgLib/avutil.lib" `
|
||||
-DFFMPEG_LIBSWSCALE="$VcpkgLib/swscale.lib" `
|
||||
-DFFMPEG_LIBSWRESAMPLE="$VcpkgLib/swresample.lib" `
|
||||
-DUSE_SYSTEM_CURL=OFF `
|
||||
-DUSE_FAUDIO=OFF `
|
||||
-DUSE_SDL=ON `
|
||||
-DUSE_SYSTEM_SDL=OFF `
|
||||
-DUSE_SYSTEM_FFMPEG=ON `
|
||||
-DUSE_SYSTEM_OPENCV=ON `
|
||||
-DUSE_SYSTEM_OPENAL=OFF `
|
||||
-DUSE_SYSTEM_LIBPNG=ON `
|
||||
-DUSE_DISCORD_RPC=ON `
|
||||
-DOpenGL_GL_PREFERENCE=LEGACY `
|
||||
-DWITH_LLVM=ON `
|
||||
-DSTATIC_LINK_LLVM=ON `
|
||||
-DBUILD_RPCS3_TESTS=OFF `
|
||||
-DRUN_RPCS3_TESTS=OFF
|
||||
Write-Host "CMake configuration complete"
|
||||
|
||||
# Build with ninja
|
||||
Write-Host "Starting build with Ninja..."
|
||||
& ninja
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "Build failed with exit code $LASTEXITCODE"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Build succeeded"
|
||||
|
||||
# Go back to root directory
|
||||
Set-Location ..
|
||||
Write-Host "Returned to root directory: $(Get-Location)"
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
# Pull all the submodules except some
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ && !/opencv/ && !/ffmpeg/ && !/curl/ && !/FAudio/ && !/zlib/ { print $3 }' .gitmodules)
|
||||
|
||||
mkdir build && cd build || exit 1
|
||||
|
||||
export CC="clang"
|
||||
export CXX="clang++"
|
||||
export LINKER=lld
|
||||
export LINKER_FLAG="-fuse-ld=${LINKER}"
|
||||
|
||||
if [ -n "$LLVMVER" ]; then
|
||||
export AR="llvm-ar-$LLVMVER"
|
||||
export RANLIB="llvm-ranlib-$LLVMVER"
|
||||
else
|
||||
export AR="llvm-ar"
|
||||
export RANLIB="llvm-ranlib"
|
||||
fi
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_PREFIX_PATH=/clang64 \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF \
|
||||
-DUSE_PRECOMPILED_HEADERS=OFF \
|
||||
-DCMAKE_C_FLAGS="$CFLAGS" \
|
||||
-DCMAKE_CXX_FLAGS="$CFLAGS" \
|
||||
-DCMAKE_EXE_LINKER_FLAGS="${LINKER_FLAG}" \
|
||||
-DCMAKE_MODULE_LINKER_FLAGS="${LINKER_FLAG}" \
|
||||
-DCMAKE_SHARED_LINKER_FLAGS="${LINKER_FLAG}" \
|
||||
-DCMAKE_AR="$AR" \
|
||||
-DCMAKE_RANLIB="$RANLIB" \
|
||||
-DUSE_SYSTEM_CURL=ON \
|
||||
-DUSE_FAUDIO=OFF \
|
||||
-DUSE_SDL=ON \
|
||||
-DUSE_SYSTEM_SDL=OFF \
|
||||
-DUSE_SYSTEM_FFMPEG=ON \
|
||||
-DUSE_SYSTEM_OPENCV=ON \
|
||||
-DUSE_SYSTEM_OPENAL=OFF \
|
||||
-DUSE_DISCORD_RPC=ON \
|
||||
-DOpenGL_GL_PREFERENCE=LEGACY \
|
||||
-DWITH_LLVM=ON \
|
||||
-DLLVM_DIR=/clang64/lib/cmake/llvm \
|
||||
-DVulkan_LIBRARY=/clang64/lib/libvulkan-1.dll.a \
|
||||
-DSTATIC_LINK_LLVM=ON \
|
||||
-DBUILD_RPCS3_TESTS=OFF \
|
||||
-DRUN_RPCS3_TESTS=OFF \
|
||||
-G Ninja
|
||||
|
||||
ninja; build_status=$?;
|
||||
|
||||
cd ..
|
||||
|
||||
# If it compiled succesfully let's deploy.
|
||||
if [ "$build_status" -eq 0 ]; then
|
||||
.ci/deploy-windows-clang.sh "x86_64"
|
||||
fi
|
||||
@@ -26,9 +26,6 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
|
||||
rm -f ./AppDir/usr/lib/libvulkan.so*
|
||||
|
||||
# Remove unused Qt6 libraries
|
||||
rm -f ./AppDir/usr/lib/libQt6OpenGL.so*
|
||||
rm -f ./AppDir/usr/lib/libQt6Qml*.so*
|
||||
rm -f ./AppDir/usr/lib/libQt6Quick.so*
|
||||
rm -f ./AppDir/usr/lib/libQt6VirtualKeyboard.so*
|
||||
rm -f ./AppDir/usr/plugins/platforminputcontexts/libqtvirtualkeyboardplugin.so*
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# First let's print some info about our caches
|
||||
"$(cygpath -u "$CCACHE_BIN_DIR")"/ccache.exe --show-stats -v
|
||||
|
||||
# BUILD_blablabla is Azure specific, so we wrap it for portability
|
||||
ARTIFACT_DIR="$BUILD_ARTIFACTSTAGINGDIRECTORY"
|
||||
BUILD="llvmlibs_mt.7z"
|
||||
|
||||
# Package artifacts
|
||||
7z a -m0=LZMA2 -mx9 "$BUILD" ./build/lib/Release-x64/llvm_build
|
||||
|
||||
# Generate sha256 hashes
|
||||
# Write to file for GitHub releases
|
||||
sha256sum "$BUILD" | awk '{ print $1 }' | tee "$BUILD.sha256"
|
||||
echo "$(cat "$BUILD.sha256");$(stat -c %s "$BUILD")B" > GitHubReleaseMessage.txt
|
||||
|
||||
# Move files to publishing directory
|
||||
cp -- "$BUILD" "$ARTIFACT_DIR"
|
||||
cp -- "$BUILD.sha256" "$ARTIFACT_DIR"
|
||||
@@ -0,0 +1,33 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# source ci-vars.env
|
||||
# shellcheck disable=SC1091
|
||||
. .ci/ci-vars.env
|
||||
|
||||
cd build || exit 1
|
||||
|
||||
CPU_ARCH="${1:-x86_64}"
|
||||
|
||||
echo "Deploying rpcs3 windows clang-cl $CPU_ARCH"
|
||||
|
||||
# BUILD_blablabla is CI specific, so we wrap it for portability
|
||||
ARTIFACT_DIR=$(cygpath -u "$BUILD_ARTIFACTSTAGINGDIRECTORY")
|
||||
|
||||
# Prepare compatibility and SDL database for packaging
|
||||
mkdir ./bin/config
|
||||
mkdir ./bin/config/input_configs
|
||||
curl -fsSL 'https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt' 1> ./bin/config/input_configs/gamecontrollerdb.txt
|
||||
curl -fsSL 'https://rpcs3.net/compatibility?api=v1&export' | iconv -t UTF-8 1> ./bin/GuiConfigs/compat_database.dat
|
||||
|
||||
# Package artifacts
|
||||
7z a -m0=LZMA2 -mx9 "$BUILD" ./bin/*
|
||||
|
||||
# Generate sha256 hashes
|
||||
# Write to file for GitHub releases
|
||||
sha256sum "$BUILD" | awk '{ print $1 }' | tee "$BUILD.sha256"
|
||||
echo "$(cat "$BUILD.sha256");$(stat -c %s "$BUILD")B" > GitHubReleaseMessage.txt
|
||||
|
||||
# Move files to publishing directory
|
||||
mkdir -p "$ARTIFACT_DIR"
|
||||
cp -- "$BUILD" "$ARTIFACT_DIR"
|
||||
cp -- "$BUILD.sha256" "$ARTIFACT_DIR"
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# source ci-vars.env
|
||||
# shellcheck disable=SC1091
|
||||
. .ci/ci-vars.env
|
||||
|
||||
cd build || exit 1
|
||||
|
||||
CPU_ARCH="${1:-x86_64}"
|
||||
|
||||
echo "Deploying rpcs3 windows clang $CPU_ARCH"
|
||||
|
||||
# BUILD_blablabla is CI specific, so we wrap it for portability
|
||||
ARTIFACT_DIR=$(cygpath -u "$BUILD_ARTIFACTSTAGINGDIRECTORY")
|
||||
MSYS2_CLANG_BIN=$(cygpath -w /clang64/bin)
|
||||
MSYS2_USR_BIN=$(cygpath -w /usr/bin)
|
||||
|
||||
echo "Installing dependencies of: ./bin/rpcs3.exe (MSYS2 dir is '$MSYS2_CLANG_BIN', usr dir is '$MSYS2_USR_BIN')"
|
||||
cmake -DMSYS2_CLANG_BIN="$MSYS2_CLANG_BIN" -DMSYS2_USR_BIN="$MSYS2_USR_BIN" -Dexe=./bin/rpcs3.exe -P ../buildfiles/cmake/CopyRuntimeDependencies.cmake
|
||||
|
||||
# Prepare compatibility and SDL database for packaging
|
||||
mkdir ./bin/config
|
||||
mkdir ./bin/config/input_configs
|
||||
curl -fsSL 'https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt' 1> ./bin/config/input_configs/gamecontrollerdb.txt
|
||||
curl -fsSL 'https://rpcs3.net/compatibility?api=v1&export' | iconv -t UTF-8 1> ./bin/GuiConfigs/compat_database.dat
|
||||
|
||||
# Package artifacts
|
||||
7z a -m0=LZMA2 -mx9 "$BUILD" ./bin/*
|
||||
|
||||
# Generate sha256 hashes
|
||||
# Write to file for GitHub releases
|
||||
sha256sum "$BUILD" | awk '{ print $1 }' | tee "$BUILD.sha256"
|
||||
echo "$(cat "$BUILD.sha256");$(stat -c %s "$BUILD")B" > GitHubReleaseMessage.txt
|
||||
|
||||
# Move files to publishing directory
|
||||
mkdir -p "$ARTIFACT_DIR"
|
||||
cp -- "$BUILD" "$ARTIFACT_DIR"
|
||||
cp -- "$BUILD.sha256" "$ARTIFACT_DIR"
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# First let's see print some info about our caches
|
||||
# First let's print some info about our caches
|
||||
"$(cygpath -u "$CCACHE_BIN_DIR")"/ccache.exe --show-stats -v
|
||||
|
||||
# BUILD_blablabla is Azure specific, so we wrap it for portability
|
||||
# BUILD_blablabla is CI specific, so we wrap it for portability
|
||||
ARTIFACT_DIR="$BUILD_ARTIFACTSTAGINGDIRECTORY"
|
||||
|
||||
# Remove unecessary files
|
||||
|
||||
+1
-2
@@ -1,5 +1,4 @@
|
||||
# Variables set by Azure Pipelines
|
||||
CI_HAS_ARTIFACTS
|
||||
# Variables set by CI
|
||||
BUILD_REASON
|
||||
BUILD_SOURCEVERSION
|
||||
BUILD_ARTIFACTSTAGINGDIRECTORY
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# Export variables for later stages of the Azure pipeline
|
||||
# Values done in this manner will appear as environment variables
|
||||
# in later stages.
|
||||
|
||||
# From pure-sh-bible
|
||||
# Setting 'IFS' tells 'read' where to split the string.
|
||||
while IFS='=' read -r key val; do
|
||||
# Skip over lines containing comments.
|
||||
[ "${key##\#*}" ] || continue
|
||||
echo "##vso[task.setvariable variable=$key]$val"
|
||||
done < ".ci/ci-vars.env"
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# Export variables for later stages of the Cirrus pipeline
|
||||
# Values done in this manner will appear as environment variables
|
||||
# in later stages.
|
||||
|
||||
# From pure-sh-bible
|
||||
# Setting 'IFS' tells 'read' where to split the string.
|
||||
while IFS='=' read -r key val; do
|
||||
# Skip over lines containing comments.
|
||||
[ "${key##\#*}" ] || continue
|
||||
export "$key"="$val"
|
||||
done < ".ci/ci-vars.env"
|
||||
@@ -15,4 +15,4 @@ pkg install "llvm$LLVM_COMPILER_VER"
|
||||
pkg install git ccache cmake ninja "qt$QT_VER_MAIN-multimedia" "qt$QT_VER_MAIN-svg" glew openal-soft ffmpeg
|
||||
|
||||
# Optional dependencies (libevdev is pulled by qtX-base)
|
||||
pkg install pkgconf alsa-lib pulseaudio sdl3 evdev-proto vulkan-headers vulkan-loader
|
||||
pkg install pkgconf alsa-lib pulseaudio sdl3 evdev-proto vulkan-headers vulkan-loader opencv
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# Resource/dependency URLs
|
||||
CCACHE_URL="https://github.com/ccache/ccache/releases/download/v4.11.2/ccache-4.11.2-windows-x86_64.zip"
|
||||
|
||||
DEP_URLS=" \
|
||||
$CCACHE_URL"
|
||||
|
||||
# CI doesn't make a cache dir if it doesn't exist, so we do it manually
|
||||
[ -d "$DEPS_CACHE_DIR" ] || mkdir "$DEPS_CACHE_DIR"
|
||||
|
||||
# Pull the llvm submodule
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init --depth=1 -- 3rdparty/llvm
|
||||
|
||||
# Git bash doesn't have rev, so here it is
|
||||
rev()
|
||||
{
|
||||
echo "$1" | awk '{ for(i = length($0); i != 0; --i) { a = a substr($0, i, 1); } } END { print a }'
|
||||
}
|
||||
|
||||
# Usage: download_and_verify url checksum algo file
|
||||
# Check to see if a file is already cached, and the checksum matches. If not, download it.
|
||||
# Tries up to 3 times
|
||||
download_and_verify()
|
||||
{
|
||||
url="$1"
|
||||
correctChecksum="$2"
|
||||
algo="$3"
|
||||
fileName="$4"
|
||||
|
||||
for _ in 1 2 3; do
|
||||
[ -e "$DEPS_CACHE_DIR/$fileName" ] || curl -fLo "$DEPS_CACHE_DIR/$fileName" "$url"
|
||||
fileChecksum=$("${algo}sum" "$DEPS_CACHE_DIR/$fileName" | awk '{ print $1 }')
|
||||
[ "$fileChecksum" = "$correctChecksum" ] && return 0
|
||||
done
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Some dependencies install here
|
||||
[ -d "./build/lib_ext/Release-x64" ] || mkdir -p "./build/lib_ext/Release-x64"
|
||||
|
||||
for url in $DEP_URLS; do
|
||||
# Get the filename from the URL and remove query strings (?arg=something).
|
||||
fileName="$(rev "$(rev "$url" | cut -d'/' -f1)" | cut -d'?' -f1)"
|
||||
[ -z "$fileName" ] && echo "Unable to parse url: $url" && exit 1
|
||||
|
||||
# shellcheck disable=SC1003
|
||||
case "$url" in
|
||||
*ccache*) checksum=$CCACHE_SHA; algo="sha256"; outDir="$CCACHE_BIN_DIR" ;;
|
||||
*) echo "Unknown url resource: $url"; exit 1 ;;
|
||||
esac
|
||||
|
||||
download_and_verify "$url" "$checksum" "$algo" "$fileName"
|
||||
7z x -y "$DEPS_CACHE_DIR/$fileName" -aos -o"$outDir"
|
||||
done
|
||||
|
||||
# Setup ccache tool
|
||||
[ -d "$CCACHE_DIR" ] || mkdir -p "$(cygpath -u "$CCACHE_DIR")"
|
||||
CCACHE_SH_DIR=$(cygpath -u "$CCACHE_BIN_DIR")
|
||||
mv "$CCACHE_SH_DIR"/ccache-*/* "$CCACHE_SH_DIR"
|
||||
cp "$CCACHE_SH_DIR"/ccache.exe "$CCACHE_SH_DIR"/cl.exe
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
CPU_ARCH="${1:-win64}"
|
||||
COMPILER="${2:-msvc}"
|
||||
|
||||
# These are CI specific, so we wrap them for portability
|
||||
REPO_NAME="$BUILD_REPOSITORY_NAME"
|
||||
REPO_BRANCH="$BUILD_SOURCEBRANCHNAME"
|
||||
PR_NUMBER="$BUILD_PR_NUMBER"
|
||||
|
||||
# Gather explicit version number and number of commits
|
||||
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_version.cpp)
|
||||
COMM_COUNT=$(git rev-list --count HEAD)
|
||||
COMM_HASH=$(git rev-parse --short=8 HEAD)
|
||||
|
||||
# Format the above into filenames
|
||||
if [ -n "$PR_NUMBER" ]; then
|
||||
AVVER="${COMM_TAG}-${COMM_HASH}"
|
||||
BUILD_RAW="rpcs3-v${AVVER}_${CPU_ARCH}_${COMPILER}"
|
||||
BUILD="${BUILD_RAW}.7z"
|
||||
else
|
||||
AVVER="${COMM_TAG}-${COMM_COUNT}"
|
||||
BUILD_RAW="rpcs3-v${AVVER}-${COMM_HASH}_${CPU_ARCH}_${COMPILER}"
|
||||
BUILD="${BUILD_RAW}.7z"
|
||||
fi
|
||||
|
||||
# BRANCH is used for experimental build warnings for pr builds, used in main_window.cpp.
|
||||
# BUILD is the name of the release artifact
|
||||
# BUILD_RAW is just filename
|
||||
# AVVER is used for GitHub releases, it is the version number.
|
||||
BRANCH="${REPO_NAME}/${REPO_BRANCH}"
|
||||
|
||||
# SC2129
|
||||
{
|
||||
echo "BRANCH=$BRANCH"
|
||||
echo "BUILD=$BUILD"
|
||||
echo "BUILD_RAW=$BUILD_RAW"
|
||||
echo "AVVER=$AVVER"
|
||||
} >> .ci/ci-vars.env
|
||||
+2
-37
@@ -1,10 +1,5 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# These are Azure specific, so we wrap them for portability
|
||||
REPO_NAME="$BUILD_REPOSITORY_NAME"
|
||||
REPO_BRANCH="$SYSTEM_PULLREQUEST_SOURCEBRANCH"
|
||||
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/"
|
||||
@@ -33,13 +28,13 @@ DEP_URLS=" \
|
||||
$VULKAN_SDK_URL\
|
||||
$CCACHE_URL"
|
||||
|
||||
# Azure pipelines doesn't make a cache dir if it doesn't exist, so we do it manually
|
||||
# CI doesn't make a cache dir if it doesn't exist, so we do it manually
|
||||
[ -d "$DEPS_CACHE_DIR" ] || mkdir "$DEPS_CACHE_DIR"
|
||||
|
||||
# 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 --depth=1 --jobs=8 $(awk '/path/ && !/FAudio/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/FAudio/ && !/llvm/ && !/feralinteractive/ { print $3 }' .gitmodules)
|
||||
|
||||
# Git bash doesn't have rev, so here it is
|
||||
rev()
|
||||
@@ -99,33 +94,3 @@ done
|
||||
CCACHE_SH_DIR=$(cygpath -u "$CCACHE_BIN_DIR")
|
||||
mv "$CCACHE_SH_DIR"/ccache-*/* "$CCACHE_SH_DIR"
|
||||
cp "$CCACHE_SH_DIR"/ccache.exe "$CCACHE_SH_DIR"/cl.exe
|
||||
|
||||
# Gather explicit version number and number of commits
|
||||
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_version.cpp)
|
||||
COMM_COUNT=$(git rev-list --count HEAD)
|
||||
COMM_HASH=$(git rev-parse --short=8 HEAD)
|
||||
|
||||
# Format the above into filenames
|
||||
if [ -n "$PR_NUMBER" ]; then
|
||||
AVVER="${COMM_TAG}-${COMM_HASH}"
|
||||
BUILD_RAW="rpcs3-v${AVVER}_win64"
|
||||
BUILD="${BUILD_RAW}.7z"
|
||||
else
|
||||
AVVER="${COMM_TAG}-${COMM_COUNT}"
|
||||
BUILD_RAW="rpcs3-v${AVVER}-${COMM_HASH}_win64"
|
||||
BUILD="${BUILD_RAW}.7z"
|
||||
fi
|
||||
|
||||
# BRANCH is used for experimental build warnings for pr builds, used in main_window.cpp.
|
||||
# BUILD is the name of the release artifact
|
||||
# BUILD_RAW is just filename
|
||||
# AVVER is used for GitHub releases, it is the version number.
|
||||
BRANCH="${REPO_NAME}/${REPO_BRANCH}"
|
||||
|
||||
# SC2129
|
||||
{
|
||||
echo "BRANCH=$BRANCH"
|
||||
echo "BUILD=$BUILD"
|
||||
echo "BUILD_RAW=$BUILD_RAW"
|
||||
echo "AVVER=$AVVER"
|
||||
} >> .ci/ci-vars.env
|
||||
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
env:
|
||||
CIRRUS_CLONE_DEPTH: 0 # Unshallow clone to obtain proper GIT_VERSION
|
||||
BUILD_REPOSITORY_NAME: $CIRRUS_REPO_FULL_NAME
|
||||
SYSTEM_PULLREQUEST_SOURCEBRANCH: $CIRRUS_BRANCH
|
||||
SYSTEM_PULLREQUEST_PULLREQUESTID: $CIRRUS_PR
|
||||
BUILD_SOURCEVERSION: $CIRRUS_CHANGE_IN_REPO
|
||||
BUILD_SOURCEBRANCHNAME: $CIRRUS_BRANCH
|
||||
RPCS3_TOKEN: ENCRYPTED[100ebb8e3552bf2021d0ef55dccda3e58d27be5b6cab0b0b92843ef490195d3c4edaefa087e4a3b425caa6392300b9b1]
|
||||
QT_VER_MAIN: '6'
|
||||
QT_VER: '6.9.0'
|
||||
LLVM_COMPILER_VER: '19'
|
||||
LLVM_VER: '19.1.7'
|
||||
|
||||
# windows_task:
|
||||
# matrix:
|
||||
# - name: Cirrus Windows
|
||||
# windows_container:
|
||||
# image: cirrusci/windowsservercore:visualstudio2019
|
||||
# cpu: 8
|
||||
# memory: 16G
|
||||
# env:
|
||||
# CIRRUS_SHELL: "bash"
|
||||
# COMPILER: msvc
|
||||
# BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}\artifacts\
|
||||
# QT_VER_MSVC: 'msvc2022'
|
||||
# QT_DATE: '202503301022'
|
||||
# QTDIR: C:\Qt\${QT_VER}\${QT_VER_MSVC}_64
|
||||
# VULKAN_VER: '1.3.268.0'
|
||||
# VULKAN_SDK_SHA: '8459ef49bd06b697115ddd3d97c9aec729e849cd775f5be70897718a9b3b9db5'
|
||||
# VULKAN_SDK: C:\VulkanSDK\${VULKAN_VER}
|
||||
# CACHE_DIR: "./cache"
|
||||
# UPLOAD_COMMIT_HASH: 7d09e3be30805911226241afbb14f8cdc2eb054e
|
||||
# UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-win"
|
||||
# deps_cache:
|
||||
# folder: "./cache"
|
||||
# #obj_cache:
|
||||
# # folder: "./tmp"
|
||||
# #obj2_cache:
|
||||
# # folder: "./rpcs3/x64"
|
||||
# setup_script:
|
||||
# - './.ci/get_keys-windows.sh'
|
||||
# - './.ci/setup-windows.sh'
|
||||
# rpcs3_script:
|
||||
# - export PATH=${PATH}:"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin"
|
||||
# - msbuild.exe rpcs3.sln //p:Configuration=Release //m
|
||||
# deploy_script:
|
||||
# - mkdir artifacts
|
||||
# - source './.ci/export-cirrus-vars.sh'
|
||||
# - './.ci/deploy-windows.sh'
|
||||
# artifacts:
|
||||
# name: Artifact
|
||||
# path: "*.7z*"
|
||||
# push_script: |
|
||||
# if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ]; then
|
||||
# source './.ci/export-cirrus-vars.sh'
|
||||
# './.ci/github-upload.sh'
|
||||
# fi;
|
||||
|
||||
# linux_task:
|
||||
# container:
|
||||
# image: rpcs3/rpcs3-ci-jammy:1.6
|
||||
# cpu: 4
|
||||
# memory: 16G
|
||||
# env:
|
||||
# BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}/artifacts
|
||||
# ARTDIR: ${CIRRUS_WORKING_DIR}/artifacts/
|
||||
# CCACHE_DIR: "/tmp/ccache_dir"
|
||||
# CCACHE_MAXSIZE: 300M
|
||||
# CI_HAS_ARTIFACTS: true
|
||||
# UPLOAD_COMMIT_HASH: d812f1254a1157c80fd402f94446310560f54e5f
|
||||
# UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux"
|
||||
# DEPLOY_APPIMAGE: true
|
||||
# APPDIR: "./appdir"
|
||||
# RELEASE_MESSAGE: "../GitHubReleaseMessage.txt"
|
||||
# ccache_cache:
|
||||
# folder: "/tmp/ccache_dir"
|
||||
# matrix:
|
||||
# - name: Cirrus Linux GCC
|
||||
# env:
|
||||
# COMPILER: gcc
|
||||
# gcc_script:
|
||||
# - mkdir artifacts
|
||||
# - ".ci/build-linux.sh"
|
||||
# - name: Cirrus Linux Clang
|
||||
# env:
|
||||
# COMPILER: clang
|
||||
# clang_script:
|
||||
# - mkdir artifacts
|
||||
# - ".ci/build-linux.sh"
|
||||
# artifacts:
|
||||
# name: Artifact
|
||||
# path: "artifacts/*"
|
||||
# push_script: |
|
||||
# if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ] && [ "$COMPILER" = "gcc" ]; then
|
||||
# COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_version.cpp)
|
||||
# COMM_COUNT=$(git rev-list --count HEAD)
|
||||
# COMM_HASH=$(git rev-parse --short=8 HEAD)
|
||||
|
||||
# export AVVER="${COMM_TAG}-${COMM_COUNT}"
|
||||
|
||||
# .ci/github-upload.sh
|
||||
# fi;
|
||||
|
||||
freebsd_task:
|
||||
matrix:
|
||||
- name: Cirrus FreeBSD
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-5
|
||||
cpu: 8
|
||||
memory: 8G
|
||||
env:
|
||||
CCACHE_MAXSIZE: 300M # 3x clean build, rounded
|
||||
CCACHE_DIR: /tmp/ccache_dir
|
||||
ccache_cache:
|
||||
folder: /tmp/ccache_dir
|
||||
install_script: "sh -ex ./.ci/install-freebsd.sh"
|
||||
script: "./.ci/build-freebsd.sh"
|
||||
|
||||
# linux_aarch64_task:
|
||||
# env:
|
||||
# BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}/artifacts
|
||||
# ARTDIR: ${CIRRUS_WORKING_DIR}/artifacts/
|
||||
# CCACHE_DIR: "/tmp/ccache_dir"
|
||||
# CCACHE_MAXSIZE: 300M
|
||||
# CI_HAS_ARTIFACTS: true
|
||||
# UPLOAD_COMMIT_HASH: a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1
|
||||
# UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux-arm64"
|
||||
# DEPLOY_APPIMAGE: true
|
||||
# APPDIR: "./appdir"
|
||||
# RELEASE_MESSAGE: "../GitHubReleaseMessage.txt"
|
||||
# COMPILER: clang
|
||||
# ccache_cache:
|
||||
# folder: "/tmp/ccache_dir"
|
||||
# matrix:
|
||||
# - name: Cirrus Linux AArch64 Clang
|
||||
# arm_container:
|
||||
# image: 'docker.io/rpcs3/rpcs3-ci-jammy-aarch64:1.6'
|
||||
# cpu: 8
|
||||
# memory: 8G
|
||||
# clang_script:
|
||||
# - mkdir artifacts
|
||||
# - "sh -ex ./.ci/build-linux-aarch64.sh"
|
||||
# artifacts:
|
||||
# name: Artifact
|
||||
# path: "artifacts/*"
|
||||
# push_script: |
|
||||
# if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ]; then
|
||||
# COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_version.cpp)
|
||||
# COMM_COUNT=$(git rev-list --count HEAD)
|
||||
# COMM_HASH=$(git rev-parse --short=8 HEAD)
|
||||
# export AVVER="${COMM_TAG}-${COMM_COUNT}"
|
||||
# .ci/github-upload.sh
|
||||
# fi;
|
||||
@@ -0,0 +1,72 @@
|
||||
name: Build LLVM
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
BUILD_ARTIFACTSTAGINGDIRECTORY: ${{ github.workspace }}/artifacts/
|
||||
|
||||
jobs:
|
||||
Windows_Build:
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
name: LLVM Windows (MSVC)
|
||||
runs-on: windows-2025
|
||||
env:
|
||||
COMPILER: msvc
|
||||
CCACHE_SHA: '1f39f3ad5aae3fe915e99ad1302633bc8f6718e58fa7c0de2b0ba7e080f0f08c'
|
||||
CCACHE_BIN_DIR: 'C:\ccache_bin'
|
||||
CCACHE_DIR: 'C:\ccache'
|
||||
CCACHE_INODECACHE: 'true'
|
||||
CCACHE_SLOPPINESS: 'time_macros'
|
||||
DEPS_CACHE_DIR: ./dependency_cache
|
||||
steps:
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@main
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Restore Dependencies Cache
|
||||
uses: actions/cache/restore@main
|
||||
id: restore-dependencies-cache
|
||||
with:
|
||||
path: ${{ env.DEPS_CACHE_DIR }}
|
||||
key: "${{ runner.os }}-${{ env.COMPILER }}-llvm-${{ env.CCACHE_SHA }}"
|
||||
restore-keys: ${{ runner.os }}-${{ env.COMPILER }}-llvm
|
||||
|
||||
- name: Download and unpack dependencies
|
||||
run: .ci/setup-llvm.sh
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
uses: microsoft/setup-msbuild@main
|
||||
|
||||
- name: Compile LLVM
|
||||
shell: pwsh
|
||||
run: msbuild 3rdparty\llvm\llvm_build.vcxproj /p:SolutionDir="$(pwd)/" /p:Configuration=Release /v:minimal /p:Platform=x64 /p:PreferredToolArchitecture=x64 /p:CLToolPath=${{ env.CCACHE_BIN_DIR }} /p:UseMultiToolTask=true /p:CustomAfterMicrosoftCommonTargets="${{ github.workspace }}\buildfiles\msvc\ci_only.targets"
|
||||
|
||||
- name: Pack up build artifacts
|
||||
run: |
|
||||
mkdir -p "${{ env.BUILD_ARTIFACTSTAGINGDIRECTORY }}"
|
||||
.ci/deploy-llvm.sh
|
||||
|
||||
- name: Upload artifacts (7z)
|
||||
uses: actions/upload-artifact@main
|
||||
with:
|
||||
name: LLVM for Windows (MSVC)
|
||||
path: ${{ env.BUILD_ARTIFACTSTAGINGDIRECTORY }}
|
||||
compression-level: 0
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Save Dependencies Cache
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@main
|
||||
with:
|
||||
path: ${{ env.DEPS_CACHE_DIR }}
|
||||
key: ${{ steps.restore-dependencies-cache.outputs.cache-primary-key }}
|
||||
+289
-26
@@ -5,8 +5,6 @@ defaults:
|
||||
shell: bash
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master # Only trigger push event on 'master' branch
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -17,6 +15,7 @@ concurrency:
|
||||
env:
|
||||
BUILD_REPOSITORY_NAME: ${{ github.repository }}
|
||||
BUILD_SOURCEBRANCHNAME: ${{ github.ref_name }}
|
||||
BUILD_PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
BUILD_SOURCEVERSION: ${{ github.sha }}
|
||||
BUILD_ARTIFACTSTAGINGDIRECTORY: ${{ github.workspace }}/artifacts/
|
||||
|
||||
@@ -44,11 +43,14 @@ jobs:
|
||||
compiler: clang
|
||||
UPLOAD_COMMIT_HASH: a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1
|
||||
UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux-arm64"
|
||||
- os: ubuntu-24.04-arm
|
||||
docker_img: "rpcs3/rpcs3-ci-jammy-aarch64:1.6"
|
||||
build_sh: "/rpcs3/.ci/build-linux-aarch64.sh"
|
||||
compiler: gcc
|
||||
name: RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CCACHE_DIR: ${{ github.workspace }}/ccache
|
||||
CI_HAS_ARTIFACTS: true
|
||||
DEPLOY_APPIMAGE: true
|
||||
APPDIR: "/rpcs3/build/appdir"
|
||||
ARTDIR: "/root/artifacts"
|
||||
@@ -63,19 +65,19 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: actions/cache@main
|
||||
- name: Restore build Ccache
|
||||
uses: actions/cache/restore@main
|
||||
id: restore-build-ccache
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ runner.arch }}-${{github.run_id}}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ runner.arch }}-
|
||||
restore-keys: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ runner.arch }}-
|
||||
|
||||
- name: Docker setup and build
|
||||
run: |
|
||||
docker pull --quiet ${{ matrix.docker_img }}
|
||||
docker run \
|
||||
-v $PWD:/rpcs3 \
|
||||
docker run \
|
||||
-v $PWD:/rpcs3 \
|
||||
--env-file .ci/docker.env \
|
||||
-v ${{ env.CCACHE_DIR }}:/root/.ccache \
|
||||
-v ${{ env.BUILD_ARTIFACTSTAGINGDIRECTORY }}:${{ env.ARTDIR }} \
|
||||
@@ -104,6 +106,13 @@ jobs:
|
||||
export AVVER="${COMM_TAG}-${COMM_COUNT}"
|
||||
.ci/github-upload.sh
|
||||
|
||||
- name: Save build Ccache
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@main
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ steps.restore-build-ccache.outputs.cache-primary-key }}
|
||||
|
||||
Mac_Build:
|
||||
# Only run push event on master branch of main repo, but run all PRs
|
||||
if: github.event_name != 'push' || (github.repository == 'RPCS3/rpcs3' && github.ref_name == 'master')
|
||||
@@ -123,37 +132,37 @@ jobs:
|
||||
runs-on: macos-14
|
||||
env:
|
||||
CCACHE_DIR: /tmp/ccache_dir
|
||||
CI_HAS_ARTIFACTS: true
|
||||
QT_VER: '6.7.3'
|
||||
QT_VER_MAIN: '6'
|
||||
LLVM_COMPILER_VER: '19'
|
||||
RELEASE_MESSAGE: ../GitHubReleaseMessage.txt
|
||||
UPLOAD_COMMIT_HASH: ${{ matrix.UPLOAD_COMMIT_HASH }}
|
||||
UPLOAD_REPO_FULL_NAME: ${{ matrix.UPLOAD_REPO_FULL_NAME }}
|
||||
RUN_UNIT_TESTS: github.event_name == 'pull_request' && 'ON' || 'OFF'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@main
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Cache
|
||||
uses: actions/cache@main
|
||||
- name: Restore Build Ccache
|
||||
uses: actions/cache/restore@main
|
||||
id: restore-build-ccache
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ runner.os }}-ccache-${{ matrix.name }}-${{github.run_id}}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-ccache-${{ matrix.name }}-
|
||||
restore-keys: ${{ runner.os }}-ccache-${{ matrix.name }}-
|
||||
|
||||
- name: Setup Qt Cache
|
||||
uses: actions/cache@main
|
||||
- name: Restore Qt Cache
|
||||
uses: actions/cache/restore@main
|
||||
id: restore-qt-cache
|
||||
with:
|
||||
path: /tmp/Qt
|
||||
key: ${{ runner.os }}-qt-${{ matrix.name }}-${{ env.QT_VER }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-qt-${{ matrix.name }}-${{ env.QT_VER }}
|
||||
restore-keys: ${{ runner.os }}-qt-${{ matrix.name }}-${{ env.QT_VER }}
|
||||
|
||||
- name: Build
|
||||
run: ${{ matrix.build_sh }}
|
||||
run: ${{ matrix.build_sh }}
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@main
|
||||
@@ -179,6 +188,20 @@ jobs:
|
||||
RPCS3_TOKEN: ${{ secrets.RPCS3_TOKEN }}
|
||||
run: .ci/github-upload.sh
|
||||
|
||||
- name: Save Build Ccache
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@main
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ steps.restore-build-ccache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Save Qt Cache
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@main
|
||||
with:
|
||||
path: /tmp/Qt
|
||||
key: ${{ steps.restore-qt-cache.outputs.cache-primary-key }}
|
||||
|
||||
Windows_Build:
|
||||
# Only run push event on master branch of main repo, but run all PRs
|
||||
if: github.event_name != 'push' || (github.repository == 'RPCS3/rpcs3' && github.ref_name == 'master')
|
||||
@@ -187,9 +210,9 @@ jobs:
|
||||
env:
|
||||
COMPILER: msvc
|
||||
QT_VER_MAIN: '6'
|
||||
QT_VER: '6.9.0'
|
||||
QT_VER: '6.9.1'
|
||||
QT_VER_MSVC: 'msvc2022'
|
||||
QT_DATE: '202503301022'
|
||||
QT_DATE: '202505291653'
|
||||
LLVM_VER: '19.1.7'
|
||||
VULKAN_VER: '1.3.268.0'
|
||||
VULKAN_SDK_SHA: '8459ef49bd06b697115ddd3d97c9aec729e849cd775f5be70897718a9b3b9db5'
|
||||
@@ -223,22 +246,26 @@ jobs:
|
||||
- name: Get Cache Keys
|
||||
run: .ci/get_keys-windows.sh
|
||||
|
||||
- name: Setup Build Ccache
|
||||
uses: actions/cache@main
|
||||
- name: Restore Build Ccache
|
||||
uses: actions/cache/restore@main
|
||||
id: restore-build-ccache
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: "${{ runner.os }}-ccache-${{ env.COMPILER }}-${{github.run_id}}"
|
||||
restore-keys: ${{ runner.os }}-ccache-${{ env.COMPILER }}-
|
||||
|
||||
- name: Setup Dependencies Cache
|
||||
uses: actions/cache@main
|
||||
- name: Restore Dependencies Cache
|
||||
uses: actions/cache/restore@main
|
||||
id: restore-dependencies-cache
|
||||
with:
|
||||
path: ${{ env.DEPS_CACHE_DIR }}
|
||||
key: "${{ runner.os }}-${{ env.COMPILER }}-${{ env.QT_VER }}-${{ env.VULKAN_SDK_SHA }}-${{ env.CCACHE_SHA }}-${{ hashFiles('llvm.lock') }}"
|
||||
restore-keys: ${{ runner.os }}-${{ env.COMPILER }}-
|
||||
|
||||
- name: Download and unpack dependencies
|
||||
run: .ci/setup-windows.sh
|
||||
run: |
|
||||
.ci/setup-windows.sh
|
||||
.ci/setup-windows-ci-vars.sh win64 msvc
|
||||
|
||||
- name: Export Variables
|
||||
run: |
|
||||
@@ -281,3 +308,239 @@ jobs:
|
||||
env:
|
||||
RPCS3_TOKEN: ${{ secrets.RPCS3_TOKEN }}
|
||||
run: .ci/github-upload.sh
|
||||
|
||||
- name: Save Build Ccache
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@main
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ steps.restore-build-ccache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Save Dependencies Cache
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@main
|
||||
with:
|
||||
path: ${{ env.DEPS_CACHE_DIR }}
|
||||
key: ${{ steps.restore-dependencies-cache.outputs.cache-primary-key }}
|
||||
|
||||
Windows_Build_Clang:
|
||||
# Only run push event on master branch of main repo, but run all PRs
|
||||
if: github.event_name != 'push' || (github.repository == 'RPCS3/rpcs3' && github.ref_name == 'master')
|
||||
name: RPCS3 Windows Clang
|
||||
runs-on: windows-2025
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- msys2: clang64
|
||||
compiler: clang
|
||||
arch: win64
|
||||
env:
|
||||
CCACHE_DIR: 'C:\ccache'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@main
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.msys2 }}
|
||||
update: true
|
||||
cache: true
|
||||
install: |
|
||||
mingw-w64-clang-x86_64-clang
|
||||
mingw-w64-clang-x86_64-ccache
|
||||
mingw-w64-clang-x86_64-cmake
|
||||
mingw-w64-clang-x86_64-lld
|
||||
mingw-w64-clang-x86_64-ninja
|
||||
mingw-w64-clang-x86_64-llvm
|
||||
mingw-w64-clang-x86_64-ffmpeg
|
||||
mingw-w64-clang-x86_64-opencv
|
||||
mingw-w64-clang-x86_64-glew
|
||||
mingw-w64-clang-x86_64-vulkan
|
||||
mingw-w64-clang-x86_64-vulkan-headers
|
||||
mingw-w64-clang-x86_64-vulkan-loader
|
||||
mingw-w64-clang-x86_64-gtest
|
||||
mingw-w64-clang-x86_64-qt6-base
|
||||
mingw-w64-clang-x86_64-qt6-declarative
|
||||
mingw-w64-clang-x86_64-qt6-multimedia
|
||||
mingw-w64-clang-x86_64-qt6-svg
|
||||
base-devel
|
||||
curl
|
||||
git
|
||||
p7zip
|
||||
|
||||
- name: Restore build Ccache
|
||||
uses: actions/cache/restore@main
|
||||
id: restore-build-ccache
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ runner.arch }}-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ runner.arch }}-
|
||||
|
||||
- name: Build RPCS3
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
export CCACHE_DIR=$(cygpath -u "$CCACHE_DIR")
|
||||
echo "CCACHE_DIR=$CCACHE_DIR"
|
||||
.ci/setup-windows-ci-vars.sh ${{ matrix.arch }} ${{ matrix.compiler }}
|
||||
.ci/build-windows-clang.sh
|
||||
|
||||
- name: Save build Ccache
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@main
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ steps.restore-build-ccache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@main
|
||||
with:
|
||||
name: RPCS3 for Windows (${{ runner.arch }}, ${{ matrix.compiler }})
|
||||
path: ${{ env.BUILD_ARTIFACTSTAGINGDIRECTORY }}
|
||||
compression-level: 0
|
||||
if-no-files-found: error
|
||||
|
||||
Windows_Build_ClangCL:
|
||||
if: always()
|
||||
name: RPCS3 Windows Clang-CL
|
||||
runs-on: windows-2025
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- compiler: clangcl
|
||||
arch: win64
|
||||
env:
|
||||
CCACHE_DIR: 'C:\ccache'
|
||||
VCPKG_TRIPLET: x64-windows
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@main
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Clone vcpkg
|
||||
run: git clone --depth 1 --branch 2025.06.13 https://github.com/microsoft/vcpkg.git
|
||||
|
||||
- name: Bootstrap vcpkg
|
||||
shell: pwsh
|
||||
run: .\vcpkg\bootstrap-vcpkg.bat
|
||||
|
||||
- name: Restore vcpkg cache
|
||||
uses: actions/cache/restore@main
|
||||
id: restore-vcpkg-cache
|
||||
with:
|
||||
path: |
|
||||
vcpkg/installed
|
||||
vcpkg/buildtrees
|
||||
key: vcpkg-${{ runner.os }}-${{ matrix.compiler }}-${{ runner.arch }}-${{ github.run_id }}
|
||||
restore-keys: vcpkg-${{ runner.os }}-${{ matrix.compiler }}-${{ runner.arch }}-
|
||||
|
||||
- name: Install dependencies with vcpkg
|
||||
shell: pwsh
|
||||
run: |
|
||||
.\vcpkg\vcpkg.exe install `
|
||||
ffmpeg[avcodec,avformat,swscale,swresample] `
|
||||
llvm `
|
||||
opencv `
|
||||
qtbase `
|
||||
qtsvg `
|
||||
qtmultimedia `
|
||||
qttools `
|
||||
zlib `
|
||||
vulkan `
|
||||
libpng `
|
||||
--triplet $env:VCPKG_TRIPLET `
|
||||
--clean-after-build
|
||||
|
||||
- name: Save vcpkg cache
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@main
|
||||
with:
|
||||
path: |
|
||||
vcpkg/installed
|
||||
vcpkg/buildtrees
|
||||
key: ${{ steps.restore-vcpkg-cache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Add LLVM and Ninja to PATH
|
||||
shell: pwsh
|
||||
run: |
|
||||
Add-Content -Path $env:GITHUB_PATH -Value "C:\Program Files\LLVM\bin"
|
||||
Add-Content -Path $env:GITHUB_PATH -Value "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin"
|
||||
Add-Content -Path $env:GITHUB_PATH -Value "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin"
|
||||
Add-Content -Path $env:GITHUB_PATH -Value "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja"
|
||||
|
||||
- name: Restore build Ccache
|
||||
uses: actions/cache/restore@main
|
||||
id: restore-build-ccache
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ runner.arch }}-16248552313
|
||||
restore-keys: ${{ runner.os }}-ccache-${{ matrix.compiler }}-${{ runner.arch }}-
|
||||
|
||||
- name: Setup CI Variables
|
||||
run: .ci/setup-windows-ci-vars.sh ${{ matrix.arch }} ${{ matrix.compiler }}
|
||||
|
||||
- name: Build RPCS3
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64
|
||||
powershell -ExecutionPolicy Bypass -File .ci/build-windows-clang-cl.ps1
|
||||
|
||||
- name: Save build Ccache
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@main
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ steps.restore-build-ccache.outputs.cache-primary-key }}
|
||||
|
||||
- name: Deploy RPCS3
|
||||
run: .ci/deploy-windows-clang-cl.sh x86_64
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@main
|
||||
with:
|
||||
name: RPCS3 for Windows (clang-cl)
|
||||
path: ${{ env.BUILD_ARTIFACTSTAGINGDIRECTORY }}
|
||||
compression-level: 0
|
||||
if-no-files-found: error
|
||||
|
||||
FreeBSD_Build:
|
||||
# Only run push event on master branch of main repo, but run all PRs
|
||||
if: github.event_name != 'push' || (github.repository == 'RPCS3/rpcs3' && github.ref_name == 'master')
|
||||
name: RPCS3 FreeBSD
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
CCACHE_DIR: ${{ github.workspace }}/ccache
|
||||
QT_VER_MAIN: '6'
|
||||
LLVM_COMPILER_VER: '19'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@main
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Restore Build Ccache
|
||||
uses: actions/cache/restore@main
|
||||
id: restore-build-ccache
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: FreeBSD-ccache-${{github.run_id}}
|
||||
restore-keys: FreeBSD-ccache-
|
||||
|
||||
- name: FreeBSD build
|
||||
id: root
|
||||
uses: vmactions/freebsd-vm@v1
|
||||
with:
|
||||
envs: 'QT_VER_MAIN LLVM_COMPILER_VER CCACHE_DIR'
|
||||
usesh: true
|
||||
run: .ci/install-freebsd.sh && .ci/build-freebsd.sh
|
||||
|
||||
- name: Save Build Ccache
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@main
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ steps.restore-build-ccache.outputs.cache-primary-key }}
|
||||
|
||||
@@ -108,3 +108,7 @@
|
||||
path = 3rdparty/GPUOpen/VulkanMemoryAllocator
|
||||
url = ../../GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/feralinteractive/feralinteractive"]
|
||||
path = 3rdparty/feralinteractive/feralinteractive
|
||||
url = ../../FeralInteractive/gamemode.git
|
||||
ignore = dirty
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/7zip/7zip updated: e5431fa6f5...395149956d
Vendored
+4
@@ -357,6 +357,9 @@ add_subdirectory(opencv EXCLUDE_FROM_ALL)
|
||||
# FUSION
|
||||
add_subdirectory(fusion EXCLUDE_FROM_ALL)
|
||||
|
||||
# FERAL INTERACTIVE
|
||||
add_subdirectory(feralinteractive EXCLUDE_FROM_ALL)
|
||||
|
||||
# add nice ALIAS targets for ease of use
|
||||
if(USE_SYSTEM_LIBUSB)
|
||||
add_library(3rdparty::libusb ALIAS usb-1.0-shared)
|
||||
@@ -389,3 +392,4 @@ add_library(3rdparty::miniupnpc ALIAS libminiupnpc-static)
|
||||
add_library(3rdparty::rtmidi ALIAS rtmidi)
|
||||
add_library(3rdparty::opencv ALIAS ${OPENCV_TARGET})
|
||||
add_library(3rdparty::fusion ALIAS Fusion)
|
||||
add_library(3rdparty::feralinteractive ALIAS 3rdparty_feralinteractive)
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/FAudio updated: 6077ea740a...e6ddfabab2
Vendored
+1
@@ -11,6 +11,7 @@ if(USE_SYSTEM_OPENAL)
|
||||
else()
|
||||
option(ALSOFT_UTILS "Build utility programs" OFF)
|
||||
option(ALSOFT_EXAMPLES "Build example programs" OFF)
|
||||
set(LIBTYPE "STATIC")
|
||||
add_subdirectory(openal-soft EXCLUDE_FROM_ALL)
|
||||
add_library(3rdparty_openal INTERFACE)
|
||||
target_link_libraries(3rdparty_openal INTERFACE OpenAL::OpenAL)
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/curl/curl updated: 4dacb79fcd...fdb8a789d2
+9
@@ -0,0 +1,9 @@
|
||||
# Feral Interactive
|
||||
|
||||
add_library(3rdparty_feralinteractive INTERFACE)
|
||||
|
||||
if (CMAKE_SYSTEM MATCHES "Linux")
|
||||
target_include_directories(3rdparty_feralinteractive INTERFACE feralinteractive/lib)
|
||||
target_compile_definitions(3rdparty_feralinteractive INTERFACE -DGAMEMODE_AVAILABLE)
|
||||
target_link_libraries(3rdparty_feralinteractive INTERFACE feralinteractive)
|
||||
endif()
|
||||
+1
Submodule 3rdparty/feralinteractive/feralinteractive added at c54d6d4243
Vendored
+1
-1
Submodule 3rdparty/libpng/libpng updated: ea12796820...2b978915d8
Vendored
+1
-1
Submodule 3rdparty/libsdl-org/SDL updated: 8d604353a5...c9a6709bd2
Vendored
+1
-1
Submodule 3rdparty/libusb/libusb updated: a61afe5f75...15a7ebb4d4
Vendored
+10
-7
@@ -58,20 +58,23 @@ if(WITH_LLVM)
|
||||
else()
|
||||
message(STATUS "Using prebuilt or system LLVM")
|
||||
|
||||
if (LLVM_DIR AND NOT IS_ABSOLUTE "${LLVM_DIR}")
|
||||
# change relative LLVM_DIR to be relative to the source dir
|
||||
set(LLVM_DIR ${CMAKE_SOURCE_DIR}/${LLVM_DIR})
|
||||
if (LLVM_DIR)
|
||||
message(STATUS "LLVM_DIR: ${LLVM_DIR}")
|
||||
|
||||
if (NOT IS_ABSOLUTE "${LLVM_DIR}")
|
||||
# change relative LLVM_DIR to be relative to the source dir
|
||||
set(LLVM_DIR ${CMAKE_SOURCE_DIR}/${LLVM_DIR})
|
||||
message(STATUS "Changed LLVM_DIR to relative path: ${LLVM_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(LLVM CONFIG)
|
||||
|
||||
if (NOT LLVM_FOUND)
|
||||
message(FATAL_ERROR "Can't find LLVM libraries from the CMAKE_PREFIX_PATH path or LLVM_DIR. \
|
||||
Enable BUILD_LLVM option to build LLVM from included as a git submodule.")
|
||||
message(FATAL_ERROR "Can't find LLVM libraries from the CMAKE_PREFIX_PATH path or LLVM_DIR. Enable BUILD_LLVM option to build LLVM from included as a git submodule.")
|
||||
endif()
|
||||
if (LLVM_VERSION VERSION_LESS 18)
|
||||
message(FATAL_ERROR "Found LLVM version ${LLVM_VERSION}. Required version 18 or above. \
|
||||
Enable BUILD_LLVM option to build LLVM from included as a git submodule.")
|
||||
message(FATAL_ERROR "Found LLVM version ${LLVM_VERSION}. Required version 18 or above. Enable BUILD_LLVM option to build LLVM from included as a git submodule.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
Vendored
+5
-1
@@ -4,7 +4,11 @@ set(OPENCV_TARGET 3rdparty_dummy_lib PARENT_SCOPE)
|
||||
|
||||
if (USE_SYSTEM_OPENCV)
|
||||
message(STATUS "RPCS3: using system OpenCV")
|
||||
find_package(OpenCV COMPONENTS core photo)
|
||||
find_package(OpenCV CONFIG COMPONENTS core photo)
|
||||
|
||||
if(NOT OPENCV_FOUND)
|
||||
find_package(OpenCV COMPONENTS core photo)
|
||||
endif()
|
||||
|
||||
if(OPENCV_FOUND)
|
||||
message(STATUS "RPCS3: found system OpenCV")
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/opencv/opencv updated: f76628fb5b...50fb5e701d
Vendored
+9
-7
@@ -39,13 +39,14 @@ check_tags()
|
||||
|
||||
echo "Checking $path"
|
||||
|
||||
# git_call fetch --prune --all
|
||||
git_call fetch --prune --all
|
||||
|
||||
# Get the latest tag (by commit date, not tag name)
|
||||
local tag_list=$(git_call rev-list --tags --max-count=1)
|
||||
local latest_tag=$(git_call describe --tags "$tag_list")
|
||||
local highest_tag=$(git_call tag -l | sort -V | tail -n1)
|
||||
|
||||
if [ -n "$latest_tag" ]; then
|
||||
if [ -n "$latest_tag" ] || [ -n "$highest_tag" ]; then
|
||||
|
||||
# Get the current tag
|
||||
local current_tag=$(git_call describe --tags --abbrev=0)
|
||||
@@ -53,28 +54,29 @@ check_tags()
|
||||
if [ -n "$current_tag" ]; then
|
||||
|
||||
if [ "$verbose" -eq 1 ]; then
|
||||
echo "$path -> latest: $latest_tag, current: $current_tag"
|
||||
echo "$path -> latest: $latest_tag, highest: $highest_tag, current: $current_tag"
|
||||
fi
|
||||
|
||||
local ts0=$(git_call log -1 --format=%ct $highest_tag)
|
||||
local ts1=$(git_call log -1 --format=%ct $latest_tag)
|
||||
local ts2=$(git_call log -1 --format=%ct $current_tag)
|
||||
|
||||
if (( ts1 > ts2 )); then
|
||||
if (( ts0 > ts2 )) || (( ts1 > ts2 )); then
|
||||
if [ "$verbose" -eq 1 ]; then
|
||||
echo -e "\t $path: latest is newer"
|
||||
elif [ "$verbose" -eq 0 ]; then
|
||||
echo "$path -> latest: $latest_tag, current: $current_tag"
|
||||
echo "$path -> latest: $latest_tag, highest: $highest_tag, current: $current_tag"
|
||||
fi
|
||||
|
||||
# Critical section guarded by flock
|
||||
(
|
||||
flock 200
|
||||
echo "$path -> latest: $latest_tag, current: $current_tag" >> "$resultfile"
|
||||
echo "$path -> latest: $latest_tag, highest: $highest_tag, current: $current_tag" >> "$resultfile"
|
||||
) 200>"$lockfile"
|
||||
fi
|
||||
|
||||
elif [ "$verbose" -eq 1 ]; then
|
||||
echo "$path -> latest: $latest_tag"
|
||||
echo "$path -> latest: $latest_tag, highest: $highest_tag"
|
||||
fi
|
||||
elif [ "$verbose" -eq 1 ]; then
|
||||
|
||||
|
||||
Vendored
+13
-1
@@ -22,5 +22,17 @@ else()
|
||||
|
||||
add_subdirectory(wolfssl EXCLUDE_FROM_ALL)
|
||||
|
||||
target_compile_definitions(wolfssl PUBLIC WOLFSSL_DES_ECB HAVE_WRITE_DUP FP_MAX_BITS=8192 WOLFSSL_NO_OPTIONS_H)
|
||||
target_compile_definitions(wolfssl PUBLIC WOLFSSL_DES_ECB HAVE_WRITE_DUP WOLFSSL_NO_OPTIONS_H)
|
||||
|
||||
if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Disable 128-bit Math
|
||||
set(WOLFSSL_ASM ON CACHE BOOL "" FORCE)
|
||||
set(WOLFSSL_FAST_MATH OFF CACHE BOOL "" FORCE)
|
||||
target_compile_definitions(wolfssl PUBLIC WOLFSSL_SP_NO_128BIT FP_MAX_BITS=4096)
|
||||
|
||||
# Disable warnings
|
||||
target_compile_options(wolfssl PRIVATE /w)
|
||||
else()
|
||||
target_compile_definitions(wolfssl PUBLIC FP_MAX_BITS=8192)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
+5
-5
@@ -19,26 +19,26 @@ The following tools are required to build RPCS3 on Windows 10 or later:
|
||||
with standalone **CMake** tool.
|
||||
|
||||
- [Python 3.6+](https://www.python.org/downloads/) (add to PATH)
|
||||
- [Qt 6.9.0](https://www.qt.io/download-qt-installer) In case you can't download from the official installer, you can use [Another Qt installer](https://github.com/miurahr/aqtinstall) (In that case you will need to manually add the "qtmultimedia" module when installing Qt)
|
||||
- [Qt 6.9.1](https://www.qt.io/download-qt-installer) In case you can't download from the official installer, you can use [Another Qt installer](https://github.com/miurahr/aqtinstall) (In that case you will need to manually add the "qtmultimedia" module when installing Qt)
|
||||
- [Vulkan SDK 1.3.268.0](https://vulkan.lunarg.com/sdk/home) (see "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html)) for now future SDKs don't work. You need precisely 1.3.268.0.
|
||||
|
||||
The `sln` solution available only on **Visual Studio** is the preferred building solution. It easily allows to build the **RPCS3** application in `Release` and `Debug` mode.
|
||||
|
||||
In order to build **RPCS3** with the `sln` solution (with **Visual Studio**), **Qt** libs need to be detected. To detect the libs:
|
||||
- add and set the `QTDIR` environment variable, e.g. `<QtInstallFolder>\6.9.0\msvc2022_64\`
|
||||
- add and set the `QTDIR` environment variable, e.g. `<QtInstallFolder>\6.9.1\msvc2022_64\`
|
||||
- or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2022)
|
||||
|
||||
**NOTE:** If you have issues with the **Visual Studio Qt Plugin**, you may want to uninstall it and install the [Legacy Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.LEGACYQtVisualStudioTools2022) instead.
|
||||
|
||||
In order to build **RPCS3** with the `CMake` solution (with both **Visual Studio** and standalone **CMake** tool):
|
||||
- add and set the `Qt6_ROOT` environment variable to the **Qt** libs path, e.g. `<QtInstallFolder>\6.9.0\msvc2022_64\`
|
||||
- add and set the `Qt6_ROOT` environment variable to the **Qt** libs path, e.g. `<QtInstallFolder>\6.9.1\msvc2022_64\`
|
||||
|
||||
### Linux
|
||||
|
||||
These are the essentials tools to build RPCS3 on Linux. Some of them can be installed through your favorite package manager:
|
||||
- Clang 17+ or GCC 13+
|
||||
- [CMake 3.28.0+](https://www.cmake.org/download/)
|
||||
- [Qt 6.9.0](https://www.qt.io/download-qt-installer)
|
||||
- [Qt 6.9.1](https://www.qt.io/download-qt-installer)
|
||||
- [Vulkan SDK 1.3.268.0](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html)) for now future SDKs don't work. You need precisely 1.3.268.0.
|
||||
- [SDL3](https://github.com/libsdl-org/SDL/releases) (for the FAudio backend)
|
||||
|
||||
@@ -121,7 +121,7 @@ Start **Visual Studio**, click on `Open a project or solution` and select the `r
|
||||
##### Configuring the Qt Plugin (if used)
|
||||
|
||||
1) go to `Extensions->Qt VS Tools->Qt Versions`
|
||||
2) add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\6.9.0\msvc2022_64`, version will fill in automatically
|
||||
2) add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\6.9.1\msvc2022_64`, version will fill in automatically
|
||||
3) go to `Extensions->Qt VS Tools->Options->Legacy Project Format`. (Only available in the **Legacy Qt Plugin**)
|
||||
4) set `Build: Run pre-build setup` to `true`. (Only available in the **Legacy Qt Plugin**)
|
||||
|
||||
|
||||
+32
-12
@@ -1,5 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.28)
|
||||
|
||||
find_program(CCACHE_PATH ccache HINTS ENV PATH)
|
||||
if(CCACHE_PATH)
|
||||
message(STATUS "Using ccache: ${CCACHE_PATH}")
|
||||
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PATH}")
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PATH}")
|
||||
endif()
|
||||
|
||||
project(rpcs3 LANGUAGES C CXX)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
@@ -22,16 +29,23 @@ option(STATIC_LINK_LLVM "Link against LLVM statically. This will get set to ON i
|
||||
option(USE_FAUDIO "FAudio audio backend" ON)
|
||||
option(USE_LIBEVDEV "libevdev-based joystick support" ON)
|
||||
option(USE_DISCORD_RPC "Discord rich presence integration" OFF)
|
||||
option(USE_SYSTEM_ZLIB "Prefer system ZLIB instead of the builtin one" ON)
|
||||
option(USE_VULKAN "Vulkan render backend" ON)
|
||||
option(USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF)
|
||||
option(USE_SDL "Enables SDL input handler" OFF)
|
||||
option(USE_SYSTEM_SDL "Prefer system SDL instead of the builtin one" ON)
|
||||
option(USE_SYSTEM_FFMPEG "Prefer system ffmpeg instead of the prebuild one" OFF)
|
||||
option(USE_SYSTEM_OPENAL "Prefer system OpenAL instead of the prebuild one" ON)
|
||||
option(USE_SYSTEM_CURL "Prefer system Curl instead of the prebuild one" ON)
|
||||
option(USE_SYSTEM_OPENCV "Prefer system OpenCV instead of the builtin one" ON)
|
||||
option(USE_SYSTEM_CUBEB "Prefer system cubeb instead of the builtin one" OFF)
|
||||
option(USE_SYSTEM_CURL "Prefer system Curl instead of the prebuild one" ON)
|
||||
option(USE_SYSTEM_FAUDIO "Prefer system FAudio instead of the builtin one" OFF)
|
||||
option(USE_SYSTEM_FFMPEG "Prefer system ffmpeg instead of the prebuild one" OFF)
|
||||
option(USE_SYSTEM_FLATBUFFERS "Prefer system flatbuffers instead of the builtin one" OFF)
|
||||
option(USE_SYSTEM_LIBPNG "Prefer system libpng instead of the builtin one" OFF)
|
||||
option(USE_SYSTEM_LIBUSB "Prefer system libusb instead of the builtin one" OFF)
|
||||
option(USE_SYSTEM_MVK "Prefer system MoltenVK instead of the builtin one" OFF)
|
||||
option(USE_SYSTEM_OPENAL "Prefer system OpenAL instead of the prebuild one" ON)
|
||||
option(USE_SYSTEM_OPENCV "Prefer system OpenCV instead of the builtin one" ON)
|
||||
option(USE_SYSTEM_PUGIXML "Prefer system pugixml instead of the builtin one" OFF)
|
||||
option(USE_SYSTEM_SDL "Prefer system SDL instead of the builtin one" ON)
|
||||
option(USE_SYSTEM_WOLFSSL "Prefer system MoltenVK instead of the builtin one" OFF)
|
||||
option(USE_SYSTEM_ZLIB "Prefer system ZLIB instead of the builtin one" ON)
|
||||
option(HAS_MEMORY_BREAKPOINTS "Add support for memory breakpoints to the interpreter" OFF)
|
||||
option(USE_LTO "Use LTO for building" ON)
|
||||
option(BUILD_RPCS3_TESTS "Build RPCS3 unit tests." OFF)
|
||||
@@ -102,18 +116,15 @@ if(MSVC)
|
||||
message(AUTHOR_WARNING "Debug build currently can not work with static CRT.")
|
||||
endif()
|
||||
endif()
|
||||
add_compile_options(/MP)
|
||||
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
add_compile_options(/MP)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
message( FATAL_ERROR "RPCS3 can only be compiled on 64-bit platforms." )
|
||||
endif()
|
||||
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER ccache)
|
||||
endif()
|
||||
|
||||
if(APPLE AND CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
|
||||
include_directories(/opt/homebrew/include)
|
||||
link_directories(/opt/homebrew/lib)
|
||||
@@ -143,6 +154,15 @@ if(NOT WIN32)
|
||||
add_compile_options(-pthread)
|
||||
endif()
|
||||
|
||||
## Look for Gamemode if its installed on Linux
|
||||
if(LINUX)
|
||||
find_program(GAMEMODE_FOUND gamemoded) ## Only works if gamemode is installed on system (might include lib32 case)
|
||||
if(GAMEMODE_FOUND)
|
||||
add_compile_definitions(GAMEMODE_AVAILABLE)
|
||||
endif()
|
||||
message(GAMEMODE_AVAILABLE="${GAMEMODE_AVAILABLE}")
|
||||
endif()
|
||||
|
||||
# TODO: do real installation, including copying directory structure
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${PROJECT_BINARY_DIR}/bin")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${PROJECT_BINARY_DIR}/bin")
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
RPCS3
|
||||
=====
|
||||
|
||||
[](https://cirrus-ci.com/github/RPCS3/rpcs3)
|
||||
[](https://github.com/RPCS3/rpcs3/actions/workflows/rpcs3.yml)
|
||||
[](https://discord.gg/rpcs3)
|
||||
|
||||
|
||||
@@ -525,7 +525,7 @@ void fmt_class_string<u128>::format(std::string& out, u64 arg)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
fmt::append(out, "0x%016llx%016llx", num.hi, num.lo);
|
||||
#else
|
||||
fmt::append(out, "0x%016llx%016llx", static_cast<u64>(num >> 64), static_cast<u64>(num));
|
||||
|
||||
+1
-1
@@ -393,7 +393,7 @@ namespace fmt
|
||||
raw_throw_exception(src_loc, reinterpret_cast<const char*>(fmt), type_info_v<Args...>, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
[[noreturn]] ~throw_exception();
|
||||
#endif
|
||||
};
|
||||
|
||||
+14
-4
@@ -96,7 +96,7 @@ class thread_future
|
||||
thread_future* prev{};
|
||||
|
||||
protected:
|
||||
atomic_t<void(*)(thread_base*, thread_future*)> exec{};
|
||||
atomic_t<void(*)(const thread_base*, thread_future*)> exec{};
|
||||
|
||||
atomic_t<u32> done{0};
|
||||
|
||||
@@ -374,13 +374,23 @@ private:
|
||||
static const u64 process_affinity_mask;
|
||||
};
|
||||
|
||||
#if defined(__has_cpp_attribute)
|
||||
#if __has_cpp_attribute(no_unique_address)
|
||||
#define NO_UNIQUE_ADDRESS [[no_unique_address]]
|
||||
#else
|
||||
#define NO_UNIQUE_ADDRESS
|
||||
#endif
|
||||
#else
|
||||
#define NO_UNIQUE_ADDRESS
|
||||
#endif
|
||||
|
||||
// Used internally
|
||||
template <bool Discard, typename Ctx, typename... Args>
|
||||
class thread_future_t : public thread_future, result_storage<Ctx, std::conditional_t<Discard, int, void>, Args...>
|
||||
{
|
||||
[[no_unique_address]] decltype(std::make_tuple(std::forward<Args>(std::declval<Args>())...)) m_args;
|
||||
NO_UNIQUE_ADDRESS decltype(std::make_tuple(std::forward<Args>(std::declval<Args>())...)) m_args;
|
||||
|
||||
[[no_unique_address]] Ctx m_func;
|
||||
NO_UNIQUE_ADDRESS Ctx m_func;
|
||||
|
||||
using future = thread_future_t;
|
||||
|
||||
@@ -389,7 +399,7 @@ public:
|
||||
: m_args(std::forward<Args>(args)...)
|
||||
, m_func(std::forward<Ctx>(func))
|
||||
{
|
||||
thread_future::exec.raw() = +[](thread_base* tb, thread_future* tf)
|
||||
thread_future::exec.raw() = +[](const thread_base* tb, thread_future* tf)
|
||||
{
|
||||
const auto _this = static_cast<future*>(tf);
|
||||
|
||||
|
||||
@@ -94,8 +94,6 @@ if defined BUILD_SOURCEBRANCHNAME (
|
||||
|
||||
rem // This must be a CI build
|
||||
|
||||
echo SYSTEM_PULLREQUEST_SOURCEBRANCH: %SYSTEM_PULLREQUEST_SOURCEBRANCH%
|
||||
|
||||
if defined BUILD_REPOSITORY_NAME (
|
||||
echo BUILD_REPOSITORY_NAME: %BUILD_REPOSITORY_NAME%
|
||||
) else (
|
||||
@@ -110,9 +108,7 @@ if defined BUILD_SOURCEBRANCHNAME (
|
||||
|
||||
rem // These environment variables are defined by CI
|
||||
rem // BUILD_REPOSITORY_NAME will look like "RPCS3/rpcs3"
|
||||
rem // SYSTEM_PULLREQUEST_SOURCEBRANCH will look like "master"
|
||||
rem // BUILD_SOURCEBRANCHNAME will look like "master"
|
||||
rem // See https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables
|
||||
set GIT_FULL_BRANCH=%BUILD_REPOSITORY_NAME%/%BUILD_SOURCEBRANCHNAME%
|
||||
echo GIT_FULL_BRANCH: !GIT_FULL_BRANCH!
|
||||
|
||||
@@ -129,12 +125,12 @@ if defined BUILD_SOURCEBRANCHNAME (
|
||||
rem // This must be a pull request or a build from a fork.
|
||||
echo Assuming pull request build
|
||||
|
||||
if "%SYSTEM_PULLREQUEST_SOURCEBRANCH%"=="master" (
|
||||
if "%BUILD_SOURCEBRANCHNAME%"=="master" (
|
||||
rem // If pull request comes from a master branch, GIT_BRANCH = username/branch in order to distinguish from upstream/master
|
||||
for /f "tokens=1* delims=/" %%a in ("%BUILD_REPOSITORY_NAME%") do set user=%%a
|
||||
set "GIT_BRANCH=!user!/%SYSTEM_PULLREQUEST_SOURCEBRANCH%"
|
||||
set "GIT_BRANCH=!user!/%BUILD_SOURCEBRANCHNAME%"
|
||||
) else (
|
||||
set GIT_BRANCH=%SYSTEM_PULLREQUEST_SOURCEBRANCH%
|
||||
set GIT_BRANCH=%BUILD_SOURCEBRANCHNAME%
|
||||
)
|
||||
|
||||
rem // Make GIT_VERSION the last commit (shortened); Don't include commit count on non-release builds
|
||||
|
||||
@@ -84,9 +84,8 @@ public:
|
||||
transactional_storage& operator=(const transactional_storage&) = delete;
|
||||
|
||||
transactional_storage(transactional_storage&& other)
|
||||
: pool(std::move(other.pool))
|
||||
{
|
||||
pool = std::move(other.pool);
|
||||
|
||||
std::unique_lock lock_other{other.current_mutex};
|
||||
const std::shared_ptr<T> other_current = other.current;
|
||||
other.current = nullptr;
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
# Check and configure compiler options for RPCS3
|
||||
|
||||
if(MSVC)
|
||||
add_compile_options(/Zc:throwingNew- /constexpr:steps16777216)
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
check_cxx_compiler_flag("-msse -msse2 -mcx16" COMPILER_X86)
|
||||
if (COMPILER_X86)
|
||||
add_compile_options(-msse -msse2 -mcx16 -mavx -mavx2 -mavx512f -mavx512vbmi -mavx512vl -mavx512dq -mavx512vpopcntdq -maes -mrtm -mpclmul -mmwaitx -mwaitpkg)
|
||||
endif()
|
||||
add_link_options(/dynamicbase)
|
||||
else()
|
||||
add_compile_options(/Zc:throwingNew- /constexpr:steps16777216)
|
||||
add_link_options(/DYNAMICBASE)
|
||||
endif()
|
||||
|
||||
add_compile_definitions(
|
||||
_CRT_SECURE_NO_DEPRECATE=1 _CRT_NON_CONFORMING_SWPRINTFS=1 _SCL_SECURE_NO_WARNINGS=1
|
||||
NOMINMAX _ENABLE_EXTENDED_ALIGNED_STORAGE=1 _HAS_EXCEPTIONS=0)
|
||||
add_link_options(/DYNAMICBASE:YES)
|
||||
|
||||
#TODO: Some of these could be cleaned up
|
||||
add_compile_options(/wd4805) # Comparing boolean and int
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# Copy remaining DLLS
|
||||
|
||||
cmake_path(GET exe PARENT_PATH exe_dir)
|
||||
cmake_path(CONVERT "${MSYS2_CLANG_BIN}" TO_CMAKE_PATH_LIST msys2_clang_bin)
|
||||
cmake_path(CONVERT "${MSYS2_USR_BIN}" TO_CMAKE_PATH_LIST msys2_usr_bin)
|
||||
|
||||
message(STATUS "Getting runtime dependencies for '${exe}' in '${exe_dir}'")
|
||||
message(STATUS "Dependency dirs: '${msys2_clang_bin}', '${msys2_usr_bin}'")
|
||||
|
||||
file(GET_RUNTIME_DEPENDENCIES EXECUTABLES ${exe}
|
||||
RESOLVED_DEPENDENCIES_VAR resolved_deps
|
||||
UNRESOLVED_DEPENDENCIES_VAR unresolved_deps
|
||||
DIRECTORIES ${msys2_clang_bin} ${msys2_usr_bin})
|
||||
|
||||
foreach(dep IN LISTS resolved_deps)
|
||||
cmake_path(GET dep FILENAME dep_filename)
|
||||
cmake_path(GET dep PARENT_PATH dep_dir_raw)
|
||||
cmake_path(CONVERT "${dep_dir_raw}" TO_CMAKE_PATH_LIST dep_dir)
|
||||
|
||||
string(COMPARE EQUAL "${dep_dir}" "${msys2_clang_bin}" is_clang_path)
|
||||
string(COMPARE EQUAL "${dep_dir}" "${msys2_usr_bin}" is_usr_path)
|
||||
|
||||
set(same_path FALSE)
|
||||
if(is_clang_path OR is_usr_path)
|
||||
set(same_path TRUE)
|
||||
endif()
|
||||
|
||||
if(same_path)
|
||||
set(dest "${exe_dir}/${dep_filename}")
|
||||
if(NOT EXISTS "${dest}")
|
||||
file(COPY "${dep}" DESTINATION "${exe_dir}")
|
||||
message(STATUS "Copied '${dep_filename}' to '${exe_dir}'")
|
||||
else()
|
||||
message(STATUS "Already exists: '${dest}', skipping.")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Found and ignored '${dep}' in '${dep_dir}'. Is clang path: ${is_clang_path}, is usr path: ${is_usr_path}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Warn about unresolved dependencies
|
||||
if(unresolved_deps)
|
||||
message(WARNING "Unresolved dependencies:")
|
||||
foreach(dep IN LISTS unresolved_deps)
|
||||
cmake_path(GET dep PARENT_PATH dep_dir)
|
||||
string(TOLOWER "${dep_dir}" dep_dir_lower)
|
||||
if(NOT dep_dir_lower MATCHES ".*(windows[/\\]system32|windows[/\\]winsxs|program files).*")
|
||||
message(STATUS " - ${dep_dir}/${dep}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
@@ -154,12 +154,12 @@ if (NOT ANDROID)
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/GuiConfigs $<TARGET_FILE_DIR:rpcs3>/GuiConfigs)
|
||||
elseif(WIN32)
|
||||
add_custom_command(TARGET rpcs3 POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:OpenAL::OpenAL> $<TARGET_FILE_DIR:rpcs3>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/Icons $<TARGET_FILE_DIR:rpcs3>/Icons
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/GuiConfigs $<TARGET_FILE_DIR:rpcs3>/GuiConfigs
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/test $<TARGET_FILE_DIR:rpcs3>/test
|
||||
COMMAND "${WINDEPLOYQT_EXECUTABLE}" --no-compiler-runtime --no-opengl-sw --no-patchqt
|
||||
--no-translations --no-system-d3d-compiler --no-system-dxc-compiler --no-ffmpeg --no-quick-import
|
||||
--plugindir "$<IF:$<CXX_COMPILER_ID:MSVC>,$<TARGET_FILE_DIR:rpcs3>/plugins,$<TARGET_FILE_DIR:rpcs3>/share/qt6/plugins>"
|
||||
--no-translations --no-system-d3d-compiler --no-system-dxc-compiler --no-quick-import
|
||||
--plugindir "$<TARGET_FILE_DIR:rpcs3>/qt6/plugins"
|
||||
--verbose 0 "$<TARGET_FILE:rpcs3>")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -197,6 +197,21 @@ void aesni_gcm_mult( unsigned char c[16],
|
||||
const unsigned char b[16] )
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_MSVC_X64_INTRINSICS)
|
||||
#ifdef __clang__
|
||||
__m128i xa, xb, m0, m1, x10, x32, r;
|
||||
|
||||
xa[1] = _byteswap_uint64( *((unsigned __int64*)a + 0) );
|
||||
xa[0] = _byteswap_uint64( *((unsigned __int64*)a + 1) );
|
||||
xb[1] = _byteswap_uint64( *((unsigned __int64*)b + 0) );
|
||||
xb[0] = _byteswap_uint64( *((unsigned __int64*)b + 1) );
|
||||
|
||||
clmul256( xa, xb, &m0, &m1 );
|
||||
sll256( m0, m1, &x10, &x32 );
|
||||
r = reducemod128( x10, x32 );
|
||||
|
||||
*((unsigned __int64*)c + 0) = _byteswap_uint64( r[1] );
|
||||
*((unsigned __int64*)c + 1) = _byteswap_uint64( r[0] );
|
||||
#else
|
||||
__m128i xa, xb, m0, m1, x10, x32, r;
|
||||
|
||||
xa.m128i_u64[1] = _byteswap_uint64( *((unsigned __int64*)a + 0) );
|
||||
@@ -210,6 +225,7 @@ void aesni_gcm_mult( unsigned char c[16],
|
||||
|
||||
*((unsigned __int64*)c + 0) = _byteswap_uint64( r.m128i_u64[1] );
|
||||
*((unsigned __int64*)c + 1) = _byteswap_uint64( r.m128i_u64[0] );
|
||||
#endif
|
||||
#else
|
||||
unsigned char aa[16], bb[16], cc[16];
|
||||
size_t i;
|
||||
|
||||
@@ -337,7 +337,7 @@ f64 XAudio2Backend::GetCallbackFrameLen()
|
||||
return std::max<f64>(min_latency, _10ms); // 10ms is the minimum for XAudio
|
||||
}
|
||||
|
||||
void XAudio2Backend::OnVoiceProcessingPassStart(UINT32 BytesRequired)
|
||||
void XAudio2Backend::OnVoiceProcessingPassStart(UINT32 BytesRequired) noexcept
|
||||
{
|
||||
std::unique_lock lock(m_cb_mutex, std::defer_lock);
|
||||
if (BytesRequired && !m_reset_req.observe() && lock.try_lock_for(std::chrono::microseconds{50}) && m_write_callback && m_playing)
|
||||
@@ -366,7 +366,7 @@ void XAudio2Backend::OnVoiceProcessingPassStart(UINT32 BytesRequired)
|
||||
}
|
||||
}
|
||||
|
||||
void XAudio2Backend::OnCriticalError(HRESULT Error)
|
||||
void XAudio2Backend::OnCriticalError(HRESULT Error) noexcept
|
||||
{
|
||||
XAudio.error("OnCriticalError() called: %s (0x%08x)", std::system_category().message(Error), static_cast<u32>(Error));
|
||||
|
||||
|
||||
@@ -54,18 +54,18 @@ private:
|
||||
atomic_t<bool> m_reset_req = false;
|
||||
|
||||
// XAudio voice callbacks
|
||||
void OnVoiceProcessingPassStart(UINT32 BytesRequired) override;
|
||||
void OnVoiceProcessingPassEnd() override {}
|
||||
void OnStreamEnd() override {}
|
||||
void OnBufferStart(void* /* pBufferContext */) override {}
|
||||
void OnBufferEnd(void* /* pBufferContext*/) override {}
|
||||
void OnLoopEnd(void* /* pBufferContext */) override {}
|
||||
void OnVoiceError(void* /* pBufferContext */, HRESULT /* Error */) override {}
|
||||
void OnVoiceProcessingPassStart(UINT32 BytesRequired) noexcept override;
|
||||
void OnVoiceProcessingPassEnd() noexcept override {}
|
||||
void OnStreamEnd() noexcept override {}
|
||||
void OnBufferStart(void* /* pBufferContext */) noexcept override {}
|
||||
void OnBufferEnd(void* /* pBufferContext*/) noexcept override {}
|
||||
void OnLoopEnd(void* /* pBufferContext */) noexcept override {}
|
||||
void OnVoiceError(void* /* pBufferContext */, HRESULT /* Error */) noexcept override {}
|
||||
|
||||
// XAudio engine callbacks
|
||||
void OnProcessingPassStart() override {};
|
||||
void OnProcessingPassEnd() override {};
|
||||
void OnCriticalError(HRESULT Error) override;
|
||||
void OnProcessingPassStart() noexcept override {};
|
||||
void OnProcessingPassEnd() noexcept override {};
|
||||
void OnCriticalError(HRESULT Error) noexcept override;
|
||||
|
||||
// IMMNotificationClient callbacks
|
||||
IFACEMETHODIMP_(ULONG) AddRef() override { return 1; };
|
||||
|
||||
@@ -29,6 +29,10 @@ if(USE_ASAN)
|
||||
set_source_files_properties(../../Utilities/Thread.cpp PROPERTIES COMPILE_DEFINITIONS USE_ASAN)
|
||||
endif()
|
||||
|
||||
if(NOT USE_SYSTEM_OPENAL)
|
||||
target_compile_definitions(rpcs3_emu PUBLIC AL_LIBTYPE_STATIC)
|
||||
endif()
|
||||
|
||||
if(HAS_MEMORY_BREAKPOINTS)
|
||||
target_compile_definitions(rpcs3_emu PRIVATE RPCS3_HAS_MEMORY_BREAKPOINTS)
|
||||
endif()
|
||||
|
||||
@@ -434,7 +434,7 @@ struct llvm_value_t<T*> : llvm_value_t<T>
|
||||
|
||||
static llvm::Type* get_type(llvm::LLVMContext& context)
|
||||
{
|
||||
return llvm_value_t<T>::get_type(context)->getPointerTo();
|
||||
return llvm::PointerType::getUnqual(context);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -351,7 +351,7 @@ public:
|
||||
for (u32 i = 0; i < CELL_GEM_MAX_NUM; i++)
|
||||
{
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(i));
|
||||
const bool connected = pad && pad->is_connected() && i < attribute.max_connect;
|
||||
const bool connected = pad && pad->is_connected() && !pad->is_copilot() && i < attribute.max_connect;
|
||||
const bool is_real_move = g_cfg.io.move != move_handler::real || pad->m_pad_handler == pad_handler::move;
|
||||
|
||||
update_connection(i, connected && is_real_move);
|
||||
@@ -407,7 +407,7 @@ public:
|
||||
std::lock_guard pad_lock(pad::g_pad_mutex);
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
if (pad && pad->m_pad_handler == pad_handler::move)
|
||||
if (pad && pad->m_pad_handler == pad_handler::move && !pad->is_copilot())
|
||||
{
|
||||
if (!pad->move_data.calibration_requested || !pad->move_data.calibration_succeeded)
|
||||
{
|
||||
@@ -437,7 +437,7 @@ public:
|
||||
std::lock_guard pad_lock(pad::g_pad_mutex);
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
if (pad && pad->m_pad_handler == pad_handler::move)
|
||||
if (pad && pad->m_pad_handler == pad_handler::move && !pad->is_copilot())
|
||||
{
|
||||
pad->move_data.calibration_requested = false;
|
||||
pad->move_data.calibration_succeeded = false;
|
||||
@@ -469,7 +469,7 @@ public:
|
||||
for (u32 i = 0; i < std::min<u32>(attribute.max_connect, CELL_GEM_MAX_NUM); i++)
|
||||
{
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(i));
|
||||
if (pad && pad->m_pad_handler == pad_handler::move && pad->is_connected())
|
||||
if (pad && pad->m_pad_handler == pad_handler::move && pad->is_connected() && !pad->is_copilot())
|
||||
{
|
||||
connected_controllers++;
|
||||
|
||||
@@ -490,7 +490,7 @@ public:
|
||||
for (u32 i = 0; i < std::min<u32>(attribute.max_connect, CELL_GEM_MAX_NUM); i++)
|
||||
{
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(i));
|
||||
if (pad && pad->is_connected())
|
||||
if (pad && pad->is_connected() && !pad->is_copilot())
|
||||
{
|
||||
connected_controllers++;
|
||||
|
||||
@@ -1776,7 +1776,7 @@ static void ds3_input_to_pad(const u32 gem_num, be_t<u16>& digital_buttons, be_t
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (!pad->is_connected())
|
||||
if (!pad->is_connected() || pad->is_copilot())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1864,7 +1864,7 @@ static void ds3_pos_to_gem_state(u32 gem_num, gem_config::gem_controller& contro
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (!pad->is_connected())
|
||||
if (!pad->is_connected() || pad->is_copilot())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1895,7 +1895,7 @@ static void ps_move_pos_to_gem_state(u32 gem_num, gem_config::gem_controller& co
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (pad->m_pad_handler != pad_handler::move || !pad->is_connected())
|
||||
if (pad->m_pad_handler != pad_handler::move || !pad->is_connected() || pad->is_copilot())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1940,7 +1940,7 @@ static void ds3_input_to_ext(u32 gem_num, gem_config::gem_controller& controller
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (!pad->is_connected())
|
||||
if (!pad->is_connected() || pad->is_copilot())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1952,7 +1952,7 @@ static void ds3_input_to_ext(u32 gem_num, gem_config::gem_controller& controller
|
||||
|
||||
ext.status = controller.ext_status;
|
||||
|
||||
for (const AnalogStick& stick : pad->m_sticks)
|
||||
for (const AnalogStick& stick : pad->m_sticks_external)
|
||||
{
|
||||
switch (stick.m_offset)
|
||||
{
|
||||
@@ -1964,7 +1964,7 @@ static void ds3_input_to_ext(u32 gem_num, gem_config::gem_controller& controller
|
||||
}
|
||||
}
|
||||
|
||||
for (const Button& button : pad->m_buttons)
|
||||
for (const Button& button : pad->m_buttons_external)
|
||||
{
|
||||
if (!button.m_pressed)
|
||||
continue;
|
||||
@@ -2400,7 +2400,7 @@ error_code cellGemEnableMagnetometer(u32 gem_num, u32 enable)
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (pad && pad->m_pad_handler == pad_handler::move)
|
||||
if (pad && pad->m_pad_handler == pad_handler::move && !pad->is_copilot())
|
||||
{
|
||||
pad->move_data.magnetometer_enabled = controller.enabled_magnetometer;
|
||||
}
|
||||
@@ -2448,7 +2448,7 @@ error_code cellGemEnableMagnetometer2(u32 gem_num, u32 enable)
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (pad && pad->m_pad_handler == pad_handler::move)
|
||||
if (pad && pad->m_pad_handler == pad_handler::move && !pad->is_copilot())
|
||||
{
|
||||
pad->move_data.magnetometer_enabled = controller.enabled_magnetometer;
|
||||
}
|
||||
@@ -2777,7 +2777,7 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (pad && pad->is_connected())
|
||||
if (pad && pad->is_connected() && !pad->is_copilot())
|
||||
{
|
||||
inertial_state->temperature = pad->move_data.temperature;
|
||||
inertial_state->accelerometer[0] = pad->move_data.accelerometer_x;
|
||||
@@ -3392,7 +3392,7 @@ error_code cellGemReadExternalPortDeviceInfo(u32 gem_num, vm::ptr<u32> ext_id, v
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (pad->m_pad_handler != pad_handler::move || !pad->is_connected())
|
||||
if (pad->m_pad_handler != pad_handler::move || !pad->is_connected() || pad->is_copilot())
|
||||
{
|
||||
return CELL_GEM_NOT_CONNECTED;
|
||||
}
|
||||
@@ -3706,7 +3706,7 @@ error_code cellGemWriteExternalPort(u32 gem_num, vm::ptr<u8[CELL_GEM_EXTERNAL_PO
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (pad->m_pad_handler != pad_handler::move || !pad->is_connected())
|
||||
if (pad->m_pad_handler != pad_handler::move || !pad->is_connected() || pad->is_copilot())
|
||||
{
|
||||
return CELL_GEM_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
@@ -411,60 +411,27 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
|
||||
}
|
||||
};
|
||||
|
||||
for (const Button& button : pad->m_buttons)
|
||||
for (const Button& button : pad->m_buttons_external)
|
||||
{
|
||||
// here we check btns, and set pad accordingly,
|
||||
// if something changed, set btnChanged
|
||||
|
||||
bool pressed = button.m_pressed;
|
||||
u16 value = button.m_value;
|
||||
|
||||
// Merge copilots
|
||||
if (!pad->copilots.empty())
|
||||
{
|
||||
for (const auto& copilot : pad->copilots)
|
||||
{
|
||||
if (!copilot || !copilot->is_connected())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const Button& other : copilot->m_buttons)
|
||||
{
|
||||
if (button.m_offset == other.m_offset && button.m_outKeyCode == other.m_outKeyCode)
|
||||
{
|
||||
if (other.m_pressed)
|
||||
{
|
||||
pressed = true;
|
||||
|
||||
if (value < other.m_value)
|
||||
{
|
||||
value = other.m_value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (button.m_offset)
|
||||
{
|
||||
case CELL_PAD_BTN_OFFSET_DIGITAL1:
|
||||
{
|
||||
if (pressed)
|
||||
if (button.m_pressed)
|
||||
pad->m_digital_1 |= button.m_outKeyCode;
|
||||
else
|
||||
pad->m_digital_1 &= ~button.m_outKeyCode;
|
||||
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_LEFT: set_value(pad->m_press_left, value); break;
|
||||
case CELL_PAD_CTRL_DOWN: set_value(pad->m_press_down, value); break;
|
||||
case CELL_PAD_CTRL_RIGHT: set_value(pad->m_press_right, value); break;
|
||||
case CELL_PAD_CTRL_UP: set_value(pad->m_press_up, value); break;
|
||||
// These arent pressure btns
|
||||
case CELL_PAD_CTRL_LEFT: set_value(pad->m_press_left, button.m_value); break;
|
||||
case CELL_PAD_CTRL_DOWN: set_value(pad->m_press_down, button.m_value); break;
|
||||
case CELL_PAD_CTRL_RIGHT: set_value(pad->m_press_right, button.m_value); break;
|
||||
case CELL_PAD_CTRL_UP: set_value(pad->m_press_up, button.m_value); break;
|
||||
// These aren't pressure btns
|
||||
case CELL_PAD_CTRL_R3:
|
||||
case CELL_PAD_CTRL_L3:
|
||||
case CELL_PAD_CTRL_START:
|
||||
@@ -475,21 +442,21 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
|
||||
}
|
||||
case CELL_PAD_BTN_OFFSET_DIGITAL2:
|
||||
{
|
||||
if (pressed)
|
||||
if (button.m_pressed)
|
||||
pad->m_digital_2 |= button.m_outKeyCode;
|
||||
else
|
||||
pad->m_digital_2 &= ~button.m_outKeyCode;
|
||||
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_SQUARE: set_value(pad->m_press_square, value); break;
|
||||
case CELL_PAD_CTRL_CROSS: set_value(pad->m_press_cross, value); break;
|
||||
case CELL_PAD_CTRL_CIRCLE: set_value(pad->m_press_circle, value); break;
|
||||
case CELL_PAD_CTRL_TRIANGLE: set_value(pad->m_press_triangle, value); break;
|
||||
case CELL_PAD_CTRL_R1: set_value(pad->m_press_R1, value); break;
|
||||
case CELL_PAD_CTRL_L1: set_value(pad->m_press_L1, value); break;
|
||||
case CELL_PAD_CTRL_R2: set_value(pad->m_press_R2, value); break;
|
||||
case CELL_PAD_CTRL_L2: set_value(pad->m_press_L2, value); break;
|
||||
case CELL_PAD_CTRL_SQUARE: set_value(pad->m_press_square, button.m_value); break;
|
||||
case CELL_PAD_CTRL_CROSS: set_value(pad->m_press_cross, button.m_value); break;
|
||||
case CELL_PAD_CTRL_CIRCLE: set_value(pad->m_press_circle, button.m_value); break;
|
||||
case CELL_PAD_CTRL_TRIANGLE: set_value(pad->m_press_triangle, button.m_value); break;
|
||||
case CELL_PAD_CTRL_R1: set_value(pad->m_press_R1, button.m_value); break;
|
||||
case CELL_PAD_CTRL_L1: set_value(pad->m_press_L1, button.m_value); break;
|
||||
case CELL_PAD_CTRL_R2: set_value(pad->m_press_R2, button.m_value); break;
|
||||
case CELL_PAD_CTRL_L2: set_value(pad->m_press_L2, button.m_value); break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
@@ -498,18 +465,18 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
|
||||
{
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_PRESS_RIGHT: set_value(pad->m_press_right, value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_LEFT: set_value(pad->m_press_left, value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_UP: set_value(pad->m_press_up, value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_DOWN: set_value(pad->m_press_down, value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_TRIANGLE: set_value(pad->m_press_triangle, value, true, 255, 63); break; // Infrared on RIDE Skateboard
|
||||
case CELL_PAD_CTRL_PRESS_CIRCLE: set_value(pad->m_press_circle, value, true, 255, 63); break; // Infrared on RIDE Skateboard
|
||||
case CELL_PAD_CTRL_PRESS_CROSS: set_value(pad->m_press_cross, value, true, 255, 63); break; // Infrared on RIDE Skateboard
|
||||
case CELL_PAD_CTRL_PRESS_SQUARE: set_value(pad->m_press_square, value, true, 255, 63); break; // Infrared on RIDE Skateboard
|
||||
case CELL_PAD_CTRL_PRESS_L1: set_value(pad->m_press_L1, value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_R1: set_value(pad->m_press_R1, value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_L2: set_value(pad->m_press_L2, value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_R2: set_value(pad->m_press_R2, value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_RIGHT: set_value(pad->m_press_right, button.m_value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_LEFT: set_value(pad->m_press_left, button.m_value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_UP: set_value(pad->m_press_up, button.m_value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_DOWN: set_value(pad->m_press_down, button.m_value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_TRIANGLE: set_value(pad->m_press_triangle, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard
|
||||
case CELL_PAD_CTRL_PRESS_CIRCLE: set_value(pad->m_press_circle, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard
|
||||
case CELL_PAD_CTRL_PRESS_CROSS: set_value(pad->m_press_cross, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard
|
||||
case CELL_PAD_CTRL_PRESS_SQUARE: set_value(pad->m_press_square, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard
|
||||
case CELL_PAD_CTRL_PRESS_L1: set_value(pad->m_press_L1, button.m_value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_R1: set_value(pad->m_press_R1, button.m_value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_L2: set_value(pad->m_press_L2, button.m_value, true); break;
|
||||
case CELL_PAD_CTRL_PRESS_R2: set_value(pad->m_press_R2, button.m_value, true); break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
@@ -519,46 +486,14 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
|
||||
}
|
||||
}
|
||||
|
||||
for (const AnalogStick& stick : pad->m_sticks)
|
||||
for (const AnalogStick& stick : pad->m_sticks_external)
|
||||
{
|
||||
u16 value = stick.m_value;
|
||||
|
||||
// Merge copilots
|
||||
if (!pad->copilots.empty())
|
||||
{
|
||||
const auto normalize = [](s32 value)
|
||||
{
|
||||
return (value - 128) / 127.0f;
|
||||
};
|
||||
|
||||
f32 accumulated_value = normalize(value);
|
||||
|
||||
for (const auto& copilot : pad->copilots)
|
||||
{
|
||||
if (!copilot || !copilot->is_connected())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const AnalogStick& other : copilot->m_sticks)
|
||||
{
|
||||
if (stick.m_offset == other.m_offset)
|
||||
{
|
||||
accumulated_value += normalize(other.m_value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value = static_cast<u16>(std::round(std::clamp(accumulated_value * 127.0f + 128.0f, 0.0f, 255.0f)));
|
||||
}
|
||||
|
||||
switch (stick.m_offset)
|
||||
{
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: set_value(pad->m_analog_left_x, value); break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: set_value(pad->m_analog_left_y, value); break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: set_value(pad->m_analog_right_x, value); break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: set_value(pad->m_analog_right_y, value); break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: set_value(pad->m_analog_left_x, stick.m_value); break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: set_value(pad->m_analog_left_y, stick.m_value); break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: set_value(pad->m_analog_right_x, stick.m_value); break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: set_value(pad->m_analog_right_y, stick.m_value); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -1305,7 +1240,7 @@ error_code cellPadLddGetPortNo(s32 handle)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
|
||||
const auto handler = pad::get_pad_thread();
|
||||
auto& pads = handler->GetPads();
|
||||
const auto& pads = handler->GetPads();
|
||||
|
||||
if (handle < 0 || static_cast<u32>(handle) >= pads.size())
|
||||
return CELL_PAD_ERROR_INVALID_PARAMETER;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "Emu/Io/pad_types.h"
|
||||
|
||||
#include <array>
|
||||
#include "util/types.hpp"
|
||||
|
||||
enum CellPadError : u32
|
||||
{
|
||||
|
||||
@@ -700,11 +700,32 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
u32 errDialog, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncFixed funcFixed, PFuncStat funcStat,
|
||||
PFuncFile funcFile, u32 container, u32 unk_op_flags /*TODO*/, vm::ptr<void> userdata, u32 userId, PFuncDone funcDone)
|
||||
{
|
||||
if (const auto& [ok, list] = setList.try_read(); ok)
|
||||
cellSaveData.notice("savedata_op(): setList = { .sortType=%d, .sortOrder=%d, .dirNamePrefix='%s' }", list.sortType, list.sortOrder, list.dirNamePrefix);
|
||||
if (setList)
|
||||
{
|
||||
if (const auto& [ok, list] = setList.try_read(); ok)
|
||||
{
|
||||
cellSaveData.notice("savedata_op(): setList = { .sortType=%d, .sortOrder=%d, .dirNamePrefix='%s' }", list.sortType, list.sortOrder, list.dirNamePrefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
cellSaveData.error("savedata_op(): Failed to read setList!");
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto& [ok, buf] = setBuf.try_read(); ok)
|
||||
cellSaveData.notice("savedata_op(): setBuf = { .dirListMax=%d, .fileListMax=%d, .bufSize=%d }", buf.dirListMax, buf.fileListMax, buf.bufSize);
|
||||
if (setBuf)
|
||||
{
|
||||
if (const auto& [ok, buf] = setBuf.try_read(); ok)
|
||||
{
|
||||
cellSaveData.notice("savedata_op(): setBuf = { .dirListMax=%d, .fileListMax=%d, .bufSize=%d }", buf.dirListMax, buf.fileListMax, buf.bufSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
cellSaveData.error("savedata_op(): Failed to read setBuf!");
|
||||
}
|
||||
}
|
||||
|
||||
// There is a lot going on in this function, ensure function log and past log commands have completed for ease of debugging
|
||||
logs::listener::sync_all();
|
||||
|
||||
if (const auto ecode = savedata_check_args(operation, version, dirName, errDialog, setList, setBuf, funcList, funcFixed, funcStat,
|
||||
funcFile, container, unk_op_flags, userdata, userId, funcDone))
|
||||
@@ -858,25 +879,34 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
const u32 order = setList->sortOrder;
|
||||
const u32 type = setList->sortType;
|
||||
|
||||
std::sort(save_entries.begin(), save_entries.end(), [=](const SaveDataEntry& entry1, const SaveDataEntry& entry2)
|
||||
std::sort(save_entries.begin(), save_entries.end(), [order, type](const SaveDataEntry& entry1, const SaveDataEntry& entry2) -> bool
|
||||
{
|
||||
if (order == CELL_SAVEDATA_SORTORDER_DESCENT && type == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME)
|
||||
const bool mtime_lower = entry1.mtime < entry2.mtime;
|
||||
const bool mtime_equal = entry1.mtime == entry2.mtime;
|
||||
const bool subtitle_lower = entry1.subtitle < entry2.subtitle;
|
||||
const bool subtitle_equal = entry1.subtitle == entry2.subtitle;
|
||||
const bool revert_order = order == CELL_SAVEDATA_SORTORDER_DESCENT;
|
||||
|
||||
if (type == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME)
|
||||
{
|
||||
return entry1.mtime >= entry2.mtime;
|
||||
if (mtime_equal)
|
||||
{
|
||||
return subtitle_lower != revert_order;
|
||||
}
|
||||
|
||||
return mtime_lower != revert_order;
|
||||
}
|
||||
if (order == CELL_SAVEDATA_SORTORDER_DESCENT && type == CELL_SAVEDATA_SORTTYPE_SUBTITLE)
|
||||
else if (type == CELL_SAVEDATA_SORTTYPE_SUBTITLE)
|
||||
{
|
||||
return entry1.subtitle >= entry2.subtitle;
|
||||
}
|
||||
if (order == CELL_SAVEDATA_SORTORDER_ASCENT && type == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME)
|
||||
{
|
||||
return entry1.mtime < entry2.mtime;
|
||||
}
|
||||
if (order == CELL_SAVEDATA_SORTORDER_ASCENT && type == CELL_SAVEDATA_SORTTYPE_SUBTITLE)
|
||||
{
|
||||
return entry1.subtitle < entry2.subtitle;
|
||||
if (subtitle_equal)
|
||||
{
|
||||
return mtime_lower != revert_order;
|
||||
}
|
||||
|
||||
return subtitle_lower != revert_order;
|
||||
}
|
||||
|
||||
ensure(false);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1220,7 +1220,7 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr<CellVdecP
|
||||
|
||||
if (arg4 || format->unk0 || format->unk1)
|
||||
{
|
||||
fmt::throw_exception("cellVdecGetPictureExt: Unknown arguments (arg4=*0x%x, unk0=0x%x, unk1=0x%x)", arg4, format->unk0, format->unk1);
|
||||
cellVdec.todo("cellVdecGetPictureExt: Unknown arguments (arg4=*0x%x, unk0=0x%x, unk1=0x%x)", arg4, format->unk0, format->unk1);
|
||||
}
|
||||
|
||||
vdec_frame frame;
|
||||
|
||||
@@ -4265,7 +4265,7 @@ error_code sceNpManagerGetEntitlementById(vm::cptr<char> entId, vm::ptr<SceNpEnt
|
||||
return SCE_NP_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
return SCE_NP_ERROR_ID_NOT_FOUND;
|
||||
}
|
||||
|
||||
error_code sceNpManagerGetSigninId(vm::ptr<void> signInId)
|
||||
|
||||
@@ -5760,7 +5760,7 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module<lv2_obj>& module
|
||||
// Define some types
|
||||
const auto _func = FunctionType::get(translator.get_type<void>(), {
|
||||
translator.get_type<u8*>(), // Exec base
|
||||
translator.GetContextType()->getPointerTo(), // PPU context
|
||||
translator.get_type<u8*>(), // PPU context
|
||||
translator.get_type<u64>(), // Segment address (for PRX)
|
||||
translator.get_type<u8*>(), // Memory base
|
||||
translator.get_type<u64>(), // r0
|
||||
|
||||
@@ -340,7 +340,7 @@ Function* PPUTranslator::GetSymbolResolver(const ppu_module<lv2_obj>& info)
|
||||
|
||||
const auto ftype = FunctionType::get(get_type<void>(), {
|
||||
get_type<u8*>(), // Exec base
|
||||
GetContextType()->getPointerTo(), // PPU context
|
||||
m_ir->getPtrTy(), // PPU context
|
||||
get_type<u64>(), // Segment address (for PRX)
|
||||
get_type<u8*>(), // Memory base
|
||||
get_type<u64>(), // r0
|
||||
@@ -380,7 +380,7 @@ Function* PPUTranslator::GetSymbolResolver(const ppu_module<lv2_obj>& info)
|
||||
const auto addr_array = new GlobalVariable(*m_module, addr_array_type, false, GlobalValue::PrivateLinkage, ConstantDataArray::get(m_context, vec_addrs));
|
||||
|
||||
// Create an array of function pointers
|
||||
const auto func_table_type = ArrayType::get(ftype->getPointerTo(), functions.size());
|
||||
const auto func_table_type = ArrayType::get(m_ir->getPtrTy(), functions.size());
|
||||
const auto init_func_table = ConstantArray::get(func_table_type, functions);
|
||||
const auto func_table = new GlobalVariable(*m_module, func_table_type, false, GlobalVariable::PrivateLinkage, init_func_table);
|
||||
|
||||
@@ -407,7 +407,7 @@ Function* PPUTranslator::GetSymbolResolver(const ppu_module<lv2_obj>& info)
|
||||
const auto func_pc = ZExt(m_ir->CreateLoad(ptr_inst->getResultElementType(), ptr_inst), get_type<u64>());
|
||||
|
||||
ptr_inst = dyn_cast<GetElementPtrInst>(m_ir->CreateGEP(func_table->getValueType(), func_table, {m_ir->getInt64(0), index_value}));
|
||||
assert(ptr_inst->getResultElementType() == ftype->getPointerTo());
|
||||
assert(ptr_inst->getResultElementType() == m_ir->getPtrTy());
|
||||
|
||||
const auto faddr = m_ir->CreateLoad(ptr_inst->getResultElementType(), ptr_inst);
|
||||
const auto faddr_int = m_ir->CreatePtrToInt(faddr, get_type<uptr>());
|
||||
@@ -612,7 +612,7 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect)
|
||||
const auto pos = m_ir->CreateShl(indirect, 1);
|
||||
const auto ptr = dyn_cast<GetElementPtrInst>(m_ir->CreateGEP(get_type<u8>(), m_exec, pos));
|
||||
const auto val = m_ir->CreateLoad(get_type<u64>(), ptr);
|
||||
callee = FunctionCallee(type, m_ir->CreateIntToPtr(val, type->getPointerTo()));
|
||||
callee = FunctionCallee(type, m_ir->CreateIntToPtr(val, m_ir->getPtrTy()));
|
||||
|
||||
// Load new segment address
|
||||
const auto seg_base_ptr = m_ir->CreateIntToPtr(m_ir->CreateAdd(
|
||||
@@ -2794,8 +2794,8 @@ void PPUTranslator::MFOCRF(ppu_opcode_t op)
|
||||
else if (std::none_of(m_cr + 0, m_cr + 32, [](auto* p) { return p; }))
|
||||
{
|
||||
// MFCR (optimized)
|
||||
Value* ln0 = m_ir->CreateIntToPtr(m_ir->CreatePtrToInt(m_ir->CreateStructGEP(m_thread_type, m_thread, 99), GetType<uptr>()), GetType<u8[16]>()->getPointerTo());
|
||||
Value* ln1 = m_ir->CreateIntToPtr(m_ir->CreatePtrToInt(m_ir->CreateStructGEP(m_thread_type, m_thread, 115), GetType<uptr>()), GetType<u8[16]>()->getPointerTo());
|
||||
Value* ln0 = m_ir->CreateIntToPtr(m_ir->CreatePtrToInt(m_ir->CreateStructGEP(m_thread_type, m_thread, 99), GetType<uptr>()), m_ir->getPtrTy());
|
||||
Value* ln1 = m_ir->CreateIntToPtr(m_ir->CreatePtrToInt(m_ir->CreateStructGEP(m_thread_type, m_thread, 115), GetType<uptr>()), m_ir->getPtrTy());
|
||||
|
||||
ln0 = m_ir->CreateLoad(GetType<u8[16]>(), ln0);
|
||||
ln1 = m_ir->CreateLoad(GetType<u8[16]>(), ln1);
|
||||
@@ -5384,7 +5384,7 @@ MDNode* PPUTranslator::CheckBranchProbability(u32 bo)
|
||||
void PPUTranslator::build_interpreter()
|
||||
{
|
||||
#define BUILD_VEC_INST(i) { \
|
||||
m_function = llvm::cast<llvm::Function>(m_module->getOrInsertFunction("op_" #i, get_type<void>(), m_thread_type->getPointerTo()).getCallee()); \
|
||||
m_function = llvm::cast<llvm::Function>(m_module->getOrInsertFunction("op_" #i, get_type<void>(), m_ir->getPtrTy()).getCallee()); \
|
||||
std::fill(std::begin(m_globals), std::end(m_globals), nullptr); \
|
||||
std::fill(std::begin(m_locals), std::end(m_locals), nullptr); \
|
||||
IRBuilder<> irb(BasicBlock::Create(m_context, "__entry", m_function)); \
|
||||
|
||||
@@ -130,6 +130,18 @@ bool spu_thread::read_reg(const u32 addr, u32& value)
|
||||
return true;
|
||||
}
|
||||
|
||||
case Prxy_QueryMask_offs:
|
||||
{
|
||||
value = mfc_prxy_mask;
|
||||
return true;
|
||||
}
|
||||
|
||||
case Prxy_QueryType_offs:
|
||||
{
|
||||
value = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
case SPU_Out_MBox_offs:
|
||||
{
|
||||
value = ch_out_mbox.pop();
|
||||
@@ -138,7 +150,29 @@ bool spu_thread::read_reg(const u32 addr, u32& value)
|
||||
|
||||
case SPU_MBox_Status_offs:
|
||||
{
|
||||
value = (ch_out_mbox.get_count() & 0xff) | ((4 - ch_in_mbox.get_count()) << 8 & 0xff00) | (ch_out_intr_mbox.get_count() << 16 & 0xff0000);
|
||||
// Load channel counts atomically
|
||||
auto counts = std::make_tuple(ch_out_mbox.get_count(), ch_in_mbox.get_count(), ch_out_intr_mbox.get_count());
|
||||
|
||||
while (true)
|
||||
{
|
||||
atomic_fence_acquire();
|
||||
|
||||
const auto counts_check = std::make_tuple(ch_out_mbox.get_count(), ch_in_mbox.get_count(), ch_out_intr_mbox.get_count());
|
||||
|
||||
if (counts_check == counts)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Update and reload
|
||||
counts = counts_check;
|
||||
}
|
||||
|
||||
const u32 out_mbox = std::get<0>(counts);
|
||||
const u32 in_mbox = 4 - std::get<1>(counts);
|
||||
const u32 intr_mbox = std::get<2>(counts);
|
||||
|
||||
value = (out_mbox & 0xff) | ((in_mbox << 8) & 0xff00) | ((intr_mbox << 16) & 0xff0000);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -345,6 +379,8 @@ bool spu_thread::test_is_problem_state_register_offset(u32 offset, bool for_read
|
||||
case MFC_QStatus_offs:
|
||||
case SPU_Out_MBox_offs:
|
||||
case SPU_MBox_Status_offs:
|
||||
case Prxy_QueryType_offs:
|
||||
case Prxy_QueryMask_offs:
|
||||
case SPU_Status_offs:
|
||||
case Prxy_TagStatus_offs:
|
||||
case SPU_NPC_offs:
|
||||
|
||||
@@ -2886,7 +2886,7 @@ public:
|
||||
|
||||
// Create interpreter table
|
||||
const auto if_type = get_ftype<void, u8*, u8*, u32, u32, u8*, u32, u8*>();
|
||||
m_function_table = new GlobalVariable(*m_module, ArrayType::get(if_type->getPointerTo(), 1ull << m_interp_magn), true, GlobalValue::InternalLinkage, nullptr);
|
||||
m_function_table = new GlobalVariable(*m_module, ArrayType::get(m_ir->getPtrTy(), 1ull << m_interp_magn), true, GlobalValue::InternalLinkage, nullptr);
|
||||
|
||||
init_luts();
|
||||
|
||||
@@ -2930,7 +2930,7 @@ public:
|
||||
m_ir->CreateStore(m_ir->CreateCall(get_intrinsic<u64>(Intrinsic::read_register), {rsp_name}), native_sp);
|
||||
|
||||
// Decode (shift) and load function pointer
|
||||
const auto first = m_ir->CreateLoad(if_type->getPointerTo(), m_ir->CreateGEP(if_type->getPointerTo(), m_interp_table, m_ir->CreateLShr(m_interp_op, 32u - m_interp_magn)));
|
||||
const auto first = m_ir->CreateLoad(m_ir->getPtrTy(), m_ir->CreateGEP(m_ir->getPtrTy(), m_interp_table, m_ir->CreateLShr(m_interp_op, 32u - m_interp_magn)));
|
||||
const auto call0 = m_ir->CreateCall(if_type, first, {m_lsptr, m_thread, m_interp_pc, m_interp_op, m_interp_table, m_interp_7f0, m_interp_regs});
|
||||
call0->setCallingConv(CallingConv::GHC);
|
||||
m_ir->CreateRetVoid();
|
||||
@@ -3074,7 +3074,7 @@ public:
|
||||
const auto next_pc = itype & spu_itype::branch ? m_interp_pc : m_interp_pc_next;
|
||||
const auto be32_op = m_ir->CreateLoad(get_type<u32>(), m_ir->CreateGEP(get_type<u8>(), m_lsptr, m_ir->CreateZExt(next_pc, get_type<u64>())));
|
||||
const auto next_op = m_ir->CreateCall(get_intrinsic<u32>(Intrinsic::bswap), {be32_op});
|
||||
const auto next_if = m_ir->CreateLoad(if_type->getPointerTo(), m_ir->CreateGEP(if_type->getPointerTo(), m_interp_table, m_ir->CreateLShr(next_op, 32u - m_interp_magn)));
|
||||
const auto next_if = m_ir->CreateLoad(m_ir->getPtrTy(), m_ir->CreateGEP(m_ir->getPtrTy(), m_interp_table, m_ir->CreateLShr(next_op, 32u - m_interp_magn)));
|
||||
llvm::cast<LoadInst>(next_if)->setVolatile(true);
|
||||
|
||||
if (!(itype & spu_itype::branch))
|
||||
@@ -3199,7 +3199,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
m_function_table->setInitializer(ConstantArray::get(ArrayType::get(if_type->getPointerTo(), 1ull << m_interp_magn), iptrs));
|
||||
m_function_table->setInitializer(ConstantArray::get(ArrayType::get(m_ir->getPtrTy(), 1ull << m_interp_magn), iptrs));
|
||||
m_function_table = nullptr;
|
||||
|
||||
for (auto& f : *_module)
|
||||
@@ -7808,7 +7808,7 @@ public:
|
||||
m_ir->CreateStore(splat<u64[2]>(-1).eval(m_ir), m_ir->CreateGEP(get_type<u8>(), m_thread, stack0.value));
|
||||
const auto targ = m_ir->CreateAdd(m_ir->CreateLShr(_ret, 32), get_segment_base());
|
||||
const auto type = m_finfo->chunk->getFunctionType();
|
||||
const auto fval = m_ir->CreateIntToPtr(targ, type->getPointerTo());
|
||||
const auto fval = m_ir->CreateIntToPtr(targ, m_ir->getPtrTy());
|
||||
tail_chunk({type, fval}, m_ir->CreateTrunc(m_ir->CreateLShr(link, 32), get_type<u32>()));
|
||||
m_ir->SetInsertPoint(fail);
|
||||
}
|
||||
|
||||
@@ -4047,6 +4047,22 @@ void do_cell_atomic_128_store(u32 addr, const void* to_write)
|
||||
auto& sdata = *vm::get_super_ptr<spu_rdata_t>(addr);
|
||||
auto& res = *utils::bless<atomic_t<u128>>(vm::g_reservations + (addr & 0xff80) / 2);
|
||||
|
||||
if (std::memcmp(static_cast<const u8*>(to_write), &sdata, 16) == 0 && std::memcmp(static_cast<const u8*>(to_write) + 64, &sdata[64], 16) == 0)
|
||||
{
|
||||
const auto& write_data = *static_cast<const spu_rdata_t*>(to_write);
|
||||
const u64 at_read_time = vm::reservation_acquire(addr);
|
||||
|
||||
if (!(at_read_time & 127))
|
||||
{
|
||||
if (cmp_rdata(sdata, write_data) && at_read_time == vm::reservation_acquire(addr) && cmp_rdata(sdata, write_data))
|
||||
{
|
||||
// Write of the same data (verified atomically)
|
||||
vm::try_reservation_update(addr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (u64 j = 0;; j++)
|
||||
{
|
||||
auto [_oldd, _ok] = res.fetch_op([&](u128& r)
|
||||
|
||||
@@ -285,8 +285,10 @@ private:
|
||||
|
||||
libusb_context* ctx = nullptr;
|
||||
|
||||
#ifndef _WIN32
|
||||
#if LIBUSB_API_VERSION >= 0x01000102
|
||||
libusb_hotplug_callback_handle callback_handle {};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool hotplug_supported = false;
|
||||
@@ -302,6 +304,7 @@ void LIBUSB_CALL callback_transfer(struct libusb_transfer* transfer)
|
||||
usbh.transfer_complete(transfer);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#if LIBUSB_API_VERSION >= 0x01000102
|
||||
static int LIBUSB_CALL hotplug_callback(libusb_context* /*ctx*/, libusb_device * /*dev*/, libusb_hotplug_event event, void * /*user_data*/)
|
||||
{
|
||||
@@ -309,6 +312,7 @@ static int LIBUSB_CALL hotplug_callback(libusb_context* /*ctx*/, libusb_device *
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LIBUSB_API_VERSION >= 0x0100010A
|
||||
static void LIBUSB_CALL log_cb(libusb_context* /*ctx*/, enum libusb_log_level level, const char* str)
|
||||
@@ -597,9 +601,11 @@ usb_handler_thread::~usb_handler_thread()
|
||||
libusb_free_transfer(transfers[index].transfer);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#if LIBUSB_API_VERSION >= 0x01000102
|
||||
if (ctx && hotplug_supported)
|
||||
libusb_hotplug_deregister_callback(ctx, callback_handle);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (ctx)
|
||||
|
||||
@@ -173,7 +173,7 @@ void usb_device_buzz::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint*/
|
||||
{
|
||||
const auto& pad = pads[i];
|
||||
|
||||
if (!pad->is_connected())
|
||||
if (!pad->is_connected() || pad->is_copilot())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), m_controller_index);
|
||||
|
||||
if (!pad->is_connected())
|
||||
if (!pad->is_connected() || pad->is_copilot())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -198,9 +198,9 @@ void usb_device_gametablet::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endp
|
||||
const auto gamepad_handler = pad::get_pad_thread();
|
||||
const auto& pads = gamepad_handler->GetPads();
|
||||
const auto& pad = ::at32(pads, m_controller_index);
|
||||
if (pad->is_connected())
|
||||
if (pad->is_connected() && !pad->is_copilot())
|
||||
{
|
||||
for (Button& button : pad->m_buttons)
|
||||
for (Button& button : pad->m_buttons_external)
|
||||
{
|
||||
if (!button.m_pressed)
|
||||
{
|
||||
|
||||
@@ -258,7 +258,7 @@ void usb_device_guncon3::interrupt_transfer(u32 buf_size, u8* buf, u32 endpoint,
|
||||
const auto gamepad_handler = pad::get_pad_thread();
|
||||
const auto& pads = gamepad_handler->GetPads();
|
||||
const auto& pad = ::at32(pads, m_controller_index);
|
||||
if (pad->is_connected())
|
||||
if (pad->is_connected() && !pad->is_copilot())
|
||||
{
|
||||
cfg->handle_input(pad, true, input_callback);
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ void usb_device_topshotelite::interrupt_transfer(u32 buf_size, u8* buf, u32 /*en
|
||||
const auto gamepad_handler = pad::get_pad_thread();
|
||||
const auto& pads = gamepad_handler->GetPads();
|
||||
const auto& pad = ::at32(pads, m_controller_index);
|
||||
if (pad->is_connected())
|
||||
if (pad->is_connected() && !pad->is_copilot())
|
||||
{
|
||||
cfg->handle_input(pad, true, input_callback);
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ void usb_device_topshotfearmaster::interrupt_transfer(u32 buf_size, u8* buf, u32
|
||||
const auto gamepad_handler = pad::get_pad_thread();
|
||||
const auto& pads = gamepad_handler->GetPads();
|
||||
const auto& pad = ::at32(pads, m_controller_index);
|
||||
if (pad->is_connected())
|
||||
if (pad->is_connected() && !pad->is_copilot())
|
||||
{
|
||||
cfg->handle_input(pad, true, input_callback);
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
|
||||
const auto& pads = handler->GetPads();
|
||||
const auto& pad = ::at32(pads, m_controller_index);
|
||||
|
||||
if (!pad->is_connected())
|
||||
if (!pad->is_connected() || pad->is_copilot())
|
||||
return;
|
||||
|
||||
const auto& cfg = ::at32(g_cfg_turntable.players, m_controller_index);
|
||||
|
||||
@@ -90,10 +90,10 @@ public:
|
||||
|
||||
void handle_input(std::shared_ptr<Pad> pad, bool press_only, const std::function<void(T, pad_button, u16, bool, bool&)>& func) const
|
||||
{
|
||||
if (!pad)
|
||||
if (!pad || pad->is_copilot())
|
||||
return;
|
||||
|
||||
for (const Button& button : pad->m_buttons)
|
||||
for (const Button& button : pad->m_buttons_external)
|
||||
{
|
||||
if (button.m_pressed || !press_only)
|
||||
{
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
for (const AnalogStick& stick : pad->m_sticks)
|
||||
for (const AnalogStick& stick : pad->m_sticks_external)
|
||||
{
|
||||
if (handle_input(func, stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true, true))
|
||||
{
|
||||
|
||||
@@ -56,7 +56,7 @@ bool event_is_number(const char* s)
|
||||
}
|
||||
|
||||
// compare /dev/input/eventX and /dev/input/eventY where X and Y are numbers
|
||||
int event_strcmp_events(const char* x, const char* y)
|
||||
bool event_cmp_less_than(const char* x, const char* y)
|
||||
{
|
||||
// find a common string
|
||||
int n = 0;
|
||||
@@ -71,14 +71,10 @@ int event_strcmp_events(const char* x, const char* y)
|
||||
const int a = atoi(x + n);
|
||||
const int b = atoi(y + n);
|
||||
|
||||
if (a == b)
|
||||
return 0;
|
||||
if (a < b)
|
||||
return -1;
|
||||
return 1;
|
||||
return a < b;
|
||||
}
|
||||
|
||||
return strcmp(x, y);
|
||||
return strcmp(x, y) < 0;
|
||||
}
|
||||
|
||||
evdev_gun_handler::evdev_gun_handler()
|
||||
@@ -243,7 +239,7 @@ bool evdev_gun_handler::init()
|
||||
// Sort the udev entries by devnode name so that they are created in the proper order
|
||||
std::sort(sorted_devices.begin(), sorted_devices.end(), [](const event_udev_entry& a, const event_udev_entry& b)
|
||||
{
|
||||
return event_strcmp_events(a.devnode, b.devnode);
|
||||
return event_cmp_less_than(a.devnode, b.devnode);
|
||||
});
|
||||
|
||||
for (const event_udev_entry& entry : sorted_devices)
|
||||
|
||||
@@ -379,20 +379,22 @@ enum special_button_value
|
||||
struct Button
|
||||
{
|
||||
u32 m_offset = 0;
|
||||
std::set<u32> m_key_codes{};
|
||||
u32 m_outKeyCode = 0;
|
||||
u16 m_value = 0;
|
||||
bool m_pressed = false;
|
||||
|
||||
std::set<u32> m_key_codes{};
|
||||
|
||||
u16 m_actual_value = 0; // only used in keyboard_pad_handler
|
||||
bool m_analog = false; // only used in keyboard_pad_handler
|
||||
bool m_trigger = false; // only used in keyboard_pad_handler
|
||||
std::map<u32, u16> m_pressed_keys{}; // only used in keyboard_pad_handler
|
||||
|
||||
Button(){}
|
||||
Button(u32 offset, std::set<u32> key_codes, u32 outKeyCode)
|
||||
: m_offset(offset)
|
||||
, m_key_codes(std::move(key_codes))
|
||||
, m_outKeyCode(outKeyCode)
|
||||
, m_key_codes(std::move(key_codes))
|
||||
{
|
||||
if (offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
|
||||
{
|
||||
@@ -419,9 +421,10 @@ struct Button
|
||||
struct AnalogStick
|
||||
{
|
||||
u32 m_offset = 0;
|
||||
u16 m_value = 128;
|
||||
|
||||
std::set<u32> m_key_codes_min{};
|
||||
std::set<u32> m_key_codes_max{};
|
||||
u16 m_value = 128;
|
||||
|
||||
std::map<u32, u16> m_pressed_keys_min{}; // only used in keyboard_pad_handler
|
||||
std::map<u32, u16> m_pressed_keys_max{}; // only used in keyboard_pad_handler
|
||||
@@ -543,6 +546,9 @@ struct Pad
|
||||
std::array<AnalogSensor, 4> m_sensors{};
|
||||
std::array<VibrateMotor, 2> m_vibrateMotors{};
|
||||
|
||||
std::vector<Button> m_buttons_external;
|
||||
std::array<AnalogStick, 4> m_sticks_external{};
|
||||
|
||||
std::vector<std::shared_ptr<Pad>> copilots;
|
||||
|
||||
// These hold bits for their respective buttons
|
||||
@@ -612,6 +618,12 @@ struct Pad
|
||||
return umax;
|
||||
}
|
||||
|
||||
bool is_copilot() const
|
||||
{
|
||||
const u32 copilot_player_id = copilot_player();
|
||||
return copilot_player_id != umax && copilot_player_id != m_player_id;
|
||||
}
|
||||
|
||||
bool is_connected() const
|
||||
{
|
||||
return !!(m_port_status & CELL_PAD_STATUS_CONNECTED);
|
||||
|
||||
@@ -210,7 +210,7 @@ void usb_device_usio::translate_input_taiko()
|
||||
const usz offset = player * 8ULL;
|
||||
auto& status = m_io_status[0];
|
||||
|
||||
if (const auto& pad = ::at32(handler->GetPads(), pad_number); pad->is_connected() && is_input_allowed())
|
||||
if (const auto& pad = ::at32(handler->GetPads(), pad_number); pad->is_connected() && !pad->is_copilot() && is_input_allowed())
|
||||
{
|
||||
const auto& cfg = ::at32(g_cfg_usio.players, pad_number);
|
||||
cfg->handle_input(pad, false, [&](usio_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& /*abort*/)
|
||||
@@ -295,7 +295,7 @@ void usb_device_usio::translate_input_tekken()
|
||||
auto& status = m_io_status[player / 2];
|
||||
auto& input = digital_input[player / 2];
|
||||
|
||||
if (const auto& pad = ::at32(handler->GetPads(), pad_number); pad->is_connected() && is_input_allowed())
|
||||
if (const auto& pad = ::at32(handler->GetPads(), pad_number); pad->is_connected() && !pad->is_copilot() && is_input_allowed())
|
||||
{
|
||||
const auto& cfg = ::at32(g_cfg_usio.players, pad_number);
|
||||
cfg->handle_input(pad, false, [&](usio_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& /*abort*/)
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace vm
|
||||
|
||||
// Update reservation status
|
||||
void reservation_update(u32 addr);
|
||||
std::pair<bool, u64> try_reservation_update(u32 addr);
|
||||
|
||||
struct reservation_waiter_t
|
||||
{
|
||||
@@ -81,7 +82,8 @@ namespace vm
|
||||
|
||||
static inline atomic_t<reservation_waiter_t>* reservation_notifier_begin_wait(u32 raddr, u64 rtime)
|
||||
{
|
||||
atomic_t<reservation_waiter_t>& waiter = *reservation_notifier(raddr).first;
|
||||
const auto notifiers = reservation_notifier(raddr);
|
||||
atomic_t<reservation_waiter_t>& waiter = *notifiers.first;
|
||||
|
||||
waiter.atomic_op([](reservation_waiter_t& value)
|
||||
{
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace np
|
||||
u32 last_free = 0;
|
||||
bool found_space = false;
|
||||
|
||||
for (auto& a : m_allocs)
|
||||
for (const auto& a : m_allocs)
|
||||
{
|
||||
if ((a.first - last_free) >= alloc_size)
|
||||
{
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#include <iphlpapi.h>
|
||||
#else
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#include <WS2tcpip.h>
|
||||
#else
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <poll.h>
|
||||
#include <netdb.h>
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -9,16 +9,17 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -28,13 +29,13 @@
|
||||
#include <flatbuffers/flatbuffers.h>
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#pragma GCC diagnostic ignored "-Wextern-c-compat"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#pragma clang diagnostic ignored "-Wextern-c-compat"
|
||||
#endif
|
||||
#include <wolfssl/ssl.h>
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "rpcn_types.h"
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
#include "util/v128.hpp"
|
||||
#include "util/simd.hpp"
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_ARM64)
|
||||
#if !defined(_MSC_VER)
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
@@ -14,11 +19,6 @@
|
||||
#include "Emu/CPU/sse2neon.h"
|
||||
#endif
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) || !defined(__SSE2__)
|
||||
#define SSE4_1_FUNC
|
||||
#define AVX2_FUNC
|
||||
|
||||
@@ -285,6 +285,13 @@ namespace rsx
|
||||
return pos;
|
||||
}
|
||||
|
||||
void operator += (const rsx::simple_array<Ty>& that)
|
||||
{
|
||||
const auto old_size = _size;
|
||||
resize(_size + that._size);
|
||||
std::memcpy(data() + old_size, that.data(), that.size_bytes());
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
_size = 0;
|
||||
@@ -305,6 +312,11 @@ namespace rsx
|
||||
return _size * sizeof(Ty);
|
||||
}
|
||||
|
||||
u32 size_bytes32() const
|
||||
{
|
||||
return _size * sizeof(Ty);
|
||||
}
|
||||
|
||||
u32 capacity() const
|
||||
{
|
||||
return _capacity;
|
||||
|
||||
@@ -678,6 +678,7 @@ namespace rsx
|
||||
}
|
||||
|
||||
m_ranges.insert(pos, this_range);
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +128,8 @@ namespace gl
|
||||
case ::glsl::program_domain::glsl_compute_program:
|
||||
base_name = "shaderlog/ComputeProgram";
|
||||
break;
|
||||
default:
|
||||
fmt::throw_exception("Unexpected program type %d", static_cast<int>(type));
|
||||
}
|
||||
|
||||
fs::write_file(fs::get_cache_dir() + base_name + std::to_string(m_id) + ".glsl", fs::rewrite, str, length);
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace rsx
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!pad->is_connected())
|
||||
if (!pad->is_connected() || pad->is_copilot())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ namespace rsx
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const Button& button : pad->m_buttons)
|
||||
for (const Button& button : pad->m_buttons_external)
|
||||
{
|
||||
pad_button button_id = pad_button::pad_button_max_enum;
|
||||
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
|
||||
@@ -391,7 +391,7 @@ namespace rsx
|
||||
break;
|
||||
}
|
||||
|
||||
for (const AnalogStick& stick : pad->m_sticks)
|
||||
for (const AnalogStick& stick : pad->m_sticks_external)
|
||||
{
|
||||
pad_button button_id = pad_button::pad_button_max_enum;
|
||||
pad_button release_id = pad_button::pad_button_max_enum;
|
||||
|
||||
@@ -14,8 +14,8 @@ R"(
|
||||
#define SAMPLER_MODE_TEXTURE2D 3
|
||||
|
||||
#ifdef VULKAN
|
||||
layout(set=0, binding=1) uniform sampler2D fs0;
|
||||
layout(set=0, binding=2) uniform sampler2DArray fs1;
|
||||
layout(set=0, binding=0) uniform sampler2D fs0;
|
||||
layout(set=0, binding=1) uniform sampler2DArray fs1;
|
||||
#else
|
||||
layout(binding=31) uniform sampler2D fs0;
|
||||
layout(binding=30) uniform sampler2DArray fs1;
|
||||
|
||||
@@ -6,7 +6,10 @@ namespace glsl
|
||||
{
|
||||
glsl_vertex_program = 0,
|
||||
glsl_fragment_program = 1,
|
||||
glsl_compute_program = 2
|
||||
glsl_compute_program = 2,
|
||||
|
||||
// Meta
|
||||
glsl_invalid_program = 0xff
|
||||
};
|
||||
|
||||
enum glsl_rules : unsigned char
|
||||
|
||||
@@ -20,8 +20,9 @@ namespace program_common
|
||||
COMPILER_OPT_ENABLE_KIL = (1 << 11),
|
||||
COMPILER_OPT_ENABLE_STIPPLING = (1 << 12),
|
||||
COMPILER_OPT_ENABLE_INSTANCING = (1 << 13),
|
||||
COMPILER_OPT_ENABLE_VTX_TEXTURES = (1 << 14),
|
||||
|
||||
COMPILER_OPT_MAX = COMPILER_OPT_ENABLE_INSTANCING
|
||||
COMPILER_OPT_MAX = COMPILER_OPT_ENABLE_VTX_TEXTURES
|
||||
};
|
||||
|
||||
static std::string get_vertex_interpreter()
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace vk
|
||||
{
|
||||
struct fence;
|
||||
|
||||
enum // callback commands
|
||||
enum rctrl_command : u32 // callback commands
|
||||
{
|
||||
rctrl_queue_submit = 0x80000000,
|
||||
rctrl_run_gc = 0x80000001,
|
||||
|
||||
@@ -35,4 +35,31 @@ namespace vk
|
||||
|
||||
fmt::throw_exception("Unknown register name: %s", varying_register_name);
|
||||
}
|
||||
|
||||
int get_texture_index(std::string_view name)
|
||||
{
|
||||
if (name.length() < 2)
|
||||
{
|
||||
fmt::throw_exception("Invalid texture name: '%s'", name);
|
||||
}
|
||||
|
||||
constexpr int max_index_length = 2;
|
||||
const int name_length = static_cast<int>(name.length());
|
||||
std::string index;
|
||||
|
||||
for (int char_idx = name_length - max_index_length; char_idx < name_length; ++char_idx)
|
||||
{
|
||||
if (std::isdigit(name[char_idx]))
|
||||
{
|
||||
index += name[char_idx];
|
||||
}
|
||||
}
|
||||
|
||||
if (index.empty())
|
||||
{
|
||||
fmt::throw_exception("Invalid texture name: '%s'", name);
|
||||
}
|
||||
|
||||
return std::atoi(index.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,6 @@ namespace vk
|
||||
using namespace ::glsl;
|
||||
|
||||
int get_varying_register_location(std::string_view varying_register_name);
|
||||
|
||||
int get_texture_index(std::string_view name);
|
||||
}
|
||||
|
||||
@@ -8,157 +8,6 @@
|
||||
|
||||
namespace vk
|
||||
{
|
||||
rsx::simple_array<VkDescriptorSetLayoutBinding> get_common_binding_table()
|
||||
{
|
||||
const auto& binding_table = vk::get_current_renderer()->get_pipeline_binding_table();
|
||||
rsx::simple_array<VkDescriptorSetLayoutBinding> bindings(binding_table.instancing_constants_buffer_slot + 1);
|
||||
|
||||
u32 idx = 0;
|
||||
|
||||
// Vertex stream, one stream for cacheable data, one stream for transient data
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.vertex_buffers_first_bind_slot + i;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
idx++;
|
||||
}
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.fragment_constant_buffers_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.fragment_state_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.fragment_texture_params_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.vertex_constant_buffers_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
|
||||
bindings[idx].binding = binding_table.vertex_params_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.conditional_render_predicate_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.rasterizer_env_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.instancing_lookup_table_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.instancing_constants_buffer_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
return bindings;
|
||||
}
|
||||
|
||||
std::tuple<VkPipelineLayout, VkDescriptorSetLayout, rsx::simple_array<VkDescriptorSetLayoutBinding>>
|
||||
get_common_pipeline_layout(VkDevice dev)
|
||||
{
|
||||
const auto& binding_table = vk::get_current_renderer()->get_pipeline_binding_table();
|
||||
auto bindings = get_common_binding_table();
|
||||
u32 idx = ::size32(bindings);
|
||||
|
||||
bindings.resize(binding_table.total_descriptor_bindings);
|
||||
|
||||
for (auto binding = binding_table.textures_first_bind_slot;
|
||||
binding < binding_table.vertex_textures_first_bind_slot;
|
||||
binding++)
|
||||
{
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
idx++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rsx::limits::vertex_textures_count; i++)
|
||||
{
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.vertex_textures_first_bind_slot + i;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
idx++;
|
||||
}
|
||||
|
||||
ensure(idx == binding_table.total_descriptor_bindings);
|
||||
|
||||
std::array<VkPushConstantRange, 1> push_constants;
|
||||
push_constants[0].offset = 0;
|
||||
push_constants[0].size = 20;
|
||||
push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
|
||||
if (vk::emulate_conditional_rendering())
|
||||
{
|
||||
// Conditional render toggle
|
||||
push_constants[0].size = 24;
|
||||
}
|
||||
|
||||
const auto set_layout = vk::descriptors::create_layout(bindings);
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_info = {};
|
||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
layout_info.setLayoutCount = 1;
|
||||
layout_info.pSetLayouts = &set_layout;
|
||||
layout_info.pushConstantRangeCount = 1;
|
||||
layout_info.pPushConstantRanges = push_constants.data();
|
||||
|
||||
VkPipelineLayout result;
|
||||
CHECK_RESULT(vkCreatePipelineLayout(dev, &layout_info, nullptr, &result));
|
||||
return std::make_tuple(result, set_layout, bindings);
|
||||
}
|
||||
|
||||
rsx::simple_array<VkDescriptorPoolSize> get_descriptor_pool_sizes(const rsx::simple_array<VkDescriptorSetLayoutBinding>& bindings)
|
||||
{
|
||||
// Compile descriptor pool sizes
|
||||
|
||||
@@ -5,13 +5,6 @@
|
||||
|
||||
namespace vk
|
||||
{
|
||||
// Grab standard layout for decompiled RSX programs. Also used by the interpreter.
|
||||
// FIXME: This generates a bloated monstrosity that needs to die.
|
||||
std::tuple<VkPipelineLayout, VkDescriptorSetLayout, rsx::simple_array<VkDescriptorSetLayoutBinding>> get_common_pipeline_layout(VkDevice dev);
|
||||
|
||||
// Returns the standard binding layout without texture slots. Those have special handling depending on the consumer.
|
||||
rsx::simple_array<VkDescriptorSetLayoutBinding> get_common_binding_table();
|
||||
|
||||
// Returns an array of pool sizes that can be used to generate a proper descriptor pool
|
||||
rsx::simple_array<VkDescriptorPoolSize> get_descriptor_pool_sizes(const rsx::simple_array<VkDescriptorSetLayoutBinding>& bindings);
|
||||
}
|
||||
|
||||
@@ -8,64 +8,43 @@
|
||||
|
||||
namespace vk
|
||||
{
|
||||
std::vector<std::pair<VkDescriptorType, u8>> compute_task::get_descriptor_layout()
|
||||
std::vector<glsl::program_input> compute_task::get_inputs()
|
||||
{
|
||||
std::vector<std::pair<VkDescriptorType, u8>> result;
|
||||
result.emplace_back(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, ssbo_count);
|
||||
std::vector<glsl::program_input> result;
|
||||
for (unsigned i = 0; i < ssbo_count; ++i)
|
||||
{
|
||||
const auto input = glsl::program_input::make
|
||||
(
|
||||
::glsl::glsl_compute_program,
|
||||
"ssbo" + std::to_string(i),
|
||||
glsl::program_input_type::input_type_storage_buffer,
|
||||
0,
|
||||
i
|
||||
);
|
||||
result.push_back(input);
|
||||
}
|
||||
|
||||
if (use_push_constants && push_constants_size > 0)
|
||||
{
|
||||
const auto input = glsl::program_input::make
|
||||
(
|
||||
::glsl::glsl_compute_program,
|
||||
"push_constants",
|
||||
glsl::program_input_type::input_type_push_constant,
|
||||
0,
|
||||
0,
|
||||
glsl::push_constant_ref{ .offset = 0, .size = push_constants_size }
|
||||
);
|
||||
result.push_back(input);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void compute_task::init_descriptors()
|
||||
{
|
||||
rsx::simple_array<VkDescriptorPoolSize> descriptor_pool_sizes;
|
||||
rsx::simple_array<VkDescriptorSetLayoutBinding> bindings;
|
||||
|
||||
const auto layout = get_descriptor_layout();
|
||||
for (const auto &e : layout)
|
||||
{
|
||||
descriptor_pool_sizes.push_back({e.first, e.second});
|
||||
|
||||
for (unsigned n = 0; n < e.second; ++n)
|
||||
{
|
||||
bindings.push_back
|
||||
({
|
||||
u32(bindings.size()),
|
||||
e.first,
|
||||
1,
|
||||
VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
nullptr
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Reserve descriptor pools
|
||||
m_descriptor_pool.create(*g_render_device, descriptor_pool_sizes);
|
||||
m_descriptor_layout = vk::descriptors::create_layout(bindings);
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_info = {};
|
||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
layout_info.setLayoutCount = 1;
|
||||
layout_info.pSetLayouts = &m_descriptor_layout;
|
||||
|
||||
VkPushConstantRange push_constants{};
|
||||
if (use_push_constants)
|
||||
{
|
||||
push_constants.size = push_constants_size;
|
||||
push_constants.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||
|
||||
layout_info.pushConstantRangeCount = 1;
|
||||
layout_info.pPushConstantRanges = &push_constants;
|
||||
}
|
||||
|
||||
CHECK_RESULT(vkCreatePipelineLayout(*g_render_device, &layout_info, nullptr, &m_pipeline_layout));
|
||||
}
|
||||
|
||||
void compute_task::create()
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
init_descriptors();
|
||||
|
||||
switch (vk::get_driver_vendor())
|
||||
{
|
||||
case vk::driver_vendor::unknown:
|
||||
@@ -121,10 +100,6 @@ namespace vk
|
||||
m_program.reset();
|
||||
m_param_buffer.reset();
|
||||
|
||||
vkDestroyDescriptorSetLayout(*g_render_device, m_descriptor_layout, nullptr);
|
||||
vkDestroyPipelineLayout(*g_render_device, m_pipeline_layout, nullptr);
|
||||
m_descriptor_pool.destroy();
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
@@ -142,26 +117,23 @@ namespace vk
|
||||
shader_stage.module = handle;
|
||||
shader_stage.pName = "main";
|
||||
|
||||
VkComputePipelineCreateInfo info{};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||
info.stage = shader_stage;
|
||||
info.layout = m_pipeline_layout;
|
||||
info.basePipelineIndex = -1;
|
||||
info.basePipelineHandle = VK_NULL_HANDLE;
|
||||
VkComputePipelineCreateInfo create_info
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
||||
.stage = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.module = handle,
|
||||
.pName = "main"
|
||||
},
|
||||
};
|
||||
|
||||
auto compiler = vk::get_pipe_compiler();
|
||||
m_program = compiler->compile(info, m_pipeline_layout, vk::pipe_compiler::COMPILE_INLINE);
|
||||
declare_inputs();
|
||||
m_program = compiler->compile(create_info, vk::pipe_compiler::COMPILE_INLINE, {}, get_inputs());
|
||||
}
|
||||
|
||||
ensure(m_used_descriptors < VK_MAX_COMPUTE_TASKS);
|
||||
|
||||
m_descriptor_set = m_descriptor_pool.allocate(m_descriptor_layout, VK_TRUE);
|
||||
|
||||
bind_resources();
|
||||
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, m_program->pipeline);
|
||||
m_descriptor_set.bind(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline_layout);
|
||||
bind_resources(cmd);
|
||||
m_program->bind(cmd, VK_PIPELINE_BIND_POINT_COMPUTE);
|
||||
}
|
||||
|
||||
void compute_task::run(const vk::command_buffer& cmd, u32 invocations_x, u32 invocations_y, u32 invocations_z)
|
||||
@@ -271,15 +243,19 @@ namespace vk
|
||||
m_src += suffix;
|
||||
}
|
||||
|
||||
void cs_shuffle_base::bind_resources()
|
||||
void cs_shuffle_base::bind_resources(const vk::command_buffer& cmd)
|
||||
{
|
||||
m_program->bind_buffer({ m_data->value, m_data_offset, m_data_length }, 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_descriptor_set);
|
||||
set_parameters(cmd);
|
||||
m_program->bind_uniform({ m_data->value, m_data_offset, m_data_length }, 0, 0);
|
||||
}
|
||||
|
||||
void cs_shuffle_base::set_parameters(const vk::command_buffer& cmd, const u32* params, u8 count)
|
||||
void cs_shuffle_base::set_parameters(const vk::command_buffer& cmd)
|
||||
{
|
||||
ensure(use_push_constants);
|
||||
vkCmdPushConstants(cmd, m_pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, count * 4, params);
|
||||
if (!m_params.empty())
|
||||
{
|
||||
ensure(use_push_constants);
|
||||
vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, m_params.size_bytes32(), m_params.data());
|
||||
}
|
||||
}
|
||||
|
||||
void cs_shuffle_base::run(const vk::command_buffer& cmd, const vk::buffer* data, u32 data_length, u32 data_offset)
|
||||
@@ -317,15 +293,15 @@ namespace vk
|
||||
" uint stencil_offset;\n";
|
||||
}
|
||||
|
||||
void cs_interleave_task::bind_resources()
|
||||
void cs_interleave_task::bind_resources(const vk::command_buffer& cmd)
|
||||
{
|
||||
m_program->bind_buffer({ m_data->value, m_data_offset, m_ssbo_length }, 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_descriptor_set);
|
||||
set_parameters(cmd);
|
||||
m_program->bind_uniform({ m_data->value, m_data_offset, m_ssbo_length }, 0, 0);
|
||||
}
|
||||
|
||||
void cs_interleave_task::run(const vk::command_buffer& cmd, const vk::buffer* data, u32 data_offset, u32 data_length, u32 zeta_offset, u32 stencil_offset)
|
||||
{
|
||||
u32 parameters[4] = { data_length, zeta_offset - data_offset, stencil_offset - data_offset, 0 };
|
||||
set_parameters(cmd, parameters, 4);
|
||||
m_params = { data_length, zeta_offset - data_offset, stencil_offset - data_offset, 0 };
|
||||
|
||||
ensure(stencil_offset > data_offset);
|
||||
m_ssbo_length = stencil_offset + (data_length / 4) - data_offset;
|
||||
@@ -377,10 +353,10 @@ namespace vk
|
||||
m_src = fmt::replace_all(m_src, syntax_replace);
|
||||
}
|
||||
|
||||
void cs_aggregator::bind_resources()
|
||||
void cs_aggregator::bind_resources(const vk::command_buffer& /*cmd*/)
|
||||
{
|
||||
m_program->bind_buffer({ src->value, 0, block_length }, 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_descriptor_set);
|
||||
m_program->bind_buffer({ dst->value, 0, 4 }, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_descriptor_set);
|
||||
m_program->bind_uniform({ src->value, 0, block_length }, 0, 0);
|
||||
m_program->bind_uniform({ dst->value, 0, 4 }, 0, 1);
|
||||
}
|
||||
|
||||
void cs_aggregator::run(const vk::command_buffer& cmd, const vk::buffer* dst, const vk::buffer* src, u32 num_words)
|
||||
|
||||
@@ -19,12 +19,6 @@ namespace vk
|
||||
std::unique_ptr<vk::glsl::program> m_program;
|
||||
std::unique_ptr<vk::buffer> m_param_buffer;
|
||||
|
||||
vk::descriptor_pool m_descriptor_pool;
|
||||
descriptor_set m_descriptor_set;
|
||||
VkDescriptorSetLayout m_descriptor_layout = nullptr;
|
||||
VkPipelineLayout m_pipeline_layout = nullptr;
|
||||
u32 m_used_descriptors = 0;
|
||||
|
||||
bool initialized = false;
|
||||
bool unroll_loops = true;
|
||||
bool use_push_constants = false;
|
||||
@@ -37,15 +31,11 @@ namespace vk
|
||||
compute_task() = default;
|
||||
virtual ~compute_task() { destroy(); }
|
||||
|
||||
virtual std::vector<std::pair<VkDescriptorType, u8>> get_descriptor_layout();
|
||||
|
||||
void init_descriptors();
|
||||
|
||||
void create();
|
||||
void destroy();
|
||||
|
||||
virtual void bind_resources() {}
|
||||
virtual void declare_inputs() {}
|
||||
virtual std::vector<glsl::program_input> get_inputs();
|
||||
virtual void bind_resources(const vk::command_buffer& /*cmd*/) {}
|
||||
|
||||
void load_program(const vk::command_buffer& cmd);
|
||||
|
||||
@@ -60,6 +50,8 @@ namespace vk
|
||||
u32 m_data_length = 0;
|
||||
u32 kernel_size = 1;
|
||||
|
||||
rsx::simple_array<u32> m_params;
|
||||
|
||||
std::string variables, work_kernel, loop_advance, suffix;
|
||||
std::string method_declarations;
|
||||
|
||||
@@ -67,9 +59,9 @@ namespace vk
|
||||
|
||||
void build(const char* function_name, u32 _kernel_size = 0);
|
||||
|
||||
void bind_resources() override;
|
||||
void bind_resources(const vk::command_buffer& cmd) override;
|
||||
|
||||
void set_parameters(const vk::command_buffer& cmd, const u32* params, u8 count);
|
||||
void set_parameters(const vk::command_buffer& cmd);
|
||||
|
||||
void run(const vk::command_buffer& cmd, const vk::buffer* data, u32 data_length, u32 data_offset = 0);
|
||||
};
|
||||
@@ -135,7 +127,7 @@ namespace vk
|
||||
|
||||
cs_interleave_task();
|
||||
|
||||
void bind_resources() override;
|
||||
void bind_resources(const vk::command_buffer& cmd) override;
|
||||
|
||||
void run(const vk::command_buffer& cmd, const vk::buffer* data, u32 data_offset, u32 data_length, u32 zeta_offset, u32 stencil_offset);
|
||||
};
|
||||
@@ -352,9 +344,10 @@ namespace vk
|
||||
cs_shuffle_base::build("");
|
||||
}
|
||||
|
||||
void bind_resources() override
|
||||
void bind_resources(const vk::command_buffer& cmd) override
|
||||
{
|
||||
m_program->bind_buffer({ m_data->value, m_data_offset, m_ssbo_length }, 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_descriptor_set);
|
||||
set_parameters(cmd);
|
||||
m_program->bind_uniform({ m_data->value, m_data_offset, m_ssbo_length }, 0, 0);
|
||||
}
|
||||
|
||||
void run(const vk::command_buffer& cmd, const vk::buffer* data, u32 src_offset, u32 src_length, u32 dst_offset)
|
||||
@@ -371,8 +364,7 @@ namespace vk
|
||||
data_offset = src_offset;
|
||||
}
|
||||
|
||||
u32 parameters[4] = { src_length, src_offset - data_offset, dst_offset - data_offset, 0 };
|
||||
set_parameters(cmd, parameters, 4);
|
||||
m_params = { src_length, src_offset - data_offset, dst_offset - data_offset, 0 };
|
||||
cs_shuffle_base::run(cmd, data, src_length, data_offset);
|
||||
}
|
||||
};
|
||||
@@ -453,15 +445,17 @@ namespace vk
|
||||
m_src = fmt::replace_all(m_src, syntax_replace);
|
||||
}
|
||||
|
||||
void bind_resources() override
|
||||
void bind_resources(const vk::command_buffer& cmd) override
|
||||
{
|
||||
m_program->bind_buffer({ src_buffer->value, in_offset, block_length }, 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_descriptor_set);
|
||||
m_program->bind_buffer({ dst_buffer->value, out_offset, block_length }, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_descriptor_set);
|
||||
set_parameters(cmd);
|
||||
|
||||
m_program->bind_uniform({ src_buffer->value, in_offset, block_length }, 0, 0);
|
||||
m_program->bind_uniform({ dst_buffer->value, out_offset, block_length }, 0, 1);
|
||||
}
|
||||
|
||||
void set_parameters(const vk::command_buffer& cmd)
|
||||
{
|
||||
vkCmdPushConstants(cmd, m_pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, push_constants_size, params.data);
|
||||
vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, push_constants_size, params.data);
|
||||
}
|
||||
|
||||
void run(const vk::command_buffer& cmd, const vk::buffer* dst, u32 out_offset, const vk::buffer* src, u32 in_offset, u32 data_length, u32 width, u32 height, u32 depth, u32 mipmaps) override
|
||||
@@ -480,7 +474,6 @@ namespace vk
|
||||
params.logw = rsx::ceil_log2(width);
|
||||
params.logh = rsx::ceil_log2(height);
|
||||
params.logd = rsx::ceil_log2(depth);
|
||||
set_parameters(cmd);
|
||||
|
||||
const u32 num_bytes_per_invocation = (sizeof(_BlockType) * optimal_group_size);
|
||||
const u32 linear_invocations = utils::aligned_div(data_length, num_bytes_per_invocation);
|
||||
@@ -497,7 +490,7 @@ namespace vk
|
||||
|
||||
cs_aggregator();
|
||||
|
||||
void bind_resources() override;
|
||||
void bind_resources(const vk::command_buffer& cmd) override;
|
||||
|
||||
void run(const vk::command_buffer& cmd, const vk::buffer* dst, const vk::buffer* src, u32 num_words);
|
||||
};
|
||||
@@ -581,16 +574,18 @@ namespace vk
|
||||
m_src = fmt::replace_all(m_src, syntax_replace);
|
||||
}
|
||||
|
||||
void bind_resources() override
|
||||
void bind_resources(const vk::command_buffer& cmd) override
|
||||
{
|
||||
const auto op = static_cast<int>(Op);
|
||||
m_program->bind_buffer({ src_buffer->value, in_offset, in_block_length }, 0 ^ op, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_descriptor_set);
|
||||
m_program->bind_buffer({ dst_buffer->value, out_offset, out_block_length }, 1 ^ op, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_descriptor_set);
|
||||
set_parameters(cmd);
|
||||
|
||||
const auto op = static_cast<u32>(Op);
|
||||
m_program->bind_uniform({ src_buffer->value, in_offset, in_block_length }, 0u, 0u ^ op);
|
||||
m_program->bind_uniform({ dst_buffer->value, out_offset, out_block_length }, 0u, 1u ^ op);
|
||||
}
|
||||
|
||||
void set_parameters(const vk::command_buffer& cmd)
|
||||
{
|
||||
vkCmdPushConstants(cmd, m_pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, push_constants_size, ¶ms);
|
||||
vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, push_constants_size, ¶ms);
|
||||
}
|
||||
|
||||
void run(const vk::command_buffer& cmd, const RSX_detiler_config& config)
|
||||
@@ -653,7 +648,6 @@ namespace vk
|
||||
params.image_height = (Op == RSX_detiler_op::decode) ? tile_aligned_height : config.image_height;
|
||||
params.image_pitch = config.image_pitch;
|
||||
params.image_bpp = config.image_bpp;
|
||||
set_parameters(cmd);
|
||||
|
||||
const u32 subtexels_per_invocation = (config.image_bpp < 4) ? (4 / config.image_bpp) : 1;
|
||||
const u32 virtual_width = config.image_width / subtexels_per_invocation;
|
||||
|
||||
+22
-65
@@ -554,9 +554,8 @@ bool VKGSRender::bind_texture_env()
|
||||
if (view) [[likely]]
|
||||
{
|
||||
m_program->bind_uniform({ fs_sampler_handles[i]->value, view->value, view->image()->current_layout },
|
||||
i,
|
||||
::glsl::program_domain::glsl_fragment_program,
|
||||
m_current_frame->descriptor_set);
|
||||
vk::glsl::binding_set_index_fragment,
|
||||
m_fs_binding_table->ftex_location[i]);
|
||||
|
||||
if (current_fragment_program.texture_state.redirected_textures & (1 << i))
|
||||
{
|
||||
@@ -576,27 +575,22 @@ bool VKGSRender::bind_texture_env()
|
||||
}
|
||||
|
||||
m_program->bind_uniform({ m_stencil_mirror_sampler->value, stencil_view->value, stencil_view->image()->current_layout },
|
||||
i,
|
||||
::glsl::program_domain::glsl_fragment_program,
|
||||
m_current_frame->descriptor_set,
|
||||
true);
|
||||
vk::glsl::binding_set_index_fragment,
|
||||
m_fs_binding_table->ftex_stencil_location[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const VkImageViewType view_type = vk::get_view_type(current_fragment_program.get_texture_dimension(i));
|
||||
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer, view_type)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
|
||||
i,
|
||||
::glsl::program_domain::glsl_fragment_program,
|
||||
m_current_frame->descriptor_set);
|
||||
vk::glsl::binding_set_index_fragment,
|
||||
m_fs_binding_table->ftex_location[i]);
|
||||
|
||||
if (current_fragment_program.texture_state.redirected_textures & (1 << i))
|
||||
{
|
||||
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer, view_type)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
|
||||
i,
|
||||
::glsl::program_domain::glsl_fragment_program,
|
||||
m_current_frame->descriptor_set,
|
||||
true);
|
||||
vk::glsl::binding_set_index_fragment,
|
||||
m_fs_binding_table->ftex_stencil_location[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -610,9 +604,8 @@ bool VKGSRender::bind_texture_env()
|
||||
{
|
||||
const auto view_type = vk::get_view_type(current_vertex_program.get_texture_dimension(i));
|
||||
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer, view_type)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
|
||||
i,
|
||||
::glsl::program_domain::glsl_vertex_program,
|
||||
m_current_frame->descriptor_set);
|
||||
vk::glsl::binding_set_index_vertex,
|
||||
m_vs_binding_table->vtex_location[i]);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -634,9 +627,8 @@ bool VKGSRender::bind_texture_env()
|
||||
const auto view_type = vk::get_view_type(current_vertex_program.get_texture_dimension(i));
|
||||
|
||||
m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(*m_current_command_buffer, view_type)->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL },
|
||||
i,
|
||||
::glsl::program_domain::glsl_vertex_program,
|
||||
m_current_frame->descriptor_set);
|
||||
vk::glsl::binding_set_index_vertex,
|
||||
m_vs_binding_table->vtex_location[i]);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -644,9 +636,8 @@ bool VKGSRender::bind_texture_env()
|
||||
validate_image_layout_for_read_access(*m_current_command_buffer, image_ptr, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, sampler_state);
|
||||
|
||||
m_program->bind_uniform({ vs_sampler_handles[i]->value, image_ptr->value, image_ptr->image()->current_layout },
|
||||
i,
|
||||
::glsl::program_domain::glsl_vertex_program,
|
||||
m_current_frame->descriptor_set);
|
||||
vk::glsl::binding_set_index_vertex,
|
||||
m_vs_binding_table->vtex_location[i]);
|
||||
}
|
||||
|
||||
return out_of_memory;
|
||||
@@ -721,7 +712,7 @@ bool VKGSRender::bind_interpreter_texture_env()
|
||||
}
|
||||
}
|
||||
|
||||
m_shader_interpreter.update_fragment_textures(texture_env, m_current_frame->descriptor_set);
|
||||
m_shader_interpreter.update_fragment_textures(texture_env);
|
||||
return out_of_memory;
|
||||
}
|
||||
|
||||
@@ -770,9 +761,6 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||
return;
|
||||
}
|
||||
|
||||
const auto old_persistent_buffer = m_persistent_attribute_storage ? m_persistent_attribute_storage->value : null_buffer_view->value;
|
||||
const auto old_volatile_buffer = m_volatile_attribute_storage ? m_volatile_attribute_storage->value : null_buffer_view->value;
|
||||
|
||||
// Programs data is dependent on vertex state
|
||||
auto upload_info = upload_vertex_data();
|
||||
if (!upload_info.vertex_draw_count)
|
||||
@@ -827,8 +815,6 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||
auto volatile_buffer = m_volatile_attribute_storage ? m_volatile_attribute_storage->value : null_buffer_view->value;
|
||||
bool update_descriptors = false;
|
||||
|
||||
const auto& binding_table = m_device->get_pipeline_binding_table();
|
||||
|
||||
if (m_current_draw.subdraw_id == 0)
|
||||
{
|
||||
update_descriptors = true;
|
||||
@@ -848,33 +834,6 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||
vk::clear_status_interrupt(vk::heap_changed);
|
||||
}
|
||||
}
|
||||
else if (persistent_buffer != old_persistent_buffer || volatile_buffer != old_volatile_buffer)
|
||||
{
|
||||
// Need to update descriptors; make a copy for the next draw
|
||||
VkDescriptorSet previous_set = m_current_frame->descriptor_set.value();
|
||||
m_current_frame->descriptor_set.flush();
|
||||
m_current_frame->descriptor_set = allocate_descriptor_set();
|
||||
rsx::simple_array<VkCopyDescriptorSet> copy_cmds(binding_table.total_descriptor_bindings);
|
||||
|
||||
for (u32 n = 0; n < binding_table.total_descriptor_bindings; ++n)
|
||||
{
|
||||
copy_cmds[n] =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, // sType
|
||||
nullptr, // pNext
|
||||
previous_set, // srcSet
|
||||
n, // srcBinding
|
||||
0u, // srcArrayElement
|
||||
m_current_frame->descriptor_set.value(), // dstSet
|
||||
n, // dstBinding
|
||||
0u, // dstArrayElement
|
||||
1u // descriptorCount
|
||||
};
|
||||
}
|
||||
|
||||
m_current_frame->descriptor_set.push(copy_cmds);
|
||||
update_descriptors = true;
|
||||
}
|
||||
|
||||
// Update vertex fetch parameters
|
||||
update_vertex_env(sub_index, upload_info);
|
||||
@@ -882,9 +841,9 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||
ensure(m_vertex_layout_storage);
|
||||
if (update_descriptors)
|
||||
{
|
||||
m_program->bind_uniform(persistent_buffer, binding_table.vertex_buffers_first_bind_slot, m_current_frame->descriptor_set);
|
||||
m_program->bind_uniform(volatile_buffer, binding_table.vertex_buffers_first_bind_slot + 1, m_current_frame->descriptor_set);
|
||||
m_program->bind_uniform(m_vertex_layout_storage->value, binding_table.vertex_buffers_first_bind_slot + 2, m_current_frame->descriptor_set);
|
||||
m_program->bind_uniform(persistent_buffer, vk::glsl::binding_set_index_vertex, m_vs_binding_table->vertex_buffers_location);
|
||||
m_program->bind_uniform(volatile_buffer, vk::glsl::binding_set_index_vertex, m_vs_binding_table->vertex_buffers_location + 1);
|
||||
m_program->bind_uniform(m_vertex_layout_storage->value, vk::glsl::binding_set_index_vertex, m_vs_binding_table->vertex_buffers_location + 2);
|
||||
}
|
||||
|
||||
bool reload_state = (!m_current_draw.subdraw_id++);
|
||||
@@ -908,10 +867,12 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||
reload_state = true;
|
||||
});
|
||||
|
||||
// Bind both pipe and descriptors in one go
|
||||
// FIXME: We only need to rebind the pipeline when reload state is set. Flags?
|
||||
m_program->bind(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||
|
||||
if (reload_state)
|
||||
{
|
||||
vkCmdBindPipeline(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline);
|
||||
|
||||
update_draw_state();
|
||||
begin_render_pass();
|
||||
|
||||
@@ -929,7 +890,6 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||
}
|
||||
|
||||
// Bind the new set of descriptors for use with this draw call
|
||||
m_current_frame->descriptor_set.bind(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline_layout);
|
||||
m_frame_stats.setup_time += m_profiler.duration();
|
||||
|
||||
if (!upload_info.index_info)
|
||||
@@ -1083,9 +1043,6 @@ void VKGSRender::end()
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate descriptor set
|
||||
m_current_frame->descriptor_set = allocate_descriptor_set();
|
||||
|
||||
// Load program execution environment
|
||||
load_program_env();
|
||||
m_frame_stats.setup_time += m_profiler.duration();
|
||||
|
||||
@@ -26,8 +26,85 @@ std::string VKFragmentDecompilerThread::compareFunction(COMPARE f, const std::st
|
||||
return glsl::compareFunctionImpl(f, Op0, Op1);
|
||||
}
|
||||
|
||||
void VKFragmentDecompilerThread::prepareBindingTable()
|
||||
{
|
||||
// First check if we have constants and textures as those need extra work
|
||||
bool has_constants = false, has_textures = false;
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
{
|
||||
if (has_constants && has_textures)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (PT.type.starts_with("sampler"))
|
||||
{
|
||||
has_textures = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
ensure(PT.type.starts_with("vec"));
|
||||
has_constants = true;
|
||||
}
|
||||
|
||||
unsigned location = 0; // All bindings must be set from this var
|
||||
vk_prog->binding_table.context_buffer_location = location++;
|
||||
if (has_constants)
|
||||
{
|
||||
vk_prog->binding_table.cbuf_location = location++;
|
||||
}
|
||||
|
||||
vk_prog->binding_table.tex_param_location = location++;
|
||||
vk_prog->binding_table.polygon_stipple_params_location = location++;
|
||||
|
||||
std::memset(vk_prog->binding_table.ftex_location, 0xff, sizeof(vk_prog->binding_table.ftex_location));
|
||||
std::memset(vk_prog->binding_table.ftex_stencil_location, 0xff, sizeof(vk_prog->binding_table.ftex_stencil_location));
|
||||
|
||||
if (has_textures) [[ likely ]]
|
||||
{
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
{
|
||||
if (!PT.type.starts_with("sampler"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
const auto texture_id = vk::get_texture_index(PI.name);
|
||||
const auto mask = 1u << texture_id;
|
||||
|
||||
// Allocate real binding
|
||||
vk_prog->binding_table.ftex_location[texture_id] = location++;
|
||||
|
||||
// Tag the stencil mirror if required
|
||||
if (properties.redirected_sampler_mask & mask) [[ unlikely ]]
|
||||
{
|
||||
vk_prog->binding_table.ftex_stencil_location[texture_id] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize stencil offsets
|
||||
if (properties.redirected_sampler_mask != 0) [[ unlikely ]]
|
||||
{
|
||||
for (auto& stencil_location : vk_prog->binding_table.ftex_stencil_location)
|
||||
{
|
||||
if (stencil_location != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
stencil_location = location++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VKFragmentDecompilerThread::insertHeader(std::stringstream & OS)
|
||||
{
|
||||
prepareBindingTable();
|
||||
|
||||
std::vector<const char*> required_extensions;
|
||||
|
||||
if (device_props.has_native_half_support)
|
||||
@@ -97,21 +174,18 @@ void VKFragmentDecompilerThread::insertOutputs(std::stringstream & OS)
|
||||
|
||||
void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
||||
{
|
||||
u32 location = m_binding_table.textures_first_bind_slot;
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
{
|
||||
if (PT.type != "sampler1D" &&
|
||||
PT.type != "sampler2D" &&
|
||||
PT.type != "sampler3D" &&
|
||||
PT.type != "samplerCube")
|
||||
if (!PT.type.starts_with("sampler"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
std::string samplerType = PT.type;
|
||||
|
||||
ensure(PI.name.length() > 3);
|
||||
int index = atoi(&PI.name[3]);
|
||||
const int index = vk::get_texture_index(PI.name);
|
||||
const auto mask = (1 << index);
|
||||
|
||||
if (properties.multisampled_sampler_mask & mask)
|
||||
@@ -135,39 +209,37 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
||||
}
|
||||
}
|
||||
|
||||
vk::glsl::program_input in;
|
||||
in.location = location;
|
||||
in.domain = glsl::glsl_fragment_program;
|
||||
in.name = PI.name;
|
||||
in.type = vk::glsl::input_type_texture;
|
||||
|
||||
const int id = vk::get_texture_index(PI.name);
|
||||
auto in = vk::glsl::program_input::make(
|
||||
glsl::glsl_fragment_program,
|
||||
PI.name,
|
||||
vk::glsl::input_type_texture,
|
||||
vk::glsl::binding_set_index_fragment,
|
||||
vk_prog->binding_table.ftex_location[id]
|
||||
);
|
||||
inputs.push_back(in);
|
||||
|
||||
OS << "layout(set=0, binding=" << location++ << ") uniform " << samplerType << " " << PI.name << ";\n";
|
||||
OS << "layout(set=1, binding=" << in.location << ") uniform " << samplerType << " " << PI.name << ";\n";
|
||||
|
||||
if (properties.redirected_sampler_mask & mask)
|
||||
{
|
||||
// Insert stencil mirror declaration
|
||||
in.name += "_stencil";
|
||||
in.location = location;
|
||||
|
||||
in.location = vk_prog->binding_table.ftex_stencil_location[id];
|
||||
inputs.push_back(in);
|
||||
|
||||
OS << "layout(set=0, binding=" << location++ << ") uniform u" << samplerType << " " << in.name << ";\n";
|
||||
OS << "layout(set=1, binding=" << in.location << ") uniform u" << samplerType << " " << in.name << ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ensure(location <= m_binding_table.vertex_textures_first_bind_slot); // "Too many sampler descriptors!"
|
||||
|
||||
std::string constants_block;
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
{
|
||||
if (PT.type == "sampler1D" ||
|
||||
PT.type == "sampler2D" ||
|
||||
PT.type == "sampler3D" ||
|
||||
PT.type == "samplerCube")
|
||||
if (PT.type.starts_with("sampler"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
@@ -177,13 +249,13 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
||||
|
||||
if (!constants_block.empty())
|
||||
{
|
||||
OS << "layout(std140, set = 0, binding = 2) uniform FragmentConstantsBuffer\n";
|
||||
OS << "layout(std140, set=1, binding=" << vk_prog->binding_table.cbuf_location << ") uniform FragmentConstantsBuffer\n";
|
||||
OS << "{\n";
|
||||
OS << constants_block;
|
||||
OS << "};\n\n";
|
||||
}
|
||||
|
||||
OS << "layout(std140, set = 0, binding = 3) uniform FragmentStateBuffer\n";
|
||||
OS << "layout(std140, set=1, binding=" << vk_prog->binding_table.context_buffer_location << ") uniform FragmentStateBuffer\n";
|
||||
OS << "{\n";
|
||||
OS << " float fog_param0;\n";
|
||||
OS << " float fog_param1;\n";
|
||||
@@ -195,32 +267,39 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
||||
OS << " float wpos_bias;\n";
|
||||
OS << "};\n\n";
|
||||
|
||||
OS << "layout(std140, set = 0, binding = 4) uniform TextureParametersBuffer\n";
|
||||
OS << "layout(std140, set=1, binding=" << vk_prog->binding_table.tex_param_location << ") uniform TextureParametersBuffer\n";
|
||||
OS << "{\n";
|
||||
OS << " sampler_info texture_parameters[16];\n";
|
||||
OS << "};\n\n";
|
||||
|
||||
OS << "layout(std140, set = 0, binding = " << std::to_string(m_binding_table.rasterizer_env_bind_slot) << ") uniform RasterizerHeap\n";
|
||||
OS << "layout(std140, set=1, binding=" << vk_prog->binding_table.polygon_stipple_params_location << ") uniform RasterizerHeap\n";
|
||||
OS << "{\n";
|
||||
OS << " uvec4 stipple_pattern[8];\n";
|
||||
OS << "};\n\n";
|
||||
|
||||
vk::glsl::program_input in;
|
||||
in.location = m_binding_table.fragment_constant_buffers_bind_slot;
|
||||
in.domain = glsl::glsl_fragment_program;
|
||||
in.name = "FragmentConstantsBuffer";
|
||||
in.type = vk::glsl::input_type_uniform_buffer;
|
||||
inputs.push_back(in);
|
||||
vk::glsl::program_input in
|
||||
{
|
||||
.domain = glsl::glsl_fragment_program,
|
||||
.type = vk::glsl::input_type_uniform_buffer,
|
||||
.set = vk::glsl::binding_set_index_fragment
|
||||
};
|
||||
|
||||
in.location = m_binding_table.fragment_state_bind_slot;
|
||||
if (!constants_block.empty())
|
||||
{
|
||||
in.location = vk_prog->binding_table.cbuf_location;
|
||||
in.name = "FragmentConstantsBuffer";
|
||||
inputs.push_back(in);
|
||||
}
|
||||
|
||||
in.location = vk_prog->binding_table.context_buffer_location;
|
||||
in.name = "FragmentStateBuffer";
|
||||
inputs.push_back(in);
|
||||
|
||||
in.location = m_binding_table.fragment_texture_params_bind_slot;
|
||||
in.location = vk_prog->binding_table.tex_param_location;
|
||||
in.name = "TextureParametersBuffer";
|
||||
inputs.push_back(in);
|
||||
|
||||
in.location = m_binding_table.rasterizer_env_bind_slot;
|
||||
in.location = vk_prog->binding_table.polygon_stipple_params_location;
|
||||
in.name = "RasterizerHeap";
|
||||
inputs.push_back(in);
|
||||
}
|
||||
@@ -372,7 +451,6 @@ void VKFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
|
||||
|
||||
void VKFragmentDecompilerThread::Task()
|
||||
{
|
||||
m_binding_table = vk::g_render_device->get_pipeline_binding_table();
|
||||
m_shader = Decompile();
|
||||
vk_prog->SetInputs(inputs);
|
||||
}
|
||||
@@ -406,10 +484,7 @@ void VKFragmentProgram::Decompile(const RSXFragmentProgram& prog)
|
||||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
if (PT.type == "sampler1D" ||
|
||||
PT.type == "sampler2D" ||
|
||||
PT.type == "sampler3D" ||
|
||||
PT.type == "samplerCube")
|
||||
if (PT.type.starts_with("sampler"))
|
||||
continue;
|
||||
|
||||
usz offset = atoi(PI.name.c_str() + 2);
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace vk
|
||||
class shader_interpreter;
|
||||
}
|
||||
|
||||
struct VKFragmentDecompilerThread : public FragmentProgramDecompiler
|
||||
class VKFragmentDecompilerThread : public FragmentProgramDecompiler
|
||||
{
|
||||
friend class vk::shader_interpreter;
|
||||
|
||||
@@ -19,7 +19,8 @@ struct VKFragmentDecompilerThread : public FragmentProgramDecompiler
|
||||
std::vector<vk::glsl::program_input> inputs;
|
||||
class VKFragmentProgram *vk_prog;
|
||||
glsl::shader_properties m_shader_props{};
|
||||
vk::pipeline_binding_table m_binding_table{};
|
||||
|
||||
void prepareBindingTable();
|
||||
|
||||
public:
|
||||
VKFragmentDecompilerThread(std::string& shader, ParamArray& parr, const RSXFragmentProgram &prog, u32& size, class VKFragmentProgram& dst)
|
||||
@@ -32,6 +33,7 @@ public:
|
||||
|
||||
void Task();
|
||||
const std::vector<vk::glsl::program_input>& get_inputs() { return inputs; }
|
||||
|
||||
protected:
|
||||
std::string getFloatTypeName(usz elementCount) override;
|
||||
std::string getHalfTypeName(usz elementCount) override;
|
||||
@@ -63,8 +65,19 @@ public:
|
||||
std::vector<usz> FragmentConstantOffsetCache;
|
||||
|
||||
std::array<u32, 4> output_color_masks{ {} };
|
||||
|
||||
std::vector<vk::glsl::program_input> uniforms;
|
||||
|
||||
struct
|
||||
{
|
||||
u32 context_buffer_location = umax; // Rasterizer context
|
||||
u32 cbuf_location = umax; // Constants register file
|
||||
u32 tex_param_location = umax; // Texture configuration data
|
||||
u32 polygon_stipple_params_location = umax; // Polygon stipple settings
|
||||
u32 ftex_location[16]; // Texture locations array
|
||||
u32 ftex_stencil_location[16]; // Texture stencil mirror array
|
||||
|
||||
} binding_table;
|
||||
|
||||
void SetInputs(std::vector<vk::glsl::program_input>& inputs);
|
||||
/**
|
||||
* Decompile a fragment shader located in the PS3's Memory. This function operates synchronously.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user