mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-07 13:39:55 +00:00
Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into feat/webrtc-rms-level
# Conflicts: # core/libs/prx/libwebrtc/CMakeLists.txt # core/libs/prx/libwebrtc/Export.cpp # core/libs/prx/libwebrtc/include/Api.hpp # docs/dev/debt/libwebrtc.md
This commit is contained in:
commit
6db8445d06
1599 files changed
+122805
-11178
No files matched your search
@@ -32,7 +32,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: build-${{ github.event_name }}-${{ github.event.pull_request.number || inputs.pr || github.ref }}
|
||||
group: build-${{ github.event_name }}-${{ github.event.pull_request.number || inputs.pr || (github.event_name == 'push' && github.sha) || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name != 'push' }}
|
||||
|
||||
env:
|
||||
@@ -56,6 +56,7 @@ jobs:
|
||||
relinker: ${{ steps.gate.outputs.relinker }}
|
||||
register-context: ${{ steps.gate.outputs.register-context }}
|
||||
write-watch: ${{ steps.gate.outputs.write-watch }}
|
||||
edge-watch: ${{ steps.gate.outputs.edge-watch }}
|
||||
mingw-host-tests: ${{ steps.gate.outputs.mingw-host-tests }}
|
||||
full: ${{ steps.gate.outputs.full }}
|
||||
relinker-hosts: ${{ steps.gate.outputs.relinker-hosts }}
|
||||
@@ -139,6 +140,8 @@ jobs:
|
||||
registerContext: edits('register-context') ||
|
||||
touches('core/libs/tests/register_context/', 'core/libs/tests/RegisterContext.cpp', libc),
|
||||
writeWatch: edits('write-watch') || touches('core/libs/tests/write_watch/', 'core/libs/tests/WriteWatch.cpp', libc),
|
||||
edgeWatch: edits('edge-watch') || touches('core/libs/tests/edge_watch/', 'core/libs/tests/EdgeWatch.cpp',
|
||||
'core/libs/prx/libkernel/Equeue/src/EdgeWatch.cpp', 'core/libs/prx/libkernel/Equeue/include/EdgeWatch.hpp', libc),
|
||||
mingwHostTests: edits('eligibility') || edits('windows') || touches(
|
||||
'core/CMakeLists.txt', 'core/libs/', 'cmake/', '3rdparty/', '.gitmodules', 'tools/build_mingw_host_only_tests.py',
|
||||
'tools/build_changed_guest_tests.py', 'tools/configure_seed.py', 'tools/select_tests.py',
|
||||
@@ -178,6 +181,7 @@ jobs:
|
||||
core.setOutput('relinker', run.relinker);
|
||||
core.setOutput('register-context', run.registerContext);
|
||||
core.setOutput('write-watch', run.writeWatch);
|
||||
core.setOutput('edge-watch', run.edgeWatch);
|
||||
core.setOutput('mingw-host-tests', false);
|
||||
core.setOutput('full', true);
|
||||
core.setOutput('relinker-hosts', relinkerHosts(true, true));
|
||||
@@ -268,6 +272,7 @@ jobs:
|
||||
core.setOutput('relinker', relinker);
|
||||
core.setOutput('register-context', registerContext);
|
||||
core.setOutput('write-watch', writeWatch);
|
||||
core.setOutput('edge-watch', run.edgeWatch);
|
||||
core.setOutput('mingw-host-tests', !manual && run.mingwHostTests);
|
||||
core.setOutput('full', full);
|
||||
core.setOutput('relinker-hosts', relinkerHosts(full, linux));
|
||||
@@ -328,10 +333,10 @@ jobs:
|
||||
- if: runner.os == 'Windows'
|
||||
run: echo 'C:\winlibs\mingw64\bin' >> "$GITHUB_PATH"
|
||||
- if: ${{ matrix.architectures == 'x86_64' }}
|
||||
run: sudo softwareupdate --install-rosetta --agree-to-license
|
||||
run: arch -x86_64 /usr/bin/true || sudo softwareupdate --install-rosetta --agree-to-license
|
||||
- run: cmake -S . -B build-relinker -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DANYPS5_RELINKER_ONLY=ON -DBUILD_TESTING=ON -DCMAKE_OSX_ARCHITECTURES=${{ matrix.architectures }}
|
||||
- run: cmake --build build-relinker --parallel 3
|
||||
- run: ctest --test-dir build-relinker --output-on-failure --timeout 120 --parallel 4
|
||||
- run: ctest --test-dir build-relinker --output-on-failure --timeout 120 --parallel 4 --no-tests=error
|
||||
|
||||
relinker-asan:
|
||||
needs: eligibility
|
||||
@@ -648,7 +653,7 @@ jobs:
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
path: build/externals
|
||||
key: ffmpeg-${{ runner.os }}-${{ steps.submodules.outputs.ffmpeg }}
|
||||
key: ffmpeg-${{ runner.os }}-winlibs-${{ env.WINLIBS_ZIP }}-${{ steps.submodules.outputs.ffmpeg }}
|
||||
- id: seed-cache
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
@@ -707,7 +712,7 @@ jobs:
|
||||
- name: Build and run changed guest core/libs tests
|
||||
if: github.event_name == 'pull_request'
|
||||
shell: cmd
|
||||
run: python tools/build_changed_guest_tests.py build changed.txt
|
||||
run: python tools/build_changed_guest_tests.py build changed.txt --output-log ctest.log
|
||||
- id: libs
|
||||
if: github.event_name != 'pull_request'
|
||||
shell: cmd
|
||||
@@ -736,3 +741,36 @@ jobs:
|
||||
awk '/Test +#[0-9]+: / && $NF == "sec" { for (i = 1; i <= NF; i++) if ($i ~ /^#[0-9]+:$/) name = $(i + 1); t = $(NF - 1) + 0; if (t > max[name]) max[name] = t }
|
||||
END { for (name in max) if (max[name] > 30) printf "::warning title=Slow test::%s took %.1f s on %s; tests must finish in 30 s (CONTRIBUTING.md)\n", name, max[name], ENVIRON["RUNNER_OS"] }' ctest.log
|
||||
|
||||
edge-watch:
|
||||
needs: eligibility
|
||||
if: ${{ needs.eligibility.outputs.edge-watch == 'true' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-15-intel, macos-15]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
ref: ${{ needs.eligibility.outputs.sha }}
|
||||
persist-credentials: false
|
||||
- name: Merge the pull request into main
|
||||
if: ${{ needs.eligibility.outputs.head != '' }}
|
||||
shell: bash
|
||||
env:
|
||||
PR_NUMBER: ${{ needs.eligibility.outputs.pr }}
|
||||
PR_HEAD: ${{ needs.eligibility.outputs.head }}
|
||||
run: |
|
||||
read -ra numbers <<< "$PR_NUMBER"
|
||||
read -ra heads <<< "$PR_HEAD"
|
||||
refspecs=()
|
||||
for number in "${numbers[@]}"; do refspecs+=("+refs/pull/$number/head:refs/remotes/pull/$number"); done
|
||||
git fetch --no-tags --unshallow origin "${refspecs[@]}"
|
||||
for i in "${!numbers[@]}"; do
|
||||
if [ "$(git rev-parse "refs/remotes/pull/${numbers[i]}")" != "${heads[i]}" ]; then echo "::error::Pull request #${numbers[i]} has newer commits; start a new build"; exit 1; fi
|
||||
if ! git -c user.name=ci -c user.email=ci@localhost merge --no-ff --no-edit "refs/remotes/pull/${numbers[i]}"; then echo "::error::Pull request #${numbers[i]} does not merge cleanly into main and the pull requests before it; rebase it first"; exit 1; fi
|
||||
done
|
||||
- run: cmake -S core/libs/tests/edge_watch -B build/edge-watch -DCMAKE_BUILD_TYPE=Release
|
||||
- run: cmake --build build/edge-watch --parallel
|
||||
- run: ctest --test-dir build/edge-watch --output-on-failure --repeat until-fail:3 --no-tests=error
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
run: |
|
||||
cmake -S core/libs/tests/emscripten -B build-native -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build-native --parallel 2
|
||||
ctest --test-dir build-native --output-on-failure
|
||||
ctest --test-dir build-native --output-on-failure --no-tests=error
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '26'
|
||||
@@ -40,4 +40,4 @@ jobs:
|
||||
source "$RUNNER_TEMP/emsdk/emsdk_env.sh"
|
||||
emcmake cmake -S core/libs/tests/emscripten -B build-portable -DCMAKE_BUILD_TYPE=Release -DANYPS5_NODE="$ANYPS5_TEST_NODE"
|
||||
cmake --build build-portable --parallel 2
|
||||
ctest --test-dir build-portable --output-on-failure
|
||||
ctest --test-dir build-portable --output-on-failure --no-tests=error
|
||||
@@ -31,6 +31,7 @@ jobs:
|
||||
force_label 'unblocks title' 0e8a16 'Names a title ID on the Unblocks line'
|
||||
force_label perf fef2c0 'Performance change'
|
||||
force_label 'perf numbers missing' e99695 'perf pull request without a before and after summary line'
|
||||
force_label 'review queue' 1d76db 'Next in the maintainer review queue: checks pass, no open change request, no conflict'
|
||||
|
||||
label relinker 5319e7 'core/relinker'
|
||||
label libc fbca04 'libc'
|
||||
|
||||
@@ -5,7 +5,11 @@ on:
|
||||
branches: [main]
|
||||
paths:
|
||||
- core/libs/prx/**
|
||||
- core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaOpcode.hpp
|
||||
- core/shader/recompiler/**
|
||||
- tools/progress.py
|
||||
- tools/shader_scan.py
|
||||
- tools/rdna2_isa_forms.txt
|
||||
- tools/rdna_isa.txt
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -30,7 +34,7 @@ jobs:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
run: |
|
||||
python3 tools/progress.py "$RUNNER_TEMP/progress"
|
||||
python3 tools/progress.py --require-shader-source "$RUNNER_TEMP/progress"
|
||||
site=$(gh api "repos/$GH_REPO/pages" --jq .html_url)
|
||||
if curl -fsSL "${site%/}/progress.json?$GITHUB_SHA" -o "$RUNNER_TEMP/deployed.json" &&
|
||||
cmp -s "$RUNNER_TEMP/deployed.json" "$RUNNER_TEMP/progress/progress.json"; then
|
||||
|
||||
@@ -12,6 +12,8 @@ on:
|
||||
- tools/package_release.py
|
||||
- tools/nid_names.py
|
||||
- tools/progress.py
|
||||
- tools/shader_scan.py
|
||||
- tools/rdna2_isa_forms.txt
|
||||
- tools/progress_history.py
|
||||
- tools/rdna_isa.txt
|
||||
- tools/test_web.py
|
||||
@@ -47,7 +49,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
run: python3 tools/build_web.py --build build-wasm --release
|
||||
- run: python3 tools/progress.py build-wasm/web
|
||||
- run: python3 tools/progress.py --require-shader-source build-wasm/web
|
||||
- run: python3 tools/progress_history.py build-wasm/web
|
||||
- uses: actions/upload-pages-artifact@v5
|
||||
with:
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
name: PR review queue
|
||||
on:
|
||||
schedule:
|
||||
- cron: '50 * * * *'
|
||||
workflow_dispatch:
|
||||
permissions: {}
|
||||
concurrency:
|
||||
group: pr-review-queue
|
||||
jobs:
|
||||
queue:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
QUEUE_ISSUE: ${{ vars.REVIEW_QUEUE_ISSUE }}
|
||||
run: |
|
||||
if [ -n "$QUEUE_ISSUE" ]; then
|
||||
python3 -I tools/pr_ready.py --issue "$QUEUE_ISSUE"
|
||||
else
|
||||
python3 -I tools/pr_ready.py
|
||||
fi
|
||||
@@ -175,7 +175,42 @@ jobs:
|
||||
run: |
|
||||
gh api --method POST "repos/$GH_REPO/releases/generate-notes" -f tag_name="$RELEASE_TAG" > "$RUNNER_TEMP/release-notes.json"
|
||||
python tools/prepare_release_notes.py --input "$RUNNER_TEMP/release-notes.json" --body "$RUNNER_TEMP/release-body.md" --full dist/release-notes.md
|
||||
- name: Create draft and upload files
|
||||
run: gh release create "$RELEASE_TAG" dist/* --verify-tag --draft --title "$RELEASE_TAG" --notes-file "$RUNNER_TEMP/release-body.md"
|
||||
- name: Create or refresh draft and upload files
|
||||
shell: bash
|
||||
run: |
|
||||
release_marker="<!-- anyps5-release-workflow:$GITHUB_SHA -->"
|
||||
printf '\n%s\n' "$release_marker" >> "$RUNNER_TEMP/release-body.md"
|
||||
release_state="$(
|
||||
gh release list --limit 10000 --json tagName,isDraft |
|
||||
python -c 'import json, os, sys; matches = [release for release in json.load(sys.stdin) if release["tagName"] == os.environ["RELEASE_TAG"]]; print("missing" if not matches else ("draft" if matches[0]["isDraft"] else "published"))'
|
||||
)"
|
||||
case "$release_state" in
|
||||
missing)
|
||||
gh release create "$RELEASE_TAG" dist/* --verify-tag --draft --title "$RELEASE_TAG" --notes-file "$RUNNER_TEMP/release-body.md"
|
||||
;;
|
||||
draft)
|
||||
release_body="$(gh release view "$RELEASE_TAG" --json body --jq .body)"
|
||||
if [[ "$release_body" != *"$release_marker"* ]]; then
|
||||
echo "::error::Draft release $RELEASE_TAG was not created by this workflow for $GITHUB_SHA"
|
||||
exit 1
|
||||
fi
|
||||
gh release edit "$RELEASE_TAG" --draft=true --title "$RELEASE_TAG" --notes-file "$RUNNER_TEMP/release-body.md"
|
||||
gh release upload "$RELEASE_TAG" dist/* --clobber
|
||||
;;
|
||||
published)
|
||||
echo "::error::Release $RELEASE_TAG is already published"
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo "::error::Unexpected release state for $RELEASE_TAG: $release_state"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
for file in dist/*; do basename "$file"; done | LC_ALL=C sort > "$RUNNER_TEMP/expected-release-assets"
|
||||
gh release view "$RELEASE_TAG" --json assets --jq '.assets[].name' | LC_ALL=C sort > "$RUNNER_TEMP/actual-release-assets"
|
||||
if ! diff -u "$RUNNER_TEMP/expected-release-assets" "$RUNNER_TEMP/actual-release-assets"; then
|
||||
echo "::error::Draft release assets do not exactly match the packaged files"
|
||||
exit 1
|
||||
fi
|
||||
- name: Publish complete release
|
||||
run: gh release edit "$RELEASE_TAG" --draft=false
|
||||
@@ -16,6 +16,7 @@ jobs:
|
||||
steps:
|
||||
- env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
shell: bash
|
||||
run: |
|
||||
gh pr list -R "$GITHUB_REPOSITORY" --label stale -L 1000 --json number,labels \
|
||||
--jq '.[] | select(all(.labels[]; .name != "needs rebase")) | .number' |
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Web release tools
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/web-release-tools.yml
|
||||
- demo/web/**
|
||||
- tools/build_web.py
|
||||
- tools/nid_names.py
|
||||
- tools/package_headers.py
|
||||
- tools/package_release.py
|
||||
- tools/test_web.py
|
||||
- tools/tests/test_build_web.py
|
||||
- tools/tests/test_web_release.py
|
||||
- core/relinker/relinker/tests/guest_import_fixtures.py
|
||||
- core/relinker/relinker/tests/test_guest_intel_trampolines.py
|
||||
- core/relinker/relinker/tests/test_guest_module_directories.py
|
||||
- core/relinker/relinker/tests/test_linux_load_alignment.py
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: web-release-tools-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
release-tools:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Test web library assets
|
||||
run: python3 tools/tests/test_build_web.py
|
||||
- name: Test web release packaging
|
||||
run: python3 tools/tests/test_web_release.py
|
||||
@@ -35,6 +35,8 @@ jobs:
|
||||
run: node demo/web/tests/archive-windows.test.mjs demo/web
|
||||
- name: Test archive reserved names
|
||||
run: node demo/web/tests/archive-reserved.test.mjs demo/web
|
||||
- name: Test library manifest validation
|
||||
run: node --test demo/web/tests/worker-manifest.test.mjs
|
||||
- name: Check browser module syntax
|
||||
run: |
|
||||
node --check demo/web/app.mjs
|
||||
|
||||
@@ -81,7 +81,7 @@ jobs:
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
path: build/externals
|
||||
key: ffmpeg-${{ runner.os }}-${{ steps.submodules.outputs.ffmpeg }}
|
||||
key: ffmpeg-${{ runner.os }}-msys2-${{ steps.submodules.outputs.ffmpeg }}
|
||||
- shell: cmd
|
||||
run: cmake -S . -B build %CONFIGURE% "-DANYPS5_AGC_EXECUTION_TESTS=F16ToF32Unpack;F64FmaSubnormals;RegistrationPrepareShutdown"
|
||||
- if: steps.ffmpeg-cache.outputs.cache-hit != 'true'
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
run: cmake --build build --target libs
|
||||
- shell: cmd
|
||||
working-directory: build
|
||||
run: ctest --output-on-failure --timeout 120 --parallel 4 --output-log ctest.log --output-junit ctest.xml
|
||||
run: ctest --output-on-failure --timeout 120 --parallel 4 --output-log ctest.log --output-junit ctest.xml --no-tests=error
|
||||
- run: python tools/check_skips.py build/ctest.xml --job windows
|
||||
- name: Report tests slower than 30 s
|
||||
if: ${{ !cancelled() }}
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
[submodule "3rdparty/SDL2"]
|
||||
path = 3rdparty/SDL2
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
[submodule "3rdparty/libressl-openbsd"]
|
||||
path = 3rdparty/libressl-openbsd
|
||||
url = https://github.com/libressl/openbsd.git
|
||||
[submodule "3rdparty/Vulkan-Headers"]
|
||||
path = 3rdparty/Vulkan-Headers
|
||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
|
||||
+1
Submodule 3rdparty/libressl-openbsd added at 078b3d1df8.
@@ -8,7 +8,7 @@ AnyPS5 relinks PS5 executables into native Linux or Windows programs that run ag
|
||||
- New third-party code is a submodule at `3rdparty/<name>`: add its `.gitmodules` entry (`git submodule add <url> 3rdparty/<name>`) and build it from source with CMake. Never `find_package` or copy sources in.
|
||||
- Known gaps go in `docs/dev/debt/<library>.md`; notes, reports and logs go in the pull request. Add no other files.
|
||||
- Commit subjects and PR titles are Conventional Commits.
|
||||
- PR body: copy [the template](.github/pull_request_template.md), keep every line, tick every box, and fill `What`, `Tested`, `Depends on` (#N or none), `Unblocks` (title ID and discussion, or none), `GPUs tested` (AGC, shader recompiler, VideoOut; otherwise n/a) and `AI-assisted` (yes or no).
|
||||
- PR body: copy [the template](.github/pull_request_template.md), keep every line, tick every box, and fill `What`, `Tested`, `Depends on` (#N or none), `Fixes` (Fixes #N or none), `Unblocks` (title ID and discussion, or none), `GPUs tested` (AGC, shader recompiler, VideoOut; otherwise n/a) and `AI-assisted` (yes or no).
|
||||
- Before pushing run `python3 tools/check_conventions.py --base origin/main`; before opening run `python3 tools/pr_overlap.py --branch <branch>`.
|
||||
- Build and test: [BUILD](docs/dev/BUILD.md); a relinker-only change builds with `-DANYPS5_RELINKER_ONLY=ON`.
|
||||
- A speed claim shows `tools/trace_digest.py` summaries of `main` and of the change from the same machine and scene.
|
||||
|
||||
+70
-1
@@ -220,6 +220,8 @@ if(BUILD_TESTING)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_pr_overlap.py)
|
||||
add_test(NAME pr_labels COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_pr_labels.py)
|
||||
add_test(NAME pr_ready COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_pr_ready.py)
|
||||
add_test(NAME progress_history COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_progress_history.py ProgressHistoryTests)
|
||||
add_test(NAME progress_history_output COMMAND ${Python3_EXECUTABLE}
|
||||
@@ -227,6 +229,8 @@ if(BUILD_TESTING)
|
||||
set_tests_properties(progress_history_output PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME progress_report COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_progress.py)
|
||||
add_test(NAME shader_scan COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_shader_scan.py)
|
||||
add_test(NAME progress_report_inputs COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_progress_report_inputs.py)
|
||||
add_test(NAME tools_compdb_inventory COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/tests/test_compile_database_inventory.py)
|
||||
@@ -254,6 +258,8 @@ if(BUILD_TESTING)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_unwrap_self.py)
|
||||
add_test(NAME audit_dump COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_audit_dump.py)
|
||||
add_test(NAME ffmpeg_cache_keys COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_ffmpeg_cache_keys.py)
|
||||
foreach(shard RANGE 0 11)
|
||||
if(shard EQUAL 0)
|
||||
set(conventions_test_name conventions_function_bodies)
|
||||
@@ -268,7 +274,18 @@ if(BUILD_TESTING)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_performance_csv.py)
|
||||
set_tests_properties(performance_csv PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME conventions_wrapped_declarations COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_wrapped_declarations.py)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_wrapped_declarations.py WrappedDeclarationTests)
|
||||
set_tests_properties(conventions_wrapped_declarations PROPERTIES TIMEOUT 30)
|
||||
set(conventions_wrapped_declarations_source "${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_wrapped_declarations.py")
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${conventions_wrapped_declarations_source}")
|
||||
file(STRINGS "${conventions_wrapped_declarations_source}" conventions_wrapped_declarations_classes REGEX "^class [A-Za-z0-9_]*Tests\\(")
|
||||
foreach(test_class IN LISTS conventions_wrapped_declarations_classes)
|
||||
string(REGEX REPLACE "^class ([A-Za-z0-9_]+).*" "\\1" test_class "${test_class}")
|
||||
if(NOT test_class STREQUAL "WrappedDeclarationTests")
|
||||
add_test(NAME conventions_wrapped_declarations_${test_class} COMMAND ${Python3_EXECUTABLE} "${conventions_wrapped_declarations_source}" ${test_class})
|
||||
set_tests_properties(conventions_wrapped_declarations_${test_class} PROPERTIES TIMEOUT 30)
|
||||
endif()
|
||||
endforeach()
|
||||
add_test(NAME conventions_ci_gate COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_ci_gate.py)
|
||||
add_test(NAME preview_pad_timeline COMMAND ${Python3_EXECUTABLE}
|
||||
@@ -276,8 +293,12 @@ if(BUILD_TESTING)
|
||||
set_tests_properties(preview_pad_timeline PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME conventions_git_errors COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_git.py)
|
||||
add_test(NAME tools_base_ref COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_base_ref.py)
|
||||
add_test(NAME tools_configure_diff COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/tests/test_compare_configure_checks.py)
|
||||
set_tests_properties(tools_configure_diff PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME ctest_no_tests_flag COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/tests/test_ctest_no_tests_flag.py)
|
||||
set_tests_properties(ctest_no_tests_flag PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME conventions_doc_links COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_doc_links.py)
|
||||
add_test(NAME conventions_unknown_nids COMMAND ${Python3_EXECUTABLE}
|
||||
@@ -286,10 +307,18 @@ if(BUILD_TESTING)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_debt_length.py)
|
||||
add_test(NAME test_registration COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_test_registration.py)
|
||||
add_test(NAME unbuilt_exports COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_unbuilt_exports.py)
|
||||
add_test(NAME test_script_registration COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/check_test_registration.py --scripts)
|
||||
add_test(NAME tools_sanitizer_json COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_sanitizer_json.py)
|
||||
set_tests_properties(tools_sanitizer_json PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME build_eligibility COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_build_eligibility.py)
|
||||
add_test(NAME tools_release_notes_check COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_release_notes_check.py)
|
||||
set_tests_properties(tools_release_notes_check PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME check_skips_ctest COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_skips_ctest.py)
|
||||
set_tests_properties(check_skips_ctest PROPERTIES TIMEOUT 30)
|
||||
@@ -299,8 +328,12 @@ if(BUILD_TESTING)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_skips.py)
|
||||
add_test(NAME sanitizer_report COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_sanitizer_report.py)
|
||||
add_test(NAME relinker_fuzz_fixture_warnings COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_relinker_fuzz_fixture_warnings.py)
|
||||
add_test(NAME select_tests COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_select_tests.py)
|
||||
add_test(NAME relinker_test_step COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_relinker_test_step.py)
|
||||
add_test(NAME tools_self_inspect COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/tests/test_inspect_self.py)
|
||||
set_tests_properties(tools_self_inspect PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME check_main_sync COMMAND ${Python3_EXECUTABLE}
|
||||
@@ -364,6 +397,14 @@ if(BUILD_TESTING)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_pr_overlap_wrapped_exports.py)
|
||||
add_test(NAME pr_overlap_own_branch COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_pr_overlap_own_branch.py)
|
||||
add_test(NAME main_sync_renames COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_main_sync_renames.py RenamedPathsTests.test_feature_rename_keeps_the_original_path)
|
||||
set_tests_properties(main_sync_renames PROPERTIES TIMEOUT 20)
|
||||
foreach(test_case IN ITEMS test_feature_rename_with_detection_disabled test_main_rename_keeps_the_original_path test_main_rename_with_detection_disabled)
|
||||
add_test(NAME main_sync_renames_${test_case} COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_main_sync_renames.py RenamedPathsTests.${test_case})
|
||||
set_tests_properties(main_sync_renames_${test_case} PROPERTIES TIMEOUT 20)
|
||||
endforeach()
|
||||
add_test(NAME pr_overlap_errors COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_pr_overlap_errors.py)
|
||||
add_test(NAME pr_overlap_branch_scan COMMAND ${Python3_EXECUTABLE}
|
||||
@@ -389,6 +430,8 @@ if(BUILD_TESTING)
|
||||
add_test(NAME pad_input COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_pad_input.py)
|
||||
set_tests_properties(pad_input PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME stale_conflicts_workflow COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_stale_conflicts_workflow.py)
|
||||
add_test(NAME pad_timeline COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_pad_timeline.py)
|
||||
set_tests_properties(pad_timeline PROPERTIES TIMEOUT 20)
|
||||
@@ -442,10 +485,16 @@ if(BUILD_TESTING)
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_env_reference.py" "EnvReferenceDiffTests.${test_case}")
|
||||
set_tests_properties(conventions_env_reference_${test_case} PROPERTIES TIMEOUT 30)
|
||||
endforeach()
|
||||
add_test(NAME tools_annotation_symbols_json COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_annotation_symbols_json.py)
|
||||
set_tests_properties(tools_annotation_symbols_json PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME conventions_body_bom COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_body_bom.py)
|
||||
add_test(NAME conventions_blob_reads COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_blob_reads.py)
|
||||
add_test(NAME ab_split_csv COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_ab_split_csv.py)
|
||||
set_tests_properties(ab_split_csv PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME conventions_agent_files COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_check_conventions_agent_files.py)
|
||||
add_test(NAME conventions_alignment COMMAND ${Python3_EXECUTABLE}
|
||||
@@ -473,6 +522,26 @@ if(BUILD_TESTING)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
set(unwrap_self_test_source "${CMAKE_CURRENT_SOURCE_DIR}/tools/tests/test_unwrap_self.py")
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${unwrap_self_test_source}")
|
||||
file(STRINGS "${unwrap_self_test_source}" unwrap_self_cases REGEX "^class |^ def test_")
|
||||
set(unwrap_self_first TRUE)
|
||||
foreach(test_case IN LISTS unwrap_self_cases)
|
||||
if(test_case MATCHES "^class ([A-Za-z0-9_]+)")
|
||||
set(unwrap_self_class "${CMAKE_MATCH_1}")
|
||||
else()
|
||||
string(REGEX REPLACE "^ def (test_[A-Za-z0-9_]+).*" "\\1" test_case "${test_case}")
|
||||
if(unwrap_self_first)
|
||||
set_tests_properties(unwrap_self PROPERTIES
|
||||
ENVIRONMENT "UNWRAP_SELF_TEST=${unwrap_self_class}.${test_case}" TIMEOUT 30)
|
||||
set(unwrap_self_first FALSE)
|
||||
else()
|
||||
add_test(NAME unwrap_self_${unwrap_self_class}_${test_case} COMMAND ${Python3_EXECUTABLE}
|
||||
"${unwrap_self_test_source}" "${unwrap_self_class}.${test_case}")
|
||||
set_tests_properties(unwrap_self_${unwrap_self_class}_${test_case} PROPERTIES TIMEOUT 30)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
add_test(NAME tools_headers_manifest COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/tests/test_public_headers_manifest.py)
|
||||
set_tests_properties(tools_headers_manifest PROPERTIES TIMEOUT 20)
|
||||
add_test(NAME conventions_pr_template COMMAND ${Python3_EXECUTABLE}
|
||||
|
||||
+5
-4
@@ -40,16 +40,16 @@ For pull requests, full Linux and Windows builds and tests run only when a colla
|
||||
gh workflow run build.yml --repo boykopovar/AnyPS5 --ref main --field pr=1234
|
||||
```
|
||||
|
||||
This manual run also builds and tests the relinker on Linux, Windows and macOS when the pull request changes a file the relinker-only build uses, regardless of the author's previous contributions. The relinker matrix also runs automatically when a pull request targeting `main` is opened, updated or reopened, if its author already has a commit in `main` and it changes a file the relinker-only build uses; full builds never run automatically for pull requests. Every job that runs automatically for pull requests runs only when the pull request changes its files: a `paths` filter on the `pull_request` trigger, or `needs: eligibility` with an `if` on the files output it sets in `build.yml`. The Conventions check fails a workflow change that adds a job without one. All build jobs build the selected pull request merged into the current `main` (GitHub's merge commit), so a pull request that no longer merges cleanly must be rebased first. New commits require another manual run for full builds.
|
||||
This manual run also builds and tests the relinker on Linux, Windows and macOS when the pull request changes a file the relinker-only build uses, regardless of the author's previous contributions. The relinker matrix also runs automatically when a pull request targeting `main` is opened, updated or reopened, if its author already has a commit or a merged pull request in `main` and it changes a file the relinker-only build uses; full builds never run automatically for pull requests. Every job that runs automatically for pull requests runs only when the pull request changes its files: a `paths` filter on the `pull_request` trigger, or `needs: eligibility` with an `if` on the files output it sets in `build.yml`. The Conventions check fails a workflow change that adds a job without one. All build jobs check out the current `main` and merge the head of each selected pull request into it with `git merge --no-ff`, so a pull request that no longer merges cleanly must be rebased first. New commits require another manual run for full builds.
|
||||
|
||||
With `--field full=false`, the manual run skips the full builds and runs only the relinker matrix on Linux, Windows and macOS, if the pull request changes a file the relinker-only build uses, such as the Python tools and their tests in `tools/`.
|
||||
|
||||
With `--field linux=false`, the manual run skips the full Linux build and adds Linux to the relinker matrix, if the pull requests change a file the relinker-only build uses. With `--field select=true`, the full builds build and run only the tests whose build inputs the pull requests change; push builds of `main` always run every test.
|
||||
|
||||
The Conventions check runs automatically for every contributor, including first-time contributors. It uses the checker from the current tip of the base branch, so rules added after a pull request was opened apply to its next run, and reads pull request Git objects without executing pull request code. The Conventions check runs on every pull request and fails when a rule on this page is broken. It accepts code comments only when the pull request also changes [technical debt](docs/dev/TechnicalDebt.md), the index or a file in `docs/dev/debt/`, and only UTF-8 text files. Run it locally before pushing:
|
||||
The Conventions check runs automatically for every contributor, including first-time contributors. It uses the checker from the current tip of the base branch, so rules added after a pull request was opened apply to its next run, and reads pull request Git objects without executing pull request code. The Conventions check runs on every pull request and fails when a rule on this page is broken. It accepts code comments only when the pull request also changes [technical debt](docs/dev/TechnicalDebt.md), the index or a file in `docs/dev/debt/`, and only UTF-8 text files. Run it locally before pushing; without `--base` it compares with `upstream/main`, then `origin/main`, then `main`, so a fork whose `origin/main` is behind the project is not checked against that old state:
|
||||
|
||||
```
|
||||
python3 tools/check_conventions.py --base origin/main
|
||||
python3 tools/check_conventions.py
|
||||
```
|
||||
|
||||
## Branches and pull requests
|
||||
@@ -62,6 +62,7 @@ The [pull request template](.github/pull_request_template.md) is the checklist f
|
||||
- Keep the branch up to date with `main` and resolve conflicts yourself; rebasing and force-pushing is fine.
|
||||
- An AGC test executable and its tests are registered in `core/libs/prx/libSceAgcDriver/tests/cmake/<executable>.cmake`; the tests of an execution test in `tests/execution/` go in the fragment of its `agc_driver_<name>_tests` executable. `CMakeLists.txt` includes the fragments in sorted order, so a fragment uses nothing another fragment defines. A pull request whose change to `libSceAgcDriver/CMakeLists.txt` conflicts after the split rebases and runs `python3 tools/agc_test_split.py resolve` during the stopped rebase, which moves its registrations to their fragments and leaves conflict markers where `main` changed the same lines.
|
||||
- A pull request that conflicts with `main` and has no activity for 7 days is labeled `stale` with a reminder. It is not closed.
|
||||
- An hourly job gives the `review queue` label to the oldest 30 pull requests that need no more work from their author, `unblocks title` ones first, and lists them in the review queue issue. A pull request needs more work while it is a draft, conflicts with `main`, has a `perf numbers missing` or `open PR limit` label, has a failing or unfinished check other than Intake, Labels, Eligibility and the progress report, or has a change request whose reviewer was not asked again; pushing alone does not answer a change request. `python3 tools/pr_ready.py --explain <number>` prints what blocks a pull request.
|
||||
- If a pull request needs another one first, say so on the checklist line (`Depends on: #N`; `none` otherwise).
|
||||
- If a pull request fixes a reported issue, write `Fixes #N` on its checklist line (`none` otherwise). GitHub closes the issue on merge, and the `fix error` label is added within the hour.
|
||||
- If a pull request fixes a stop or a wrong result seen on a title, name it on the checklist line with the title ID and its [Game bring-up](https://github.com/boykopovar/AnyPS5/discussions/categories/game-bring-up) discussion (`Unblocks: PPSA01325 #3232`; `none` otherwise). Reviewers review these first. Such a pull request gets the `unblocks title` label.
|
||||
@@ -69,7 +70,7 @@ The [pull request template](.github/pull_request_template.md) is the checklist f
|
||||
- Fixes a title needs go to `main` as pull requests. A Game bring-up discussion lists the open pull requests and local changes the title still needs; update the list when one is merged, closed or replaced.
|
||||
- The PR overlap comment lists open pull requests that change the same lines or exports; agree with their authors which one goes first and declare it with `Depends on`.
|
||||
- Run the tests before opening the pull request and describe what was tested (OS, title or homebrew).
|
||||
- A pull request that claims a change in speed shows the summary lines of `main` and of the change, from the same machine and scene, and attaches the traces, captured as the [Performance report](.github/ISSUE_TEMPLATE/performance.yml) issue form describes. A slow scene is reported with the same form. A pull request titled `perf(...)` or `perf:` is labeled `perf`, and `perf numbers missing` until its description holds two valid summary lines with different commits.
|
||||
- A pull request that claims a change in speed shows the summary lines of `main` and of the change, from the same machine and scene, and attaches the traces, captured as the [Performance report](.github/ISSUE_TEMPLATE/performance.yml) issue form describes. A slow scene is reported with the same form. A pull request titled `perf(...)` or `perf:` is labeled `perf`, and `perf numbers missing` until its description holds two valid summary lines with different commits. A `perf(tools)`, `perf(ci)` or `perf(build)` pull request has no title to capture, so it is labeled `perf` only and reports its own before and after timings.
|
||||
- Changes to the AGC driver, the shader recompiler or VideoOut run the same focused tests on `main` and the change with `VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation`, `ANYPS5_NO_SHADER_CACHE=1` and `ANYPS5_REQUIRE_VULKAN=1` using `ctest -V` from the same machine and GPU, confirm neither log reports `was not found but was requested by env var VK_INSTANCE_LAYERS`, confirm the change introduces no new `VUID-` validation errors compared with `main`, and name each GPU the GPU tests ran on (vendor, model, driver, OS) on the `GPUs tested` checklist line. CI runs these tests only on lavapipe, and hardware drivers fail where lavapipe and other vendors pass, so a reviewer can ask for a run on another vendor before merging.
|
||||
- Investigation notes, reports, screenshots and logs go in the pull request, not in the repository. Images for documentation go in the [gist](https://gist.github.com/boykopovar/0e53f2e1426f29ecd41e3b51540b8a90) comments.
|
||||
- Say whether the change was written with AI assistance. The author of the pull request is responsible for every line of it.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
**English** | [Português (Brasil)](docs/user/README.pt-BR.md) | [Español](docs/user/README.es.md) | [简体中文](docs/user/README.zh-CN.md) | [Русский](docs/user/README.ru.md)
|
||||
**English** | [Português (Brasil)](docs/user/README.pt-BR.md) | [Español](docs/user/README.es.md) | [Italiano](docs/user/README.it.md) | [简体中文](docs/user/README.zh-CN.md) | [Русский](docs/user/README.ru.md)
|
||||
|
||||
# About
|
||||
|
||||
@@ -16,7 +16,7 @@ Includes a [relinker](core/relinker) that converts executable to the target syst
|
||||
|
||||
## Status
|
||||
|
||||
[](https://boykopovar.github.io/AnyPS5/progress.html) [](https://boykopovar.github.io/AnyPS5/progress.html)
|
||||
[](https://boykopovar.github.io/AnyPS5/progress.html) [](https://boykopovar.github.io/AnyPS5/progress.html) [](https://boykopovar.github.io/AnyPS5/history.html)
|
||||
|
||||
[](https://boykopovar.github.io/AnyPS5/progress.html)
|
||||
|
||||
|
||||
@@ -160,6 +160,9 @@ set(PATCHED_OUTPUTS ${LIBC_PATCHED})
|
||||
foreach(LIB_DIR ${LIBS_DIRS})
|
||||
if(IS_DIRECTORY ${LIB_DIR})
|
||||
get_filename_component(LIB_NAME ${LIB_DIR} NAME)
|
||||
if((ANYPS5_ENABLE_ASAN OR ANYPS5_ENABLE_TSAN) AND LIB_NAME STREQUAL "libSceAddressSanitizer")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
if(EXISTS ${LIB_DIR}/CMakeLists.txt)
|
||||
set(LIBS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
@@ -182,7 +185,7 @@ foreach(LIB_DIR ${LIBS_DIRS})
|
||||
target_link_options(${LIB_NAME} PRIVATE LINKER:-z,now)
|
||||
endif()
|
||||
if(WIN32 AND LIB_NAME STREQUAL "libSceNet")
|
||||
target_link_libraries(${LIB_NAME} PRIVATE ws2_32)
|
||||
target_link_libraries(${LIB_NAME} PRIVATE ws2_32 iphlpapi)
|
||||
target_compile_definitions(${LIB_NAME} PRIVATE _WIN32_WINNT=0x0602)
|
||||
elseif(WIN32 AND LIB_NAME STREQUAL "libSceNetCtl")
|
||||
target_link_libraries(${LIB_NAME} PRIVATE ws2_32 iphlpapi)
|
||||
@@ -295,7 +298,12 @@ elseif(TARGET mimalloc)
|
||||
list(APPEND PATCHED_OUTPUTS ${PATCHED_DIR}/libmimalloc.dylib)
|
||||
endif()
|
||||
|
||||
include(prx/libSceFreeType/BuildInfo.cmake)
|
||||
|
||||
add_custom_target(libs DEPENDS ${PATCHED_OUTPUTS})
|
||||
include(prx/libSceLibreSsl/ErrorQueue.cmake)
|
||||
include(prx/libSceLibreSsl/MemoryBio.cmake)
|
||||
include(prx/libSceLibreSsl/Cmac.cmake)
|
||||
|
||||
include(prx/libSceLibreSsl/ProtocolSelection.cmake)
|
||||
|
||||
@@ -355,6 +363,16 @@ if(BUILD_TESTING)
|
||||
set_tests_properties(guest_kernel_sys_neo_mode PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel_sys>")
|
||||
endif()
|
||||
add_test_executable(guest_kernel_sys_constant_unknowns_tests tests/GuestKernelSysConstantUnknowns.cpp)
|
||||
target_include_directories(guest_kernel_sys_constant_unknowns_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_kernel_sys_constant_unknowns_tests PRIVATE libkernel_sys libkernel libc)
|
||||
configure_windows_unwind(guest_kernel_sys_constant_unknowns_tests)
|
||||
add_test(NAME guest_kernel_sys_constant_unknowns COMMAND guest_kernel_sys_constant_unknowns_tests)
|
||||
set_tests_properties(guest_kernel_sys_constant_unknowns PROPERTIES TIMEOUT 20)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_kernel_sys_constant_unknowns PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libkernel_sys>")
|
||||
endif()
|
||||
add_test_executable(nid_buffer_validation_tests nid/tests/BufferValidation.cpp)
|
||||
target_include_directories(nid_buffer_validation_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/nid/include)
|
||||
target_compile_features(nid_buffer_validation_tests PRIVATE cxx_std_20)
|
||||
@@ -472,7 +490,7 @@ if(BUILD_TESTING)
|
||||
endif()
|
||||
add_test_executable(guest_kernel_sys_tests tests/GuestKernelSys.cpp)
|
||||
target_include_directories(guest_kernel_sys_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_kernel_sys_tests PRIVATE libkernel_sys libSceAmpr libkernel libc)
|
||||
target_link_libraries(guest_kernel_sys_tests PRIVATE libkernel_sys libSceNet libSceAmpr libkernel libc)
|
||||
configure_windows_unwind(guest_kernel_sys_tests)
|
||||
add_test(NAME guest_kernel_sys COMMAND guest_kernel_sys_tests)
|
||||
set_tests_properties(guest_kernel_sys PROPERTIES TIMEOUT 20)
|
||||
@@ -533,6 +551,16 @@ if(BUILD_TESTING)
|
||||
set_tests_properties(guest_playready PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libScePlayReady>")
|
||||
endif()
|
||||
add_test_executable(guest_sdec_version_tests tests/GuestSdecVersion.cpp)
|
||||
target_include_directories(guest_sdec_version_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_sdec_version_tests PRIVATE libSceVdecSavc libSceVdecSavc2 libSceVdecShevc libkernel libc)
|
||||
configure_windows_unwind(guest_sdec_version_tests)
|
||||
add_test(NAME guest_sdec_version COMMAND guest_sdec_version_tests)
|
||||
set_tests_properties(guest_sdec_version PROPERTIES TIMEOUT 20)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_sdec_version PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceVdecSavc>;PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceVdecSavc2>;PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceVdecShevc>")
|
||||
endif()
|
||||
if(Python3_Interpreter_FOUND)
|
||||
add_test(NAME nid_verneed COMMAND ${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/nid/tests/test_verneed.py $<TARGET_FILE:nid_patcher>)
|
||||
@@ -671,6 +699,13 @@ if(BUILD_TESTING)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
add_test_executable(windows_crash_thread_name_tests tests/WindowsCrashThreadName.cpp)
|
||||
add_dependencies(windows_crash_thread_name_tests libc)
|
||||
configure_host_test_executable(windows_crash_thread_name_tests)
|
||||
add_test(NAME windows_crash_thread_name COMMAND windows_crash_thread_name_tests $<TARGET_FILE:libc>)
|
||||
set_tests_properties(windows_crash_thread_name PROPERTIES TIMEOUT 20
|
||||
PASS_REGULAR_EXPRESSION "on thread [0-9]+ 'a+Z'[^~]*thread [0-9]+ 'c+Y':"
|
||||
FAIL_REGULAR_EXPRESSION "Zb|Yd|did not fault")
|
||||
add_test_executable(windows_crash_text_tests tests/WindowsCrashText.cpp)
|
||||
add_dependencies(windows_crash_text_tests libc)
|
||||
if(MINGW)
|
||||
@@ -680,6 +715,13 @@ if(BUILD_TESTING)
|
||||
set_tests_properties(windows_crash_text PROPERTIES TIMEOUT 20
|
||||
PASS_REGULAR_EXPRESSION "faulting[^~]*FATAL: unhandled exception 0xc0000005[^~]* \\[r12\\] \"allocation failed in the heap\"[\r\n]+ \\[r13\\] u\"LowLevelFatalError \\[File:Unknown\\] \\[Line: 42\\] Out of memory\"[\r\n]+ \\[r14\\] \"PAGE END\"[.][.][.]"
|
||||
FAIL_REGULAR_EXPRESSION "\\[rbx\\] u?\"|did not fault")
|
||||
add_test_executable(windows_integer_overflow_report_tests tests/WindowsIntegerOverflowReport.cpp)
|
||||
add_dependencies(windows_integer_overflow_report_tests libc)
|
||||
configure_host_test_executable(windows_integer_overflow_report_tests)
|
||||
add_test(NAME windows_integer_overflow_report COMMAND windows_integer_overflow_report_tests $<TARGET_FILE:libc>)
|
||||
set_tests_properties(windows_integer_overflow_report PROPERTIES TIMEOUT 20
|
||||
PASS_REGULAR_EXPRESSION "dividing[^~]*FATAL: unhandled exception 0xc0000095"
|
||||
FAIL_REGULAR_EXPRESSION "did not fault")
|
||||
endif()
|
||||
|
||||
add_test_executable(guest_voice_port_attr_tests tests/GuestVoicePortAttr.cpp)
|
||||
@@ -777,7 +819,7 @@ if(BUILD_TESTING)
|
||||
target_include_directories(guest_np_common_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_np_common_tests PRIVATE libSceNpCommon libkernel libc)
|
||||
configure_windows_unwind(guest_np_common_tests)
|
||||
foreach(testCase IN ITEMS ids sync clock)
|
||||
foreach(testCase IN ITEMS ids sync clock wake)
|
||||
add_test(NAME guest_np_common_${testCase} COMMAND guest_np_common_tests ${testCase})
|
||||
set_tests_properties(guest_np_common_${testCase} PROPERTIES TIMEOUT 20)
|
||||
if(WIN32)
|
||||
@@ -843,6 +885,16 @@ if(BUILD_TESTING)
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceSigninDialog>")
|
||||
endif()
|
||||
|
||||
add_test_executable(guest_audiodec_cpu_tests tests/GuestAudiodecCpu.cpp)
|
||||
target_include_directories(guest_audiodec_cpu_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_audiodec_cpu_tests PRIVATE libSceAudiodecCpu libc)
|
||||
configure_windows_unwind(guest_audiodec_cpu_tests)
|
||||
add_test(NAME guest_audiodec_cpu COMMAND guest_audiodec_cpu_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_audiodec_cpu PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceAudiodecCpu>")
|
||||
endif()
|
||||
|
||||
add_test_executable(guest_usb_storage_dialog_tests tests/GuestUsbStorageDialog.cpp)
|
||||
target_include_directories(guest_usb_storage_dialog_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_usb_storage_dialog_tests PRIVATE libSceUsbStorageDialog libSceUserService libc)
|
||||
@@ -1090,6 +1142,16 @@ if(BUILD_TESTING)
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceNpCppWebApi>")
|
||||
endif()
|
||||
|
||||
add_test_executable(guest_np_cpp_web_api_matches_tests tests/GuestNpCppWebApiMatches.cpp)
|
||||
target_include_directories(guest_np_cpp_web_api_matches_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_np_cpp_web_api_matches_tests PRIVATE libSceNpCppWebApi libc)
|
||||
configure_windows_unwind(guest_np_cpp_web_api_matches_tests)
|
||||
add_test(NAME guest_np_cpp_web_api_matches COMMAND guest_np_cpp_web_api_matches_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_np_cpp_web_api_matches PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceNpCppWebApi>")
|
||||
endif()
|
||||
|
||||
add_test_executable(savedata_native_write_replacement_tests tests/SaveDataWriteReplacement.cpp)
|
||||
target_include_directories(savedata_native_write_replacement_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(savedata_native_write_replacement_tests PRIVATE libSceSaveData.native)
|
||||
@@ -1237,6 +1299,16 @@ if(BUILD_TESTING)
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceNpGameIntent>")
|
||||
endif()
|
||||
|
||||
add_test_executable(guest_sdma_tests tests/GuestSdma.cpp)
|
||||
target_include_directories(guest_sdma_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_sdma_tests PRIVATE libSceSdma libc)
|
||||
configure_windows_unwind(guest_sdma_tests)
|
||||
add_test(NAME guest_sdma COMMAND guest_sdma_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_sdma PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceSdma>")
|
||||
endif()
|
||||
|
||||
add_test_executable(guest_gnm_neo_shaders_tests tests/GuestGnmNeoShaders.cpp)
|
||||
target_include_directories(guest_gnm_neo_shaders_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_gnm_neo_shaders_tests PRIVATE libSceGnmDriverForNeoMode libc)
|
||||
@@ -1268,6 +1340,15 @@ if(BUILD_TESTING)
|
||||
set_tests_properties(guest_gnm_neo_default_state PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceGnmDriverForNeoMode>")
|
||||
endif()
|
||||
add_test_executable(guest_division_prx_abi_tests tests/GuestDivisionPrxAbi.cpp nid/src/NidCompute.cpp nid/src/Sha1.cpp)
|
||||
target_include_directories(guest_division_prx_abi_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/nid/include)
|
||||
configure_host_test_executable(guest_division_prx_abi_tests)
|
||||
target_link_libraries(guest_division_prx_abi_tests PRIVATE ${CMAKE_DL_LIBS})
|
||||
add_custom_target(guest_division_prx_library DEPENDS ${LIBC_PATCHED})
|
||||
add_dependencies(guest_division_prx_abi_tests guest_division_prx_library)
|
||||
add_test(NAME guest_division_prx_abi COMMAND guest_division_prx_abi_tests $<TARGET_FILE:libc> ${PATCHED_DIR}/libc.prx)
|
||||
set_tests_properties(guest_division_prx_abi PROPERTIES TIMEOUT 20)
|
||||
|
||||
endif()
|
||||
|
||||
include(prx/libSceFreeType/CurveBounds.cmake)
|
||||
|
||||
@@ -1711,6 +1711,16 @@ struct SaveDataMount3 {
|
||||
std::uint8_t reserved[32];
|
||||
};
|
||||
|
||||
struct SaveDataMount2 {
|
||||
int user_id;
|
||||
int pad;
|
||||
const SceSaveDataDirName* dir_name;
|
||||
std::uint64_t blocks;
|
||||
std::uint32_t mount_mode;
|
||||
std::uint8_t reserved[32];
|
||||
int pad2;
|
||||
};
|
||||
|
||||
struct SaveDataDirNameSearchCond {
|
||||
std::int32_t user_id;
|
||||
std::int32_t pad;
|
||||
@@ -1810,6 +1820,8 @@ struct SaveDataEvent {
|
||||
std::uint8_t reserved[40];
|
||||
};
|
||||
|
||||
using SaveDataEventCallback = void (APS5_VABI *)(const SaveDataEvent* event, void* userdata);
|
||||
|
||||
struct SaveDataBackup {
|
||||
std::int32_t user_id;
|
||||
std::int32_t pad;
|
||||
@@ -1819,6 +1831,40 @@ struct SaveDataBackup {
|
||||
std::uint8_t reserved[32];
|
||||
};
|
||||
|
||||
struct SaveDataCheckBackupData {
|
||||
std::int32_t user_id;
|
||||
std::int32_t pad;
|
||||
const SceSaveDataTitleId* title_id;
|
||||
const SceSaveDataDirName* dir_name;
|
||||
SaveDataParam* param;
|
||||
SaveDataIcon* icon;
|
||||
std::uint8_t reserved[32];
|
||||
};
|
||||
|
||||
struct SaveDataRestoreBackupData {
|
||||
std::int32_t user_id;
|
||||
std::int32_t pad;
|
||||
const SceSaveDataTitleId* title_id;
|
||||
const SceSaveDataDirName* dir_name;
|
||||
const void* fingerprint;
|
||||
std::uint32_t unused;
|
||||
std::uint8_t reserved[32];
|
||||
std::int32_t pad2;
|
||||
};
|
||||
static_assert(offsetof(SaveDataCheckBackupData, title_id) == 0x08);
|
||||
static_assert(offsetof(SaveDataCheckBackupData, dir_name) == 0x10);
|
||||
static_assert(offsetof(SaveDataCheckBackupData, param) == 0x18);
|
||||
static_assert(offsetof(SaveDataCheckBackupData, icon) == 0x20);
|
||||
static_assert(offsetof(SaveDataCheckBackupData, reserved) == 0x28);
|
||||
static_assert(sizeof(SaveDataCheckBackupData) == 0x48);
|
||||
static_assert(offsetof(SaveDataRestoreBackupData, title_id) == 0x08);
|
||||
static_assert(offsetof(SaveDataRestoreBackupData, dir_name) == 0x10);
|
||||
static_assert(offsetof(SaveDataRestoreBackupData, fingerprint) == 0x18);
|
||||
static_assert(offsetof(SaveDataRestoreBackupData, unused) == 0x20);
|
||||
static_assert(offsetof(SaveDataRestoreBackupData, reserved) == 0x24);
|
||||
static_assert(offsetof(SaveDataRestoreBackupData, pad2) == 0x44);
|
||||
static_assert(sizeof(SaveDataRestoreBackupData) == 0x48);
|
||||
|
||||
struct SaveDataConvert {
|
||||
std::int32_t user_id;
|
||||
std::int32_t pad;
|
||||
@@ -2047,6 +2093,29 @@ struct JpegDecImageInfo {
|
||||
std::uint32_t output_image_height;
|
||||
};
|
||||
|
||||
struct JpegDecInputChunk {
|
||||
const void* data;
|
||||
std::uint32_t size;
|
||||
std::uint32_t reserved;
|
||||
};
|
||||
|
||||
using JpegDecInputCallback = std::int32_t (APS5_VABI *)(JpegDecInputChunk*, void*);
|
||||
|
||||
struct JpegDecInputControlParam {
|
||||
JpegDecInputCallback input;
|
||||
void* input_argument;
|
||||
void* image_mem_addr;
|
||||
void* coefficient_mem_addr;
|
||||
std::uint32_t image_mem_size;
|
||||
std::uint32_t coefficient_mem_size;
|
||||
std::uint16_t operation;
|
||||
std::uint16_t down_scale;
|
||||
std::uint16_t pixel_format;
|
||||
std::uint16_t alpha_value;
|
||||
std::uint32_t image_pitch;
|
||||
std::uint32_t reserved;
|
||||
};
|
||||
|
||||
struct PlayGoInitParams {
|
||||
const void* buf_addr;
|
||||
std::uint32_t buf_size;
|
||||
|
||||
@@ -188,7 +188,10 @@ std::optional<TrieLocation> FindTrie(const std::vector<std::uint8_t>& binary, co
|
||||
return found;
|
||||
}
|
||||
|
||||
void ParseTrieNode(const std::vector<std::uint8_t>& data, std::size_t start, std::size_t end, std::size_t node, std::string& prefix, std::set<std::size_t>& visited, std::vector<MachOExport>& out) {
|
||||
constexpr std::size_t kMaxExportTrieDepth = 1024;
|
||||
|
||||
void ParseTrieNode(const std::vector<std::uint8_t>& data, std::size_t start, std::size_t end, std::size_t node, std::string& prefix, std::set<std::size_t>& visited, std::vector<MachOExport>& out, std::size_t depth) {
|
||||
if (depth > kMaxExportTrieDepth) throw std::runtime_error("export trie nesting too deep");
|
||||
if (node >= end - start) throw std::runtime_error("export trie node out of bounds");
|
||||
if (!visited.insert(node).second) throw std::runtime_error("export trie has a cycle");
|
||||
std::size_t cursor = start + node;
|
||||
@@ -216,7 +219,7 @@ void ParseTrieNode(const std::vector<std::uint8_t>& data, std::size_t start, std
|
||||
const auto child = ReadUleb(data, cursor, end);
|
||||
const auto length = prefix.size();
|
||||
prefix += label;
|
||||
ParseTrieNode(data, start, end, static_cast<std::size_t>(child), prefix, visited, out);
|
||||
ParseTrieNode(data, start, end, static_cast<std::size_t>(child), prefix, visited, out, depth + 1);
|
||||
prefix.resize(length);
|
||||
}
|
||||
}
|
||||
@@ -227,7 +230,7 @@ std::vector<MachOExport> ParseTrie(const std::vector<std::uint8_t>& binary, std:
|
||||
if (size == 0) return exports;
|
||||
std::string prefix;
|
||||
std::set<std::size_t> visited;
|
||||
ParseTrieNode(binary, offset, std::size_t{offset} + size, 0, prefix, visited, exports);
|
||||
ParseTrieNode(binary, offset, std::size_t{offset} + size, 0, prefix, visited, exports, 0);
|
||||
return exports;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,9 @@ void PeNidPatcher::PatchNids(std::vector<std::uint8_t>& pe, const std::string& l
|
||||
|
||||
const std::size_t namesArrayOffset = RvaToOffset(pe, exportTable.AddressOfNames, peHeaderOffset, numberOfSections, sizeOfOptionalHeader);
|
||||
const std::size_t ordinalsArrayOffset = RvaToOffset(pe, exportTable.AddressOfNameOrdinals, peHeaderOffset, numberOfSections, sizeOfOptionalHeader);
|
||||
if (std::uint64_t{namesArrayOffset} + std::uint64_t{exportTable.NumberOfNames} * 4u > pe.size() ||
|
||||
std::uint64_t{ordinalsArrayOffset} + std::uint64_t{exportTable.NumberOfNames} * 2u > pe.size())
|
||||
throw std::runtime_error("export name tables out of file bounds");
|
||||
|
||||
std::vector<std::uint32_t> nameRvas(exportTable.NumberOfNames);
|
||||
std::vector<std::string> names(exportTable.NumberOfNames);
|
||||
|
||||
@@ -117,8 +117,8 @@ def dylib_command(path):
|
||||
return struct.pack("<IIIIII", LC_LOAD_DYLIB, size, 24, 2, 0x10000, 0x10000) + name.ljust(size - 24, b"\0")
|
||||
|
||||
|
||||
def build_dylib(exports, imports, signed=False, bind_opcodes=False):
|
||||
trie = build_trie(exports)
|
||||
def build_dylib(exports, imports, signed=False, bind_opcodes=False, trie=None):
|
||||
trie = build_trie(exports) if trie is None else trie
|
||||
fixups = build_fixups(imports)
|
||||
linkedit = bytearray(trie + fixups)
|
||||
trie_command = (struct.pack("<IIII", LC_DYLD_EXPORTS_TRIE, 16, PAGE, len(trie)))
|
||||
@@ -270,6 +270,22 @@ def check_refusals(patcher, directory):
|
||||
assert result.returncode != 0 and "signed Mach-O images cannot grow linkedit data" in result.stdout + result.stderr, (result.stdout, result.stderr)
|
||||
|
||||
|
||||
def chain_trie(depth):
|
||||
def fixed_uleb(value):
|
||||
return bytes([((value >> (7 * index)) & 0x7F) | 0x80 for index in range(4)] + [(value >> 28) & 0x7F])
|
||||
|
||||
node_size = 9
|
||||
nodes = [b"\x00\x01a\x00" + fixed_uleb(node_size * (index + 1)) for index in range(depth - 1)]
|
||||
nodes.append(b"\x02\x00\x00\x00")
|
||||
return b"".join(nodes) + bytes(-sum(map(len, nodes)) % 8)
|
||||
|
||||
|
||||
def check_deep_trie(patcher, directory):
|
||||
image = build_dylib([("_puts_nid_postfix", 0, 0x100)], [], trie=chain_trie(200000))
|
||||
result, _ = patch(patcher, directory, "deep-trie.dylib", image)
|
||||
assert result.returncode != 0 and "export trie nesting too deep" in result.stdout + result.stderr, (result.returncode, result.stdout, result.stderr)
|
||||
|
||||
|
||||
def check_short_imports(patcher, directory):
|
||||
imports = [("_sceXy", 1), ("_malloc", 2), ("_sceKernelFoo", 1), ("_sceNetRecv", 1)]
|
||||
result, path = patch(patcher, directory, "short.dylib", build_dylib([("_puts_nid_postfix", 0, 0x100)], imports))
|
||||
@@ -297,6 +313,7 @@ def main():
|
||||
check_preserved(patcher, directory)
|
||||
check_export_list(patcher, directory)
|
||||
check_refusals(patcher, directory)
|
||||
check_deep_trie(patcher, directory)
|
||||
print("NID patcher Mach-O tests passed")
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import struct
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
@@ -564,6 +565,18 @@ class LibraryImportTests(unittest.TestCase):
|
||||
self.assertIn("delay-loaded", result.stdout + result.stderr)
|
||||
self.assertEqual(patched, image)
|
||||
|
||||
def test_huge_name_count_is_rejected_before_allocation(self):
|
||||
for count in (0xFFFFFFFF, 0x40000000):
|
||||
with self.subTest(count=count):
|
||||
image = self.library(["puts"])
|
||||
struct.pack_into("<I", image, 0x600 + 24, count)
|
||||
start = time.monotonic()
|
||||
result, patched = self.patch(image)
|
||||
self.assertLess(time.monotonic() - start, 10)
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertIn("export name tables out of file bounds", result.stdout + result.stderr)
|
||||
self.assertEqual(patched, image)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,272 @@
|
||||
#pragma once
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI libAacsUnknown__plus_0gHTNd4xs4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown__plus_3dyyKZMTyw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown__plus_7ZoZWbIhlE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown__plus_CiBKXuK8c8_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown__plus_RinEsZfOmw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown__plus_XVwfwtkAi4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown__minus_2QNA1pCQqU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown__minus_kAJeMNy_minus_0E_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown__minus_lknLNU2NAU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown__minus_xuQAxlUvmk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_0bhkzdWU6Y4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_0oisD9Dr3FI_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_12CP5PHvlgs_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_15QPrQC1usM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_1CNq2v6hoig_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_1aMnfYcnn1I_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_1bzdduTshZ4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_1eNkqOSGM_plus_A_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_1hyWLxCZ_minus_X8_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_1pvpAK9Rg1k_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_23BaEjHuFUA_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_2HaRuPcSWtE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_2KQWcFTN8ZE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_2YklE8dG4v8_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_38ZtQUT4lMs_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_3LFB_minus_Ey4DUk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_3OYBQUy9yVI_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_3ZqZuNL3qrM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_3odIlZa6t2I_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_4IQhgxl103g_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_4r3seYGdIK0_nid_no_patch();
|
||||
int APS5_VABI AacsPermissionActivate();
|
||||
int APS5_VABI libAacsUnknown_54hkTYBIxqs_nid_no_patch();
|
||||
int APS5_VABI AacsBusDecrypt();
|
||||
int APS5_VABI AacsModuleStop();
|
||||
int APS5_VABI libAacsUnknown_6ToH2wFRWf4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_6XcWJGADJeU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_753FlqNkJlM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_7ETkLi9auE0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_7KCIejRxaB0_nid_no_patch();
|
||||
int APS5_VABI AacsDecrypt();
|
||||
int APS5_VABI libAacsUnknown_7eM7N1Anox4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_7iLrHfVzuvs_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_7qIZfzr0Dgk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_85kBXEP1moE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_8Gj9M3o_minus_rrY_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_8TJlScPxUa8_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_8YaNJTuYU_plus_g_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_9S1fVMePqpI_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_9UJqpmNn494_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_9eTs6_minus_zAOJs_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_9rQgwWQB9NE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_AVRC3P8reF0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Apl9mjDSCE0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_B10mYlgLwMM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_BFdZY3ocsJo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_BO_plus_NBS2KrZc_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_BaMuhhCt_minus_dQ_nid_no_patch();
|
||||
int APS5_VABI AacsPermissionCheck();
|
||||
int APS5_VABI libAacsUnknown_DWJK8GjbNHo_nid_no_patch();
|
||||
int APS5_VABI AacsModuleInit();
|
||||
int APS5_VABI libAacsUnknown_EBGsSrhNRnM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_EFpFjkHGewY_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_EIEQ4mWz5sU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ELsVqt8cS3Q_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_EQWDDRWfuOU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ESDneLy_plus_ExU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ETDNd_minus_CDbkc_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_EX5Y3UepfU4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_EgaEREMnudw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_FA1OyesdYiA_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_FEgD32GcLdM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_FEi5mHUWB0M_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_FHWdAzU_minus_rRI_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Fl0RrZ7B27g_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_G4zfSFYC1f8_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_GD6inRSAHfo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_GWA91aXeU1Y_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_GXLnqJJ85dM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_GpsjAdWq5hk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_HXafooMuNTY_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_HhIFaBlod8A_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_HmdBrUh2Xz4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_HuTXuHqMrVE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ILwfo94p_minus_ng_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Iofb1lKwTNA_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_IxvgFI5JtxE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_JXvlGrRcNlg_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Jmviii0cDro_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_JolZPea7pio_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_JqeAwcly1Lc_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_JqrjeblDpqo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_KG5C7s3p_plus_mM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_KLxEGrIPbbo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_L6tIkKT5Vdg_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_LFpG7wYNZ_plus_I_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_LT_minus_aek5dBRQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_LTIva3bGCXI_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_MCPkB4DYvAM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_MILG1Bi10BQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_MLHm3u_minus_UfPk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_MRMYIqUmmcQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_MVoCh7vg9Bk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_NK6Ke_minus_y45cI_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_NL6gDScOFl8_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_NOWYNS5AnRg_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_NRv4EFuYq9I_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_NSph9LkyLmI_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_OI1om0rmEYk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_OOrYw04s_plus_VU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ObJaLtAn3TM_nid_no_patch();
|
||||
int APS5_VABI AacsModuleStart();
|
||||
int APS5_VABI libAacsUnknown_Ozlqilsf3Tw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_PHgHus4a3M0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_PUDoXp1l_minus_Po_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Q2eGSNdsRq0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Q3vOGHtSk9Y_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Q74CET98b04_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_QCq8qc_plus_kt7g_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_QDc8xyN5AQw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_QabaLwU3b9o_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_RI7fQrbtZko_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_RZFK7f3Oi24_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_RkkCme3dsyo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_SJ9GmthhZDk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_SjEjF5V5XHc_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_SjewOoJlr9c_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_TK5prfVU4b0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_TQCLQjHkkW0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_TuTNDTTOXHo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_U2zlEU4AhRk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_U6RAXYIdJJE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_UArM6xy6B3g_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_UMZJ2F8Lr4o_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_UqqcPoUuAqE_nid_no_patch();
|
||||
int APS5_VABI AacsPermissionGetNonce();
|
||||
int APS5_VABI libAacsUnknown_VnixdJqGnjU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_WOxxWZjZMfQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_WaOsDN_plus_9lZg_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_WknurdpKTqo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_WrEjdzfOo2I_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_XQuTyX2WprY_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_XUL7r8v2Q3Y_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_XbP3p94ujkg_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_XhMh4CEdKGU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Xokc3inTVbM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_XrkLs6PFhac_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Xy748BBvB2w_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_YDl9jLvW_plus_SM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_YOlHXj4rrzQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Yqt0NzhE_minus_eU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_Z9yhz8_plus_DS3k_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ZCRVIAxld6o_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ZEdbi75pkX0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ZUEIg4QZJ_plus_k_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ZnJgSGpLzGs_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_a3D2_minus_Eh_minus_DW8_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_aOX5VPrNfqo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_aXeMNVrwOTw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_aZmsxlYbNes_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_aacj8q7PTFI_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_b0ZC6N9oQlU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_bHqBriHrgXA_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_bQl9nHS7Jgg_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_bQmoqxNo0rE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_c04ksdAcncM_nid_no_patch();
|
||||
int APS5_VABI AacsSelectKeyFrom();
|
||||
int APS5_VABI libAacsUnknown_c9tUe3nNpxo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_cI0YmNGV22E_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_cnGJD38STwQ_nid_no_patch();
|
||||
int APS5_VABI AacsModuleTerm();
|
||||
int APS5_VABI libAacsUnknown_e_minus_SciZxh1HY_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_e_minus_yS_plus_nlBtlE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_e0UQuzSUkI8_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_e5qwpKPf1aI_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_eRXHQokealY_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_egjNL_minus_sA_minus_s0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_eoQNtjg5QyQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_f5FWQj_minus__minus_MwM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_fWmfE_minus_A0k90_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_fkra1GmOMmQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_flzhCbf4xnw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_gAV79zVGfzI_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_gPhz2sY_plus_lHM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_gTXUpBIgmcg_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_gmOvd0UR6rk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_h6JW5ZErMHE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_hDCeckXsgIw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_hFXdc25NmT4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_hWhpklSoZ7g_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_hct40EnKHyM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_i0ZMaUuKzkE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_iIgtd05IlbA_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_iJ3zPE02P1w_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_iOLQbPwqsJU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_igIuBDqdlZo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_j0quzCtmBr4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_jXZJmZu3ihs_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_jdd4KuD7bOg_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_jpKit8Qv76g_nid_no_patch();
|
||||
int APS5_VABI AacsPermissionSet();
|
||||
int APS5_VABI libAacsUnknown_kX1hCR9FDo0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_kYQis7lBy_plus_U_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_kaxfKxeOvbU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_keNMJVznBe0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_kk8ELO4Y2Fo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_l18OOzQPPKo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_l8uscgUMuWE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ldkS5zx7P6s_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_llme91x0I_minus_k_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_lq8QnjYyTGQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_mExJcLz6QWE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_mR3leJVBYbw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_mbKaZoh30DM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_mlZY17mBv9M_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_mnf5OTi_minus_urc_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_moU18PvmqEU_nid_no_patch();
|
||||
int APS5_VABI AacsPermissionInit();
|
||||
int APS5_VABI libAacsUnknown_o33b_plus_5keZic_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_oJobSSDssQw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_oU59phxP5U4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_oij_plus_E5v8qjM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_p8Lv5g5o9pY_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_p9sZ84FK_minus_qw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ptrqNcGG0eM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_qFchDSE1J3o_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_qGMyKAQhniM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_qKmr8FI7Too_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_qPi2nzCUYiQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_qpebtLhTJBc_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_r960kCkFF3I_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_rMR6nG8LdyQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_rOM7gjFX3nM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_raaoezfuSqY_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ruidkq8amJE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_s_plus_BvUCe_plus_t_plus_I_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_s6CgM5B_plus_8zc_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_sjNkMwi80Os_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_sv8IiSJQ0Mo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_tPYLJSOXQ8k_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_tWHiNKLyUn4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_uG7mSoxfjL0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ujgxfJSpLrc_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_ulInPmGONKo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_uvJDUwXFtw0_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_uvLxjEqwYKk_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_v5IGfww3qSA_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_vM2spx6P6RU_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_vcFZSn_plus_m4_minus_o_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_w4Go9bJ_minus_JGQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_x34TWztyXy8_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_x82CfygyUPA_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_xQoCQNT3skQ_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_y56l_minus_E5S0Qs_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_y5OsRUqNoX4_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_yFNWXXeNxF0_nid_no_patch();
|
||||
int APS5_VABI AacsUpdateKeyArea();
|
||||
int APS5_VABI libAacsUnknown_yZjYlfcfEFE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_yaNpz6jnOzE_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_yrqEHk366AM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_z0b7NKDfWpo_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_zgZWaxsJGyM_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_zreU_plus_KU3nLw_nid_no_patch();
|
||||
int APS5_VABI libAacsUnknown_zt4Xv_minus_4fjx0_nid_no_patch();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "prx/libAacs/include/InventoryExports.hpp"
|
||||
@@ -0,0 +1,328 @@
|
||||
#include "prx/libCss/include/InventoryExports.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
#include "prx/libc/include/general/ExportMacros.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI libCssUnknown__plus_zpMhCilHTQ_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("+zpMhCilHTQ", libCssUnknown__plus_zpMhCilHTQ_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown__minus_WR4_minus_J79nn0_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("-WR4-J79nn0", libCssUnknown__minus_WR4_minus_J79nn0_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_45oyUIl85dg_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("45oyUIl85dg", libCssUnknown_45oyUIl85dg_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_4qq5OHYaFU8_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("4qq5OHYaFU8", libCssUnknown_4qq5OHYaFU8_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_6BDNwI1e59c_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("6BDNwI1e59c", libCssUnknown_6BDNwI1e59c_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_6QhXfVttAyU_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("6QhXfVttAyU", libCssUnknown_6QhXfVttAyU_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_74insBAQhg8_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("74insBAQhg8", libCssUnknown_74insBAQhg8_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_7YdC9p2cTSQ_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("7YdC9p2cTSQ", libCssUnknown_7YdC9p2cTSQ_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_81obgoH2X2g_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("81obgoH2X2g", libCssUnknown_81obgoH2X2g_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_9T_minus_RYQ7HwqI_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("9T-RYQ7HwqI", libCssUnknown_9T_minus_RYQ7HwqI_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_9wgr5dQqxyg_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("9wgr5dQqxyg", libCssUnknown_9wgr5dQqxyg_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_AfC4Omb8svg_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("AfC4Omb8svg", libCssUnknown_AfC4Omb8svg_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_B314wB_plus_fU6g_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("B314wB+fU6g", libCssUnknown_B314wB_plus_fU6g_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_BpqeQbNU0qo_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("BpqeQbNU0qo", libCssUnknown_BpqeQbNU0qo_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_CnQiuTNrJcM_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("CnQiuTNrJcM", libCssUnknown_CnQiuTNrJcM_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_E96QCyLgJ3o_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("E96QCyLgJ3o", libCssUnknown_E96QCyLgJ3o_nid_no_patch);
|
||||
|
||||
int APS5_VABI dvdAuthInitialize() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI DvdMac() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI libCssUnknown_FTFSIzVj7gE_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("FTFSIzVj7gE", libCssUnknown_FTFSIzVj7gE_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_FsJO2R6pcFY_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("FsJO2R6pcFY", libCssUnknown_FsJO2R6pcFY_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_HaAxhqb2xoM_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("HaAxhqb2xoM", libCssUnknown_HaAxhqb2xoM_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_Hm2XEUlTjSk_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("Hm2XEUlTjSk", libCssUnknown_Hm2XEUlTjSk_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_IcknOdMyfxQ_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("IcknOdMyfxQ", libCssUnknown_IcknOdMyfxQ_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_J6BYqrHA5UM_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("J6BYqrHA5UM", libCssUnknown_J6BYqrHA5UM_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_KUvq4G5VBPo_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("KUvq4G5VBPo", libCssUnknown_KUvq4G5VBPo_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_LAcpQCmLWwI_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("LAcpQCmLWwI", libCssUnknown_LAcpQCmLWwI_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_MRbX1Lg7JPo_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("MRbX1Lg7JPo", libCssUnknown_MRbX1Lg7JPo_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_OM3ptXltjzo_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("OM3ptXltjzo", libCssUnknown_OM3ptXltjzo_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_Q4g0Ji0W5GY_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("Q4g0Ji0W5GY", libCssUnknown_Q4g0Ji0W5GY_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_SRPTG7u8o98_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("SRPTG7u8o98", libCssUnknown_SRPTG7u8o98_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_TJdtvWbNKhs_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("TJdtvWbNKhs", libCssUnknown_TJdtvWbNKhs_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_UCT_minus_EFL9GlY_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("UCT-EFL9GlY", libCssUnknown_UCT_minus_EFL9GlY_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_UlBK7McbIBI_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("UlBK7McbIBI", libCssUnknown_UlBK7McbIBI_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_VLaRWTMO9U8_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("VLaRWTMO9U8", libCssUnknown_VLaRWTMO9U8_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_VMBVlZevTLw_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("VMBVlZevTLw", libCssUnknown_VMBVlZevTLw_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_Wdf6DHvrt4g_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("Wdf6DHvrt4g", libCssUnknown_Wdf6DHvrt4g_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_X9dl5pCTGiE_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("X9dl5pCTGiE", libCssUnknown_X9dl5pCTGiE_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_XWqQyI3K47s_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("XWqQyI3K47s", libCssUnknown_XWqQyI3K47s_nid_no_patch);
|
||||
|
||||
int APS5_VABI dvdAuthFinalize() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI libCssUnknown_bQpZTilHSL0_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("bQpZTilHSL0", libCssUnknown_bQpZTilHSL0_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_cN12O1uQ6Fo_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("cN12O1uQ6Fo", libCssUnknown_cN12O1uQ6Fo_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_cTnMCeNpGqc_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("cTnMCeNpGqc", libCssUnknown_cTnMCeNpGqc_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_czKT3U30FFE_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("czKT3U30FFE", libCssUnknown_czKT3U30FFE_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_daklpMlbo00_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("daklpMlbo00", libCssUnknown_daklpMlbo00_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_f7iq9LsamYo_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("f7iq9LsamYo", libCssUnknown_f7iq9LsamYo_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_gbja3RUMWJ4_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("gbja3RUMWJ4", libCssUnknown_gbja3RUMWJ4_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_giIpEkyo9Hg_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("giIpEkyo9Hg", libCssUnknown_giIpEkyo9Hg_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_hD3HhdNG_plus_xw_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("hD3HhdNG+xw", libCssUnknown_hD3HhdNG_plus_xw_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_hbTTMmwE3lo_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("hbTTMmwE3lo", libCssUnknown_hbTTMmwE3lo_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_hbvafh9uQqY_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("hbvafh9uQqY", libCssUnknown_hbvafh9uQqY_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_jYGAlLsijgw_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("jYGAlLsijgw", libCssUnknown_jYGAlLsijgw_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_k1_plus_Z1AtnLYI_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("k1+Z1AtnLYI", libCssUnknown_k1_plus_Z1AtnLYI_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_k5AW5Xs4aqg_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("k5AW5Xs4aqg", libCssUnknown_k5AW5Xs4aqg_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_kc5B1ELiUv4_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("kc5B1ELiUv4", libCssUnknown_kc5B1ELiUv4_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_nhK3hP3XL3Y_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("nhK3hP3XL3Y", libCssUnknown_nhK3hP3XL3Y_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_ohRg1gu5G1w_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("ohRg1gu5G1w", libCssUnknown_ohRg1gu5G1w_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_pTycImStaM4_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("pTycImStaM4", libCssUnknown_pTycImStaM4_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_rylZqUytLj8_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("rylZqUytLj8", libCssUnknown_rylZqUytLj8_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_szOnkd_plus_7b3U_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("szOnkd+7b3U", libCssUnknown_szOnkd_plus_7b3U_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_utwkEaQy6D4_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("utwkEaQy6D4", libCssUnknown_utwkEaQy6D4_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_wDe5E_minus_Nfd7E_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("wDe5E-Nfd7E", libCssUnknown_wDe5E_minus_Nfd7E_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_xQX0HWKQKDA_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("xQX0HWKQKDA", libCssUnknown_xQX0HWKQKDA_nid_no_patch);
|
||||
|
||||
int APS5_VABI libCssUnknown_z4KQSeB3_plus_6U_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("z4KQSeB3+6U", libCssUnknown_z4KQSeB3_plus_6U_nid_no_patch);
|
||||
|
||||
int APS5_VABI CpsInitKey() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI libCssUnknown_zxv6uaL0lAs_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("zxv6uaL0lAs", libCssUnknown_zxv6uaL0lAs_nid_no_patch);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI libCssUnknown__plus_zpMhCilHTQ_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown__minus_WR4_minus_J79nn0_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_45oyUIl85dg_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_4qq5OHYaFU8_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_6BDNwI1e59c_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_6QhXfVttAyU_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_74insBAQhg8_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_7YdC9p2cTSQ_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_81obgoH2X2g_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_9T_minus_RYQ7HwqI_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_9wgr5dQqxyg_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_AfC4Omb8svg_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_B314wB_plus_fU6g_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_BpqeQbNU0qo_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_CnQiuTNrJcM_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_E96QCyLgJ3o_nid_no_patch();
|
||||
int APS5_VABI dvdAuthInitialize();
|
||||
int APS5_VABI DvdMac();
|
||||
int APS5_VABI libCssUnknown_FTFSIzVj7gE_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_FsJO2R6pcFY_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_HaAxhqb2xoM_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_Hm2XEUlTjSk_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_IcknOdMyfxQ_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_J6BYqrHA5UM_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_KUvq4G5VBPo_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_LAcpQCmLWwI_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_MRbX1Lg7JPo_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_OM3ptXltjzo_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_Q4g0Ji0W5GY_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_SRPTG7u8o98_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_TJdtvWbNKhs_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_UCT_minus_EFL9GlY_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_UlBK7McbIBI_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_VLaRWTMO9U8_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_VMBVlZevTLw_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_Wdf6DHvrt4g_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_X9dl5pCTGiE_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_XWqQyI3K47s_nid_no_patch();
|
||||
int APS5_VABI dvdAuthFinalize();
|
||||
int APS5_VABI libCssUnknown_bQpZTilHSL0_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_cN12O1uQ6Fo_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_cTnMCeNpGqc_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_czKT3U30FFE_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_daklpMlbo00_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_f7iq9LsamYo_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_gbja3RUMWJ4_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_giIpEkyo9Hg_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_hD3HhdNG_plus_xw_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_hbTTMmwE3lo_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_hbvafh9uQqY_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_jYGAlLsijgw_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_k1_plus_Z1AtnLYI_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_k5AW5Xs4aqg_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_kc5B1ELiUv4_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_nhK3hP3XL3Y_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_ohRg1gu5G1w_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_pTycImStaM4_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_rylZqUytLj8_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_szOnkd_plus_7b3U_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_utwkEaQy6D4_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_wDe5E_minus_Nfd7E_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_xQX0HWKQKDA_nid_no_patch();
|
||||
int APS5_VABI libCssUnknown_z4KQSeB3_plus_6U_nid_no_patch();
|
||||
int APS5_VABI CpsInitKey();
|
||||
int APS5_VABI libCssUnknown_zxv6uaL0lAs_nid_no_patch();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "prx/libCss/include/InventoryExports.hpp"
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
APS5_DUMMY_FUN
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#pragma once
|
||||
@@ -0,0 +1,251 @@
|
||||
#include "prx/libc/include/general/ExportMacros.hpp"
|
||||
#include "prx/libReactNative.Modules.Vsh.WebAppLauncher/include/InventoryExports.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI CheckSystemEvents() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CommerceDialogBrowseCategory() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CommerceDialogBrowseProduct() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CommerceDialogInit() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CommerceDialogRedeemPromotionCode() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CommerceHidePsStoreIcon() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CommerceSetPsStoreIconLayout() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CommerceShowPsStoreIcon() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI DisableSystemMedia() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI ErrorDialogClose() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI ErrorDialogInit() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI ErrorDialogOpen() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetAccountAgeA() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetAccountCountryA() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetAccountIdA() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetAccountLanguage2() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetAuthorizationCode() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetClosedCaptionSettings() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetOnlineId() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetProcessTime() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetVideoOutputStatus() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetVideoOutputStatusInt() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI Hide() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI IsDebuggingSupported() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI NpWebAbortRequest() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI NpWebDeleteRequest() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI NpWebInitialize() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI NpWebReadData() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI NpWebTerminate() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI OpenClosedCaptionAdvancedSettings() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI OpenClosedCaptionSettings() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SoundInitialize() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SoundLoad() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SoundPlay() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SoundTerminate() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SpeechCancel() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SpeechClose() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SpeechInitialize() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SpeechSpeak() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SpeechStatus() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SpeechTerminate() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SystemDialogInit() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SystemDialogOpen() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SystemServiceParamGetInt() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI SystemServiceParamGetString() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory__plus_ucrAt9fI7c_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("+ucrAt9fI7c", libReactNativeWebAppLauncherInventory__plus_ucrAt9fI7c_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_06N_minus_dAyE_plus_HY_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("06N-dAyE+HY", libReactNativeWebAppLauncherInventory_06N_minus_dAyE_plus_HY_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_41blU2JCqLQ_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("41blU2JCqLQ", libReactNativeWebAppLauncherInventory_41blU2JCqLQ_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_BGgSEXB1Now_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("BGgSEXB1Now", libReactNativeWebAppLauncherInventory_BGgSEXB1Now_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_CAK_minus_S2JVdsk_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("CAK-S2JVdsk", libReactNativeWebAppLauncherInventory_CAK_minus_S2JVdsk_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_QxCdpkEsOgo_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("QxCdpkEsOgo", libReactNativeWebAppLauncherInventory_QxCdpkEsOgo_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_Tjj_plus__plus_S2qvOU_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("Tjj++S2qvOU", libReactNativeWebAppLauncherInventory_Tjj_plus__plus_S2qvOU_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_f5NHqUziG_plus_4_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("f5NHqUziG+4", libReactNativeWebAppLauncherInventory_f5NHqUziG_plus_4_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_mI_minus_ltMuVN_plus_Q_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("mI-ltMuVN+Q", libReactNativeWebAppLauncherInventory_mI_minus_ltMuVN_plus_Q_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_vDup_plus_0mWZf8_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("vDup+0mWZf8", libReactNativeWebAppLauncherInventory_vDup_plus_0mWZf8_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_wR1ucKGDM9Q_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("wR1ucKGDM9Q", libReactNativeWebAppLauncherInventory_wR1ucKGDM9Q_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_xPA_minus_tXzPGpc_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("xPA-tXzPGpc", libReactNativeWebAppLauncherInventory_xPA_minus_tXzPGpc_nid_no_patch);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI CheckSystemEvents();
|
||||
int APS5_VABI CommerceDialogBrowseCategory();
|
||||
int APS5_VABI CommerceDialogBrowseProduct();
|
||||
int APS5_VABI CommerceDialogInit();
|
||||
int APS5_VABI CommerceDialogRedeemPromotionCode();
|
||||
int APS5_VABI CommerceHidePsStoreIcon();
|
||||
int APS5_VABI CommerceSetPsStoreIconLayout();
|
||||
int APS5_VABI CommerceShowPsStoreIcon();
|
||||
int APS5_VABI DisableSystemMedia();
|
||||
int APS5_VABI ErrorDialogClose();
|
||||
int APS5_VABI ErrorDialogInit();
|
||||
int APS5_VABI ErrorDialogOpen();
|
||||
int APS5_VABI GetAccountAgeA();
|
||||
int APS5_VABI GetAccountCountryA();
|
||||
int APS5_VABI GetAccountIdA();
|
||||
int APS5_VABI GetAccountLanguage2();
|
||||
int APS5_VABI GetAuthorizationCode();
|
||||
int APS5_VABI GetClosedCaptionSettings();
|
||||
int APS5_VABI GetOnlineId();
|
||||
int APS5_VABI GetProcessTime();
|
||||
int APS5_VABI GetVideoOutputStatus();
|
||||
int APS5_VABI GetVideoOutputStatusInt();
|
||||
int APS5_VABI Hide();
|
||||
int APS5_VABI IsDebuggingSupported();
|
||||
int APS5_VABI NpWebAbortRequest();
|
||||
int APS5_VABI NpWebDeleteRequest();
|
||||
int APS5_VABI NpWebInitialize();
|
||||
int APS5_VABI NpWebReadData();
|
||||
int APS5_VABI NpWebTerminate();
|
||||
int APS5_VABI OpenClosedCaptionAdvancedSettings();
|
||||
int APS5_VABI OpenClosedCaptionSettings();
|
||||
int APS5_VABI SoundInitialize();
|
||||
int APS5_VABI SoundLoad();
|
||||
int APS5_VABI SoundPlay();
|
||||
int APS5_VABI SoundTerminate();
|
||||
int APS5_VABI SpeechCancel();
|
||||
int APS5_VABI SpeechClose();
|
||||
int APS5_VABI SpeechInitialize();
|
||||
int APS5_VABI SpeechSpeak();
|
||||
int APS5_VABI SpeechStatus();
|
||||
int APS5_VABI SpeechTerminate();
|
||||
int APS5_VABI SystemDialogInit();
|
||||
int APS5_VABI SystemDialogOpen();
|
||||
int APS5_VABI SystemServiceParamGetInt();
|
||||
int APS5_VABI SystemServiceParamGetString();
|
||||
|
||||
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory__plus_ucrAt9fI7c_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_06N_minus_dAyE_plus_HY_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_41blU2JCqLQ_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_BGgSEXB1Now_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_CAK_minus_S2JVdsk_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_QxCdpkEsOgo_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_Tjj_plus__plus_S2qvOU_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_f5NHqUziG_plus_4_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_mI_minus_ltMuVN_plus_Q_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_vDup_plus_0mWZf8_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_wR1ucKGDM9Q_nid_no_patch();
|
||||
int APS5_VABI libReactNativeWebAppLauncherInventory_xPA_minus_tXzPGpc_nid_no_patch();
|
||||
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "prx/libReactNative.Modules.Vsh.WebAppLauncher/include/InventoryExports.hpp"
|
||||
@@ -0,0 +1,361 @@
|
||||
#include "prx/libc/include/general/ExportMacros.hpp"
|
||||
#include "prx/libReactNative.Modules.Vsh/include/InventoryExports.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI CreateWebApiLibCtx() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CryptographyDecryptAES128CBC() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CryptographyDecryptAES128CBC_HS256() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CryptographyDecryptAES128GCM() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CryptographyEncryptAES128CBC() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CryptographyEncryptAES128GCM() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI CryptographyGenerateHmacSha256() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI DestroyWebApiLibCtx() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetLibHttpCtxId() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI GetPs4AppCategoryForTitleId() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI InetStatGetResultNative() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI InetStatGetStateNative() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI InetStatStartTestNative() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI InitializeNetLib() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI LoginMgrCreateUser() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI LoginMgrDestroyUser() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI LoginMgrInitialize() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI LoginMgrSetLoginFlag() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI LoginMgrSetUserStatus() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI LoginMgrTerminate() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI NpStateManagerRegisterCallback() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI NpStateManagerRtcSetTick() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI NpStateManagerStart() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI NpStateManagerStop() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI NpStateManagerUnregisterCallback() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI PSNowGetStatus() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI PSNowGetStreamingStatus() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI PSNowInitialize() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI PSNowReset() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI PSNowSendCommand() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI PSNowSetAuthCodes() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI PSNowSetSettings() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI PSNowTerminate() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayClearConnectHistory() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayConfirmDeviceRegist() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayDisconnect() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayGeneratePinCode() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayGetConnectHistory() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayGetConnectUserId() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayGetConnectionStatus() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayGetRemoteplayStatus() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayGetRpMode() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayIsRemotePlaying() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayNotifyCanWakeup() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayNotifyPinCodeError() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayNotifyUserDelete() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlayProhibitStreaming() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlaySetProhibition() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlaySetProhibitionForVsh() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RemotePlaySetRpMode() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RtcGetCurrentAdNetworkTickNative() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RtcGetCurrentDebugNetworkTickNative() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI RtcGetCurrentNetworkTickNative() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI TerminateNetLib() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI WebBrowserGetEnvelopeData() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceRemotePlayClientAddEventListener() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceRemotePlayClientAttachVirtualMicrophone() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceRemotePlayClientDetachVirtualMicrophone() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceRemotePlayClientGetClientStatus() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceRemotePlayClientInitialize() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceRemotePlayClientRemoveController() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceRemotePlayClientShowHomeScreen() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceRemotePlayClientStartMicCapture() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceRemotePlayClientStopMicCapture() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceRemotePlayClientTerminateStreaming() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory__plus_I5sPs9FLXw_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("+I5sPs9FLXw", libReactNativeModulesVshInventory__plus_I5sPs9FLXw_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory__minus_9hYGDAsb4E_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("-9hYGDAsb4E", libReactNativeModulesVshInventory__minus_9hYGDAsb4E_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_BzJsgzD97LU_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("BzJsgzD97LU", libReactNativeModulesVshInventory_BzJsgzD97LU_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_IQNf2nnftNI_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("IQNf2nnftNI", libReactNativeModulesVshInventory_IQNf2nnftNI_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_N3mcm_minus_qDFR0_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("N3mcm-qDFR0", libReactNativeModulesVshInventory_N3mcm_minus_qDFR0_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_OME2Be_plus_FlwA_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("OME2Be+FlwA", libReactNativeModulesVshInventory_OME2Be_plus_FlwA_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_PLEe_minus_toB_minus_KE_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("PLEe-toB-KE", libReactNativeModulesVshInventory_PLEe_minus_toB_minus_KE_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_QGGsQrtLW9Y_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("QGGsQrtLW9Y", libReactNativeModulesVshInventory_QGGsQrtLW9Y_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_Rm_plus_rgnBoPIE_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("Rm+rgnBoPIE", libReactNativeModulesVshInventory_Rm_plus_rgnBoPIE_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_SJU_plus_qK_plus_8yrM_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("SJU+qK+8yrM", libReactNativeModulesVshInventory_SJU_plus_qK_plus_8yrM_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_T7dL_minus_hEySvU_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("T7dL-hEySvU", libReactNativeModulesVshInventory_T7dL_minus_hEySvU_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_b_plus_MJDz3HB6s_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("b+MJDz3HB6s", libReactNativeModulesVshInventory_b_plus_MJDz3HB6s_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_bbsP8_minus_e8GZA_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("bbsP8-e8GZA", libReactNativeModulesVshInventory_bbsP8_minus_e8GZA_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_fxEQAPDRhLw_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("fxEQAPDRhLw", libReactNativeModulesVshInventory_fxEQAPDRhLw_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_j917Pp4k_minus_CI_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("j917Pp4k-CI", libReactNativeModulesVshInventory_j917Pp4k_minus_CI_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_lZ_minus_JDEqB34k_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("lZ-JDEqB34k", libReactNativeModulesVshInventory_lZ_minus_JDEqB34k_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_tKy_minus_Qdg_plus_FRc_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("tKy-Qdg+FRc", libReactNativeModulesVshInventory_tKy_minus_Qdg_plus_FRc_nid_no_patch);
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory_uQfQgwm36L4_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("uQfQgwm36L4", libReactNativeModulesVshInventory_uQfQgwm36L4_nid_no_patch);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI CreateWebApiLibCtx();
|
||||
int APS5_VABI CryptographyDecryptAES128CBC();
|
||||
int APS5_VABI CryptographyDecryptAES128CBC_HS256();
|
||||
int APS5_VABI CryptographyDecryptAES128GCM();
|
||||
int APS5_VABI CryptographyEncryptAES128CBC();
|
||||
int APS5_VABI CryptographyEncryptAES128GCM();
|
||||
int APS5_VABI CryptographyGenerateHmacSha256();
|
||||
int APS5_VABI DestroyWebApiLibCtx();
|
||||
int APS5_VABI GetLibHttpCtxId();
|
||||
int APS5_VABI GetPs4AppCategoryForTitleId();
|
||||
int APS5_VABI InetStatGetResultNative();
|
||||
int APS5_VABI InetStatGetStateNative();
|
||||
int APS5_VABI InetStatStartTestNative();
|
||||
int APS5_VABI InitializeNetLib();
|
||||
int APS5_VABI LoginMgrCreateUser();
|
||||
int APS5_VABI LoginMgrDestroyUser();
|
||||
int APS5_VABI LoginMgrInitialize();
|
||||
int APS5_VABI LoginMgrSetLoginFlag();
|
||||
int APS5_VABI LoginMgrSetUserStatus();
|
||||
int APS5_VABI LoginMgrTerminate();
|
||||
int APS5_VABI NpStateManagerRegisterCallback();
|
||||
int APS5_VABI NpStateManagerRtcSetTick();
|
||||
int APS5_VABI NpStateManagerStart();
|
||||
int APS5_VABI NpStateManagerStop();
|
||||
int APS5_VABI NpStateManagerUnregisterCallback();
|
||||
int APS5_VABI PSNowGetStatus();
|
||||
int APS5_VABI PSNowGetStreamingStatus();
|
||||
int APS5_VABI PSNowInitialize();
|
||||
int APS5_VABI PSNowReset();
|
||||
int APS5_VABI PSNowSendCommand();
|
||||
int APS5_VABI PSNowSetAuthCodes();
|
||||
int APS5_VABI PSNowSetSettings();
|
||||
int APS5_VABI PSNowTerminate();
|
||||
int APS5_VABI RemotePlayClearConnectHistory();
|
||||
int APS5_VABI RemotePlayConfirmDeviceRegist();
|
||||
int APS5_VABI RemotePlayDisconnect();
|
||||
int APS5_VABI RemotePlayGeneratePinCode();
|
||||
int APS5_VABI RemotePlayGetConnectHistory();
|
||||
int APS5_VABI RemotePlayGetConnectUserId();
|
||||
int APS5_VABI RemotePlayGetConnectionStatus();
|
||||
int APS5_VABI RemotePlayGetRemoteplayStatus();
|
||||
int APS5_VABI RemotePlayGetRpMode();
|
||||
int APS5_VABI RemotePlayIsRemotePlaying();
|
||||
int APS5_VABI RemotePlayNotifyCanWakeup();
|
||||
int APS5_VABI RemotePlayNotifyPinCodeError();
|
||||
int APS5_VABI RemotePlayNotifyUserDelete();
|
||||
int APS5_VABI RemotePlayProhibitStreaming();
|
||||
int APS5_VABI RemotePlaySetProhibition();
|
||||
int APS5_VABI RemotePlaySetProhibitionForVsh();
|
||||
int APS5_VABI RemotePlaySetRpMode();
|
||||
int APS5_VABI RtcGetCurrentAdNetworkTickNative();
|
||||
int APS5_VABI RtcGetCurrentDebugNetworkTickNative();
|
||||
int APS5_VABI RtcGetCurrentNetworkTickNative();
|
||||
int APS5_VABI TerminateNetLib();
|
||||
int APS5_VABI WebBrowserGetEnvelopeData();
|
||||
int APS5_VABI sceRemotePlayClientAddEventListener();
|
||||
int APS5_VABI sceRemotePlayClientAttachVirtualMicrophone();
|
||||
int APS5_VABI sceRemotePlayClientDetachVirtualMicrophone();
|
||||
int APS5_VABI sceRemotePlayClientGetClientStatus();
|
||||
int APS5_VABI sceRemotePlayClientInitialize();
|
||||
int APS5_VABI sceRemotePlayClientRemoveController();
|
||||
int APS5_VABI sceRemotePlayClientShowHomeScreen();
|
||||
int APS5_VABI sceRemotePlayClientStartMicCapture();
|
||||
int APS5_VABI sceRemotePlayClientStopMicCapture();
|
||||
int APS5_VABI sceRemotePlayClientTerminateStreaming();
|
||||
|
||||
|
||||
int APS5_VABI libReactNativeModulesVshInventory__plus_I5sPs9FLXw_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory__minus_9hYGDAsb4E_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_BzJsgzD97LU_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_IQNf2nnftNI_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_N3mcm_minus_qDFR0_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_OME2Be_plus_FlwA_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_PLEe_minus_toB_minus_KE_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_QGGsQrtLW9Y_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_Rm_plus_rgnBoPIE_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_SJU_plus_qK_plus_8yrM_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_T7dL_minus_hEySvU_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_b_plus_MJDz3HB6s_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_bbsP8_minus_e8GZA_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_fxEQAPDRhLw_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_j917Pp4k_minus_CI_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_lZ_minus_JDEqB34k_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_tKy_minus_Qdg_plus_FRc_nid_no_patch();
|
||||
int APS5_VABI libReactNativeModulesVshInventory_uQfQgwm36L4_nid_no_patch();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#include "prx/libReactNative.Modules.Vsh/include/InventoryExports.hpp"
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "prx/libSceAbstractStorage/include/Api.hpp"
|
||||
#include "prx/libSceAbstractStorage/include/LegacyExports.hpp"
|
||||
#include "prx/libc/include/general/ExportMacros.hpp"
|
||||
#include "prx/libSceAbstractStorage/include/InventoryExports.hpp"
|
||||
@@ -9,555 +10,445 @@
|
||||
extern "C" {
|
||||
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_7RnkdybfYiQ_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage12Serializable12readExternalESt10shared_ptrINS_7ContentEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("7RnkdybfYiQ", sceAbstractStorageUnknown_7RnkdybfYiQ_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_gINcKTbrqk4_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage12Serializable13writeExternalESt10shared_ptrINS_7ContentEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("gINcKTbrqk4", sceAbstractStorageUnknown_gINcKTbrqk4_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_F6tunp5_4ZM_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage12SerializableC1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("F6tunp5+4ZM", sceAbstractStorageUnknown_F6tunp5_4ZM_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_QRnz_VjPrkY_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage12SerializableC2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("QRnz-VjPrkY", sceAbstractStorageUnknown_QRnz_VjPrkY_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_DkAGX6EPi_g_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage12SerializableD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("DkAGX6EPi+g", sceAbstractStorageUnknown_DkAGX6EPi_g_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_tDhVqVa_tvU_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage12SerializableD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("tDhVqVa-tvU", sceAbstractStorageUnknown_tDhVqVa_tvU_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_o9RD998mN8M_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent12readExternalESt10shared_ptrINS_7ContentEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("o9RD998mN8M", sceAbstractStorageUnknown_o9RD998mN8M_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_KAJD5gNtjzg_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent13writeExternalESt10shared_ptrINS_7ContentEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("KAJD5gNtjzg", sceAbstractStorageUnknown_KAJD5gNtjzg_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_jekg6a2C_KE_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent14CreateInstanceESbIcSt11char_traitsIcENS_8StlAllocIcEEEN3paf6common9SharedPtrINS6_6BufferEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("jekg6a2C-KE", sceAbstractStorageUnknown_jekg6a2C_KE_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_SPPYTszg6LQ_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent14CreateInstanceESbIcSt11char_traitsIcENS_8StlAllocIcEEEPvm() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("SPPYTszg6LQ", sceAbstractStorageUnknown_SPPYTszg6LQ_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_ppyod3XEauc_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent4OpenEit() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("ppyod3XEauc", sceAbstractStorageUnknown_ppyod3XEauc_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_FC7E1riolAM_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent4ReadEPvlPl() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("FC7E1riolAM", sceAbstractStorageUnknown_FC7E1riolAM_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_h64Ojqk4fbE_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent5CloseEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("h64Ojqk4fbE", sceAbstractStorageUnknown_h64Ojqk4fbE_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_L9n8X5qE3gI_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent5FlushEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("L9n8X5qE3gI", sceAbstractStorageUnknown_L9n8X5qE3gI_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_UqSO97fYNAs_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent5WriteEPKvlPl() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("UqSO97fYNAs", sceAbstractStorageUnknown_UqSO97fYNAs_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_nxefs8JHV5U_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent6RemoveEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("nxefs8JHV5U", sceAbstractStorageUnknown_nxefs8JHV5U_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_TI_djeSDh5s_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent8SeekByteEliPl() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("TI+djeSDh5s", sceAbstractStorageUnknown_TI_djeSDh5s_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_23QZTBt3E60_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent8SeekTimeElPl() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("23QZTBt3E60", sceAbstractStorageUnknown_23QZTBt3E60_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_CgSbdJjHTyc_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContentC1ESbIcSt11char_traitsIcENS_8StlAllocIcEEEN3paf6common9SharedPtrINS6_6BufferEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("CgSbdJjHTyc", sceAbstractStorageUnknown_CgSbdJjHTyc_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_uhxDqVGiDTY_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContentC2ESbIcSt11char_traitsIcENS_8StlAllocIcEEEN3paf6common9SharedPtrINS6_6BufferEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("uhxDqVGiDTY", sceAbstractStorageUnknown_uhxDqVGiDTY_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_93IuLXtj1sc_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContentD0Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("93IuLXtj1sc", sceAbstractStorageUnknown_93IuLXtj1sc_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_6g_lsIudFQY_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContentD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("6g-lsIudFQY", sceAbstractStorageUnknown_6g_lsIudFQY_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_r_kkC2OXw10_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContentD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("r+kkC2OXw10", sceAbstractStorageUnknown_r_kkC2OXw10_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_xeunZETVUSk_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager10GetStorageERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEPSt10shared_ptrINS_7StorageEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("xeunZETVUSk", sceAbstractStorageUnknown_xeunZETVUSk_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_k0BKafeYaUo_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager10InitializeEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("k0BKafeYaUo", sceAbstractStorageUnknown_k0BKafeYaUo_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_iAN_9pPHZSE_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager11GetInstanceERNS_12MemAllocatorEPv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("iAN-9pPHZSE", sceAbstractStorageUnknown_iAN_9pPHZSE_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_QbKmf_2_cR0_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager11GetInstanceEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("QbKmf+2+cR0", sceAbstractStorageUnknown_QbKmf_2_cR0_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_JWT7NbPA9Ds_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager12NotifyCreateERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEb() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("JWT7NbPA9Ds", sceAbstractStorageUnknown_JWT7NbPA9Ds_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown__fMkDXxU9E0_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager12NotifyRemoveERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEb() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("+fMkDXxU9E0", sceAbstractStorageUnknown__fMkDXxU9E0_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_sFN0uAZmk04_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager15ReleaseInstanceEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("sFN0uAZmk04", sceAbstractStorageUnknown_sFN0uAZmk04_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_wvDKH1RiZhU_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager16NotifyWriteCloseERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("wvDKH1RiZhU", sceAbstractStorageUnknown_wvDKH1RiZhU_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_FxOHF0FBNfU_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager16RegisterListenerEPNS_17ItemEventListenerE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("FxOHF0FBNfU", sceAbstractStorageUnknown_FxOHF0FBNfU_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_JvyLbYhVigM_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager16RegisterListenerEPNS_20StorageEventListenerE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("JvyLbYhVigM", sceAbstractStorageUnknown_JvyLbYhVigM_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_bb_T5NMDPck_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager16get_storage_nameERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("bb-T5NMDPck", sceAbstractStorageUnknown_bb_T5NMDPck_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_LPRr40DzhbA_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager17NotifySetMetadataERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("LPRr40DzhbA", sceAbstractStorageUnknown_LPRr40DzhbA_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_oIR7L2c6df8_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager18GetStorageNameListEPSt6vectorISbIcSt11char_traitsIcENS_8StlAllocIcEEESaIS6_EE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("oIR7L2c6df8", sceAbstractStorageUnknown_oIR7L2c6df8_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_mhLGIWhMLlk_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager18UnregisterListenerEPKNS_17ItemEventListenerE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("mhLGIWhMLlk", sceAbstractStorageUnknown_mhLGIWhMLlk_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_0Ydc18_XsSw_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager18UnregisterListenerEPKNS_20StorageEventListenerE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("0Ydc18+XsSw", sceAbstractStorageUnknown_0Ydc18_XsSw_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_piG6ktf2BTU_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager20get_service_instanceENS_11ServiceTypeE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("piG6ktf2BTU", sceAbstractStorageUnknown_piG6ktf2BTU_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_iLakkVdPya4_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager21NotifyStorageAttachedERKSbIcSt11char_traitsIcENS_8StlAllocIcEEENS_11ServiceTypeE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("iLakkVdPya4", sceAbstractStorageUnknown_iLakkVdPya4_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_1Ko_sKZgqqs_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager21NotifyStorageDetachedERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("1Ko+sKZgqqs", sceAbstractStorageUnknown_1Ko_sKZgqqs_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown__PYC3_W6yUE_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager4FreeEPv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("-PYC3+W6yUE", sceAbstractStorageUnknown__PYC3_W6yUE_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_3iP9Xa6Z3z0_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager4LoadENS_11ServiceTypeE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("3iP9Xa6Z3z0", sceAbstractStorageUnknown_3iP9Xa6Z3z0_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_JREmVpFIgEY_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager6MallocEm() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("JREmVpFIgEY", sceAbstractStorageUnknown_JREmVpFIgEY_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_kCX0k5t1v_w_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager6UnloadENS_11ServiceTypeE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("kCX0k5t1v-w", sceAbstractStorageUnknown_kCX0k5t1v_w_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_3Cp_nOwl47U_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager6UpdateENS_11ServiceTypeE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("3Cp-nOwl47U", sceAbstractStorageUnknown_3Cp_nOwl47U_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_v9CSqw6Ve0w_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager9TerminateEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("v9CSqw6Ve0w", sceAbstractStorageUnknown_v9CSqw6Ve0w_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_KxTVuhlCL7o_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManagerC1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("KxTVuhlCL7o", sceAbstractStorageUnknown_KxTVuhlCL7o_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_YXXMdeJmxJw_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManagerC2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("YXXMdeJmxJw", sceAbstractStorageUnknown_YXXMdeJmxJw_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_2_S0J1RW2vQ_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManagerD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("2-S0J1RW2vQ", sceAbstractStorageUnknown_2_S0J1RW2vQ_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_K3qnBgQ0nC4_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManagerD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("K3qnBgQ0nC4", sceAbstractStorageUnknown_K3qnBgQ0nC4_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_rHzXUC9OHh8_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransaction15SendHttpRequestERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEiRKSt3mapIS5_S5_St4lessIS5_ESaISt4pairIS6_S5_EEEmb() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("rHzXUC9OHh8", sceAbstractStorageUnknown_rHzXUC9OHh8_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_Dlri33kcH6o_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransaction4InitEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("Dlri33kcH6o", sceAbstractStorageUnknown_Dlri33kcH6o_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_lH57wXDczHk_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransaction4TermEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("lH57wXDczHk", sceAbstractStorageUnknown_lH57wXDczHk_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_xJbY3QNYIzM_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransaction8SendDataEPKvm() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("xJbY3QNYIzM", sceAbstractStorageUnknown_xJbY3QNYIzM_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_tbeA_hlRlHc_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransactionC1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("tbeA-hlRlHc", sceAbstractStorageUnknown_tbeA_hlRlHc_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_01BHTyfcbBs_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransactionC2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("01BHTyfcbBs", sceAbstractStorageUnknown_01BHTyfcbBs_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_1PrEoSKt3_w_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransactionD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("1PrEoSKt3-w", sceAbstractStorageUnknown_1PrEoSKt3_w_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_MoUJZiDoHMk_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransactionD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("MoUJZiDoHMk", sceAbstractStorageUnknown_MoUJZiDoHMk_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_I69kRgYrWmY_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4Item11GetPathNameEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("I69kRgYrWmY", sceAbstractStorageUnknown_I69kRgYrWmY_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_GCMRCWH3PU0_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4Item11SetMetadataEPN23sceMetadataReaderWriter8MetadataE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("GCMRCWH3PU0", sceAbstractStorageUnknown_GCMRCWH3PU0_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_SYb4Kmj0u88_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4Item13ParseMetadataEPN23sceMetadataReaderWriter8MetadataES3_() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("SYb4Kmj0u88", sceAbstractStorageUnknown_SYb4Kmj0u88_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_k2VonUL2gF8_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4Item14GetStorageNameEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("k2VonUL2gF8", sceAbstractStorageUnknown_k2VonUL2gF8_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_zkaNI1552m4_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4Item6RenameERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("zkaNI1552m4", sceAbstractStorageUnknown_zkaNI1552m4_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_KAtGZCifCMo_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4Item7GetNameERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("KAtGZCifCMo", sceAbstractStorageUnknown_KAtGZCifCMo_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown__sxz_ThMtGM_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4Item7GetNameEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("-sxz-ThMtGM", sceAbstractStorageUnknown__sxz_ThMtGM_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_wyEuZhFhbOE_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4Item8set_metaERN23sceMetadataReaderWriter8MetadataERKSbIcSt11char_traitsIcENS_8StlAllocIcEEESA_() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("wyEuZhFhbOE", sceAbstractStorageUnknown_wyEuZhFhbOE_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_F_Tz7UzYtJ4_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4Item8set_metaERN23sceMetadataReaderWriter8MetadataERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEm() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("F-Tz7UzYtJ4", sceAbstractStorageUnknown_F_Tz7UzYtJ4_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_zC_hnmcVEOw_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemC2ERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("zC+hnmcVEOw", sceAbstractStorageUnknown_zC_hnmcVEOw_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_scYjSEuq2ik_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemD0Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("scYjSEuq2ik", sceAbstractStorageUnknown_scYjSEuq2ik_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_QPNELEk9zkI_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("QPNELEk9zkI", sceAbstractStorageUnknown_QPNELEk9zkI_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_WnE1cxQELbY_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("WnE1cxQELbY", sceAbstractStorageUnknown_WnE1cxQELbY_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_Hg0GBcA80dk_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemdlEPv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("Hg0GBcA80dk", sceAbstractStorageUnknown_Hg0GBcA80dk_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_gid_GlhKgJM_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemnwEm() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("gid+GlhKgJM", sceAbstractStorageUnknown_gid_GlhKgJM_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_oJSXws_cIv8_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage6FolderC2ERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("oJSXws+cIv8", sceAbstractStorageUnknown_oJSXws_cIv8_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_GgNWVxe_YSU_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage6FolderD0Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("GgNWVxe-YSU", sceAbstractStorageUnknown_GgNWVxe_YSU_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown__1PWHzoXWyU_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage6FolderD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("-1PWHzoXWyU", sceAbstractStorageUnknown__1PWHzoXWyU_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_sLg6rUpiYSM_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage6FolderD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("sLg6rUpiYSM", sceAbstractStorageUnknown_sLg6rUpiYSM_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_lYUGcgHYT7Y_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7AbsFreeEPv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("lYUGcgHYT7Y", sceAbstractStorageUnknown_lYUGcgHYT7Y_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_hQiPEotip7M_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7Content12GetExtensionERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("hQiPEotip7M", sceAbstractStorageUnknown_hQiPEotip7M_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_pekT_IsAkQU_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7Content12GetMimeTypesEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("pekT-IsAkQU", sceAbstractStorageUnknown_pekT_IsAkQU_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_xilbMn7q9qE_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7Content6RenameERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("xilbMn7q9qE", sceAbstractStorageUnknown_xilbMn7q9qE_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_UZbuoykGKzE_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7ContentC2ERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("UZbuoykGKzE", sceAbstractStorageUnknown_UZbuoykGKzE_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_RenWwlxG9Tw_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7ContentD0Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("RenWwlxG9Tw", sceAbstractStorageUnknown_RenWwlxG9Tw_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_JZ3wKDjl0yQ_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7ContentD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("JZ3wKDjl0yQ", sceAbstractStorageUnknown_JZ3wKDjl0yQ_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_m7OSrfA7K_s_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7ContentD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("m7OSrfA7K+s", sceAbstractStorageUnknown_m7OSrfA7K_s_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_spsjzV2pTSc_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7Service11NextStorageERSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("spsjzV2pTSc", sceAbstractStorageUnknown_spsjzV2pTSc_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_6Fp8jJ7A7CY_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7Service13CreateStorageERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEPSt10shared_ptrINS_7StorageEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("6Fp8jJ7A7CY", sceAbstractStorageUnknown_6Fp8jJ7A7CY_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_wBaVZTLTjkg_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7Service18clear_storage_listEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("wBaVZTLTjkg", sceAbstractStorageUnknown_wBaVZTLTjkg_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_DyerRilxWZ4_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7Service4LoadENS_11ServiceTypeE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("DyerRilxWZ4", sceAbstractStorageUnknown_DyerRilxWZ4_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_jCKhrVa9MEU_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7Service4StopEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("jCKhrVa9MEU", sceAbstractStorageUnknown_jCKhrVa9MEU_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_tIIRbXa2ZOk_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7Service5StartEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("tIIRbXa2ZOk", sceAbstractStorageUnknown_tIIRbXa2ZOk_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_vatp8UwS_nE_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7Service6UnLoadEPS0_() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("vatp8UwS+nE", sceAbstractStorageUnknown_vatp8UwS_nE_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_CrZTHC5yd64_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7ServiceC2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("CrZTHC5yd64", sceAbstractStorageUnknown_CrZTHC5yd64_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_IoNgvbVSw24_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7ServiceD0Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("IoNgvbVSw24", sceAbstractStorageUnknown_IoNgvbVSw24_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_PEuuRn6zhF4_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7ServiceD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("PEuuRn6zhF4", sceAbstractStorageUnknown_PEuuRn6zhF4_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_Ngfl7wTF7M0_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7ServiceD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("Ngfl7wTF7M0", sceAbstractStorageUnknown_Ngfl7wTF7M0_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_tLtIJWgGINI_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7StorageC2ERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("tLtIJWgGINI", sceAbstractStorageUnknown_tLtIJWgGINI_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_4ns7J9OrJ5g_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7StorageD0Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("4ns7J9OrJ5g", sceAbstractStorageUnknown_4ns7J9OrJ5g_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_aKBqHZKouts_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7StorageD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("aKBqHZKouts", sceAbstractStorageUnknown_aKBqHZKouts_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_fydJOJjDxX4_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage7StorageD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("fydJOJjDxX4", sceAbstractStorageUnknown_fydJOJjDxX4_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_qtgEboQL0YE_nid_no_patch() {
|
||||
int APS5_VABI _ZN15AbstractStorage9AbsMallocEm() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("qtgEboQL0YE", sceAbstractStorageUnknown_qtgEboQL0YE_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_XBlKK5ijWI8_nid_no_patch() {
|
||||
int APS5_VABI _ZNK15AbstractStorage14MemfileContent10GetServiceEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("XBlKK5ijWI8", sceAbstractStorageUnknown_XBlKK5ijWI8_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_xP3aCoP48XI_nid_no_patch() {
|
||||
int APS5_VABI _ZNK15AbstractStorage14MemfileContent13GetCapabilityEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("xP3aCoP48XI", sceAbstractStorageUnknown_xP3aCoP48XI_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_FCSUVvY_0RM_nid_no_patch() {
|
||||
int APS5_VABI _ZNK15AbstractStorage14MemfileContent7GetStatEPNS_4StatE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("FCSUVvY-0RM", sceAbstractStorageUnknown_FCSUVvY_0RM_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_oc6n6hdUrEM_nid_no_patch() {
|
||||
int APS5_VABI _ZNK15AbstractStorage4Item12GetThumbnailEPSt10shared_ptrINS_7ContentEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("oc6n6hdUrEM", sceAbstractStorageUnknown_oc6n6hdUrEM_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_Cb7xWd9_7tc_nid_no_patch() {
|
||||
int APS5_VABI _ZNK15AbstractStorage4Item15CreateThumbnailEPvPSt10shared_ptrINS_7ContentEE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("Cb7xWd9-7tc", sceAbstractStorageUnknown_Cb7xWd9_7tc_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_mv9rtQAknH4_nid_no_patch() {
|
||||
int APS5_VABI _ZNK15AbstractStorage6Folder7GetTypeEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("mv9rtQAknH4", sceAbstractStorageUnknown_mv9rtQAknH4_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_ka5TVf37Akg_nid_no_patch() {
|
||||
int APS5_VABI _ZNK15AbstractStorage7Content7GetTypeEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("ka5TVf37Akg", sceAbstractStorageUnknown_ka5TVf37Akg_nid_no_patch);
|
||||
|
||||
int APS5_VABI sceAbstractStorageUnknown_1uryzAWFUuA_nid_no_patch() {
|
||||
int APS5_VABI _ZNK15AbstractStorage7Storage7GetTypeEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("1uryzAWFUuA", sceAbstractStorageUnknown_1uryzAWFUuA_nid_no_patch);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
#pragma once
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage12Serializable12readExternalESt10shared_ptrINS_7ContentEE();
|
||||
int APS5_VABI _ZN15AbstractStorage12Serializable13writeExternalESt10shared_ptrINS_7ContentEE();
|
||||
int APS5_VABI _ZN15AbstractStorage12SerializableC1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage12SerializableC2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage12SerializableD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage12SerializableD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent12readExternalESt10shared_ptrINS_7ContentEE();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent13writeExternalESt10shared_ptrINS_7ContentEE();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent14CreateInstanceESbIcSt11char_traitsIcENS_8StlAllocIcEEEN3paf6common9SharedPtrINS6_6BufferEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent14CreateInstanceESbIcSt11char_traitsIcENS_8StlAllocIcEEEPvm();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent4OpenEit();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent4ReadEPvlPl();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent5CloseEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent5FlushEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent5WriteEPKvlPl();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent6RemoveEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent8SeekByteEliPl();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContent8SeekTimeElPl();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContentC1ESbIcSt11char_traitsIcENS_8StlAllocIcEEEN3paf6common9SharedPtrINS6_6BufferEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContentC2ESbIcSt11char_traitsIcENS_8StlAllocIcEEEN3paf6common9SharedPtrINS6_6BufferEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContentD0Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContentD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14MemfileContentD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager10GetStorageERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEPSt10shared_ptrINS_7StorageEE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager10InitializeEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager11GetInstanceERNS_12MemAllocatorEPv();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager11GetInstanceEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager12NotifyCreateERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEb();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager12NotifyRemoveERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEb();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager15ReleaseInstanceEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager16NotifyWriteCloseERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager16RegisterListenerEPNS_17ItemEventListenerE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager16RegisterListenerEPNS_20StorageEventListenerE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager16get_storage_nameERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager17NotifySetMetadataERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager18GetStorageNameListEPSt6vectorISbIcSt11char_traitsIcENS_8StlAllocIcEEESaIS6_EE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager18UnregisterListenerEPKNS_17ItemEventListenerE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager18UnregisterListenerEPKNS_20StorageEventListenerE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager20get_service_instanceENS_11ServiceTypeE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager21NotifyStorageAttachedERKSbIcSt11char_traitsIcENS_8StlAllocIcEEENS_11ServiceTypeE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager21NotifyStorageDetachedERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager4FreeEPv();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager4LoadENS_11ServiceTypeE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager6MallocEm();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager6UnloadENS_11ServiceTypeE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager6UpdateENS_11ServiceTypeE();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManager9TerminateEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManagerC1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManagerC2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManagerD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14StorageManagerD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransaction15SendHttpRequestERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEiRKSt3mapIS5_S5_St4lessIS5_ESaISt4pairIS6_S5_EEEmb();
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransaction4InitEv();
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransaction4TermEv();
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransaction8SendDataEPKvm();
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransactionC1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransactionC2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransactionD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage15HttpTransactionD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage4Item11GetPathNameEv();
|
||||
int APS5_VABI _ZN15AbstractStorage4Item11SetMetadataEPN23sceMetadataReaderWriter8MetadataE();
|
||||
int APS5_VABI _ZN15AbstractStorage4Item13ParseMetadataEPN23sceMetadataReaderWriter8MetadataES3_();
|
||||
int APS5_VABI _ZN15AbstractStorage4Item14GetStorageNameEv();
|
||||
int APS5_VABI _ZN15AbstractStorage4Item6RenameERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage4Item7GetNameERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage4Item7GetNameEv();
|
||||
int APS5_VABI _ZN15AbstractStorage4Item8set_metaERN23sceMetadataReaderWriter8MetadataERKSbIcSt11char_traitsIcENS_8StlAllocIcEEESA_();
|
||||
int APS5_VABI _ZN15AbstractStorage4Item8set_metaERN23sceMetadataReaderWriter8MetadataERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEm();
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemC2ERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemD0Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemdlEPv();
|
||||
int APS5_VABI _ZN15AbstractStorage4ItemnwEm();
|
||||
int APS5_VABI _ZN15AbstractStorage6FolderC2ERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage6FolderD0Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage6FolderD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage6FolderD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage7AbsFreeEPv();
|
||||
int APS5_VABI _ZN15AbstractStorage7Content12GetExtensionERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage7Content12GetMimeTypesEv();
|
||||
int APS5_VABI _ZN15AbstractStorage7Content6RenameERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage7ContentC2ERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage7ContentD0Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage7ContentD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage7ContentD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage7Service11NextStorageERSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage7Service13CreateStorageERKSbIcSt11char_traitsIcENS_8StlAllocIcEEEPSt10shared_ptrINS_7StorageEE();
|
||||
int APS5_VABI _ZN15AbstractStorage7Service18clear_storage_listEv();
|
||||
int APS5_VABI _ZN15AbstractStorage7Service4LoadENS_11ServiceTypeE();
|
||||
int APS5_VABI _ZN15AbstractStorage7Service4StopEv();
|
||||
int APS5_VABI _ZN15AbstractStorage7Service5StartEv();
|
||||
int APS5_VABI _ZN15AbstractStorage7Service6UnLoadEPS0_();
|
||||
int APS5_VABI _ZN15AbstractStorage7ServiceC2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage7ServiceD0Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage7ServiceD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage7ServiceD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage7StorageC2ERKSbIcSt11char_traitsIcENS_8StlAllocIcEEE();
|
||||
int APS5_VABI _ZN15AbstractStorage7StorageD0Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage7StorageD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage7StorageD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage9AbsMallocEm();
|
||||
int APS5_VABI _ZNK15AbstractStorage14MemfileContent10GetServiceEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage14MemfileContent13GetCapabilityEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage14MemfileContent7GetStatEPNS_4StatE();
|
||||
int APS5_VABI _ZNK15AbstractStorage4Item12GetThumbnailEPSt10shared_ptrINS_7ContentEE();
|
||||
int APS5_VABI _ZNK15AbstractStorage4Item15CreateThumbnailEPvPSt10shared_ptrINS_7ContentEE();
|
||||
int APS5_VABI _ZNK15AbstractStorage6Folder7GetTypeEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage7Content7GetTypeEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage7Storage7GetTypeEv();
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#include "prx/libSceAbstractStorage/include/Api.hpp"
|
||||
#include "prx/libSceAbstractStorage/include/InventoryExports.hpp"
|
||||
#include "prx/libSceAbstractStorage/include/LegacyExports.hpp"
|
||||
@@ -1,3 +1,6 @@
|
||||
#include "prx/libSceAbstractYoutube/include/LegacyExports.hpp"
|
||||
#include "prx/libc/include/general/ExportMacros.hpp"
|
||||
#include "prx/libSceAbstractYoutube/include/InventoryExports.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include "SceTypes.hpp"
|
||||
@@ -92,3 +95,267 @@ int APS5_VABI sceAbstractYoutubeUnknown_vJGnqFj6ygE_nid_no_patch() {
|
||||
APS5_EXPORT("vJGnqFj6ygE", sceAbstractYoutubeUnknown_vJGnqFj6ygE_nid_no_patch);
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage13YoutubeFolder6RemoveEb() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage13YoutubeFolderD0Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage13YoutubeFolderD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage13YoutubeFolderD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent11SetMetadataEPN23sceMetadataReaderWriter8MetadataE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent13ParseMetadataEPN23sceMetadataReaderWriter8MetadataES3_() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent4OpenEit() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent4ReadEPvlPl() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent5CloseEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent5FlushEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent5WriteEPKvlPl() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent6RemoveEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent8SeekByteEliPl() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent8SeekTimeElPl() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContentD0Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContentD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContentD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeService13SearchStorageEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeService4StopEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeService5StartEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeServiceC1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeServiceC2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeServiceD0Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeServiceD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeServiceD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeStorage14GetStorageSizeEPlS1_S1_() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeStorageD0Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeStorageD1Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeStorageD2Ev() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK15AbstractStorage13YoutubeFolder10GetServiceEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK15AbstractStorage13YoutubeFolder13GetCapabilityEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK15AbstractStorage13YoutubeFolder7GetStatEPNS_4StatE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeContent10GetServiceEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeContent13GetCapabilityEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeContent7GetStatEPNS_4StatE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeService14GetServiceTypeEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeStorage10GetServiceEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeStorage13GetCapabilityEv() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeStorage7GetStatEPNS_4StatE() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown__plus_XiOtdILEHI_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("+XiOtdILEHI", abstractYoutubeLegacyUnknown__plus_XiOtdILEHI_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_4orcGYZG2cE_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("4orcGYZG2cE", abstractYoutubeLegacyUnknown_4orcGYZG2cE_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_6svBaAI4Ggw_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("6svBaAI4Ggw", abstractYoutubeLegacyUnknown_6svBaAI4Ggw_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_CCv9CYanMNI_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("CCv9CYanMNI", abstractYoutubeLegacyUnknown_CCv9CYanMNI_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_EEx55k0zSLo_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("EEx55k0zSLo", abstractYoutubeLegacyUnknown_EEx55k0zSLo_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_HYDApQYDgcI_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("HYDApQYDgcI", abstractYoutubeLegacyUnknown_HYDApQYDgcI_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_IGnFlGNW_plus_Vo_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("IGnFlGNW+Vo", abstractYoutubeLegacyUnknown_IGnFlGNW_plus_Vo_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_JzBDUIC5xok_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("JzBDUIC5xok", abstractYoutubeLegacyUnknown_JzBDUIC5xok_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_NPYN89qO2Ks_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("NPYN89qO2Ks", abstractYoutubeLegacyUnknown_NPYN89qO2Ks_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_P_plus_ZjKSLi5lg_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("P+ZjKSLi5lg", abstractYoutubeLegacyUnknown_P_plus_ZjKSLi5lg_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_RkaqMMDQJp4_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("RkaqMMDQJp4", abstractYoutubeLegacyUnknown_RkaqMMDQJp4_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_ZpVRh3D86UY_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("ZpVRh3D86UY", abstractYoutubeLegacyUnknown_ZpVRh3D86UY_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_ZwkYXHwQ7Mc_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("ZwkYXHwQ7Mc", abstractYoutubeLegacyUnknown_ZwkYXHwQ7Mc_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_cktbTmca48I_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("cktbTmca48I", abstractYoutubeLegacyUnknown_cktbTmca48I_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_fUXj4GBxyHs_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("fUXj4GBxyHs", abstractYoutubeLegacyUnknown_fUXj4GBxyHs_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_g58APdyJ_minus_5Y_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("g58APdyJ-5Y", abstractYoutubeLegacyUnknown_g58APdyJ_minus_5Y_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_hXCJIJZZ5MY_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("hXCJIJZZ5MY", abstractYoutubeLegacyUnknown_hXCJIJZZ5MY_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_kgeuOe7oln8_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("kgeuOe7oln8", abstractYoutubeLegacyUnknown_kgeuOe7oln8_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_pR9ULw2VrSs_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("pR9ULw2VrSs", abstractYoutubeLegacyUnknown_pR9ULw2VrSs_nid_no_patch);
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_tjbj7QysZwk_nid_no_patch() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
APS5_EXPORT("tjbj7QysZwk", abstractYoutubeLegacyUnknown_tjbj7QysZwk_nid_no_patch);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI _ZN15AbstractStorage13YoutubeFolder6RemoveEb();
|
||||
int APS5_VABI _ZN15AbstractStorage13YoutubeFolderD0Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage13YoutubeFolderD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage13YoutubeFolderD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent11SetMetadataEPN23sceMetadataReaderWriter8MetadataE();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent13ParseMetadataEPN23sceMetadataReaderWriter8MetadataES3_();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent4OpenEit();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent4ReadEPvlPl();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent5CloseEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent5FlushEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent5WriteEPKvlPl();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent6RemoveEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent8SeekByteEliPl();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContent8SeekTimeElPl();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContentD0Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContentD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeContentD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeService13SearchStorageEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeService4StopEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeService5StartEv();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeServiceC1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeServiceC2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeServiceD0Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeServiceD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeServiceD2Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeStorage14GetStorageSizeEPlS1_S1_();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeStorageD0Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeStorageD1Ev();
|
||||
int APS5_VABI _ZN15AbstractStorage14YoutubeStorageD2Ev();
|
||||
int APS5_VABI _ZNK15AbstractStorage13YoutubeFolder10GetServiceEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage13YoutubeFolder13GetCapabilityEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage13YoutubeFolder7GetStatEPNS_4StatE();
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeContent10GetServiceEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeContent13GetCapabilityEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeContent7GetStatEPNS_4StatE();
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeService14GetServiceTypeEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeStorage10GetServiceEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeStorage13GetCapabilityEv();
|
||||
int APS5_VABI _ZNK15AbstractStorage14YoutubeStorage7GetStatEPNS_4StatE();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown__plus_XiOtdILEHI_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_4orcGYZG2cE_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_6svBaAI4Ggw_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_CCv9CYanMNI_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_EEx55k0zSLo_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_HYDApQYDgcI_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_IGnFlGNW_plus_Vo_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_JzBDUIC5xok_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_NPYN89qO2Ks_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_P_plus_ZjKSLi5lg_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_RkaqMMDQJp4_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_ZpVRh3D86UY_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_ZwkYXHwQ7Mc_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_cktbTmca48I_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_fUXj4GBxyHs_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_g58APdyJ_minus_5Y_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_hXCJIJZZ5MY_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_kgeuOe7oln8_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_pR9ULw2VrSs_nid_no_patch();
|
||||
int APS5_VABI abstractYoutubeLegacyUnknown_tjbj7QysZwk_nid_no_patch();
|
||||
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
#pragma once
|
||||
#include "prx/libSceAbstractYoutube/include/InventoryExports.hpp"
|
||||
#include "prx/libSceAbstractYoutube/include/LegacyExports.hpp"
|
||||
@@ -91,6 +91,19 @@ if(BUILD_TESTING)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test_executable(agc_draw_setup_tests EXCLUDE_FROM_ALL tests/DrawSetup.cpp)
|
||||
target_include_directories(agc_draw_setup_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(agc_draw_setup_tests PRIVATE libSceAgc libc)
|
||||
configure_windows_unwind(agc_draw_setup_tests)
|
||||
if(BUILD_TESTING)
|
||||
set_target_properties(agc_draw_setup_tests PROPERTIES EXCLUDE_FROM_ALL OFF)
|
||||
add_test(NAME agc_draw_setup COMMAND agc_draw_setup_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(agc_draw_setup PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test_executable(agc_rewind_patch_tests EXCLUDE_FROM_ALL tests/RewindPatch.cpp)
|
||||
target_include_directories(agc_rewind_patch_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(agc_rewind_patch_tests PRIVATE libSceAgc libc)
|
||||
@@ -129,6 +142,19 @@ if(BUILD_TESTING)
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test_executable(agc_copy_data_tests EXCLUDE_FROM_ALL tests/CopyData.cpp)
|
||||
target_include_directories(agc_copy_data_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(agc_copy_data_tests PRIVATE libSceAgc libc)
|
||||
configure_windows_unwind(agc_copy_data_tests)
|
||||
if(BUILD_TESTING)
|
||||
set_target_properties(agc_copy_data_tests PROPERTIES EXCLUDE_FROM_ALL OFF)
|
||||
add_test(NAME agc_copy_data COMMAND agc_copy_data_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(agc_copy_data PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
endif()
|
||||
configure_windows_unwind(libSceAgc)
|
||||
|
||||
add_test_executable(agc_static_buffer_tests EXCLUDE_FROM_ALL tests/StaticBuffer.cpp)
|
||||
@@ -170,6 +196,19 @@ if(BUILD_TESTING)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test_executable(agc_nop_and_compute_event_tests EXCLUDE_FROM_ALL tests/NopAndComputeEvent.cpp)
|
||||
target_include_directories(agc_nop_and_compute_event_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(agc_nop_and_compute_event_tests PRIVATE libSceAgc libc)
|
||||
configure_windows_unwind(agc_nop_and_compute_event_tests)
|
||||
if(BUILD_TESTING)
|
||||
set_target_properties(agc_nop_and_compute_event_tests PROPERTIES EXCLUDE_FROM_ALL OFF)
|
||||
add_test(NAME agc_nop_and_compute_event COMMAND agc_nop_and_compute_event_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(agc_nop_and_compute_event PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test_executable(agc_packet_info_tests EXCLUDE_FROM_ALL tests/PacketInfo.cpp)
|
||||
target_include_directories(agc_packet_info_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(agc_packet_info_tests PRIVATE libSceAgc libc)
|
||||
|
||||
@@ -18,7 +18,6 @@ extern "C" int APS5_VABI sceAgcGetFusedShaderSize_0080(SizeAlign* dst, const Sha
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI sceAgcFuseShaderHalves_nid_postfix(Shader* fusedResult, const Shader* front, const Shader* back, void* scratchMem);
|
||||
int APS5_VABI sceAgcUpdateInterpolantMapping_0100(ShaderRegister* regs, const Shader* vs, const Shader* ps);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -354,12 +354,4 @@ int APS5_VABI sceAgcGetFusedShaderSize_0080(SizeAlign* dst, const Shader* front,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceAgcUpdateInterpolantMapping_0100(ShaderRegister* regs, const Shader* vs, const Shader* ps) {
|
||||
(void)regs;
|
||||
(void)vs;
|
||||
(void)ps;
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI sceAgcCreateInterpolantMapping_0100(ShaderRegister* regs, const Shader* gs, const Shader* ps);
|
||||
int APS5_VABI sceAgcUpdateInterpolantMapping_0100(ShaderRegister* regs, const Shader* vs, const Shader* ps);
|
||||
int APS5_VABI sceAgcCreateInterpolantMapping_10000(ShaderRegister* regs, const Shader* gs, const Shader* ps);
|
||||
int APS5_VABI sceAgcUpdateInterpolantMapping_10000(ShaderRegister* regs, const Shader* gs, const Shader* ps);
|
||||
int APS5_VABI sceAgcCreateInterpolantMapping_nid_postfix(ShaderRegister* regs, const Shader* gs, const Shader* ps);
|
||||
|
||||
@@ -58,6 +58,12 @@ std::uint32_t CreateInterpolantValueFlatDefault(std::uint32_t psWord, const Shad
|
||||
return ((psWord & 0x00700000u) == 0x00400000u) ? (value | 0x00000020u) : value;
|
||||
}
|
||||
|
||||
std::uint32_t ApplyInterpolantDefaultValue0100(std::uint32_t value, std::uint32_t psWord) {
|
||||
value &= ~0x00000300u;
|
||||
value |= ((psWord >> 28u) & 0x3u) << 8u;
|
||||
return value;
|
||||
}
|
||||
|
||||
int CreateInterpolantMapping(const char* fn, ShaderRegister* regs, const Shader* gs, const Shader* ps, CreateInterpolantValueFn createValue, bool fillIdentityTail) {
|
||||
if (regs == nullptr) {
|
||||
throw std::runtime_error(std::string(fn) + ": regs is null");
|
||||
@@ -124,6 +130,37 @@ int APS5_VABI sceAgcCreateInterpolantMapping_0100(ShaderRegister* regs, const Sh
|
||||
return CreateInterpolantMapping(__func__, regs, gs, ps, CreateInterpolantValue, true);
|
||||
}
|
||||
|
||||
int APS5_VABI sceAgcUpdateInterpolantMapping_0100(ShaderRegister* regs, const Shader* vs, const Shader* ps) {
|
||||
if (regs == nullptr) {
|
||||
throw std::runtime_error(std::string(__func__) + ": regs is null");
|
||||
}
|
||||
if (ps == nullptr) {
|
||||
throw std::runtime_error(std::string(__func__) + ": ps is null");
|
||||
}
|
||||
if (ps->num_input_semantics > InterpolantRegisterCount) {
|
||||
throw std::runtime_error(std::string(__func__) + ": input semantic count exceeds 32");
|
||||
}
|
||||
if (ps->num_input_semantics == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (ps->input_semantics == nullptr) {
|
||||
throw std::runtime_error(std::string(__func__) + ": ps->input_semantics is null but num_input_semantics != 0");
|
||||
}
|
||||
if (vs == nullptr) {
|
||||
throw std::runtime_error(std::string(__func__) + ": vs is null");
|
||||
}
|
||||
if (vs->num_output_semantics != 0 && vs->output_semantics == nullptr) {
|
||||
throw std::runtime_error(std::string(__func__) + ": vs->output_semantics is null but num_output_semantics != 0");
|
||||
}
|
||||
for (std::uint32_t i = 0; i < ps->num_input_semantics; ++i) {
|
||||
const ShaderSemantic& psSemantic = ps->input_semantics[i];
|
||||
const std::uint32_t psWord = ShaderSemanticWord(psSemantic);
|
||||
const ShaderSemantic* vsSemantic = FindOutputSemantic(vs, psSemantic.semantic);
|
||||
SetInterpolantRegister(regs, i, ApplyInterpolantDefaultValue0100(CreateInterpolantValue(psWord, vsSemantic), psWord));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceAgcCreateInterpolantMapping_10000(ShaderRegister* regs, const Shader* gs, const Shader* ps) {
|
||||
return CreateInterpolantMapping(__func__, regs, gs, ps, CreateInterpolantValueSplitF16, true);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "prx/libSceAgc/Acb/include/Sync.hpp"
|
||||
#include "prx/libSceAgc/Command/include/Packet.hpp"
|
||||
#include "prx/libSceAgc/Command/include/Memory.hpp"
|
||||
#include "prx/libSceAgc/Acb/include/Memory.hpp"
|
||||
#include "prx/libSceAgc/DcbFlow/include/Memory.hpp"
|
||||
#include "prx/libSceAgc/Command/include/RegisterDefaults.hpp"
|
||||
#include "prx/libc/include/Shutdown.hpp"
|
||||
|
||||
@@ -835,6 +837,45 @@ void testAtomicGds() {
|
||||
}
|
||||
}
|
||||
|
||||
void testCopyDataAndComputeEvents() {
|
||||
Storage graphics;
|
||||
const auto* copy = sceAgcDcbCopyData(&graphics.buffer, 4, 1, 0x1122334450ull, 0xb, 2, 0x12345678u, 0, 1);
|
||||
const std::array<std::uint32_t, 6> graphicsExpected{0xc0044000u, 0x42104205u, 0x12345678u, 0, 0x22334450u, 0x11u};
|
||||
check(copy == graphics.words.data() && std::equal(graphicsExpected.begin(), graphicsExpected.end(), graphics.words.begin()), "graphics COPY_DATA packet mismatch");
|
||||
Storage wide;
|
||||
sceAgcDcbCopyData(&wide.buffer, 4, 0, 0x1000, 0xa, 0, 0x100000000ull, 1, 0);
|
||||
check(wide.words[1] == 0x00010205u && wide.words[2] == 0 && wide.words[3] == 1, "a 64-bit immediate COPY_DATA lost its high word");
|
||||
Storage compute;
|
||||
sceAgcAcbCopyData(&compute.buffer, 2, 0, 0x4000, 5, 0, 7, 0, 0);
|
||||
const std::array<std::uint32_t, 6> computeExpected{0xc0044000u, 0x205u, 7, 0, 0x4000u, 0};
|
||||
check(std::equal(computeExpected.begin(), computeExpected.end(), compute.words.begin()), "compute COPY_DATA packet mismatch");
|
||||
Storage rejected;
|
||||
rejected.words.fill(0xa5a5a5a5u);
|
||||
const auto rejectedWords = rejected.words;
|
||||
const auto* rejectedCursor = rejected.buffer.cursor_up;
|
||||
expectFailure([&] { sceAgcDcbCopyData(&rejected.buffer, 4, 4, 0x1000, 0xa, 0, 1, 0, 0); });
|
||||
check(rejected.words == rejectedWords && rejected.buffer.cursor_up == rejectedCursor, "a refused packet changed the command buffer");
|
||||
expectFailure([&] { sceAgcDcbCopyData(&rejected.buffer, 4, 0, 0x1000, 0xa, 4, 1, 0, 0); });
|
||||
check(rejected.words == rejectedWords && rejected.buffer.cursor_up == rejectedCursor, "a refused packet changed the command buffer");
|
||||
expectFailure([&] { sceAgcAcbCopyData(&rejected.buffer, 2, 0, 0x4000, 5, 0, 1, 2, 0); });
|
||||
check(rejected.words == rejectedWords && rejected.buffer.cursor_up == rejectedCursor, "a refused packet changed the command buffer");
|
||||
expectFailure([&] { sceAgcAcbCopyData(&rejected.buffer, 2, 0, 0x4000, 5, 0, 1, 0, 2); });
|
||||
check(rejected.words == rejectedWords && rejected.buffer.cursor_up == rejectedCursor, "a refused packet changed the command buffer");
|
||||
check(sceAgcDcbCopyDataGetSize() == 24 && sceAgcAcbCopyDataGetSize() == 24, "COPY_DATA packet sizes");
|
||||
Storage events;
|
||||
sceAgcAcbEventWrite(&events.buffer, 7, nullptr);
|
||||
sceAgcAcbEventWrite(&events.buffer, 0x16, nullptr);
|
||||
const std::array<std::uint32_t, 4> eventsExpected{0xc0004600u, 0x407u, 0xc0004600u, 0x16u};
|
||||
check(std::equal(eventsExpected.begin(), eventsExpected.end(), events.words.begin()), "compute EVENT_WRITE packet mismatch");
|
||||
Storage refused;
|
||||
refused.words.fill(0xa5a5a5a5u);
|
||||
const auto refusedWords = refused.words;
|
||||
const auto* refusedCursor = refused.buffer.cursor_up;
|
||||
expectFailure([&] { sceAgcAcbEventWrite(&refused.buffer, 0x40, nullptr); });
|
||||
check(refused.words == refusedWords && refused.buffer.cursor_up == refusedCursor, "a refused packet changed the command buffer");
|
||||
check(sceAgcAcbEventWriteGetSize(7) == 8, "compute EVENT_WRITE packet size");
|
||||
}
|
||||
|
||||
void testDebugRaiseException() {
|
||||
int result = -1;
|
||||
try {
|
||||
@@ -1080,6 +1121,7 @@ int main(int argc, char** argv) {
|
||||
testEndOfPipePatches();
|
||||
testAtomicGds();
|
||||
testDebugRaiseException();
|
||||
testCopyDataAndComputeEvents();
|
||||
testDefaults();
|
||||
testDefaultsTypes();
|
||||
LibcRunShutdown_nid_postfix();
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "prx/libSceAgc/Acb/include/Memory.hpp"
|
||||
#include "prx/libSceAgc/Command/include/Packet.hpp"
|
||||
#include "prx/libSceAgc/DcbFlow/include/Memory.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace {
|
||||
|
||||
struct Storage {
|
||||
std::array<std::uint32_t, 64> words{};
|
||||
CommandBuffer buffer{words.data(), words.data() + words.size(), words.data(), words.data() + words.size(), nullptr, nullptr, 0};
|
||||
};
|
||||
|
||||
void check(bool condition, const char* message) {
|
||||
if (!condition) throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
template <typename TAction>
|
||||
void expectFailure(Storage& storage, TAction action, const char* message) {
|
||||
const auto before = storage.words;
|
||||
const auto* cursor = storage.buffer.cursor_up;
|
||||
try {
|
||||
action();
|
||||
} catch (const std::runtime_error&) {
|
||||
check(storage.words == before && storage.buffer.cursor_up == cursor, message);
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
void testDrawQueueCopy() {
|
||||
Storage storage;
|
||||
const auto* packet = sceAgcDcbCopyData(&storage.buffer, 2, 1, 0x123456789ab0ull, 5, 2, 0xdeadbeef00000010ull, 1, 1);
|
||||
const std::array<std::uint32_t, 6> expected{0xc0044000u, 0x42114102u, 0x10u, 0xdeadbeefu, 0x56789ab0u, 0x1234u};
|
||||
check(packet == storage.words.data() && std::equal(expected.begin(), expected.end(), packet), "DCB COPY_DATA packet mismatch");
|
||||
check(storage.buffer.cursor_up == storage.words.data() + expected.size(), "DCB COPY_DATA cursor advance mismatch");
|
||||
check(sceAgcDcbCopyDataGetSize() == expected.size() * sizeof(std::uint32_t), "DCB COPY_DATA size differs from its packet");
|
||||
expectFailure(storage, [&] { sceAgcDcbCopyData(&storage.buffer, 2, 4, 0x1000, 4, 0, 0x2000, 0, 0); }, "a DCB destination cache policy above 3 was accepted");
|
||||
expectFailure(storage, [&] { sceAgcDcbCopyData(&storage.buffer, 2, 0, 0x1000, 4, 0, 0x2000, 2, 0); }, "a DCB item size above 1 was accepted");
|
||||
expectFailure(storage, [&] { sceAgcDcbCopyData(&storage.buffer, 2, 0, 0x1000, 10, 0, 0x100000000ull, 0, 0); }, "a DCB 32-bit immediate wider than 32 bits was accepted");
|
||||
}
|
||||
|
||||
void testComputeQueueCopy() {
|
||||
Storage storage;
|
||||
const auto* packet = sceAgcAcbCopyData(&storage.buffer, 1, 0, 0x1000, 5, 0, 0x1234, 0, 0);
|
||||
const std::array<std::uint32_t, 6> expected{0xc0044000u, 0x105u, 0x1234u, 0, 0x1000u, 0};
|
||||
check(packet == storage.words.data() && std::equal(expected.begin(), expected.end(), packet), "ACB COPY_DATA packet mismatch");
|
||||
check(storage.buffer.cursor_up == storage.words.data() + expected.size(), "ACB COPY_DATA cursor advance mismatch");
|
||||
check(sceAgcAcbCopyDataGetSize() == expected.size() * sizeof(std::uint32_t), "ACB COPY_DATA size differs from its packet");
|
||||
const auto* wide = sceAgcAcbCopyData(&storage.buffer, 1, 0, 0x1000, 5, 0, 0x100000000ull, 1, 0);
|
||||
check(wide == storage.words.data() + expected.size() && wide[1] == 0x10105u && wide[2] == 0 && wide[3] == 1, "ACB 64-bit immediate COPY_DATA packet mismatch");
|
||||
expectFailure(storage, [&] { sceAgcAcbCopyData(&storage.buffer, 1, 0, 0x1000, 5, 0, 0x100000000ull, 0, 0); }, "an ACB 32-bit immediate wider than 32 bits was accepted");
|
||||
expectFailure(storage, [&] { sceAgcAcbCopyData(&storage.buffer, 1, 0, 0x1000, 5, 0, 0, 0, 2); }, "an ACB write confirm above 1 was accepted");
|
||||
}
|
||||
|
||||
void testWriteDataSize() {
|
||||
Storage storage;
|
||||
const std::array<std::uint32_t, 3> payload{1, 2, 3};
|
||||
const auto* packet = sceAgcDcbWriteData(&storage.buffer, 2, 0, 0x2000, payload.data(), static_cast<std::uint32_t>(payload.size()), 1, 0);
|
||||
const std::array<std::uint32_t, 7> expected{0xc0053700u, 0x10100u, 0x2000u, 0, 1, 2, 3};
|
||||
check(packet == storage.words.data() && std::equal(expected.begin(), expected.end(), packet), "DCB WRITE_DATA packet mismatch");
|
||||
check(sceAgcDcbWriteDataGetSize(static_cast<std::uint32_t>(payload.size())) == expected.size() * sizeof(std::uint32_t), "DCB WRITE_DATA size differs from its packet");
|
||||
check(sceAgcDcbWriteDataGetSize(1) == 20 && sceAgcDcbWriteDataGetSize(0x3ffd) == 0x3ffd * 4 + 16, "DCB WRITE_DATA size is not four header words plus the payload");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
testDrawQueueCopy();
|
||||
testComputeQueueCopy();
|
||||
testWriteDataSize();
|
||||
} catch (const std::exception& error) {
|
||||
std::fprintf(stderr, "%s\n", error.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "prx/libSceAgc/Command/include/Packet.hpp"
|
||||
#include "prx/libSceAgc/DcbDraw/include/DrawIndexed.hpp"
|
||||
#include "prx/libSceAgc/DcbDraw/include/DrawNonIndexed.hpp"
|
||||
#include "prx/libSceAgc/DcbDraw/include/IndexBuffer.hpp"
|
||||
#include "prx/libSceAgc/DcbDraw/include/Instancing.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace {
|
||||
|
||||
struct Storage {
|
||||
std::array<std::uint32_t, 64> words{};
|
||||
CommandBuffer buffer{words.data(), words.data() + words.size(), words.data(), words.data() + words.size(), nullptr, nullptr, 0};
|
||||
};
|
||||
|
||||
void check(bool condition, const char* message) {
|
||||
if (!condition) throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
template <typename TAction>
|
||||
void expectFailure(Storage& storage, TAction action, const char* message) {
|
||||
const auto before = storage.words;
|
||||
const auto* cursor = storage.buffer.cursor_up;
|
||||
try {
|
||||
action();
|
||||
} catch (const std::runtime_error&) {
|
||||
check(storage.words == before && storage.buffer.cursor_up == cursor, message);
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
void expectPacket(const Storage& storage, const std::uint32_t* packet, const std::uint32_t* start, const std::array<std::uint32_t, N>& expected, std::uint32_t size, const char* message) {
|
||||
check(packet == start && std::equal(expected.begin(), expected.end(), packet), message);
|
||||
check(storage.buffer.cursor_up == start + N, message);
|
||||
check(size == N * sizeof(std::uint32_t), message);
|
||||
}
|
||||
|
||||
void testNumInstances() {
|
||||
Storage storage;
|
||||
const auto* packet = sceAgcDcbSetNumInstances(&storage.buffer, 7);
|
||||
expectPacket(storage, packet, storage.words.data(), std::array<std::uint32_t, 2>{0xc0002f00u, 7}, sceAgcDcbSetNumInstancesGetSize(), "NUM_INSTANCES packet mismatch");
|
||||
}
|
||||
|
||||
void testIndexSize() {
|
||||
Storage storage;
|
||||
const auto* packet = sceAgcDcbSetIndexSize(&storage.buffer, 1, 2);
|
||||
expectPacket(storage, packet, storage.words.data(), std::array<std::uint32_t, 3>{0xc0017a00u, 0x20000243u, 0x481u}, sceAgcDcbSetIndexSizeGetSize(), "index size packet mismatch");
|
||||
const auto* objectId = sceAgcDcbSetIndexSize_0600(&storage.buffer, 2, 3, 1);
|
||||
check(objectId == storage.words.data() + 3 && objectId[0] == 0xc0017a00u && objectId[1] == 0x20000243u && objectId[2] == (0x4c2u | 0x4000u), "index size packet with a per-instance object id mismatch");
|
||||
expectFailure(storage, [&] { sceAgcDcbSetIndexSize(&storage.buffer, 3, 0); }, "an index size above 2 was accepted");
|
||||
expectFailure(storage, [&] { sceAgcDcbSetIndexSize(&storage.buffer, 0, 4); }, "a cache policy above 3 was accepted");
|
||||
expectFailure(storage, [&] { sceAgcDcbSetIndexSize_0600(&storage.buffer, 0, 0, 2); }, "a per-instance object id above 1 was accepted");
|
||||
}
|
||||
|
||||
void testDrawIndexOffset() {
|
||||
Storage storage;
|
||||
const auto* packet = sceAgcDcbDrawIndexOffset(&storage.buffer, 12, 36, 0);
|
||||
expectPacket(storage, packet, storage.words.data(), std::array<std::uint32_t, 5>{0xc0033500u, 36, 12, 36, 0}, sceAgcDcbDrawIndexOffsetGetSize(), "DRAW_INDEX_OFFSET_2 packet mismatch");
|
||||
const auto* empty = sceAgcDcbDrawIndexOffset(&storage.buffer, 0, 0, 0);
|
||||
check(empty == storage.words.data() + 5 && empty[1] == 1 && empty[3] == 0, "an empty indexed offset draw did not keep a maximum size of one");
|
||||
}
|
||||
|
||||
void testDrawIndirect() {
|
||||
Storage storage;
|
||||
const auto* packet = sceAgcDcbDrawIndirect(&storage.buffer, 0x40, 0);
|
||||
expectPacket(storage, packet, storage.words.data(), std::array<std::uint32_t, 5>{0xc0032400u, 0x40, 0x280, 0x280, 2}, sceAgcDcbDrawIndirectGetSize(), "DRAW_INDIRECT packet mismatch");
|
||||
expectFailure(storage, [&] { sceAgcDcbDrawIndirect(&storage.buffer, 2, 0); }, "a misaligned indirect argument offset was accepted");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
testNumInstances();
|
||||
testIndexSize();
|
||||
testDrawIndexOffset();
|
||||
testDrawIndirect();
|
||||
} catch (const std::exception& error) {
|
||||
std::fprintf(stderr, "%s\n", error.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,81 @@ void testUpdateMapping() {
|
||||
check(update[1].value == 0x01380007u && update[3].value == 0x03680409u, "f16 DEFAULT_VAL does not come from the low default");
|
||||
}
|
||||
|
||||
void testUpdate0100Mapping() {
|
||||
const auto mappingsBefore = mappings;
|
||||
const auto linksBefore = links;
|
||||
Shader ps{};
|
||||
auto regs = filled();
|
||||
const auto untouched = filled();
|
||||
check(sceAgcUpdateInterpolantMapping_0100(regs.data(), nullptr, &ps) == 0, "_0100 update without inputs failed");
|
||||
check(std::memcmp(regs.data(), untouched.data(), sizeof(regs)) == 0, "_0100 update without inputs wrote registers");
|
||||
|
||||
std::array<ShaderSemantic, 4> inputs{semantic(1, 0, 0), semantic(2, 0, 1), semantic(3, 0, 2), semantic(4, 0, 3)};
|
||||
inputs[0].is_custom = 1;
|
||||
inputs[0].default_value = 2;
|
||||
inputs[1].default_value = 1;
|
||||
inputs[1].default_value_hi = 1;
|
||||
inputs[2].default_value_hi = 2;
|
||||
inputs[3].is_custom = 1;
|
||||
inputs[3].default_value = 3;
|
||||
inputs[3].default_value_hi = 3;
|
||||
std::array<ShaderSemantic, 3> outputs{semantic(1, 5, 0), semantic(2, 7, 1), semantic(4, 9, 3)};
|
||||
Shader vs{};
|
||||
vs.output_semantics = outputs.data();
|
||||
vs.num_output_semantics = static_cast<std::uint16_t>(outputs.size());
|
||||
ps.input_semantics = inputs.data();
|
||||
ps.num_input_semantics = static_cast<std::uint32_t>(inputs.size());
|
||||
|
||||
regs = filled();
|
||||
check(sceAgcUpdateInterpolantMapping_0100(regs.data(), &vs, &ps) == 0, "_0100 update mapping failed");
|
||||
check(regs[0].value == 0x00000625u, "_0100 update does not encode default value 2");
|
||||
check(regs[1].value == 0x01380107u, "_0100 update does not encode default value 1");
|
||||
check(regs[2].value == 0x02580020u, "_0100 unmatched interpolant update changed");
|
||||
check(regs[3].value == 0x03680709u, "_0100 full f16 interpolant update changed");
|
||||
for (std::uint32_t i = 0; i < inputs.size(); ++i) {
|
||||
check(regs[i].offset == ShaderRegs::SPI_PS_INPUT_CNTL_0 + i, "_0100 update register offset changed");
|
||||
}
|
||||
const std::size_t written = inputs.size() * sizeof(ShaderRegister);
|
||||
check(std::memcmp(regs.data() + inputs.size(), untouched.data(), sizeof(regs) - written) == 0, "_0100 update wrote past its inputs");
|
||||
check(mappings == mappingsBefore && links == linksBefore, "_0100 update resolved an ABI");
|
||||
}
|
||||
|
||||
void testUpdate0100Boundary() {
|
||||
const auto mappingsBefore = mappings;
|
||||
const auto linksBefore = links;
|
||||
std::array<ShaderSemantic, 32> inputs{};
|
||||
std::array<ShaderSemantic, 32> outputs{};
|
||||
for (std::uint32_t i = 0; i < inputs.size(); ++i) {
|
||||
inputs[i] = semantic(i + 1u, 0, 0);
|
||||
inputs[i].default_value = i % 4u;
|
||||
outputs[i] = semantic(inputs.size() - i, i, 0);
|
||||
}
|
||||
Shader ps{};
|
||||
ps.input_semantics = inputs.data();
|
||||
ps.num_input_semantics = static_cast<std::uint32_t>(inputs.size());
|
||||
Shader vs{};
|
||||
std::array<ShaderRegister, 33> regs{};
|
||||
std::memset(regs.data(), 0xcc, sizeof(regs));
|
||||
const auto untouched = regs;
|
||||
check(sceAgcUpdateInterpolantMapping_0100(regs.data(), &vs, &ps) == 0, "_0100 update rejected a producer without outputs");
|
||||
constexpr std::array<std::uint32_t, 4> defaults{0x000u, 0x100u, 0x200u, 0x300u};
|
||||
for (std::uint32_t i = 0; i < inputs.size(); ++i) {
|
||||
check(regs[i].offset == ShaderRegs::SPI_PS_INPUT_CNTL_0 + i, "_0100 full default mapping register offset changed");
|
||||
check(regs[i].value == (0x20u | defaults[i % 4u]), "_0100 full default mapping changed");
|
||||
}
|
||||
check(std::memcmp(®s.back(), &untouched.back(), sizeof(ShaderRegister)) == 0, "_0100 full default mapping wrote past 32 inputs");
|
||||
vs.output_semantics = outputs.data();
|
||||
vs.num_output_semantics = static_cast<std::uint16_t>(outputs.size());
|
||||
regs = untouched;
|
||||
check(sceAgcUpdateInterpolantMapping_0100(regs.data(), &vs, &ps) == 0, "_0100 update rejected 32 matched inputs");
|
||||
for (std::uint32_t i = 0; i < inputs.size(); ++i) {
|
||||
check(regs[i].offset == ShaderRegs::SPI_PS_INPUT_CNTL_0 + i, "_0100 full matched mapping register offset changed");
|
||||
check(regs[i].value == ((31u - i) | defaults[i % 4u]), "_0100 full matched mapping changed");
|
||||
}
|
||||
check(std::memcmp(®s.back(), &untouched.back(), sizeof(ShaderRegister)) == 0, "_0100 full matched mapping wrote past 32 inputs");
|
||||
check(mappings == mappingsBefore && links == linksBefore, "_0100 full mapping resolved an ABI");
|
||||
}
|
||||
|
||||
void testUnversionedMapping() {
|
||||
std::array<ShaderSemantic, 5> inputs{
|
||||
semantic(1, 0, 2), semantic(2, 0, 2), semantic(5, 0, 2), semantic(3, 0, 0), semantic(4, 0, 3)};
|
||||
@@ -207,6 +282,7 @@ void testRejections() {
|
||||
std::memset(regs.data(), 0xcc, sizeof(regs));
|
||||
const auto saved = regs;
|
||||
expectFailure([&] { sceAgcCreateInterpolantMapping_0100(regs.data(), &gs, &ps); });
|
||||
expectFailure([&] { sceAgcUpdateInterpolantMapping_0100(regs.data(), &gs, &ps); });
|
||||
expectFailure([&] { sceAgcCreateInterpolantMapping_10000(regs.data(), &gs, &ps); });
|
||||
expectFailure([&] { sceAgcUpdateInterpolantMapping_10000(regs.data(), &gs, &ps); });
|
||||
check(std::memcmp(regs.data(), saved.data(), sizeof(regs)) == 0, "rejected mapping wrote registers");
|
||||
@@ -216,6 +292,15 @@ void testRejections() {
|
||||
expectFailure([&] { sceAgcUpdateInterpolantMapping_10000(regs.data(), nullptr, &ps); });
|
||||
expectFailure([&] { sceAgcUpdateInterpolantMapping_10000(nullptr, &gs, &ps); });
|
||||
expectFailure([&] { sceAgcUpdateInterpolantMapping_10000(regs.data(), &gs, nullptr); });
|
||||
expectFailure([&] { sceAgcUpdateInterpolantMapping_0100(regs.data(), nullptr, &ps); });
|
||||
expectFailure([&] { sceAgcUpdateInterpolantMapping_0100(nullptr, &gs, &ps); });
|
||||
expectFailure([&] { sceAgcUpdateInterpolantMapping_0100(regs.data(), &gs, nullptr); });
|
||||
ps.input_semantics = nullptr;
|
||||
expectFailure([&] { sceAgcUpdateInterpolantMapping_0100(regs.data(), &gs, &ps); });
|
||||
ps.input_semantics = inputs.data();
|
||||
gs.output_semantics = nullptr;
|
||||
gs.num_output_semantics = 1;
|
||||
expectFailure([&] { sceAgcUpdateInterpolantMapping_0100(regs.data(), &gs, &ps); });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -238,6 +323,8 @@ int main() {
|
||||
testIdentity();
|
||||
testMapping();
|
||||
testUpdateMapping();
|
||||
testUpdate0100Mapping();
|
||||
testUpdate0100Boundary();
|
||||
testUnversionedMapping();
|
||||
testRejections();
|
||||
check(mappings == 10u && links == 8u, "mapping preparation call count changed");
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "prx/libSceAgc/Acb/include/Sync.hpp"
|
||||
#include "prx/libSceAgc/Cb/include/Sync.hpp"
|
||||
#include "prx/libSceAgc/Command/include/Packet.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace {
|
||||
|
||||
struct Storage {
|
||||
std::array<std::uint32_t, 64> words{};
|
||||
CommandBuffer buffer{words.data(), words.data() + words.size(), words.data(), words.data() + words.size(), nullptr, nullptr, 0};
|
||||
};
|
||||
|
||||
void check(bool condition, const char* message) {
|
||||
if (!condition) throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
template <typename TAction>
|
||||
void expectFailure(Storage& storage, TAction action, const char* message) {
|
||||
const auto before = storage.words;
|
||||
const auto* cursor = storage.buffer.cursor_up;
|
||||
try {
|
||||
action();
|
||||
} catch (const std::runtime_error&) {
|
||||
check(storage.words == before && storage.buffer.cursor_up == cursor, message);
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
void testNop() {
|
||||
Storage storage;
|
||||
storage.words.fill(0xaaaaaaaau);
|
||||
const auto* single = sceAgcCbNop_nid_postfix(&storage.buffer, 1);
|
||||
check(single == storage.words.data() && single[0] == 0xffff1000u && storage.words[1] == 0xaaaaaaaau, "one-dword NOP packet mismatch");
|
||||
check(sceAgcCbNopGetSize(1) == sizeof(std::uint32_t), "one-dword NOP size mismatch");
|
||||
const auto* padding = sceAgcCbNop_nid_postfix(&storage.buffer, 4);
|
||||
const std::array<std::uint32_t, 4> expected{0xc0021000u, 0, 0, 0};
|
||||
check(padding == storage.words.data() + 1 && std::equal(expected.begin(), expected.end(), padding), "four-dword NOP packet mismatch");
|
||||
check(storage.buffer.cursor_up == storage.words.data() + 5 && storage.words[5] == 0xaaaaaaaau, "NOP cursor advance mismatch");
|
||||
check(sceAgcCbNopGetSize(4) == expected.size() * sizeof(std::uint32_t), "four-dword NOP size mismatch");
|
||||
expectFailure(storage, [&] { sceAgcCbNop_nid_postfix(&storage.buffer, 0); }, "an empty NOP was accepted");
|
||||
}
|
||||
|
||||
void testComputeEventWrite() {
|
||||
Storage storage;
|
||||
const auto* packet = sceAgcAcbEventWrite(&storage.buffer, 0x16, nullptr);
|
||||
check(packet == storage.words.data() && packet[0] == 0xc0004600u && packet[1] == 0x16u, "ACB EVENT_WRITE packet mismatch");
|
||||
check(sceAgcAcbEventWriteGetSize(0x16) == 2 * sizeof(std::uint32_t), "ACB EVENT_WRITE size differs from its packet");
|
||||
const auto* flush = sceAgcAcbEventWrite(&storage.buffer, 7, nullptr);
|
||||
check(flush == storage.words.data() + 2 && flush[0] == 0xc0004600u && flush[1] == 0x407u, "ACB CS_PARTIAL_FLUSH does not carry event index 4");
|
||||
check(storage.buffer.cursor_up == storage.words.data() + 4, "ACB EVENT_WRITE cursor advance mismatch");
|
||||
expectFailure(storage, [&] { sceAgcAcbEventWrite(&storage.buffer, 0x40, nullptr); }, "an ACB event type above 0x3f was accepted");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
testNop();
|
||||
testComputeEventWrite();
|
||||
} catch (const std::exception& error) {
|
||||
std::fprintf(stderr, "%s\n", error.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "prx/libSceAgc/Misc/include/StaticBuffer.hpp"
|
||||
#include "prx/libc/include/GuestArena.hpp"
|
||||
#ifdef __APPLE__
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/DriverMemory.hpp"
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
@@ -9,7 +12,11 @@
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef __APPLE__
|
||||
constexpr std::uintptr_t StaticTable = AgcDriver::DriverDetail::RetargetPs5DriverMemory(0xfe0040000ull) + GuestArena::GuestAddressOffset;
|
||||
#else
|
||||
constexpr std::uintptr_t StaticTable = 0xfe0040000ull + GuestArena::GuestAddressOffset;
|
||||
#endif
|
||||
constexpr int InvalidStaticBuffer = static_cast<int>(0x8a6c000bu);
|
||||
|
||||
void check(bool condition, const char* message) {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
if(BUILD_TESTING)
|
||||
add_test_executable(agc_preparation_inputs_tests
|
||||
tests/PreparationInputs.cpp
|
||||
Execution/src/Driver/Shaders/ShaderDiagnostics.cpp
|
||||
${CMAKE_SOURCE_DIR}/core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp)
|
||||
target_include_directories(agc_preparation_inputs_tests PRIVATE
|
||||
${LIBS_INCLUDE_DIR}
|
||||
$<TARGET_PROPERTY:shader_recompiler_agc_driver,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
${ANYPS5_VULKAN_HEADERS_INCLUDE_DIR})
|
||||
target_link_libraries(agc_preparation_inputs_tests PRIVATE libc)
|
||||
configure_windows_unwind(agc_preparation_inputs_tests)
|
||||
foreach(mode enabled disabled selected failure concurrent write-failure capture-write-failure)
|
||||
add_test(NAME agc_preparation_inputs_${mode} COMMAND agc_preparation_inputs_tests ${mode})
|
||||
set_tests_properties(agc_preparation_inputs_${mode} PROPERTIES TIMEOUT 20)
|
||||
if(WIN32)
|
||||
set_tests_properties(agc_preparation_inputs_${mode} PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
function(ensure_agc_glslang)
|
||||
if(TARGET glslang AND TARGET SPIRV AND TARGET glslang-standalone)
|
||||
return()
|
||||
@@ -31,6 +52,16 @@ endfunction()
|
||||
|
||||
ensure_agc_glslang()
|
||||
|
||||
if(BUILD_TESTING AND WIN32)
|
||||
add_test_executable(agc_process_sampler_stack_tests tests/ProcessSamplerStack.cpp Execution/src/WorkerSampler.cpp)
|
||||
target_include_directories(agc_process_sampler_stack_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(agc_process_sampler_stack_tests PRIVATE libc)
|
||||
configure_windows_unwind(agc_process_sampler_stack_tests)
|
||||
add_test(NAME agc_process_sampler_stack COMMAND agc_process_sampler_stack_tests)
|
||||
set_tests_properties(agc_process_sampler_stack PROPERTIES TIMEOUT 20 ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
|
||||
set(agcTextureDetileShaderSource ${CMAKE_CURRENT_SOURCE_DIR}/Graphics/shaders/TextureDetile.comp)
|
||||
set(agcTextureDetileGeneratedRoot ${CMAKE_CURRENT_BINARY_DIR}/generated)
|
||||
set(agcTextureDetileGeneratedDir ${agcTextureDetileGeneratedRoot}/prx/libSceAgcDriver/Graphics/shaders)
|
||||
@@ -56,6 +87,28 @@ add_custom_command(
|
||||
DEPENDS "${agcTextureDetileShaderSource}" glslang-standalone
|
||||
VERBATIM
|
||||
)
|
||||
set(agcTextureDetileWordsShaderSpv ${agcTextureDetileGeneratedDir}/TextureDetileWords.spv)
|
||||
set(agcTextureDetileWordsShaderHeader ${agcTextureDetileGeneratedDir}/TextureDetileWords_spv.h)
|
||||
add_custom_command(
|
||||
OUTPUT "${agcTextureDetileWordsShaderHeader}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${agcTextureDetileGeneratedDir}"
|
||||
COMMAND "$<TARGET_FILE:glslang-standalone>" -V --target-env vulkan1.1 -DWORD_GROUPS=1 -o "${agcTextureDetileWordsShaderSpv}" "${agcTextureDetileShaderSource}"
|
||||
COMMAND ${CMAKE_COMMAND} -DINPUT=${agcTextureDetileWordsShaderSpv} -DOUTPUT=${agcTextureDetileWordsShaderHeader}
|
||||
-DSYMBOL=TEXTURE_DETILE_WORDS_SPV -P "${CMAKE_CURRENT_SOURCE_DIR}/embed_spirv.cmake"
|
||||
DEPENDS "${agcTextureDetileShaderSource}" glslang-standalone
|
||||
VERBATIM
|
||||
)
|
||||
set(agcTextureDetileImageWordsShaderSpv ${agcTextureDetileGeneratedDir}/TextureDetileImageWords.spv)
|
||||
set(agcTextureDetileImageWordsShaderHeader ${agcTextureDetileGeneratedDir}/TextureDetileImageWords_spv.h)
|
||||
add_custom_command(
|
||||
OUTPUT "${agcTextureDetileImageWordsShaderHeader}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${agcTextureDetileGeneratedDir}"
|
||||
COMMAND "$<TARGET_FILE:glslang-standalone>" -V --target-env vulkan1.1 -DLINEAR_IMAGE=1 -DWORD_GROUPS=1 -o "${agcTextureDetileImageWordsShaderSpv}" "${agcTextureDetileShaderSource}"
|
||||
COMMAND ${CMAKE_COMMAND} -DINPUT=${agcTextureDetileImageWordsShaderSpv} -DOUTPUT=${agcTextureDetileImageWordsShaderHeader}
|
||||
-DSYMBOL=TEXTURE_DETILE_IMAGE_WORDS_SPV -P "${CMAKE_CURRENT_SOURCE_DIR}/embed_spirv.cmake"
|
||||
DEPENDS "${agcTextureDetileShaderSource}" glslang-standalone
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(agcMeshArgumentsShaderSource ${CMAKE_CURRENT_SOURCE_DIR}/Graphics/shaders/MeshArguments.comp)
|
||||
foreach(agcReadbackKind IN ITEMS Uint Depth)
|
||||
@@ -103,6 +156,19 @@ add_custom_command(
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(agcStagingCopyBackShaderSource ${CMAKE_CURRENT_SOURCE_DIR}/Graphics/shaders/StagingCopyBack.comp)
|
||||
set(agcStagingCopyBackShaderSpv ${agcTextureDetileGeneratedDir}/StagingCopyBack.spv)
|
||||
set(agcStagingCopyBackShaderHeader ${agcTextureDetileGeneratedDir}/StagingCopyBack_spv.h)
|
||||
add_custom_command(
|
||||
OUTPUT "${agcStagingCopyBackShaderHeader}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${agcTextureDetileGeneratedDir}"
|
||||
COMMAND "$<TARGET_FILE:glslang-standalone>" -V --target-env vulkan1.1 -o "${agcStagingCopyBackShaderSpv}" "${agcStagingCopyBackShaderSource}"
|
||||
COMMAND ${CMAKE_COMMAND} -DINPUT=${agcStagingCopyBackShaderSpv} -DOUTPUT=${agcStagingCopyBackShaderHeader}
|
||||
-DSYMBOL=STAGING_COPY_BACK_SPV -P "${CMAKE_CURRENT_SOURCE_DIR}/embed_spirv.cmake"
|
||||
DEPENDS "${agcStagingCopyBackShaderSource}" glslang-standalone
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(agcCmaskClearShaderSource ${CMAKE_CURRENT_SOURCE_DIR}/Graphics/shaders/CmaskClear.comp)
|
||||
set(agcCmaskClearShaderSpv ${agcTextureDetileGeneratedDir}/CmaskClear.spv)
|
||||
set(agcCmaskClearShaderHeader ${agcTextureDetileGeneratedDir}/CmaskClear_spv.h)
|
||||
@@ -344,7 +410,9 @@ set(agcDriverSources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Graphics/src/ShaderResources.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Graphics/src/ShaderAddressResources.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Graphics/src/GuestBufferMemory.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Graphics/src/MapImportGate.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Graphics/src/ResidentMirror.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Graphics/src/ReferenceStorage.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Graphics/src/BdaResources.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Graphics/src/BufferAddress.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Graphics/src/ShaderValidation.cpp
|
||||
@@ -370,9 +438,12 @@ set(agcDriverSources
|
||||
${agcMultisampleUploadHeader}
|
||||
${agcCmaskClearShaderHeader}
|
||||
${agcMeshArgumentsShaderHeader}
|
||||
${agcStagingCopyBackShaderHeader}
|
||||
${agcTextureDetileImageShaderHeader}
|
||||
${agcTextureRepackShaderHeader}
|
||||
${agcDispatchArgumentsShaderHeader}
|
||||
${agcTextureDetileWordsShaderHeader}
|
||||
${agcTextureDetileImageWordsShaderHeader}
|
||||
${agcSampleCounterShaderHeader}
|
||||
${agcSampleDumpsShaderHeader}
|
||||
${agcPresentationShaderHeaders}
|
||||
@@ -398,6 +469,7 @@ set(agcZlibIncludeDir ${CMAKE_SOURCE_DIR}/3rdparty/libjpeg-turbo/src/spng/zlib)
|
||||
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/Execution/src/TraceFile.cpp PROPERTIES
|
||||
INCLUDE_DIRECTORIES ${agcZlibIncludeDir}
|
||||
)
|
||||
set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Execution/src/VulkanDevice.cpp APPEND PROPERTY COMPILE_DEFINITIONS VK_ENABLE_BETA_EXTENSIONS)
|
||||
|
||||
add_library(libSceAgcDriver SHARED EXCLUDE_FROM_ALL
|
||||
${agcDriverSources}
|
||||
@@ -423,6 +495,10 @@ add_shader_recompiler(shader_recompiler_agc_driver libc
|
||||
${agcShaderCacheGuardSources}
|
||||
)
|
||||
|
||||
target_include_directories(libSceAgcDriver INTERFACE
|
||||
$<TARGET_PROPERTY:shader_recompiler_agc_driver,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
target_link_libraries(libSceAgcDriver PRIVATE
|
||||
shader_recompiler_agc_driver
|
||||
decoder_png
|
||||
@@ -662,12 +738,14 @@ foreach(agcTestFragment IN LISTS agcTestFragments)
|
||||
include(${agcTestFragment})
|
||||
endforeach()
|
||||
|
||||
target_include_directories(agc_driver_gcn_compare_exec_writes_tests PRIVATE $<TARGET_PROPERTY:shader_recompiler_agc_driver,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
set_tests_properties(agc_driver_msaa_dcc_state ${multisampledDccClearTests} PROPERTIES
|
||||
ENVIRONMENT "ANYPS5_NO_SHADER_CACHE=1" TIMEOUT 30 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
|
||||
set_tests_properties(${multisampledDccClearTests} PROPERTIES SKIP_RETURN_CODE 77)
|
||||
if(WIN32)
|
||||
set_tests_properties(agc_driver_dithered_alpha_to_coverage agc_driver_two_sample_dithered_alpha_to_coverage ${multisampledDccClearTests} PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
set_tests_properties(agc_driver_dithered_alpha_to_coverage agc_driver_two_sample_dithered_alpha_to_coverage agc_driver_alpha_to_coverage_sample_mask_export agc_driver_two_sample_alpha_to_coverage_sample_mask_export ${multisampledDccClearTests} PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
endif()
|
||||
@@ -898,6 +976,22 @@ target_link_libraries(agc_compute_pipeline_replay PRIVATE libSceAgcDriver libc)
|
||||
set_target_properties(agc_compute_pipeline_replay PROPERTIES CXX_EXTENSIONS OFF)
|
||||
configure_windows_unwind(agc_compute_pipeline_replay)
|
||||
|
||||
add_library(agc_oracle_support STATIC tools/OracleCodeObject.cpp tools/OracleDispatch.cpp)
|
||||
target_include_directories(agc_oracle_support PUBLIC
|
||||
${LIBS_INCLUDE_DIR}
|
||||
$<TARGET_PROPERTY:shader_recompiler_agc_driver,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
${CMAKE_SOURCE_DIR}/core/shader/recompiler
|
||||
${ANYPS5_VULKAN_HEADERS_INCLUDE_DIR}
|
||||
${ANYPS5_SPIRV_HEADERS_INCLUDE_DIR}
|
||||
)
|
||||
target_link_libraries(agc_oracle_support PUBLIC libSceAgcDriver libc)
|
||||
set_target_properties(agc_oracle_support PROPERTIES CXX_EXTENSIONS OFF)
|
||||
|
||||
add_executable(agc_oracle_runner EXCLUDE_FROM_ALL tools/OracleRunner.cpp)
|
||||
target_link_libraries(agc_oracle_runner PRIVATE agc_oracle_support)
|
||||
set_target_properties(agc_oracle_runner PROPERTIES CXX_EXTENSIONS OFF)
|
||||
configure_windows_unwind(agc_oracle_runner)
|
||||
|
||||
if(BUILD_TESTING AND ANYPS5_ENABLE_SPIRV_TOOLS)
|
||||
add_test(NAME agc_compute_pipeline_inspection COMMAND ${CMAKE_COMMAND}
|
||||
-DREPLAY=$<TARGET_FILE:agc_compute_pipeline_replay>
|
||||
@@ -910,8 +1004,29 @@ if(BUILD_TESTING AND ANYPS5_ENABLE_SPIRV_TOOLS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test(NAME agc_driver_fill_completion_labels_cpu_overlap COMMAND agc_driver_fill_completion_labels_tests --cpu-overlap)
|
||||
add_test(NAME agc_driver_fill_completion_labels_cpu_disjoint COMMAND agc_driver_fill_completion_labels_tests --cpu-disjoint)
|
||||
add_test(NAME agc_driver_fill_completion_labels_submitted COMMAND agc_driver_fill_completion_labels_tests --submitted)
|
||||
add_test(NAME agc_driver_fill_completion_labels_inline COMMAND agc_driver_fill_completion_labels_tests)
|
||||
add_test(NAME agc_driver_fill_completion_labels_chain COMMAND agc_driver_fill_completion_labels_tests)
|
||||
add_test(NAME agc_driver_fill_completion_labels_late COMMAND agc_driver_fill_completion_labels_tests)
|
||||
set(agcFillCompletionLabelTests agc_driver_fill_completion_labels agc_driver_fill_completion_labels_cpu_overlap agc_driver_fill_completion_labels_cpu_disjoint agc_driver_fill_completion_labels_submitted agc_driver_fill_completion_labels_inline agc_driver_fill_completion_labels_chain agc_driver_fill_completion_labels_late)
|
||||
set_tests_properties(${agcFillCompletionLabelTests} PROPERTIES
|
||||
ENVIRONMENT "ANYPS5_NO_SHADER_CACHE=1;APS5_NO_OPPORTUNISTIC_REAP=1" SKIP_RETURN_CODE 77 TIMEOUT 30 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
|
||||
set_property(TEST agc_driver_fill_completion_labels_inline APPEND PROPERTY ENVIRONMENT "APS5_LABEL_RUNS_INLINE=1")
|
||||
set_property(TEST agc_driver_fill_completion_labels_chain APPEND PROPERTY ENVIRONMENT "APS5_FILL_CHAIN=1")
|
||||
set_property(TEST agc_driver_fill_completion_labels_late APPEND PROPERTY ENVIRONMENT "APS5_LABEL_TRUST_LATE=1")
|
||||
if(WIN32)
|
||||
set_tests_properties(agc_driver_fill_completion_labels_cpu_overlap agc_driver_fill_completion_labels_cpu_disjoint agc_driver_fill_completion_labels_submitted agc_driver_fill_completion_labels_inline agc_driver_fill_completion_labels_chain agc_driver_fill_completion_labels_late PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
get_directory_property(agcRegisteredTests TESTS)
|
||||
list(FILTER agcRegisteredTests EXCLUDE REGEX "^(agc_pipeline_journal(_long_paths|_extended_paths)?|agc_driver_pipeline_journal|agc_pipeline_store_replay_growth)$")
|
||||
set_property(TEST ${agcRegisteredTests} APPEND PROPERTY ENVIRONMENT "APS5_NO_PIPELINE_JOURNAL=1")
|
||||
endif()
|
||||
|
||||
target_sources(agc_driver_scattered_runs_tests PRIVATE tests/AllocationFailure.cpp)
|
||||
@@ -54,13 +54,14 @@ int AddEvent(KernelEqueue eq, std::uint32_t queue, std::uintptr_t ident, void* u
|
||||
}
|
||||
|
||||
int DeleteEvent(KernelEqueue eq, std::uintptr_t ident, const char* caller) {
|
||||
{
|
||||
std::lock_guard lock(g_mutex);
|
||||
std::erase_if(g_registrations, [&](const Registration& r) { return r.eq == eq && r.ident == ident; });
|
||||
if (eq == 0 || !EqueuePin_nid_postfix(eq)) {
|
||||
throw std::runtime_error(std::string(caller) + ": invalid event queue");
|
||||
}
|
||||
if (EqueueDeleteEvent_nid_postfix(eq, ident, EvfiltGraphicsCore) != EQUEUE_OK) {
|
||||
throw std::runtime_error(std::string(caller) + ": event is not registered");
|
||||
}
|
||||
std::lock_guard lock(g_mutex);
|
||||
std::erase_if(g_registrations, [&](const Registration& r) { return r.eq == eq && r.ident == ident; });
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -85,10 +86,16 @@ bool AgcDriverDeliverEopInterrupt(std::uint32_t queue) {
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI sceAgcDriverAddEqEvent(KernelEqueue eq, int id, void* udata) {
|
||||
if (id < 0) {
|
||||
throw std::runtime_error(std::string(__func__) + ": negative event id");
|
||||
}
|
||||
return AddEvent(eq, static_cast<std::uint32_t>(id), static_cast<std::uintptr_t>(id), udata, __func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceAgcDriverDeleteEqEvent(KernelEqueue eq, int id) {
|
||||
if (id < 0) {
|
||||
throw std::runtime_error(std::string(__func__) + ": negative event id");
|
||||
}
|
||||
return DeleteEvent(eq, static_cast<std::uintptr_t>(id), __func__);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_BDAATOMICS_HPP
|
||||
#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_BDAATOMICS_HPP
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace AgcDriver {
|
||||
|
||||
inline bool BdaAtomicsUsable(VkDriverId driver) {
|
||||
return driver != VK_DRIVER_ID_MOLTENVK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
@@ -31,8 +30,11 @@ public:
|
||||
if (!Enabled()) return;
|
||||
std::array<char, 2048> line{};
|
||||
const auto size = std::snprintf(line.data(), line.size(), format, args...);
|
||||
if (size < 0 || static_cast<std::size_t>(size) >= line.size()) throw std::runtime_error("Capture trace event exceeds 2047 bytes");
|
||||
static CaptureTrace& trace = instance();
|
||||
if (size < 0 || static_cast<std::size_t>(size) >= line.size()) {
|
||||
trace.drop();
|
||||
return;
|
||||
}
|
||||
trace.append(std::string(line.data(), static_cast<std::size_t>(size)));
|
||||
}
|
||||
|
||||
@@ -45,6 +47,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
friend struct CaptureTraceTestAccess;
|
||||
|
||||
static CaptureTrace& instance() {
|
||||
static CaptureTrace trace;
|
||||
return trace;
|
||||
@@ -57,7 +61,7 @@ private:
|
||||
std::fprintf(stderr, "Capture trace open failed for %s\n", path);
|
||||
return;
|
||||
}
|
||||
output.exceptions(std::ios::badbit | std::ios::failbit);
|
||||
active = true;
|
||||
worker = std::thread([this] { run(); });
|
||||
}
|
||||
|
||||
@@ -71,33 +75,72 @@ private:
|
||||
}
|
||||
|
||||
void append(std::string line) {
|
||||
if (!output.is_open()) return;
|
||||
const auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count();
|
||||
std::lock_guard lock(mutex);
|
||||
if (pending.size() + line.size() + 64 > 16 * 1024 * 1024) throw std::runtime_error("Capture trace queue exceeded 16 MiB");
|
||||
pending += std::to_string(++sequence) + " " + std::to_string(elapsed) + "us " + line + "\n";
|
||||
if (!active || stopping) return;
|
||||
if (droppedPending != 0 || pending.size() + line.size() + 64 > 16 * 1024 * 1024) {
|
||||
++droppedPending;
|
||||
++droppedTotal;
|
||||
return;
|
||||
}
|
||||
appendRecord(pending, line);
|
||||
if (line.starts_with("blit ")) flushRequested = true;
|
||||
if (pending.size() >= 65536 || flushRequested) changed.notify_one();
|
||||
}
|
||||
|
||||
void drop() {
|
||||
std::lock_guard lock(mutex);
|
||||
if (!active || stopping) return;
|
||||
++droppedPending;
|
||||
++droppedTotal;
|
||||
}
|
||||
|
||||
void appendRecord(std::string& destination, const std::string& line) {
|
||||
const auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count();
|
||||
destination += std::to_string(++sequence) + " " + std::to_string(elapsed) + "us " + line + "\n";
|
||||
}
|
||||
|
||||
void fail(const char* reason) {
|
||||
unsigned long long dropped;
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
active = false;
|
||||
pending.clear();
|
||||
dropped = droppedTotal;
|
||||
}
|
||||
std::fprintf(stderr, "Capture trace failed: %s (dropped records: %llu)\n", reason, dropped);
|
||||
}
|
||||
|
||||
void run() {
|
||||
try {
|
||||
for (;;) {
|
||||
std::string batch;
|
||||
{
|
||||
std::unique_lock lock(mutex);
|
||||
changed.wait_for(lock, std::chrono::milliseconds(100), [this] { return stopping || flushRequested || pending.size() >= 65536; });
|
||||
if (stopping && pending.empty()) return;
|
||||
batch.swap(pending);
|
||||
flushRequested = false;
|
||||
for (;;) {
|
||||
std::string batch;
|
||||
bool stop;
|
||||
{
|
||||
std::unique_lock lock(mutex);
|
||||
changed.wait_for(lock, std::chrono::milliseconds(100), [this] { return stopping || flushRequested || pending.size() >= 65536; });
|
||||
batch.swap(pending);
|
||||
if (droppedPending != 0) {
|
||||
appendRecord(batch, "capture-trace-dropped records=" + std::to_string(droppedPending));
|
||||
droppedPending = 0;
|
||||
}
|
||||
flushRequested = false;
|
||||
stop = stopping;
|
||||
if (stop) {
|
||||
appendRecord(batch, "capture-trace-summary dropped=" + std::to_string(droppedTotal));
|
||||
active = false;
|
||||
}
|
||||
if (batch.empty()) continue;
|
||||
output.write(batch.data(), static_cast<std::streamsize>(batch.size()));
|
||||
output.flush();
|
||||
}
|
||||
} catch (const std::exception& error) {
|
||||
std::fprintf(stderr, "Capture trace failed: %s\n", error.what());
|
||||
std::terminate();
|
||||
if (batch.empty()) continue;
|
||||
output.write(batch.data(), static_cast<std::streamsize>(batch.size()));
|
||||
if (!output) {
|
||||
fail("write failed");
|
||||
return;
|
||||
}
|
||||
output.flush();
|
||||
if (!output) {
|
||||
fail("flush failed");
|
||||
return;
|
||||
}
|
||||
if (stop) return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +151,9 @@ private:
|
||||
std::thread worker;
|
||||
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
|
||||
unsigned long long sequence = 0;
|
||||
unsigned long long droppedPending = 0;
|
||||
unsigned long long droppedTotal = 0;
|
||||
bool active = false;
|
||||
bool stopping = false;
|
||||
bool flushRequested = false;
|
||||
};
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Shaders/ShaderRegistry.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Recipe.hpp"
|
||||
#include "prx/libc/include/GuestAllocations.hpp"
|
||||
#include "IntermediateRepresentation/IrMetadata/ResourcePlan.hpp"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
@@ -15,12 +17,34 @@
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <span>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "prx/libc/include/general/AtomicSharedPtr.hpp"
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
|
||||
inline bool CaptureRegisteredViewsCurrent(std::span<const ShaderRecompiler::RegisteredImageView> views) {
|
||||
if (views.empty()) return true;
|
||||
for (std::uint32_t attempt = 0; attempt < 2u; ++attempt) {
|
||||
const auto before = GuestAllocations::GuestAllocationsGeneration_nid_postfix();
|
||||
bool current = true;
|
||||
for (const auto& view : views) {
|
||||
const auto range = GuestAllocations::GuestAllocationsLookup_nid_postfix(static_cast<std::uintptr_t>(view.address), false);
|
||||
if (view.hasRange != (range != nullptr)) {
|
||||
current = false;
|
||||
break;
|
||||
}
|
||||
if (range != nullptr && (range->address != view.rangeAddress || range->bytes != view.rangeBytes || range->allocationAddress != view.allocationAddress || range->allocationBytes != view.allocationBytes || range->backingSerial != view.backingSerial || range->readable != view.readable || range->writable != view.writable || range->gpu != view.gpu)) {
|
||||
current = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (before == GuestAllocations::GuestAllocationsGeneration_nid_postfix()) return current;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline constexpr std::size_t MaxDispatchVariants = 8;
|
||||
|
||||
struct DispatchVariant {
|
||||
@@ -30,6 +54,7 @@ struct DispatchVariant {
|
||||
std::vector<SharedWords> shared;
|
||||
std::uint64_t forgetSerial = 0;
|
||||
std::shared_ptr<const ShaderRecompiler::RecompileResult> compiled;
|
||||
std::shared_ptr<const std::vector<ShaderRecompiler::RegisteredImageView>> registeredViews;
|
||||
std::array<std::uint32_t, 4> meshIndexDescriptor{};
|
||||
|
||||
std::shared_ptr<const ShaderSnapshot> shader;
|
||||
|
||||
@@ -124,6 +124,7 @@ enum class DrawVerdict { Drawn, Nothing, Rejected };
|
||||
struct StageCapture {
|
||||
std::shared_ptr<const ShaderRecompiler::RecompileResult> compiled;
|
||||
std::shared_ptr<const ShaderRecompiler::ResourceCapture> capture;
|
||||
std::shared_ptr<const std::vector<ShaderRecompiler::RegisteredImageView>> registeredViews;
|
||||
std::vector<ShaderRecompiler::MemoryRegion> regions;
|
||||
std::vector<std::shared_ptr<const ShaderRecompiler::SrtGuestWords>> supplied;
|
||||
std::uint64_t forgetSerial = 0;
|
||||
|
||||
@@ -121,8 +121,16 @@ public:
|
||||
static std::uint64_t DrawCacheBytes();
|
||||
static ShaderMemory::PendingWrite QueryPendingSpan(std::uint64_t address, std::size_t bytes, std::span<std::byte> known);
|
||||
std::shared_ptr<const ShaderRegistry> RegisteredShaders();
|
||||
static void SetCaptureCheckHook(void (*hook)());
|
||||
|
||||
private:
|
||||
class RecaptureScope {
|
||||
public:
|
||||
RecaptureScope();
|
||||
~RecaptureScope();
|
||||
RecaptureScope(const RecaptureScope&) = delete;
|
||||
RecaptureScope& operator=(const RecaptureScope&) = delete;
|
||||
};
|
||||
friend class SampledReadScope;
|
||||
friend struct PendingView;
|
||||
friend struct PacketTimer;
|
||||
@@ -321,20 +329,21 @@ private:
|
||||
static void notePendingWait(std::span<const std::uint32_t> packet, std::uint32_t queue, std::uint64_t received);
|
||||
void landPendingWaits(std::uint32_t queue);
|
||||
struct ResolvedDispatch {
|
||||
std::uint64_t address = 0, key = 0, indirectArguments = 0;
|
||||
std::uint64_t address = 0, key = 0, indirectArguments = 0, forgetAtCapture = 0;
|
||||
std::array<std::uint32_t, 5> packet{};
|
||||
std::shared_ptr<const ShaderSnapshot> registeredShader;
|
||||
std::shared_ptr<const ShaderRecompiler::RecompileResult> compiledResult;
|
||||
std::shared_ptr<DispatchVariant> keepVariant, attachVariant;
|
||||
std::shared_ptr<DispatchEntry> missedEntry;
|
||||
std::shared_ptr<ShaderMemory> shaderMemory;
|
||||
std::vector<ShaderRecompiler::MemoryRegion> captured;
|
||||
std::vector<std::uint32_t> liveWords;
|
||||
std::shared_ptr<const ShaderRecompiler::ResourceCapture> capture;
|
||||
bool dataHit = false, cached = false, validated = false;
|
||||
bool dataHit = false, cached = false, validated = false, missedDiffering = false, noDispatchCache = false;
|
||||
std::chrono::steady_clock::time_point resolvedAt{};
|
||||
};
|
||||
struct GroupCaptureStats {
|
||||
std::uint64_t runs = 0, resolved = 0, resolvedHits = 0, adopted = 0, addressMismatches = 0, keyMismatches = 0, memoryMismatches = 0, failures = 0, stale = 0, labelOverlaps = 0, writtenBefore = 0, deviceRejects = 0, argumentMismatches = 0;
|
||||
std::uint64_t runs = 0, resolved = 0, resolvedHits = 0, adopted = 0, addressMismatches = 0, keyMismatches = 0, memoryMismatches = 0, failures = 0, stale = 0, labelOverlaps = 0, writtenBefore = 0, unknownWrites = 0, deviceRejects = 0, argumentMismatches = 0;
|
||||
double resolveMs = 0, resolveMaxMs = 0, ageMs = 0, ageMaxMs = 0;
|
||||
std::chrono::steady_clock::time_point reported = std::chrono::steady_clock::now();
|
||||
};
|
||||
@@ -365,6 +374,8 @@ private:
|
||||
bool recordLabelsForPacket(VulkanDevice* localDevice, std::uint32_t queue);
|
||||
void recordQueuedLabelsBeforeRead(std::uint32_t queue);
|
||||
bool recordQueuedLabelsAfterCapture(std::uint32_t queue, std::span<const ShaderRecompiler::MemoryRegion> regions);
|
||||
static void runCaptureCheckHook();
|
||||
static bool capturedMemoryChanged(std::span<const ShaderRecompiler::MemoryRegion> regions, std::span<Graphics::GuestMemorySnapshot> compared = {});
|
||||
void noteQueuedLabels(std::uint32_t queue);
|
||||
void recordQueuedLabelsByTry(std::uint32_t queue, std::atomic<std::uint64_t>& counter);
|
||||
static void recordQueuedLabelsFromHook();
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_DRIVER_DRIVERMEMORY_HPP
|
||||
#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_DRIVER_DRIVERMEMORY_HPP
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
|
||||
constexpr std::uint64_t Ps5DriverMemoryBase = 0xfe0000000ull;
|
||||
constexpr std::uint64_t MacOsDriverMemoryBase = 0xee0000000ull;
|
||||
constexpr std::uint64_t DriverMemorySpan = 2u << 20u;
|
||||
|
||||
constexpr std::uint64_t RetargetPs5DriverMemory(std::uint64_t address) {
|
||||
return address >= Ps5DriverMemoryBase && address - Ps5DriverMemoryBase < DriverMemorySpan ? address - Ps5DriverMemoryBase + MacOsDriverMemoryBase : address;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "prx/libSceAgcDriver/Execution/include/ShaderMemory.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/QueueState.hpp"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
@@ -17,6 +18,7 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -25,6 +27,7 @@ struct Shader;
|
||||
|
||||
namespace ShaderRecompiler {
|
||||
class ShaderPreparationContext;
|
||||
struct LinkedCalls;
|
||||
}
|
||||
|
||||
namespace AgcDriver {
|
||||
@@ -35,6 +38,7 @@ namespace AgcDriver::DriverDetail {
|
||||
|
||||
struct ShaderSnapshot;
|
||||
|
||||
struct UserDataCallSites;
|
||||
class ShaderRegistry {
|
||||
using Chunk = std::map<std::uint64_t, std::vector<std::shared_ptr<const ShaderSnapshot>>>;
|
||||
using Chunks = std::vector<std::shared_ptr<Chunk>>;
|
||||
@@ -145,7 +149,18 @@ struct PreparedShaderState {
|
||||
std::weak_ptr<const ShaderRegistry> registry;
|
||||
std::vector<std::weak_ptr<const ShaderSnapshot>> stages;
|
||||
};
|
||||
struct UserDataLink {
|
||||
std::size_t codeOffset = 0;
|
||||
std::uint32_t userDataBaseRegister = 0;
|
||||
std::uint32_t userDataCount = 0;
|
||||
std::uint32_t waveSize = 0;
|
||||
std::shared_ptr<const UserDataCallSites> sites;
|
||||
std::vector<std::uint64_t> callees;
|
||||
std::vector<std::vector<std::uint32_t>> code;
|
||||
std::shared_ptr<const ShaderRecompiler::LinkedCalls> linked;
|
||||
};
|
||||
std::vector<Entry> entries;
|
||||
std::vector<UserDataLink> userDataLinks;
|
||||
std::vector<std::vector<std::uint64_t>> registeredAbis;
|
||||
std::vector<GraphicsAbi> graphicsAbis;
|
||||
std::vector<Rectangle> rectangles;
|
||||
@@ -169,12 +184,105 @@ struct PreparedShaders : PreparedShaderState {
|
||||
std::atomic<bool> demanded{false};
|
||||
bool pending = false;
|
||||
std::vector<std::size_t> convertedSamples;
|
||||
std::vector<std::size_t> layerRowSamples;
|
||||
};
|
||||
|
||||
struct RegisteredShaderState {
|
||||
class SharedCode {
|
||||
public:
|
||||
SharedCode() = default;
|
||||
SharedCode(std::vector<std::uint32_t> values) : words(std::make_shared<std::vector<std::uint32_t>>(std::move(values))) {}
|
||||
SharedCode(std::initializer_list<std::uint32_t> values) : SharedCode(std::vector<std::uint32_t>(values)) {}
|
||||
template<std::input_iterator TIterator>
|
||||
SharedCode(TIterator first, TIterator last) : SharedCode(std::vector<std::uint32_t>(first, last)) {}
|
||||
|
||||
operator const std::vector<std::uint32_t>&() const { return Words(); }
|
||||
[[nodiscard]] const std::vector<std::uint32_t>& Words() const { return words != nullptr ? *words : none(); }
|
||||
[[nodiscard]] const std::uint32_t* data() const { return Words().data(); }
|
||||
[[nodiscard]] std::size_t size() const { return Words().size(); }
|
||||
[[nodiscard]] bool empty() const { return Words().empty(); }
|
||||
[[nodiscard]] const std::uint32_t* begin() const { return Words().data(); }
|
||||
[[nodiscard]] const std::uint32_t* end() const { return Words().data() + Words().size(); }
|
||||
[[nodiscard]] std::uint32_t operator[](std::size_t index) const { return Words()[index]; }
|
||||
[[nodiscard]] bool SharesWith(const SharedCode& other) const { return words != nullptr && words == other.words; }
|
||||
bool operator==(const SharedCode& other) const { return words == other.words || Words() == other.Words(); }
|
||||
bool operator==(const std::vector<std::uint32_t>& other) const { return Words() == other; }
|
||||
|
||||
std::vector<std::uint32_t>& Mutable() {
|
||||
if (words == nullptr) words = std::make_shared<std::vector<std::uint32_t>>();
|
||||
else if (words.use_count() > 1) words = std::make_shared<std::vector<std::uint32_t>>(*words);
|
||||
return *words;
|
||||
}
|
||||
void resize(std::size_t count) { Mutable().resize(count); }
|
||||
template<typename TIterator>
|
||||
void assign(TIterator first, TIterator last) { Mutable().assign(first, last); }
|
||||
|
||||
private:
|
||||
static const std::vector<std::uint32_t>& none() {
|
||||
static const std::vector<std::uint32_t> none;
|
||||
return none;
|
||||
}
|
||||
|
||||
std::shared_ptr<std::vector<std::uint32_t>> words;
|
||||
};
|
||||
|
||||
class RegisterList {
|
||||
public:
|
||||
using Entry = std::pair<std::uint32_t, std::uint32_t>;
|
||||
using const_iterator = std::vector<Entry>::const_iterator;
|
||||
|
||||
RegisterList() = default;
|
||||
explicit RegisterList(const Registers& registers) {
|
||||
entries.reserve(registers.size());
|
||||
registers.ForEach([&](std::uint32_t offset, std::uint32_t value) { entries.emplace_back(offset, value); });
|
||||
}
|
||||
|
||||
[[nodiscard]] Registers Expand() const {
|
||||
Registers registers;
|
||||
if (!entries.empty()) registers.emplace(entries.back().first, entries.back().second);
|
||||
for (const auto& [offset, value] : entries) registers.emplace(offset, value);
|
||||
return registers;
|
||||
}
|
||||
[[nodiscard]] const_iterator begin() const { return entries.begin(); }
|
||||
[[nodiscard]] const_iterator end() const { return entries.end(); }
|
||||
[[nodiscard]] const_iterator find(std::uint32_t offset) const {
|
||||
const auto found = std::lower_bound(entries.begin(), entries.end(), offset, [](const Entry& entry, std::uint32_t wanted) { return entry.first < wanted; });
|
||||
return found != entries.end() && found->first == offset ? found : entries.end();
|
||||
}
|
||||
[[nodiscard]] std::uint32_t at(std::uint32_t offset) const {
|
||||
const auto found = find(offset);
|
||||
if (found == end()) throw std::out_of_range("register is not set");
|
||||
return found->second;
|
||||
}
|
||||
[[nodiscard]] std::size_t size() const { return entries.size(); }
|
||||
[[nodiscard]] bool empty() const { return entries.empty(); }
|
||||
template<class TVisit>
|
||||
void ForEach(TVisit&& visit) const {
|
||||
for (const auto& [offset, value] : entries) visit(offset, value);
|
||||
}
|
||||
void emplace(std::uint32_t offset, std::uint32_t value) {
|
||||
const auto found = std::lower_bound(entries.begin(), entries.end(), offset, [](const Entry& entry, std::uint32_t wanted) { return entry.first < wanted; });
|
||||
if (found == entries.end() || found->first != offset) entries.insert(found, {offset, value});
|
||||
}
|
||||
|
||||
bool operator==(const RegisterList&) const = default;
|
||||
|
||||
private:
|
||||
std::vector<Entry> entries;
|
||||
};
|
||||
|
||||
struct DecodedShaderState {
|
||||
Registers shader;
|
||||
Registers context;
|
||||
Registers userConfig;
|
||||
};
|
||||
|
||||
struct RegisteredShaderState {
|
||||
RegisteredShaderState() = default;
|
||||
RegisteredShaderState(const DecodedShaderState& decoded) : shader(decoded.shader), context(decoded.context), userConfig(decoded.userConfig) {}
|
||||
|
||||
RegisterList shader;
|
||||
RegisterList context;
|
||||
RegisterList userConfig;
|
||||
|
||||
bool operator==(const RegisteredShaderState&) const = default;
|
||||
};
|
||||
@@ -183,7 +291,7 @@ struct ShaderSnapshot {
|
||||
std::uint64_t codeAddress;
|
||||
std::uint64_t headerAddress;
|
||||
std::uint8_t type;
|
||||
std::vector<std::uint32_t> code;
|
||||
SharedCode code;
|
||||
std::vector<std::byte> header;
|
||||
std::shared_ptr<PreparedShaders> prepared = std::make_shared<PreparedShaders>();
|
||||
std::shared_ptr<const RegisteredShaderState> registeredState;
|
||||
@@ -195,7 +303,7 @@ struct ShaderSnapshot {
|
||||
};
|
||||
|
||||
|
||||
std::shared_ptr<const ShaderSnapshot> ReadRawShader(std::uint64_t address);
|
||||
std::shared_ptr<const ShaderSnapshot> ReadRawShader(std::uint64_t address, const std::shared_ptr<const ShaderSnapshot>& retained = {});
|
||||
std::shared_ptr<const ShaderSnapshot> ReadUserDataTailContinuation(std::span<const std::uint32_t> code, std::uint32_t userDataBase, std::span<const std::uint32_t> userData);
|
||||
std::shared_ptr<const ShaderSnapshot> ProgramSnapshot(const ShaderRegistry& shaders, std::uint64_t address, std::initializer_list<std::uint8_t> types);
|
||||
void NoteRawGraphicsDraw(const ShaderSnapshot& snapshot);
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ extern std::atomic<std::uint64_t> labelFallbacks[5];
|
||||
|
||||
extern std::atomic<std::uint64_t> queuedLabels, labelGroups, immediateLabels;
|
||||
|
||||
extern std::atomic<std::uint64_t> packetLockRecords, packetLockSubmits, packetLockDeferred, packetSubmitDeferred, captureTryRecords, captureRetries, suspendPoints;
|
||||
extern std::atomic<std::uint64_t> packetLockRecords, packetLockSubmits, packetLockDeferred, packetSubmitDeferred, captureTryRecords, captureRetries, captureChangeRetries, suspendPoints;
|
||||
|
||||
extern std::atomic<std::uint64_t> recordTriesSkipped;
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@ inline bool FragmentShaderBarycentricUsable(VkDriverId driver, bool reported) {
|
||||
return reported && driver != VK_DRIVER_ID_MOLTENVK;
|
||||
}
|
||||
|
||||
inline bool HostInterpolationPreferred(VkDriverId driver) {
|
||||
return driver == VK_DRIVER_ID_MESA_RADV;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -66,6 +67,7 @@ private:
|
||||
void record(FrameCall call, bool prologueCall, std::span<const Shader* const> shaders = {}, const std::function<void()>& accept = {});
|
||||
void recordLocked(FrameCall call, bool prologueCall, std::span<const Shader* const> shaders);
|
||||
void emitDelta();
|
||||
static void collectShaderPages(std::span<const Shader* const> shaders, std::set<std::uint64_t>& blocks, std::set<std::uint64_t>& hostPages);
|
||||
void emitShaderDelta(std::span<const Shader* const> shaders);
|
||||
void writeDelta(std::span<const Span> spans, std::span<const std::uint64_t> hostPages, std::span<const Range> added = {});
|
||||
bool triggered();
|
||||
@@ -88,6 +90,7 @@ private:
|
||||
State state = State::Waiting;
|
||||
std::unique_ptr<FrameCaptureWriter> writer;
|
||||
std::vector<FrameCall> prologue;
|
||||
std::set<std::uint64_t> prologueHostPages;
|
||||
std::deque<FrameCall> reservations;
|
||||
std::vector<Range> ranges;
|
||||
std::map<std::uint64_t, std::uint64_t> shaderMarks;
|
||||
|
||||
@@ -54,6 +54,7 @@ void Write(std::uint64_t address, std::span<const std::byte> source, std::size_t
|
||||
void WriteChanged(std::uint64_t address, std::span<const std::byte> current, std::span<const std::byte> original);
|
||||
void WriteChanged(std::uint64_t address, std::span<const std::byte> current, std::span<const std::byte> original, std::uint32_t byteStoreLimit);
|
||||
std::uint32_t ChangedByteStoreLimit();
|
||||
void WriteChangedKeepingGuest(std::uint64_t address, std::span<const std::byte> current, std::span<const std::byte> original);
|
||||
|
||||
// Write tracking. The guest arena is reserved with page write watching, so CollectWrites learns which
|
||||
// pages of a range the CPU wrote since they were last collected, stamps their 64 KiB blocks with a new
|
||||
@@ -67,6 +68,8 @@ void Unwatch(std::uint64_t address, std::size_t bytes);
|
||||
void Rewatch(std::span<const std::pair<std::uint64_t, std::uint64_t>> ranges);
|
||||
bool ImportWatched(std::uint64_t address, std::size_t bytes, const std::function<bool()>& import, bool staysWatched = true, bool importMayWriteGuest = true);
|
||||
void SetUnwatchHook(void (*hook)(std::uint64_t address, std::size_t bytes));
|
||||
bool UnwatchWritesProven();
|
||||
void SetImportWalkFailureForTest(int walk, std::uint64_t span = 0);
|
||||
#ifdef _WIN32
|
||||
using FreshCollectHook = bool (*)(std::uintptr_t address, std::size_t bytes, void (*written)(void*, std::uintptr_t, std::uintptr_t), void* context);
|
||||
void SetFreshCollectHook(FreshCollectHook hook);
|
||||
@@ -124,6 +127,7 @@ std::uint64_t CollectWritesUncached(std::uint64_t address, std::size_t bytes);
|
||||
// tracker mutex, so every collect that bumped before it has finished its walk and every later
|
||||
// collect stamps newer.
|
||||
std::uint64_t TrackerGeneration();
|
||||
void AdvanceTrackerGenerationForTest(std::uint64_t generation);
|
||||
std::uint64_t NewestStamp(std::uint64_t address, std::size_t bytes);
|
||||
std::uint64_t UntrackedHint(std::uint64_t address, std::size_t bytes);
|
||||
// Whether no CPU write touched the range since `generation`: an uncached resetting collect of the
|
||||
|
||||
@@ -51,6 +51,8 @@ struct KeyboardGlyphEntry {
|
||||
};
|
||||
|
||||
inline constexpr char32_t KeyboardFallbackCode = 0xFFFD;
|
||||
inline constexpr std::uint8_t KeyboardCompositionMark = 1;
|
||||
inline constexpr std::uint8_t KeyboardSelectionMark = 2;
|
||||
|
||||
std::span<const KeyboardGlyphEntry> KeyboardGlyphTable();
|
||||
bool KeyboardHasGlyph(char32_t code);
|
||||
|
||||
@@ -14,6 +14,11 @@ namespace AgcDriver::Pm4 {
|
||||
|
||||
constexpr std::size_t GdsBytes = 0x10000;
|
||||
std::uint64_t GdsAddress();
|
||||
void RequestImportableGds(bool requested);
|
||||
bool ImportableGdsRequested();
|
||||
bool GdsShared();
|
||||
bool GdsImportable();
|
||||
void RejectGdsImport();
|
||||
|
||||
struct DrawParameters {
|
||||
std::uint64_t indexAddress;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_RASTERORDERGROUP_HPP
|
||||
#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_RASTERORDERGROUP_HPP
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace AgcDriver {
|
||||
|
||||
inline bool RasterOrderGroupUsable(VkDriverId driver) {
|
||||
return driver != VK_DRIVER_ID_MOLTENVK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -91,6 +91,7 @@ public:
|
||||
|
||||
private:
|
||||
std::shared_ptr<const ShaderRecompiler::ResourceCapture> capture(const ShaderRecompiler::RecompileRequest& request, const ShaderRecompiler::SourceHandle* handle, const ShaderRecompiler::PreparedShaderInvocation* invocation);
|
||||
std::shared_ptr<const ShaderRecompiler::ResourceCapture> captureWaitingOnFailure(const ShaderRecompiler::RecompileRequest& request, const ShaderRecompiler::SourceHandle* handle, const ShaderRecompiler::PreparedShaderInvocation* invocation);
|
||||
static constexpr std::size_t PageBytes = 4096;
|
||||
static constexpr std::size_t PageWords = PageBytes / sizeof(std::uint32_t);
|
||||
|
||||
@@ -169,6 +170,8 @@ private:
|
||||
std::size_t descriptorSpanBytes = 0;
|
||||
std::uint64_t rawInvalidations = 0;
|
||||
std::uint32_t forceSync = 0;
|
||||
std::uint64_t branchReadsRefused = 0;
|
||||
bool waitBranches = false;
|
||||
};
|
||||
|
||||
// The positions, among a dispatch-cache variant's stored words, of the pure flat-SRT leaves a
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
namespace AgcDriver {
|
||||
|
||||
inline bool SubgroupControlBarrierUsable(VkDriverId driver) {
|
||||
return driver != VK_DRIVER_ID_AMD_PROPRIETARY;
|
||||
return driver != VK_DRIVER_ID_AMD_PROPRIETARY && driver != VK_DRIVER_ID_MOLTENVK;
|
||||
}
|
||||
|
||||
inline bool WorkgroupScopeFenceUsable(VkDriverId driver) {
|
||||
|
||||
@@ -81,6 +81,8 @@ public:
|
||||
std::string DeviceName() const;
|
||||
std::string DriverInfo() const;
|
||||
bool SupportsImageFormat(VkFormat format, VkImageUsageFlags usage) const;
|
||||
bool BdaAtomicsUsable() const;
|
||||
bool RasterOrderGroupUsable() const;
|
||||
bool CalibrateClock(double& gpuNs, std::chrono::steady_clock::time_point& cpu) const;
|
||||
ShaderRecompiler::SpirvTarget Target() const;
|
||||
Graphics::SampleOrder HostSampleOrder(const Graphics::State& graphics) const;
|
||||
@@ -287,6 +289,7 @@ public:
|
||||
double gpuBusyMs, gpuGapMs, lastSubmitAfterFlipMs, blitSubmitAfterFlipMs, keyWriterWaitMs;
|
||||
};
|
||||
static PresentStatistics PresentCounts();
|
||||
static std::uint64_t FillCompletionSyncCount();
|
||||
struct PresyncStatistics {
|
||||
std::uint64_t checked, presyncs, keyChecks, keyWaits;
|
||||
};
|
||||
@@ -298,19 +301,19 @@ public:
|
||||
// records. Null when nothing is prepared: the resource cache may serve the dispatch (its
|
||||
// Revalidate stays under the mutex), or APS5_LOCKED_BUILD=1 keeps the whole build under it as
|
||||
// before. `shader` and `snapshots` must outlive the dispatch.
|
||||
std::shared_ptr<PreparedDispatch> PrepareDispatch(const ShaderRecompiler::RecompileResult& shader, std::span<const Graphics::GuestMemorySnapshot> snapshots, std::uint64_t dispatchThreads = 0, std::uint64_t programAddress = 0, std::optional<std::pair<std::uint64_t, std::size_t>> htileClear = std::nullopt);
|
||||
std::shared_ptr<PreparedDispatch> PrepareDispatch(const ShaderRecompiler::RecompileResult& shader, std::span<const Graphics::GuestMemorySnapshot> snapshots, std::uint64_t dispatchThreads = 0, std::uint64_t programAddress = 0, std::optional<std::pair<std::uint64_t, std::size_t>> htileClear = std::nullopt, const std::vector<ShaderRecompiler::RegisteredImageView>* registeredImageViews = nullptr);
|
||||
// APS5_PROFILE_DRAW: the parts of a PrepareDispatch in milliseconds, in the order key, find,
|
||||
// precollect, presync, stage A (the driver's 'prepare:' rows).
|
||||
static std::span<const double, 5> PreparePhaseMs(const PreparedDispatch& prepared);
|
||||
// `recipe`, when given, receives the Recipe a successful call built for its dispatch-cache
|
||||
// variant (design_cpu_final M4): only when the resource cache served or took the object
|
||||
// (reusable, cacheable) and recipes are on (APS5_NO_DISPATCH_RECIPE=1 builds none); else null.
|
||||
void Dispatch(const ShaderRecompiler::RecompileResult& shader, std::uint32_t x, std::uint32_t y, std::uint32_t z, std::span<const Graphics::GuestMemorySnapshot> snapshots = {}, std::uint64_t programAddress = 0, std::shared_ptr<PreparedDispatch> prepared = nullptr, std::shared_ptr<const Recipe>* recipe = nullptr, std::optional<std::pair<std::uint64_t, std::size_t>> htileClear = std::nullopt);
|
||||
void Dispatch(const ShaderRecompiler::RecompileResult& shader, std::uint32_t x, std::uint32_t y, std::uint32_t z, std::span<const Graphics::GuestMemorySnapshot> snapshots = {}, std::uint64_t programAddress = 0, std::shared_ptr<PreparedDispatch> prepared = nullptr, std::shared_ptr<const Recipe>* recipe = nullptr, std::optional<std::pair<std::uint64_t, std::size_t>> htileClear = std::nullopt, const std::vector<ShaderRecompiler::RegisteredImageView>* registeredImageViews = nullptr);
|
||||
struct IndirectOutcome {
|
||||
int cpuReason;
|
||||
double argumentReadMs;
|
||||
};
|
||||
IndirectOutcome DispatchIndirect(const ShaderRecompiler::RecompileResult& shader, std::uint64_t arguments, std::span<const Graphics::GuestMemorySnapshot> snapshots = {}, std::uint64_t programAddress = 0, std::shared_ptr<PreparedDispatch> prepared = nullptr, std::shared_ptr<const Recipe>* recipe = nullptr, const std::array<std::uint32_t, 3>& threadGroup = {});
|
||||
IndirectOutcome DispatchIndirect(const ShaderRecompiler::RecompileResult& shader, std::uint64_t arguments, std::span<const Graphics::GuestMemorySnapshot> snapshots = {}, std::uint64_t programAddress = 0, std::shared_ptr<PreparedDispatch> prepared = nullptr, std::shared_ptr<const Recipe>* recipe = nullptr, const std::array<std::uint32_t, 3>& threadGroup = {}, const std::vector<ShaderRecompiler::RegisteredImageView>* registeredImageViews = nullptr);
|
||||
// A value-equal dispatch-cache hit with a recipe (design_cpu_final M4), in two steps.
|
||||
// PrepareRecipe, WITHOUT GuestMemory::GpuMutex: the pre-checks (recipes on, the recipe's
|
||||
// device is this one, its template and pipeline objects still alive), the template's
|
||||
@@ -385,11 +388,12 @@ public:
|
||||
private:
|
||||
VulkanDevice(const PresentationWindow* window, bool compileOnly);
|
||||
friend struct VulkanDeviceTestAccess;
|
||||
std::pair<VkBuffer, std::uint64_t> scratchPoolHeader(const ShaderRecompiler::RecompileResult& shader) const;
|
||||
VkPipeline splitComputePipeline(const Graphics::Context& context, const ShaderRecompiler::RecompileResult& shader, ComputePipelineObjects& objects, const std::array<std::uint32_t, 3>& base);
|
||||
ShaderRecompiler::SpirvTarget buildTarget() const;
|
||||
Graphics::Context buildContext() const;
|
||||
// Body of Dispatch and DispatchIndirect: `arguments` 0 dispatches x, y, z groups.
|
||||
IndirectOutcome dispatch(const ShaderRecompiler::RecompileResult& shader, std::uint32_t x, std::uint32_t y, std::uint32_t z, std::uint64_t arguments, std::span<const Graphics::GuestMemorySnapshot> snapshots, std::uint64_t programAddress, std::shared_ptr<PreparedDispatch> prepared, std::shared_ptr<const Recipe>* recipe, const std::array<std::uint32_t, 3>& threadGroup = {}, std::optional<std::pair<std::uint64_t, std::size_t>> htileClear = std::nullopt);
|
||||
IndirectOutcome dispatch(const ShaderRecompiler::RecompileResult& shader, std::uint32_t x, std::uint32_t y, std::uint32_t z, std::uint64_t arguments, std::span<const Graphics::GuestMemorySnapshot> snapshots, std::uint64_t programAddress, std::shared_ptr<PreparedDispatch> prepared, std::shared_ptr<const Recipe>* recipe, const std::array<std::uint32_t, 3>& threadGroup = {}, std::optional<std::pair<std::uint64_t, std::size_t>> htileClear = std::nullopt, const std::vector<ShaderRecompiler::RegisteredImageView>* registeredImageViews = nullptr);
|
||||
IndirectOutcome recordCompletedDispatch(const ShaderRecompiler::RecompileResult& shader, std::uint32_t x, std::uint32_t y, std::uint32_t z, std::uint64_t arguments, std::uint64_t programAddress, std::shared_ptr<const Recipe>* recipeOut, const std::array<std::uint32_t, 3>& threadGroup, std::optional<std::pair<std::uint64_t, std::size_t>> htileClear, DispatchCompletion& completion);
|
||||
// The stage-A pre-sync over `surfaces` (see PrepareDispatch): the serial waited for, 0 none.
|
||||
std::uint64_t presync(std::span<const Graphics::PresyncSurface> surfaces);
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace AgcDriver {
|
||||
void StartWorkerSampler(std::uint32_t queue = 0);
|
||||
void StartCommitterSampler();
|
||||
void StopWorkerSampler();
|
||||
bool ReadableStackRegion(std::uint64_t address, std::uint64_t& low, std::uint64_t& high);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "prx/libSceAgcDriver/Graphics/include/Recorder.hpp"
|
||||
#include "Optimization/ResourceProgram.hpp"
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
@@ -140,10 +141,12 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
if (resolving) {
|
||||
if (indirectArguments == 0 && Graphics::MatchMultisampledSingleClear(std::span(snapshot.code).subspan(codeOffset), userData, compute.numThreads)) return;
|
||||
if (!partialLastGroup && matchesFillKernel(std::span(snapshot.code).subspan(codeOffset), userData, compute)) return;
|
||||
if (!partialLastGroup && indirectArguments == 0 && (MatchDwordPatternFill(packet, std::span(snapshot.code).subspan(codeOffset), userData, compute) || MatchConstantDwordFill(packet, std::span(snapshot.code).subspan(codeOffset), userData, compute) || MatchClampedGlobalFill(packet, std::span(snapshot.code).subspan(codeOffset), userData, compute) || MatchMemoryValueBufferFill(packet, std::span(snapshot.code).subspan(codeOffset), userData, compute))) return;
|
||||
if (!partialLastGroup && indirectArguments == 0 && (matchesCopyKernel(std::span(snapshot.code).subspan(codeOffset), userData, compute) || MatchesStreamCopyKernel(std::span(snapshot.code).subspan(codeOffset), userData, compute) || MatchesIndexedCopyKernel(std::span(snapshot.code).subspan(codeOffset), userData, compute))) return;
|
||||
} else {
|
||||
if (indirectArguments == 0 && Graphics::TakeMultisampledSingleClear(std::span(snapshot.code).subspan(codeOffset), userData, compute.numThreads)) {
|
||||
pendingDispatchPhases().outcome = DispatchOutcome::FillHle;
|
||||
if (resolvedAhead().empty()) gateOpened() = true;
|
||||
return;
|
||||
}
|
||||
if (indirectArguments == 0 && (packet[4] & 0x20u) == 0) {
|
||||
@@ -151,6 +154,7 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
}
|
||||
if (!partialLastGroup && fillBuffer(queue, submission.queue, packet, std::span(snapshot.code).subspan(codeOffset), userData, compute, localDevice)) {
|
||||
pendingDispatchPhases().outcome = DispatchOutcome::FillHle;
|
||||
if (resolvedAhead().empty()) gateOpened() = true;
|
||||
return;
|
||||
}
|
||||
if (DrawPipeline::Active() && !pipelineCandidate) DrawPipeline::Queue0().Drain(DrawPipeline::DrainReason::Packet, 0x15);
|
||||
@@ -166,6 +170,7 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
}
|
||||
if (!partialLastGroup && indirectArguments == 0 && copyBuffer(queue, submission.queue, packet, std::span(snapshot.code).subspan(codeOffset), userData, compute, localDevice, address)) {
|
||||
pendingDispatchPhases().outcome = DispatchOutcome::CopyHle;
|
||||
if (resolvedAhead().empty()) gateOpened() = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -188,9 +193,9 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
{0, 0, 0, threadGroup != std::array<std::uint32_t, 3>{} ? 0u : 128u}
|
||||
};
|
||||
static const bool profile = std::getenv("APS5_PROFILE_DRAW") != nullptr;
|
||||
static double captureMs = 0, keyMs = 0, recompileMs = 0, deviceMs = 0;
|
||||
static std::uint64_t cacheHits = 0;
|
||||
static std::uint64_t dispatches = 0;
|
||||
static std::atomic<double> captureMs{0}, keyMs{0}, recompileMs{0}, deviceMs{0};
|
||||
static std::atomic<std::uint64_t> cacheHits{0};
|
||||
static std::atomic<std::uint64_t> dispatches{0};
|
||||
auto lap = std::chrono::steady_clock::now();
|
||||
|
||||
std::array<double, DriverPhaseCount> phaseMs{};
|
||||
@@ -302,7 +307,8 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
}
|
||||
if (fromAhead) {
|
||||
if (const auto hook = aheadAdoptHook.load(std::memory_order_acquire)) hook();
|
||||
if (!CapturedCurrent(ahead.captured, snapshot)) {
|
||||
const auto* aheadViews = ahead.capture != nullptr ? &ahead.capture->snapshot.registeredImages : ahead.keepVariant != nullptr && ahead.keepVariant->registeredViews != nullptr ? ahead.keepVariant->registeredViews.get() : nullptr;
|
||||
if (!CapturedCurrent(ahead.captured, snapshot) || (aheadViews != nullptr && !CaptureRegisteredViewsCurrent(*aheadViews))) {
|
||||
fromAhead = false;
|
||||
++dispatchesRejectedAhead;
|
||||
++groupStats.memoryMismatches;
|
||||
@@ -365,12 +371,12 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
}
|
||||
if (!pipelined && DrawPipeline::Queue0().Busy()) DrawPipeline::Queue0().Drain(DrawPipeline::DrainReason::Packet, 0x15);
|
||||
}
|
||||
std::uint64_t forgetAtCapture = 0;
|
||||
if (cached) {
|
||||
require(keepVariant != nullptr && keepVariant->shader == registeredShader, "dispatch cache belongs to another registered shader");
|
||||
captureMs += phaseTiming.Elapsed();
|
||||
if (profile) captureMs.fetch_add(phaseTiming.Elapsed(), std::memory_order_relaxed);
|
||||
} else if (!fromAhead) {
|
||||
shaderMemory = std::make_shared<ShaderMemory>(memory, &queryPendingWrite, &observePendingWrite, hookWaitCounter(), &QueryPendingSpan);
|
||||
std::uint64_t forgetAtCapture = 0;
|
||||
|
||||
static const bool dumpShaders = std::getenv("APS5_DUMP_SHADERS") != nullptr;
|
||||
try {
|
||||
@@ -386,7 +392,7 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
captured = shaderMemory->Regions();
|
||||
request.context.memory = captured;
|
||||
if (traceCapSync()) traceCapture("dispatch-capture", address, submission.queue, captured, Graphics::Recorder::ThreadWaitedMs() - waitedBefore);
|
||||
captureMs += phaseTiming.Elapsed();
|
||||
if (profile) captureMs.fetch_add(phaseTiming.Elapsed(), std::memory_order_relaxed);
|
||||
phaseTiming.Phase(PhaseCapture);
|
||||
if (dumpShaders) static_cast<void>(dumpRequest(address, request));
|
||||
const auto started = std::chrono::steady_clock::now();
|
||||
@@ -395,11 +401,13 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
timing.Mark("capture_resources");
|
||||
compiledResult = invocation.Materialize(*capture);
|
||||
timing.Mark("materialize");
|
||||
if (compiledResult->cacheHit) ++cacheHits;
|
||||
if (profile && compiledResult->cacheHit) cacheHits.fetch_add(1, std::memory_order_relaxed);
|
||||
const auto elapsed = std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - started).count();
|
||||
static double totalMs = 0;
|
||||
totalMs += elapsed;
|
||||
if (profile && elapsed > 200) std::fprintf(stderr, "[gpu] compute shader 0x%llx recompile took %.0f ms (%zu SPIR-V words, %zu captured regions, total %.1f s)\n", static_cast<unsigned long long>(address), elapsed, compiledResult->spirv.size(), captured.size(), totalMs / 1000);
|
||||
static std::atomic<double> totalMs{0};
|
||||
if (profile) {
|
||||
const auto total = totalMs.fetch_add(elapsed, std::memory_order_relaxed) + elapsed;
|
||||
if (elapsed > 200) std::fprintf(stderr, "[gpu] compute shader 0x%llx recompile took %.0f ms (%zu SPIR-V words, %zu captured regions, total %.1f s)\n", static_cast<unsigned long long>(address), elapsed, compiledResult->spirv.size(), captured.size(), total / 1000);
|
||||
}
|
||||
} catch (const std::exception& error) {
|
||||
std::string dump;
|
||||
if (dumpShaders) {
|
||||
@@ -416,21 +424,24 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
else std::snprintf(where, sizeof(where), "compute shader 0x%llx (%s): ", static_cast<unsigned long long>(address), dump.c_str());
|
||||
throw std::runtime_error(where + reason);
|
||||
}
|
||||
recompileMs += phaseTiming.Elapsed();
|
||||
if (profile) recompileMs.fetch_add(phaseTiming.Elapsed(), std::memory_order_relaxed);
|
||||
phaseTiming.Phase(PhaseRecompile);
|
||||
insertDispatch(address, key, noDispatchCache || !CacheableResult(*compiledResult), profile, registeredShader, forgetAtCapture, memory, shaderMemory, captured, capture, compiledResult, missedEntry, missedDiffering, attachVariant, phaseTiming);
|
||||
if (!resolving) insertDispatch(address, key, noDispatchCache || !CacheableResult(*compiledResult), profile, registeredShader, forgetAtCapture, memory, shaderMemory, captured, capture, compiledResult, missedEntry, missedDiffering, attachVariant, phaseTiming);
|
||||
}
|
||||
const auto* registeredViews = capture != nullptr ? &capture->snapshot.registeredImages : keepVariant != nullptr && keepVariant->registeredViews != nullptr ? keepVariant->registeredViews.get() : nullptr;
|
||||
if (resolving) {
|
||||
auto& parked = resolvedAhead()[currentPacketOffset()];
|
||||
parked = ResolvedDispatch{};
|
||||
parked.address = address;
|
||||
parked.key = key;
|
||||
parked.indirectArguments = indirectArguments;
|
||||
parked.forgetAtCapture = forgetAtCapture;
|
||||
std::copy_n(packet.begin(), std::min(packet.size(), parked.packet.size()), parked.packet.begin());
|
||||
parked.registeredShader = registeredShader;
|
||||
parked.compiledResult = compiledResult;
|
||||
parked.keepVariant = keepVariant;
|
||||
parked.attachVariant = attachVariant;
|
||||
parked.missedEntry = missedEntry;
|
||||
parked.shaderMemory = shaderMemory;
|
||||
parked.captured = std::move(captured);
|
||||
parked.liveWords = std::move(liveWords);
|
||||
@@ -438,6 +449,8 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
parked.dataHit = dataHit;
|
||||
parked.cached = cached;
|
||||
parked.validated = validated;
|
||||
parked.missedDiffering = missedDiffering;
|
||||
parked.noDispatchCache = noDispatchCache || (compiledResult != nullptr && !CacheableResult(*compiledResult));
|
||||
parked.resolvedAt = std::chrono::steady_clock::now();
|
||||
++groupStats.resolved;
|
||||
if (cached) ++groupStats.resolvedHits;
|
||||
@@ -494,11 +507,17 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
phaseTiming.Phase(PhaseSnapshots);
|
||||
|
||||
if (pipelined) {
|
||||
runCaptureCheckHook();
|
||||
if (capturedMemoryChanged(captured)) {
|
||||
const RecaptureScope recapture;
|
||||
dispatch(queue, packet, submission, indirectArguments);
|
||||
return;
|
||||
}
|
||||
const auto recipe = keepVariant->recipe.load(std::memory_order_acquire);
|
||||
const auto epoch = DrawPipeline::EpochToken().load(std::memory_order_relaxed);
|
||||
const auto queueId = submission.queue;
|
||||
itemCommits.fetch_add(1, std::memory_order_relaxed);
|
||||
DrawPipeline::Queue0().Enqueue([this, localDevice = std::move(localDevice), result = compiledResult, snapshots = std::move(snapshots), liveWords = std::move(liveWords), groups, address, queueId, recipe, keepVariant, dataHit, epoch, htileClearCompletion, htileMask] {
|
||||
DrawPipeline::Queue0().Enqueue([this, localDevice = std::move(localDevice), result = compiledResult, capture, registeredViews, snapshots = std::move(snapshots), liveWords = std::move(liveWords), groups, address, queueId, recipe, keepVariant, dataHit, epoch, htileClearCompletion, htileMask] {
|
||||
DrawPipeline::FollowEpoch(epoch);
|
||||
GuestMemory::SetCurrentPacket(0x15, queueId);
|
||||
const auto& compiledCommit = *result;
|
||||
@@ -509,7 +528,7 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
bool writersNoted = false;
|
||||
for (;;) {
|
||||
std::shared_ptr<PreparedDispatch> prepared;
|
||||
if (recipeHit == nullptr || VulkanDevice::VerifyRecipes() || htileClearCompletion.has_value()) prepared = localDevice->PrepareDispatch(compiledCommit, snapshots, 0, address, htileClearCompletion);
|
||||
if (recipeHit == nullptr || VulkanDevice::VerifyRecipes() || htileClearCompletion.has_value()) prepared = localDevice->PrepareDispatch(compiledCommit, snapshots, 0, address, htileClearCompletion, registeredViews);
|
||||
GuestMemory::TagGpuLockSite(GuestMemory::GpuLockSite::Dispatch);
|
||||
std::lock_guard gpuLock(GuestMemory::GpuMutex());
|
||||
recordLabelsForPacket(localDevice.get(), queueId);
|
||||
@@ -527,7 +546,7 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
localDevice->Dispatch(compiledCommit, groups[0], groups[1], groups[2], snapshots, address, std::move(prepared), htileClearCompletion.has_value() ? nullptr : &builtRecipe, htileClearCompletion);
|
||||
localDevice->Dispatch(compiledCommit, groups[0], groups[1], groups[2], snapshots, address, std::move(prepared), htileClearCompletion.has_value() ? nullptr : &builtRecipe, htileClearCompletion, registeredViews);
|
||||
}
|
||||
if (htileMask.bytes != 0u) localDevice->NoteHtileMask(htileMask);
|
||||
break;
|
||||
@@ -577,13 +596,14 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
}
|
||||
}
|
||||
}
|
||||
bool captureChecked = fromAhead;
|
||||
|
||||
for (;;) {
|
||||
|
||||
std::shared_ptr<PreparedDispatch> prepared;
|
||||
if (recipeHit == nullptr || VulkanDevice::VerifyRecipes()) {
|
||||
try {
|
||||
prepared = localDevice->PrepareDispatch(compiled, snapshots, dispatchThreads, address, htileClearCompletion);
|
||||
prepared = localDevice->PrepareDispatch(compiled, snapshots, dispatchThreads, address, htileClearCompletion, registeredViews);
|
||||
} catch (const std::exception& error) {
|
||||
if (rethrow(error)) return;
|
||||
}
|
||||
@@ -605,8 +625,18 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
}
|
||||
}
|
||||
GuestMemory::TagGpuLockSite(indirectArguments != 0 ? GuestMemory::GpuLockSite::Indirect : GuestMemory::GpuLockSite::Dispatch);
|
||||
std::lock_guard gpuLock(GuestMemory::GpuMutex());
|
||||
std::unique_lock gpuLock(GuestMemory::GpuMutex());
|
||||
phaseTiming.Phase(PhaseLockWait);
|
||||
if (!captureChecked) {
|
||||
captureChecked = true;
|
||||
runCaptureCheckHook();
|
||||
if (capturedMemoryChanged(captured, snapshots)) {
|
||||
gpuLock.unlock();
|
||||
const RecaptureScope recapture;
|
||||
dispatch(queue, packet, submission, indirectArguments);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
recordLabelsForPacket(localDevice.get(), submission.queue);
|
||||
phaseTiming.Phase(PhaseLabels);
|
||||
@@ -629,10 +659,10 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
}
|
||||
if (indirectArguments != 0) countIndirect(outcome.cpuReason, outcome.argumentReadMs);
|
||||
} else if (indirectArguments != 0) {
|
||||
const auto outcome = localDevice->DispatchIndirect(compiled, indirectArguments, snapshots, address, std::move(prepared), attachTo != nullptr ? &builtRecipe : nullptr, threadGroup);
|
||||
const auto outcome = localDevice->DispatchIndirect(compiled, indirectArguments, snapshots, address, std::move(prepared), attachTo != nullptr ? &builtRecipe : nullptr, threadGroup, registeredViews);
|
||||
countIndirect(outcome.cpuReason, outcome.argumentReadMs);
|
||||
} else {
|
||||
localDevice->Dispatch(compiled, groups[0], groups[1], groups[2], snapshots, address, std::move(prepared), htileClearCompletion.has_value() ? nullptr : (attachTo != nullptr ? &builtRecipe : nullptr), htileClearCompletion);
|
||||
localDevice->Dispatch(compiled, groups[0], groups[1], groups[2], snapshots, address, std::move(prepared), htileClearCompletion.has_value() ? nullptr : (attachTo != nullptr ? &builtRecipe : nullptr), htileClearCompletion, registeredViews);
|
||||
}
|
||||
} catch (const std::exception& error) {
|
||||
if (rethrow(error)) return;
|
||||
@@ -656,7 +686,7 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
}
|
||||
phaseTiming.Phase(PhaseDevice);
|
||||
if (noteWrites && !writerKeyedEvidence()) noteWrittenBuffers(address, submission.queue, compiled);
|
||||
deviceMs += phaseTiming.Elapsed();
|
||||
if (profile) deviceMs.fetch_add(phaseTiming.Elapsed(), std::memory_order_relaxed);
|
||||
phaseTiming.Phase(PhaseTail);
|
||||
if (profile) {
|
||||
auto& pending = pendingDispatchPhases();
|
||||
@@ -667,7 +697,16 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
|
||||
pending.ms = phaseMs;
|
||||
pending.tailAt = phaseLap;
|
||||
}
|
||||
if (profile && ++dispatches % 100 == 0) AgcDriver::ProfilePrint_nid_no_patch( "[gpu] %llu dispatches (%llu dispatch cache hits, %llu evictions, %llu recompile cache hits): capture %.1f s, cache key %.1f s, recompile %.1f s, device %.1f s\n", static_cast<unsigned long long>(dispatches), static_cast<unsigned long long>(dispatchCacheHits), static_cast<unsigned long long>(dispatchCacheEvictions), static_cast<unsigned long long>(cacheHits), captureMs / 1000, keyMs / 1000, recompileMs / 1000, deviceMs / 1000);
|
||||
if (profile && dispatches.fetch_add(1, std::memory_order_relaxed) % 100 == 99) {
|
||||
std::uint64_t hits = 0;
|
||||
std::uint64_t evictions = 0;
|
||||
{
|
||||
std::lock_guard cacheLock(dispatchCacheMutex);
|
||||
hits = dispatchCacheHits;
|
||||
evictions = dispatchCacheEvictions;
|
||||
}
|
||||
AgcDriver::ProfilePrint_nid_no_patch( "[gpu] %llu dispatches (%llu dispatch cache hits, %llu evictions, %llu recompile cache hits): capture %.1f s, cache key %.1f s, recompile %.1f s, device %.1f s\n", static_cast<unsigned long long>(dispatches.load(std::memory_order_relaxed)), static_cast<unsigned long long>(hits), static_cast<unsigned long long>(evictions), static_cast<unsigned long long>(cacheHits.load(std::memory_order_relaxed)), captureMs.load(std::memory_order_relaxed) / 1000, keyMs.load(std::memory_order_relaxed) / 1000, recompileMs.load(std::memory_order_relaxed) / 1000, deviceMs.load(std::memory_order_relaxed) / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "ThreadOwned.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawPipeline.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Memory/DrawWriteRanges.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Shaders/ShaderRegistry.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Synchronization/DeferredLabels.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Pm4.hpp"
|
||||
@@ -108,10 +109,6 @@ void NoteLabel(std::vector<RunLabel>& labels, std::uint64_t address, std::span<c
|
||||
labels.push_back({address, bytes.size(), value});
|
||||
}
|
||||
|
||||
bool WritesThroughPointers(const ShaderRecompiler::RecompileResult& compiled) {
|
||||
return std::any_of(compiled.bindings.begin(), compiled.bindings.end(), [](const ShaderRecompiler::DescriptorBinding& binding) { return binding.role == ShaderRecompiler::DescriptorRole::BdaPagetable; });
|
||||
}
|
||||
|
||||
bool OverlapsLabel(std::span<const ShaderRecompiler::MemoryRegion> regions, const std::vector<RunLabel>& labels) {
|
||||
for (const auto& label : labels) {
|
||||
for (const auto& region : regions) {
|
||||
@@ -136,7 +133,6 @@ void Driver::resolveGroupAhead(const Submission& submission, const QueueState& l
|
||||
QueueState scratch = live;
|
||||
std::vector<RunLabel> labels;
|
||||
std::vector<std::pair<std::uint64_t, std::uint64_t>> writes;
|
||||
bool unknownWrites = false;
|
||||
for (const auto& label : deferredLabels().labels) NoteLabel(labels, label.address, std::span<const std::byte>(label.bytes).first(label.size));
|
||||
struct Resolving {
|
||||
std::size_t offset;
|
||||
@@ -277,7 +273,7 @@ void Driver::resolveGroupAhead(const Submission& submission, const QueueState& l
|
||||
const auto argumentsEnd = arguments + 3u * sizeof(std::uint32_t);
|
||||
const bool written = std::any_of(writes.begin(), writes.end(), [&](const auto& range) { return range.first < argumentsEnd && arguments < range.second; })
|
||||
|| std::any_of(labels.begin(), labels.end(), [&](const RunLabel& label) { return label.address < argumentsEnd && arguments < label.address + label.size; });
|
||||
if ((unknownWrites || written) && indirectArgumentsPath(packet, arguments) != IndirectGpu) {
|
||||
if (written && indirectArgumentsPath(packet, arguments) != IndirectGpu) {
|
||||
++stats.writtenBefore;
|
||||
break;
|
||||
}
|
||||
@@ -302,10 +298,31 @@ void Driver::resolveGroupAhead(const Submission& submission, const QueueState& l
|
||||
++stats.writtenBefore;
|
||||
break;
|
||||
}
|
||||
if (found->second.compiledResult != nullptr) appendWrittenRanges(*found->second.compiledResult, writes);
|
||||
if (found->second.compiledResult == nullptr || WritesThroughPointers(*found->second.compiledResult)) unknownWrites = true;
|
||||
if (found->second.compiledResult == nullptr) {
|
||||
++stats.unknownWrites;
|
||||
break;
|
||||
}
|
||||
if (!found->second.cached && found->second.registeredShader != nullptr) {
|
||||
static const bool profile = std::getenv("APS5_PROFILE_DRAW") != nullptr;
|
||||
const auto& snapshot = *found->second.registeredShader;
|
||||
std::vector<ShaderRecompiler::MemoryRegion> memory{{snapshot.codeAddress, std::as_bytes(std::span(snapshot.code))}};
|
||||
if (!snapshot.header.empty()) memory.push_back({snapshot.headerAddress, snapshot.header});
|
||||
auto lap = std::chrono::steady_clock::now();
|
||||
std::array<double, DriverPhaseCount> phaseMs{};
|
||||
auto phaseLap = lap;
|
||||
DispatchPhaseTiming phaseTiming{profile, lap, phaseMs, phaseLap};
|
||||
insertDispatch(found->second.address, found->second.key, found->second.noDispatchCache, profile, found->second.registeredShader, found->second.forgetAtCapture, memory, found->second.shaderMemory, found->second.captured, found->second.capture, found->second.compiledResult, found->second.missedEntry, found->second.missedDiffering, found->second.attachVariant, phaseTiming);
|
||||
}
|
||||
bool bounded = false;
|
||||
const auto itemWrites = DispatchWriteRanges(*found->second.compiledResult, bounded);
|
||||
if (!bounded) {
|
||||
++stats.unknownWrites;
|
||||
break;
|
||||
}
|
||||
writes.insert(writes.end(), itemWrites.begin(), itemWrites.end());
|
||||
} else {
|
||||
unknownWrites = true;
|
||||
++stats.unknownWrites;
|
||||
break;
|
||||
}
|
||||
} else if (opcode == 0x37 || opcode == 0x49) {
|
||||
const auto label = Pm4::DecodeLabelWrite(packet);
|
||||
@@ -334,10 +351,10 @@ void Driver::reportGroupCapture(std::uint32_t queue) {
|
||||
auto& stats = groupCaptureStats();
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
if (now - stats.reported < std::chrono::seconds(10)) return;
|
||||
AgcDriver::ProfilePrint_nid_no_patch("[groupcap] queue 0x%x (10 s): %llu runs resolved %llu dispatches (%llu cache hits) in %.1f ms (max %.2f ms); %llu adopted %.2f ms after the resolve on average, max %.2f ms; mismatches: address %llu key %llu memory %llu; %llu resolve failures, %llu stale, %llu label overlaps, %llu read an earlier dispatch's output, %llu rejected by the device, %llu dropped because the argument re-read differed\n",
|
||||
AgcDriver::ProfilePrint_nid_no_patch("[groupcap] queue 0x%x (10 s): %llu runs resolved %llu dispatches (%llu cache hits) in %.1f ms (max %.2f ms); %llu adopted %.2f ms after the resolve on average, max %.2f ms; mismatches: address %llu key %llu memory %llu; %llu resolve failures, %llu stale, %llu label overlaps, %llu read an earlier dispatch's output, %llu stopped at unknown writes, %llu rejected by the device, %llu dropped because the argument re-read differed\n",
|
||||
queue, static_cast<unsigned long long>(stats.runs), static_cast<unsigned long long>(stats.resolved), static_cast<unsigned long long>(stats.resolvedHits), stats.resolveMs, stats.resolveMaxMs,
|
||||
static_cast<unsigned long long>(stats.adopted), stats.adopted != 0 ? stats.ageMs / static_cast<double>(stats.adopted) : 0.0, stats.ageMaxMs, static_cast<unsigned long long>(stats.addressMismatches), static_cast<unsigned long long>(stats.keyMismatches), static_cast<unsigned long long>(stats.memoryMismatches),
|
||||
static_cast<unsigned long long>(stats.failures), static_cast<unsigned long long>(stats.stale), static_cast<unsigned long long>(stats.labelOverlaps), static_cast<unsigned long long>(stats.writtenBefore), static_cast<unsigned long long>(stats.deviceRejects), static_cast<unsigned long long>(stats.argumentMismatches));
|
||||
static_cast<unsigned long long>(stats.failures), static_cast<unsigned long long>(stats.stale), static_cast<unsigned long long>(stats.labelOverlaps), static_cast<unsigned long long>(stats.writtenBefore), static_cast<unsigned long long>(stats.unknownWrites), static_cast<unsigned long long>(stats.deviceRejects), static_cast<unsigned long long>(stats.argumentMismatches));
|
||||
stats = GroupCaptureStats{};
|
||||
stats.reported = now;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ Driver::DispatchCacheFootprint Driver::DispatchCacheSize() {
|
||||
|
||||
std::uint64_t Driver::variantBytes(const DispatchVariant& variant) {
|
||||
const auto held = [](const auto& values) { return static_cast<std::uint64_t>(values.capacity() * sizeof(values[0])); };
|
||||
return sizeof(DispatchVariant) + held(variant.runs) + held(variant.words) + held(variant.shared) + held(variant.dataPositions) + held(variant.dataSlots) + held(variant.runBases) + held(variant.shaderDataPatches) + held(variant.captured) + held(variant.spans) + (variant.vertexInfo != nullptr ? sizeof(ShaderRecompiler::ShaderVertexStageInfo) : 0) + (variant.memory != nullptr ? variant.memory->Bytes() : 0);
|
||||
return sizeof(DispatchVariant) + held(variant.runs) + held(variant.words) + held(variant.shared) + held(variant.dataPositions) + held(variant.dataSlots) + held(variant.runBases) + held(variant.shaderDataPatches) + held(variant.captured) + held(variant.spans) + (variant.registeredViews != nullptr ? held(*variant.registeredViews) : 0u) + (variant.vertexInfo != nullptr ? sizeof(ShaderRecompiler::ShaderVertexStageInfo) : 0) + (variant.memory != nullptr ? variant.memory->Bytes() : 0);
|
||||
}
|
||||
|
||||
void Driver::accountVariant(const DispatchVariant& variant, bool added) {
|
||||
|
||||
@@ -18,6 +18,7 @@ void Driver::insertDispatch(std::uint64_t address, std::uint64_t key, bool noDis
|
||||
if (!noDispatchCache) {
|
||||
auto fresh = std::make_shared<DispatchVariant>();
|
||||
fresh->compiled = compiledResult;
|
||||
if (capture != nullptr && !capture->snapshot.registeredImages.empty()) fresh->registeredViews = std::make_shared<const std::vector<ShaderRecompiler::RegisteredImageView>>(capture->snapshot.registeredImages);
|
||||
fresh->shader = registeredShader;
|
||||
fresh->forgetSerial = forgetAtCapture;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/GuestMemory.hpp"
|
||||
#include "Optimization/ResourceProgram.hpp"
|
||||
#include <cstdlib>
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
@@ -37,6 +38,7 @@ void Driver::lookupDispatch(std::uint64_t address, const Submission& submission,
|
||||
std::optional<SampledReadScope> sampling;
|
||||
|
||||
for (std::size_t i = 0; i < variants.size(); ++i) {
|
||||
if (variants[i]->registeredViews != nullptr && !CaptureRegisteredViewsCurrent(*variants[i]->registeredViews)) continue;
|
||||
regions.clear();
|
||||
appendEntryRegions(*variants[i], regions);
|
||||
++compared;
|
||||
@@ -58,16 +60,20 @@ void Driver::lookupDispatch(std::uint64_t address, const Submission& submission,
|
||||
current = variant != nullptr;
|
||||
} else {
|
||||
variant = variants.front();
|
||||
compared = 1;
|
||||
current = true;
|
||||
for (const auto& [begin, bytes] : variant->spans) {
|
||||
GuestMemory::CollectWrites(begin, bytes);
|
||||
if (!GuestMemory::UnchangedSince(begin, bytes, generation)) {
|
||||
current = false;
|
||||
break;
|
||||
current = variant->registeredViews == nullptr || CaptureRegisteredViewsCurrent(*variant->registeredViews);
|
||||
if (!current) variant.reset();
|
||||
if (variant != nullptr) {
|
||||
compared = 1;
|
||||
current = true;
|
||||
for (const auto& [begin, bytes] : variant->spans) {
|
||||
GuestMemory::CollectWrites(begin, bytes);
|
||||
if (!GuestMemory::UnchangedSince(begin, bytes, generation)) {
|
||||
current = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!current) {
|
||||
if (!current && variant != nullptr) {
|
||||
|
||||
std::uint64_t collected = 0;
|
||||
for (const auto& [begin, bytes] : variant->spans) collected = std::max(collected, GuestMemory::CollectWrites(begin, bytes));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/CaptureTrace.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp"
|
||||
#include "Optimization/ResourceProgram.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/CaptureTrace.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Diagnostics.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawPipeline.hpp"
|
||||
@@ -657,6 +658,7 @@ DrawVerdict Driver::draw(QueueState& queue, std::span<const std::uint32_t> packe
|
||||
throw;
|
||||
}
|
||||
for (std::size_t i = 0; i < matched.size(); ++i) {
|
||||
if (matched[i] != nullptr) stageCaptures[i].registeredViews = matched[i]->registeredViews;
|
||||
if (matched[i] == nullptr || (matched[i]->shaderDataPatches.empty() && matched[i]->descriptorPatches.empty())) continue;
|
||||
applyShaderDataPatches(*matched[i]);
|
||||
if (stageData[i].compiled != nullptr) stageData[i].compiled = patchDataWords(*matched[i], stageData[i].words);
|
||||
@@ -923,6 +925,7 @@ DrawVerdict Driver::finishDraw(DrawTail& tail, PerformanceTimer& timing) {
|
||||
const auto candidate = std::find_if(dataCandidates[i].begin(), dataCandidates[i].end(), [&](const auto& kept) { return kept.first->pushOffset == pushCursorBytes; });
|
||||
if (candidate != dataCandidates[i].end() && !verifyDrawDataHits()) {
|
||||
matched[i] = candidate->first;
|
||||
stageCaptures[i].registeredViews = matched[i]->registeredViews;
|
||||
matchedRegions[i] = std::move(candidate->second);
|
||||
reused[i] = true;
|
||||
programResults[i] = stageData[i].compiled != nullptr ? stageData[i].compiled.get() : matched[i]->compiled.get();
|
||||
@@ -955,7 +958,7 @@ DrawVerdict Driver::finishDraw(DrawTail& tail, PerformanceTimer& timing) {
|
||||
try {
|
||||
const auto slotEnd = (pushCursorBytes / Graphics::PipelinePushSlotBytes + 1u) * Graphics::PipelinePushSlotBytes;
|
||||
require(result.pushConstants.size() <= slotEnd - pushCursorBytes, "stage push constants exceed the pipeline push constant block");
|
||||
stages.push_back({program.binary.stage, &result, result.pushConstants.empty() ? 0u : pushCursorBytes});
|
||||
stages.push_back({program.binary.stage, &result, result.pushConstants.empty() ? 0u : pushCursorBytes, stageCaptures[i].registeredViews.get()});
|
||||
pushCursorBytes += static_cast<std::uint32_t>(result.pushConstants.size());
|
||||
} catch (...) {
|
||||
TraceMaterializationFailure(trace.token, submission, packetOffset, "push-constant-validation", completedSubdraws, std::current_exception());
|
||||
@@ -1058,6 +1061,7 @@ DrawVerdict Driver::finishDraw(DrawTail& tail, PerformanceTimer& timing) {
|
||||
if (!rejected.empty()) return DrawVerdict::Rejected;
|
||||
programResults[0] = compiledStages.back().get();
|
||||
stages[0].program = programResults[0];
|
||||
stages[0].registeredImageViews = stageCaptures[0].registeredViews.get();
|
||||
require(programResults[0]->pushConstants.size() == pushBytes && programResults[0]->parameterExports == exports, "pairing the mesh program with its pixel shader changed the push constants or the parameter exports the pixel shader was built for");
|
||||
}
|
||||
require(programResults[0]->meshBarycentrics == meshBarycentrics, "the mesh program was compiled for a different barycentric layout than its pixel shader");
|
||||
@@ -1130,6 +1134,7 @@ DrawVerdict Driver::finishDraw(DrawTail& tail, PerformanceTimer& timing) {
|
||||
for (std::size_t record = 0; record < records.size(); ++record) {
|
||||
if (drawable(records[record])) lastDrawable = record;
|
||||
}
|
||||
bool recordedOne = false;
|
||||
for (std::uint32_t record = 0; record < records.size(); ++record) {
|
||||
const auto& arguments = records[record];
|
||||
if (traceIndirect) std::fprintf(stderr, "[draw] record %u: count %u instances %u first %u vertexOffset %u startInstance %u\n", record, arguments.count, arguments.instances, arguments.firstVertexOrIndex, arguments.vertexOffset, arguments.firstInstance);
|
||||
@@ -1174,6 +1179,7 @@ DrawVerdict Driver::finishDraw(DrawTail& tail, PerformanceTimer& timing) {
|
||||
const auto pushBytes = result.pushConstants.size();
|
||||
decodeVertexInfo(programIndex);
|
||||
result = *materializeDrawStage(programIndex, pushOffsets[programIndex], queue, submission, packetOffset, trace.token, programs, graphics, pixel, vertexInfos, memory, linked, programs[programIndex].binary.stage == Stage::TessellationControl || programs[programIndex].binary.stage == Stage::TessellationEvaluation ? direct : drawParameters, localDevice, *shaderMemory, stageCaptures, recompiled, drawHit, matched, matchedRegions, profile, dumpTarget, dumpSlot1, captures, phaseTiming, phaseMs, rejected, meshBarycentrics);
|
||||
for (auto& stage : stages) if (stage.program == &result) stage.registeredImageViews = stageCaptures[programIndex].registeredViews.get();
|
||||
if (!rejected.empty()) return DrawVerdict::Rejected;
|
||||
require(result.pushConstants.size() == pushBytes, "patched program changed its push constant layout");
|
||||
}
|
||||
@@ -1185,6 +1191,11 @@ DrawVerdict Driver::finishDraw(DrawTail& tail, PerformanceTimer& timing) {
|
||||
return DrawVerdict::Rejected;
|
||||
}
|
||||
if (pipelined && pipelinedIndirect && record == lastDrawable && !gpuLock.owns_lock() && deferredLabels().labels.empty()) {
|
||||
runCaptureCheckHook();
|
||||
if (tail.queue != nullptr && capturedMemoryChanged(memory)) {
|
||||
const RecaptureScope recapture;
|
||||
return draw(*tail.queue, tail.packet, submission, tail.packetOffset, rejected);
|
||||
}
|
||||
phaseTiming.Phase(DrawRowVectors);
|
||||
auto writes = drawWriteRanges(graphics, stages);
|
||||
const auto commitQueue = submission.queue;
|
||||
@@ -1203,6 +1214,15 @@ DrawVerdict Driver::finishDraw(DrawTail& tail, PerformanceTimer& timing) {
|
||||
}
|
||||
drainBeforeInline();
|
||||
lockForDraw();
|
||||
if (!recordedOne) {
|
||||
runCaptureCheckHook();
|
||||
if (tail.queue != nullptr && capturedMemoryChanged(memory, snapshots)) {
|
||||
gpuLock.unlock();
|
||||
const RecaptureScope recapture;
|
||||
return draw(*tail.queue, tail.packet, submission, tail.packetOffset, rejected);
|
||||
}
|
||||
}
|
||||
recordedOne = true;
|
||||
noteDrawWriters(stages, submission.queue);
|
||||
phaseTiming.Phase(DrawRowVectors);
|
||||
localDevice->Draw(graphics, direct, stages, snapshots, nullptr, tracePtr);
|
||||
@@ -1239,6 +1259,11 @@ DrawVerdict Driver::finishDraw(DrawTail& tail, PerformanceTimer& timing) {
|
||||
}
|
||||
}
|
||||
if (pipelined && !drawParameters.indirect && (tail.queue == nullptr || deferredLabels().labels.empty())) {
|
||||
runCaptureCheckHook();
|
||||
if (tail.queue != nullptr && capturedMemoryChanged(memory)) {
|
||||
const RecaptureScope recapture;
|
||||
return draw(*tail.queue, tail.packet, submission, tail.packetOffset, rejected);
|
||||
}
|
||||
phaseTiming.Phase(DrawRowVectors);
|
||||
auto writes = drawWriteRanges(graphics, stages);
|
||||
const auto commitQueue = submission.queue;
|
||||
@@ -1258,6 +1283,12 @@ DrawVerdict Driver::finishDraw(DrawTail& tail, PerformanceTimer& timing) {
|
||||
}
|
||||
if (drawParameters.indirect) drainBeforeInline();
|
||||
lockForDraw();
|
||||
runCaptureCheckHook();
|
||||
if (tail.queue != nullptr && capturedMemoryChanged(memory, snapshots)) {
|
||||
gpuLock.unlock();
|
||||
const RecaptureScope recapture;
|
||||
return draw(*tail.queue, tail.packet, submission, tail.packetOffset, rejected);
|
||||
}
|
||||
noteDrawWriters(stages, submission.queue);
|
||||
phaseTiming.Phase(DrawRowVectors);
|
||||
if (recipe != nullptr) {
|
||||
|
||||
@@ -227,8 +227,8 @@ void Driver::eraseDrawEntry(std::uint64_t key, const std::shared_ptr<DrawEntry>&
|
||||
bool DecodeProgramsCurrent(const DrawDecode& decode, const ShaderRegistry&) {
|
||||
return std::all_of(decode.programs.begin(), decode.programs.end(), [&](const DrawProgram& program) {
|
||||
if (!program.snapshot->header.empty()) return true;
|
||||
return ReadRawShader(program.snapshot->codeAddress + program.codeOffset * sizeof(std::uint32_t)) == program.snapshot &&
|
||||
(program.tailContinuation == nullptr || ReadRawShader(program.tailContinuation->codeAddress) == program.tailContinuation);
|
||||
return ReadRawShader(program.snapshot->codeAddress + program.codeOffset * sizeof(std::uint32_t), program.snapshot) == program.snapshot &&
|
||||
(program.tailContinuation == nullptr || ReadRawShader(program.tailContinuation->codeAddress, program.tailContinuation) == program.tailContinuation);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ std::shared_ptr<const ShaderRecompiler::RecompileResult> Driver::materializeDraw
|
||||
stageCapture.regions = shaderMemory.TakeRecentRegions();
|
||||
stageCapture.supplied = shaderMemory.SuppliedBlocks();
|
||||
stageCapture.userDataUse = capture->userDataUse;
|
||||
stageCapture.registeredViews = std::make_shared<const std::vector<ShaderRecompiler::RegisteredImageView>>(capture->snapshot.registeredImages);
|
||||
recompiled[i] = true;
|
||||
memory = shaderMemory.Regions();
|
||||
|
||||
@@ -225,6 +226,7 @@ void Driver::cacheDrawStages(bool useDrawEntries, bool drawHit, const Pm4::DrawP
|
||||
if (stageCapture.compiled == nullptr || !CacheableResult(*stageCapture.compiled)) continue;
|
||||
auto variant = std::make_shared<DispatchVariant>();
|
||||
variant->compiled = stageCapture.compiled;
|
||||
variant->registeredViews = stageCapture.registeredViews;
|
||||
if (programs[i].binary.stage == ShaderRecompiler::ShaderStage::Mesh) {
|
||||
std::copy_n(programs[i].userData.begin() + ShaderRecompiler::MeshIndexBufferUserWord, variant->meshIndexDescriptor.size(), variant->meshIndexDescriptor.begin());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Diagnostics.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/GuestMemory.hpp"
|
||||
#include "Optimization/ResourceProgram.hpp"
|
||||
#include <algorithm>
|
||||
#include <bit>
|
||||
|
||||
@@ -141,6 +142,7 @@ void Driver::lookupDraw(const Submission& submission, const std::shared_ptr<Vulk
|
||||
bool anyLayout = false;
|
||||
for (std::size_t rank = 0; rank < variants.size(); ++rank) {
|
||||
const auto& variant = variants[rank];
|
||||
if (variant->registeredViews != nullptr && !CaptureRegisteredViewsCurrent(*variant->registeredViews)) continue;
|
||||
if (variant->pushOffset != cursor) continue;
|
||||
if (programs[i].binary.stage == ShaderRecompiler::ShaderStage::Mesh && !std::equal(variant->meshIndexDescriptor.begin(), variant->meshIndexDescriptor.end(), programs[i].userData.begin() + ShaderRecompiler::MeshIndexBufferUserWord)) {
|
||||
if (!anyLayout) outcome = EntryOutcome::Differing;
|
||||
@@ -249,6 +251,7 @@ void Driver::lookupDraw(const Submission& submission, const std::shared_ptr<Vulk
|
||||
const auto& was = dataEntry->decode->programs[i].userData;
|
||||
auto& candidates = dataCandidates[i];
|
||||
for (const auto& variant : dataEntry->stages[i]) {
|
||||
if (variant->registeredViews != nullptr && !CaptureRegisteredViewsCurrent(*variant->registeredViews)) continue;
|
||||
bool usedEqual = true;
|
||||
for (std::size_t w = 0; w < now.size() && usedEqual; ++w) {
|
||||
if (now[w] != was[w] && (w >= 64u || ((variant->userDataMask >> w) & 1u) != 0)) usedEqual = false;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/GuestMemory.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Pm4.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Synchronization/DeferredLabels.hpp"
|
||||
#include "prx/libSceAgcDriver/Graphics/include/DepthSurface.hpp"
|
||||
#include <cstdlib>
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
@@ -79,6 +80,10 @@ std::optional<DrawVerdict> Driver::precheckDraw(const QueueState& queue, const S
|
||||
auto copyDraw = DepthCopyDraw(queue, *copy);
|
||||
return draw(copyDraw, packet, submission, packetOffset, rejected);
|
||||
}
|
||||
if (const auto control = Graphics::DecodeDepthRenderControl(queue); control && ((control->control & 0x60u) != 0u || Graphics::DepthSurfaceAt(control->address))) {
|
||||
if (DrawPipeline::Active()) DrawPipeline::Queue0().Drain(DrawPipeline::DrainReason::Packet, (packet[0] >> 8u) & 0xffu);
|
||||
Graphics::NoteDepthRenderControl(*control);
|
||||
}
|
||||
if (Graphics::DepthResummarizeDrawsNothing(queue)) return DrawVerdict::Nothing;
|
||||
rejected = Graphics::DepthMaintenanceRejection(queue);
|
||||
if (!rejected.empty()) return DrawVerdict::Rejected;
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
#include <pthread.h>
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/DriverMemory.hpp"
|
||||
#endif
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
|
||||
@@ -54,9 +57,15 @@ void PrintFailure(std::exception_ptr error) {
|
||||
std::fflush(stderr);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
constexpr std::uint64_t DriverMemoryAddress = MacOsDriverMemoryBase;
|
||||
constexpr std::size_t DriverMemoryBytes = DriverMemorySpan;
|
||||
constexpr std::uint64_t FsTableAddress = RetargetPs5DriverMemory(0xfe0040000ull);
|
||||
#else
|
||||
constexpr std::uint64_t DriverMemoryAddress = 0xfe0000000ull + GuestArena::GuestAddressOffset;
|
||||
constexpr std::size_t DriverMemoryBytes = 2u << 20u;
|
||||
constexpr std::uint64_t FsTableAddress = DriverMemoryAddress + 0x40000ull;
|
||||
#endif
|
||||
constexpr std::uint64_t FsTableSlotBytes = 16u;
|
||||
constexpr std::uint64_t FsTableSlots = 6u;
|
||||
constexpr std::uint64_t FsRoutineRecords = 8u;
|
||||
@@ -73,6 +82,10 @@ void MapDriverMemory() {
|
||||
#ifdef _WIN32
|
||||
mapped = reinterpret_cast<void*>(DriverMemoryAddress);
|
||||
GuestArena::GuestArenaCommit_nid_postfix(mapped, DriverMemoryBytes, PAGE_READWRITE, DriverMemoryBytes);
|
||||
#elif defined(__APPLE__)
|
||||
mapped = mmap(reinterpret_cast<void*>(DriverMemoryAddress), DriverMemoryBytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if (mapped == MAP_FAILED) throw std::system_error(errno, std::generic_category(), "map the AGC driver memory");
|
||||
if (reinterpret_cast<std::uint64_t>(mapped) != DriverMemoryAddress) munmap(mapped, DriverMemoryBytes);
|
||||
#else
|
||||
mapped = mmap(reinterpret_cast<void*>(DriverMemoryAddress), DriverMemoryBytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0);
|
||||
if (mapped == MAP_FAILED) throw std::system_error(errno, std::generic_category(), "map the AGC driver memory");
|
||||
@@ -106,6 +119,11 @@ bool StackHoldsImport() {
|
||||
std::uintptr_t low = 0;
|
||||
std::uintptr_t high = 0;
|
||||
Bounds() {
|
||||
#ifdef __APPLE__
|
||||
const auto self = pthread_self();
|
||||
high = reinterpret_cast<std::uintptr_t>(pthread_get_stackaddr_np(self));
|
||||
low = high - pthread_get_stacksize_np(self);
|
||||
#else
|
||||
pthread_attr_t attributes;
|
||||
if (pthread_getattr_np(pthread_self(), &attributes) != 0) return;
|
||||
void* base = nullptr;
|
||||
@@ -115,6 +133,7 @@ bool StackHoldsImport() {
|
||||
high = low + size;
|
||||
}
|
||||
pthread_attr_destroy(&attributes);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
thread_local const Bounds bounds;
|
||||
|
||||
@@ -128,7 +128,7 @@ void Driver::noteCopyWriter(std::uint64_t program, std::uint64_t begin, std::uin
|
||||
knownValueEntries.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
std::lock_guard lock(writtenBuffersMutex);
|
||||
writtenBuffers.Push({program, begin, end, ++writtenBufferSerial, queue, false, std::move(known), generation});
|
||||
writtenBuffers.Push({known || !copyKnownValues() ? program : 0, begin, end, ++writtenBufferSerial, queue, false, std::move(known), generation});
|
||||
}
|
||||
|
||||
bool Driver::copyKnownValues() {
|
||||
|
||||
@@ -53,11 +53,11 @@ void Driver::noteWrittenBuffers(std::uint64_t program, std::uint32_t queue, cons
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::uint64_t, std::uint64_t>> DispatchWriteRanges(const ShaderRecompiler::RecompileResult& compiled, bool& bounded) {
|
||||
bounded = compiled.bdaAbiVersion == 0;
|
||||
bounded = compiled.bdaAbiVersion == 0 || std::any_of(compiled.bindings.begin(), compiled.bindings.end(), [](const ShaderRecompiler::DescriptorBinding& binding) { return binding.role == ShaderRecompiler::DescriptorRole::FaultBuffer; });
|
||||
std::vector<std::pair<std::uint64_t, std::uint64_t>> ranges;
|
||||
constexpr std::uint64_t UnknownImageBytes = 64ull * 1024 * 1024;
|
||||
for (const auto& binding : compiled.bindings) {
|
||||
if (binding.role == ShaderRecompiler::DescriptorRole::Gds || binding.role == ShaderRecompiler::DescriptorRole::BdaPagetable || binding.role == ShaderRecompiler::DescriptorRole::FaultBuffer) bounded = false;
|
||||
if (binding.role == ShaderRecompiler::DescriptorRole::Gds || binding.role == ShaderRecompiler::DescriptorRole::BdaPagetable) bounded = false;
|
||||
if (binding.role != ShaderRecompiler::DescriptorRole::GuestImages || binding.kind != ShaderRecompiler::DescriptorKind::StorageImage) continue;
|
||||
for (std::uint32_t element = 0; element < binding.count; ++element) {
|
||||
const bool written = element >= binding.imageWritten.size() || binding.imageWritten[element];
|
||||
@@ -111,7 +111,7 @@ std::vector<std::pair<std::uint64_t, std::uint64_t>> DrawWriteRanges(const Graph
|
||||
const bool written = element >= binding.imageWritten.size() || binding.imageWritten[element];
|
||||
if (!written || binding.guestDescriptor.size() < (static_cast<std::size_t>(element) + 1) * 8) continue;
|
||||
const auto words = std::span<const std::uint32_t>(binding.guestDescriptor).subspan(static_cast<std::size_t>(element) * 8, 8);
|
||||
if (words[0] == 0u && (words[1] & 0xffu) == 0u) continue;
|
||||
if (Graphics::IsNullTextureResource(words)) continue;
|
||||
const auto resource = Graphics::DecodeTextureResource(words);
|
||||
if (resource.baseAddress == 0) continue;
|
||||
const auto surfaceBytes = Graphics::DescribeSurface(resource).guestBytes;
|
||||
|
||||
@@ -56,7 +56,7 @@ void Driver::validate(const Submission& submission, const std::uint32_t* guest)
|
||||
const auto header = commands[cursor];
|
||||
if (Pm4::FillerPacket(header)) { ++cursor; continue; }
|
||||
if ((header & 0xc0000000u) != 0xc0000000u) {
|
||||
char what[96];
|
||||
char what[128];
|
||||
std::snprintf(what, sizeof(what), "unsupported PM4 packet type: header 0x%08x at DWORD %zu of %zu", header, cursor, commands.size());
|
||||
|
||||
dumpPackets(commands, guest);
|
||||
|
||||
@@ -27,6 +27,24 @@ namespace {
|
||||
|
||||
constexpr std::uint32_t eopSelfSignalFlipLimit = 4;
|
||||
|
||||
struct RingOrder {
|
||||
std::uint32_t queue = 0xffffffffu;
|
||||
std::uint64_t serial = 0;
|
||||
bool afterDispatch = false;
|
||||
};
|
||||
|
||||
thread_local RingOrder ringOrder;
|
||||
|
||||
void noteRingPacket(std::uint32_t queueId, std::uint64_t serial, std::uint32_t opcode, std::uint32_t header) {
|
||||
if (ringOrder.queue != queueId || ringOrder.serial != serial) ringOrder = {queueId, serial, false};
|
||||
if (opcode == 0x15 || opcode == 0x16 || opcode == 0x76) return;
|
||||
if (opcode == 0x10) {
|
||||
const auto sub = (header >> 2u) & 0x3fu;
|
||||
if ((header & 0xfcu) == 0 || sub == 0x0b || sub == 0x0c) return;
|
||||
}
|
||||
ringOrder.afterDispatch = false;
|
||||
}
|
||||
|
||||
bool orderedFills() {
|
||||
static const bool ordered = std::getenv("APS5_PIPELINE_DRAIN_FILLS") == nullptr;
|
||||
return ordered;
|
||||
@@ -63,12 +81,12 @@ bool keepsDrawPipeline(std::span<const std::uint32_t> packet, std::uint32_t head
|
||||
if (packet.size() < 7) return false;
|
||||
const auto destination = Pm4::DmaDestination(packet);
|
||||
if (destination == Pm4::DmaDestinationNowhere) return true;
|
||||
if (destination == Pm4::DmaSelectGds) return true;
|
||||
const auto bytes = Pm4::DmaBytes(packet);
|
||||
if (bytes == 0) return true;
|
||||
const auto source = Pm4::DmaSource(packet);
|
||||
if ((source == 0 || source == 3) && DrawPipeline::Queue0().Overlaps(packet[2] | (static_cast<std::uint64_t>(packet[3]) << 32u), bytes)) return false;
|
||||
const auto address = packet[4] | (static_cast<std::uint64_t>(packet[5]) << 32u);
|
||||
if (source == Pm4::DmaSelectGds && DrawPipeline::Queue0().Overlaps(Pm4::GdsAddress() + packet[2], bytes)) return false;
|
||||
const auto address = destination == Pm4::DmaSelectGds ? Pm4::GdsAddress() + packet[4] : packet[4] | (static_cast<std::uint64_t>(packet[5]) << 32u);
|
||||
return !DrawPipeline::Queue0().Overlaps(address, bytes);
|
||||
}
|
||||
case 0x3c: case 0x93: {
|
||||
@@ -273,6 +291,7 @@ void Driver::execute(const Submission& submission) {
|
||||
}
|
||||
if (APS5_ENABLE_TIMING_LOG && submission.queue == 0 && pendingFrameTiming == nullptr) includeTimingSubmission(submission, false);
|
||||
PerformanceContext timingContext(submission.queue == 0 ? pendingFrameTiming.get() : FrameTiming::Async());
|
||||
if (submission.queue != 0 && Graphics::Recorder::DispatchOverlapEnabled()) noteRingPacket(submission.queue, submission.serial, opcode, header);
|
||||
PerformanceTimer timing("Driver.Packet");
|
||||
if (!predicated) noteLabelIssue(packet, submission.queue);
|
||||
if (pipelined && !predicated && header != FlipPacketHeader && header != RenderingWaitPacketHeader && !submission.flips.contains(cursor) && (enqueueLabelPacket(packet, opcode, submission.queue) || enqueueDmaPacket(packet, opcode, submission.queue, queue))) {
|
||||
@@ -396,6 +415,7 @@ void Driver::execute(const Submission& submission) {
|
||||
CheckFailure();
|
||||
std::uint64_t batchesAtFlip = 0, unsignaledAtFlip = 0;
|
||||
bool flipInterruptDeferred = false;
|
||||
Graphics::StorageTexture::NoteFlip();
|
||||
if (!drains) {
|
||||
|
||||
GuestMemory::TagGpuLockSite(GuestMemory::GpuLockSite::Flush);
|
||||
@@ -450,6 +470,15 @@ void Driver::execute(const Submission& submission) {
|
||||
timed(&WorkerProfile::dispatchMs, [&] { resolveGroupAhead(submission, queue, cursor); });
|
||||
}
|
||||
}
|
||||
const bool ringOverlap = submission.queue != 0 && Graphics::Recorder::DispatchOverlapEnabled();
|
||||
if (ringOverlap) Graphics::Recorder::SetDispatchOrder(submission.queue + 1u, ringOrder.afterDispatch);
|
||||
struct ClearOrder {
|
||||
bool active;
|
||||
~ClearOrder() {
|
||||
if (active) Graphics::Recorder::SetDispatchOrder(0, false);
|
||||
}
|
||||
} clearOrder{ringOverlap};
|
||||
if (ringOverlap) ringOrder.afterDispatch = true;
|
||||
if (opcode == 0x15) timed(&WorkerProfile::dispatchMs, [&] { dispatch(queue, packet, submission); });
|
||||
else timed(&WorkerProfile::dispatchMs, [&] { dispatchIndirect(queue, packet, submission); });
|
||||
Pm4::NoteDispatchRegisters(packet, queue);
|
||||
|
||||
@@ -105,7 +105,7 @@ void Driver::flushBetweenPackets(std::uint32_t queue, std::uint32_t header, bool
|
||||
lastReport = reportNow;
|
||||
const auto stores = Graphics::Recorder::StoreCounts();
|
||||
const auto failed = [](TrySite site) { return static_cast<unsigned long long>(triesFailed[site].load()); };
|
||||
AgcDriver::ProfilePrint_nid_no_patch("[labels] batch flushes between packets: %llu at the next packet, %llu by deadline, %llu by size cap (%llu well overdue, waited for the mutex); %llu boundary reaps; record tries skipped (self-locking next) %llu; failed tries: label %llu, flush %llu, reap %llu, poll %llu, idle %llu, capture %llu, poll-record %llu; at the packet's own lock: %llu label groups (%.0f ms), %llu submits (%.0f ms incl. queue 0's reaps), left to it by a failed try: %llu groups, %llu submits; after a capture: %llu groups recorded by a try, %llu packets redone for a queued label over the capture; %llu suspend points; stores: %llu in %llu runs (%llu joined, %llu replaced, %llu WAW barriers, %llu joins refused; %llu runs recorded at submit, %llu in place before a writer or reader); DCC key stores: %llu queued in %llu runs (%llu before a writer, %llu joined a queued range); queued labels: %llu noted (%llu over a recorded entry), %llu same-queue wait hits, %llu groups recorded from a poll loop, %llu from the flush hook (%llu hook accesses, %llu inside a completion skipped)\n", static_cast<unsigned long long>(packetFlushes.load()), static_cast<unsigned long long>(deadlineFlushes.load()), static_cast<unsigned long long>(capFlushes.load()), static_cast<unsigned long long>(overdueLocks.load()), static_cast<unsigned long long>(boundaryReaps.load()), static_cast<unsigned long long>(recordTriesSkipped.load()), failed(TryLabel), failed(TryFlush), failed(TryReap), failed(TryPoll), failed(TryIdle), failed(TryCapture), failed(TryPollRecord), static_cast<unsigned long long>(packetLockRecords.load()), packetLockRecordUs.load() / 1000.0, static_cast<unsigned long long>(packetLockSubmits.load()), packetLockSubmitUs.load() / 1000.0, static_cast<unsigned long long>(packetLockDeferred.load()), static_cast<unsigned long long>(packetSubmitDeferred.load()), static_cast<unsigned long long>(captureTryRecords.load()), static_cast<unsigned long long>(captureRetries.load()), static_cast<unsigned long long>(suspendPoints.load()), static_cast<unsigned long long>(stores.stores), static_cast<unsigned long long>(stores.runs), static_cast<unsigned long long>(stores.joined), static_cast<unsigned long long>(stores.replaced), static_cast<unsigned long long>(stores.wawBarriers), static_cast<unsigned long long>(stores.joinsRefused), static_cast<unsigned long long>(stores.runsAtSubmit), static_cast<unsigned long long>(stores.runsForced), static_cast<unsigned long long>(stores.keyStores), static_cast<unsigned long long>(stores.keyStoreRuns), static_cast<unsigned long long>(stores.keyStoreRunsForWriter), static_cast<unsigned long long>(stores.keyStoresJoined), static_cast<unsigned long long>(stores.queuedNoted), static_cast<unsigned long long>(stores.queuedOverRecorded), static_cast<unsigned long long>(stores.queuedHits), static_cast<unsigned long long>(pollLabelRecords.load()), static_cast<unsigned long long>(hookLabelRecords.load()), static_cast<unsigned long long>(stores.queuedHookRecords), static_cast<unsigned long long>(stores.queuedHookInCompletion));
|
||||
AgcDriver::ProfilePrint_nid_no_patch("[labels] batch flushes between packets: %llu at the next packet, %llu by deadline, %llu by size cap (%llu well overdue, waited for the mutex); %llu boundary reaps; record tries skipped (self-locking next) %llu; failed tries: label %llu, flush %llu, reap %llu, poll %llu, idle %llu, capture %llu, poll-record %llu; at the packet's own lock: %llu label groups (%.0f ms), %llu submits (%.0f ms incl. queue 0's reaps), left to it by a failed try: %llu groups, %llu submits; after a capture: %llu groups recorded by a try, %llu packets redone for a queued label over the capture, %llu for captured memory that changed before recording; %llu suspend points; stores: %llu in %llu runs (%llu joined, %llu replaced, %llu WAW barriers, %llu joins refused; %llu runs recorded at submit, %llu in place before a writer or reader); DCC key stores: %llu queued in %llu runs (%llu before a writer, %llu joined a queued range); queued labels: %llu noted (%llu over a recorded entry), %llu same-queue wait hits, %llu groups recorded from a poll loop, %llu from the flush hook (%llu hook accesses, %llu inside a completion skipped)\n", static_cast<unsigned long long>(packetFlushes.load()), static_cast<unsigned long long>(deadlineFlushes.load()), static_cast<unsigned long long>(capFlushes.load()), static_cast<unsigned long long>(overdueLocks.load()), static_cast<unsigned long long>(boundaryReaps.load()), static_cast<unsigned long long>(recordTriesSkipped.load()), failed(TryLabel), failed(TryFlush), failed(TryReap), failed(TryPoll), failed(TryIdle), failed(TryCapture), failed(TryPollRecord), static_cast<unsigned long long>(packetLockRecords.load()), packetLockRecordUs.load() / 1000.0, static_cast<unsigned long long>(packetLockSubmits.load()), packetLockSubmitUs.load() / 1000.0, static_cast<unsigned long long>(packetLockDeferred.load()), static_cast<unsigned long long>(packetSubmitDeferred.load()), static_cast<unsigned long long>(captureTryRecords.load()), static_cast<unsigned long long>(captureRetries.load()), static_cast<unsigned long long>(captureChangeRetries.load()), static_cast<unsigned long long>(suspendPoints.load()), static_cast<unsigned long long>(stores.stores), static_cast<unsigned long long>(stores.runs), static_cast<unsigned long long>(stores.joined), static_cast<unsigned long long>(stores.replaced), static_cast<unsigned long long>(stores.wawBarriers), static_cast<unsigned long long>(stores.joinsRefused), static_cast<unsigned long long>(stores.runsAtSubmit), static_cast<unsigned long long>(stores.runsForced), static_cast<unsigned long long>(stores.keyStores), static_cast<unsigned long long>(stores.keyStoreRuns), static_cast<unsigned long long>(stores.keyStoreRunsForWriter), static_cast<unsigned long long>(stores.keyStoresJoined), static_cast<unsigned long long>(stores.queuedNoted), static_cast<unsigned long long>(stores.queuedOverRecorded), static_cast<unsigned long long>(stores.queuedHits), static_cast<unsigned long long>(pollLabelRecords.load()), static_cast<unsigned long long>(hookLabelRecords.load()), static_cast<unsigned long long>(stores.queuedHookRecords), static_cast<unsigned long long>(stores.queuedHookInCompletion));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,9 +16,44 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
|
||||
namespace {
|
||||
|
||||
bool gdsWritesPending(std::span<const std::uint32_t> packet, const VulkanDevice* localDevice) {
|
||||
const auto address = Pm4::GdsAddress() + packet[4];
|
||||
const auto bytes = static_cast<std::size_t>(Pm4::DmaBytes(packet));
|
||||
const std::array<std::pair<std::uint64_t, std::uint64_t>, 1> range{{{address, address + bytes}}};
|
||||
if (Graphics::Recorder::SnapshotWriteOverlaps(address, bytes) || Graphics::StorageTexture::AnyPendingOverlaps(range) || Graphics::AnyShadowedOverlaps(address, bytes)) return true;
|
||||
if (localDevice == nullptr || !Pm4::GdsImportable()) return false;
|
||||
std::lock_guard gpuLock(GuestMemory::GpuMutex());
|
||||
return localDevice->StoresPendingOver(address, bytes);
|
||||
}
|
||||
|
||||
std::uint64_t dmaAddress(std::uint32_t low, std::uint32_t high) {
|
||||
return low | (static_cast<std::uint64_t>(high) << 32u);
|
||||
}
|
||||
|
||||
bool gdsSpan(std::uint64_t offset, std::size_t bytes) {
|
||||
return offset <= Pm4::GdsBytes && bytes <= Pm4::GdsBytes - offset;
|
||||
}
|
||||
|
||||
std::optional<Pm4::MemoryCopy> decodeCopy(std::span<const std::uint32_t> packet) {
|
||||
if (auto copy = Pm4::DecodeMemoryCopy(packet)) return copy;
|
||||
if (packet.size() != 7 || !Pm4::GdsImportable()) return std::nullopt;
|
||||
const auto source = Pm4::DmaSource(packet);
|
||||
const auto destination = Pm4::DmaDestination(packet);
|
||||
const std::size_t bytes = Pm4::DmaBytes(packet);
|
||||
if (bytes == 0) return std::nullopt;
|
||||
if (source == Pm4::DmaSelectGds && (destination == 0 || destination == 3) && gdsSpan(packet[2], bytes)) return Pm4::MemoryCopy{Pm4::GdsAddress() + packet[2], dmaAddress(packet[4], packet[5]), bytes};
|
||||
if ((source == 0 || source == 3) && destination == Pm4::DmaSelectGds && gdsSpan(packet[4], bytes)) return Pm4::MemoryCopy{dmaAddress(packet[2], packet[3]), Pm4::GdsAddress() + packet[4], bytes};
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Driver::preparePacketMemory(const Submission& submission, QueueState& queue, std::span<const std::uint32_t> packet, std::uint32_t header, std::uint32_t opcode, bool& wroteOnGpu, bool& endOfPipeInterrupt, bool& interruptDeferred, bool& drawPacket, bool& sampleDump) {
|
||||
static const bool drainAll = std::getenv("APS5_DRAIN_ALL") != nullptr;
|
||||
static const bool profile = std::getenv("APS5_PROFILE_DRAW") != nullptr;
|
||||
@@ -119,7 +154,7 @@ bool Driver::preparePacketMemory(const Submission& submission, QueueState& queue
|
||||
if (!drainAll && !cpuStores && (opcode == 0x40 || opcode == 0x50 || opcode == 0x83)) {
|
||||
constexpr std::size_t gpuStoreLimit = 65536;
|
||||
bool drained = true;
|
||||
const auto copy = opcode == 0x50 ? Pm4::DecodeMemoryCopy(packet) : std::nullopt;
|
||||
const auto copy = opcode == 0x50 ? decodeCopy(packet) : std::nullopt;
|
||||
const auto copyBehindPendingSource = [&] {
|
||||
if (!copy.has_value() || copy->bytes > gpuStoreLimit || !GuestMemory::Accessible(reinterpret_cast<const void*>(copy->source), copy->bytes) || !GuestMemory::Accessible(reinterpret_cast<const void*>(copy->destination), copy->bytes, true)) return false;
|
||||
const auto end = copy->source + copy->bytes;
|
||||
@@ -137,11 +172,16 @@ bool Driver::preparePacketMemory(const Submission& submission, QueueState& queue
|
||||
if (outcome.path != 1 && outcome.path != 3) throw std::runtime_error("AGC driver: a DMA_DATA copy of up to 64 KiB that GpuCopyPossible accepted took copy path " + std::to_string(outcome.path));
|
||||
return true;
|
||||
};
|
||||
if (copyBehindPendingSource()) {
|
||||
const bool gdsDestination = opcode == 0x50 && packet.size() >= 7 && Pm4::DmaDestination(packet) == Pm4::DmaSelectGds;
|
||||
const bool gdsOnGpu = gdsDestination && Pm4::GdsImportable();
|
||||
if ((!gdsDestination || gdsOnGpu) && copyBehindPendingSource()) {
|
||||
++copiesBehindPendingSources;
|
||||
wroteOnGpu = true;
|
||||
drained = false;
|
||||
} else if (const auto store = Pm4::ResolveStore(packet, queue, gpuStoreLimit)) {
|
||||
} else if (gdsDestination && !gdsWritesPending(packet, device.Load().get())) {
|
||||
orderedAlready = true;
|
||||
drained = false;
|
||||
} else if (const auto store = gdsDestination && !gdsOnGpu ? std::nullopt : Pm4::ResolveStore(packet, queue, gpuStoreLimit)) {
|
||||
const auto bytes = store->Bytes();
|
||||
if (bytes.empty()) {
|
||||
|
||||
@@ -297,6 +337,7 @@ void Driver::dumpSampleCounters(std::uint64_t address) {
|
||||
bool Driver::enqueueDmaPacket(std::span<const std::uint32_t> packet, std::uint32_t opcode, std::uint32_t queue, const QueueState& state) {
|
||||
if (opcode != 0x50 || queue != 0 || packet.size() < 7 || !DrawPipeline::Active() || !deferredLabels().labels.empty()) return false;
|
||||
const auto source = ((packet[1] >> 29u) & 3u) | ((packet[6] >> 24u) & 4u) | ((packet[6] >> 25u) & 8u);
|
||||
if (Pm4::DmaDestination(packet) == Pm4::DmaSelectGds && gdsWritesPending(packet, device.Load().get())) return false;
|
||||
constexpr std::size_t immediateLimit = std::size_t{16} << 20u;
|
||||
constexpr std::size_t gpuStoreLimit = 65536;
|
||||
if (source == 2 && Pm4::DmaBytes(packet) > gpuStoreLimit && Pm4::DmaDestination(packet) != Pm4::DmaSelectGds) {
|
||||
@@ -307,7 +348,7 @@ bool Driver::enqueueDmaPacket(std::span<const std::uint32_t> packet, std::uint32
|
||||
DrawPipeline::Queue0().Enqueue([this, queue, fillAddress, fillBytes, pattern] {
|
||||
GuestMemory::SetCurrentPacket(0x50, queue);
|
||||
if (const auto localDevice = device.Load()) {
|
||||
storeBufferFill(queue, fillAddress, fillBytes, {pattern, pattern, pattern, pattern}, localDevice, false, false);
|
||||
storeBufferFill(queue, fillAddress, fillBytes, {pattern, pattern, pattern, pattern}, localDevice, false, true);
|
||||
++dmaFills;
|
||||
}
|
||||
}, {{fillAddress, fillAddress + fillBytes}});
|
||||
@@ -319,12 +360,17 @@ bool Driver::enqueueDmaPacket(std::span<const std::uint32_t> packet, std::uint32
|
||||
const auto address = store->address;
|
||||
std::vector<std::byte> bytes(store->Bytes().begin(), store->Bytes().end());
|
||||
const auto size = bytes.size();
|
||||
const bool gds = Pm4::DmaDestination(packet) == Pm4::DmaSelectGds;
|
||||
const bool metadataFill = Pm4::DmaDestination(packet) != 1;
|
||||
const auto fillAddress = packet[4] | (static_cast<std::uint64_t>(packet[5]) << 32u);
|
||||
const auto fillBytes = packet[6] & 0x3ffffffu;
|
||||
const auto pattern = packet[2];
|
||||
DrawPipeline::Queue0().Enqueue([this, queue, address, bytes = std::move(bytes), metadataFill, fillAddress, fillBytes, pattern] {
|
||||
DrawPipeline::Queue0().Enqueue([this, queue, address, bytes = std::move(bytes), gds, metadataFill, fillAddress, fillBytes, pattern] {
|
||||
GuestMemory::SetCurrentPacket(0x50, queue);
|
||||
if (gds) {
|
||||
GuestMemory::Write(address, bytes, 1);
|
||||
return;
|
||||
}
|
||||
if (metadataFill) {
|
||||
Graphics::NoteDepthMetadataFill(fillAddress, fillBytes, pattern);
|
||||
Graphics::NoteColorMetadataFill(fillAddress, fillBytes, pattern);
|
||||
|
||||
@@ -144,6 +144,7 @@ void Driver::run(std::uint32_t id) noexcept {
|
||||
StartWorkerSampler(id);
|
||||
Submission submission;
|
||||
static const bool profile = std::getenv("APS5_PROFILE_DRAW") != nullptr;
|
||||
static const bool idleStore = std::getenv("APS5_NO_IDLE_STORE") == nullptr;
|
||||
auto& costs = submissionCosts(id);
|
||||
try {
|
||||
PerformanceTrace::BindThread(role);
|
||||
@@ -183,7 +184,7 @@ void Driver::run(std::uint32_t id) noexcept {
|
||||
&& std::all_of(workers.begin(), workers.end(), [](const auto& item) { return item.second.pending.empty(); });
|
||||
};
|
||||
const auto idleResultsPending = [&] {
|
||||
return id == 0 && Graphics::StorageTexture::AnyPending() && allQueuesIdle() && !completionsPending();
|
||||
return idleStore && id == 0 && Graphics::StorageTexture::AnyPending() && allQueuesIdle() && !completionsPending();
|
||||
};
|
||||
const auto poll = [&](const auto& done) {
|
||||
#ifdef _WIN32
|
||||
@@ -221,13 +222,12 @@ void Driver::run(std::uint32_t id) noexcept {
|
||||
lock.lock();
|
||||
if (ready()) break;
|
||||
if (id == 0 && allQueuesIdle() && !completionsPending()
|
||||
&& ((!storeIdleResults && Graphics::StorageTexture::AnyPending()) || idleEpoch.load(std::memory_order_acquire) != idleEpochAtCheck)) continue;
|
||||
&& ((idleStore && !storeIdleResults && Graphics::StorageTexture::AnyPending()) || idleEpoch.load(std::memory_order_acquire) != idleEpochAtCheck)) continue;
|
||||
if (id == 0) queue0Dormant.store(true, std::memory_order_relaxed);
|
||||
const auto idleEpochAtWait = idleEpoch.load(std::memory_order_acquire);
|
||||
changed.wait(lock, [&] { return ready() || (id == 0 && (idleEpoch.load(std::memory_order_acquire) != idleEpochAtWait || completionsPending())); });
|
||||
if (id == 0) queue0Dormant.store(false, std::memory_order_relaxed);
|
||||
if (id == 0 && !ready() && (idleEpoch.load(std::memory_order_acquire) != idleEpochAtWait || completionsPending())) continue;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (poll(ready)) break;
|
||||
lock.unlock();
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Mutex.hpp"
|
||||
#include "ControlFlow/RequestSerializer.hpp"
|
||||
#include "Optimization/ResourceProgram.hpp"
|
||||
#include <charconv>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
#ifdef _WIN32
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
@@ -11,6 +20,15 @@ namespace AgcDriver::DriverDetail {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string captureSession() {
|
||||
#ifdef _WIN32
|
||||
const auto process = _getpid();
|
||||
#else
|
||||
const auto process = getpid();
|
||||
#endif
|
||||
return std::to_string(process) + "-" + std::to_string(std::chrono::system_clock::now().time_since_epoch().count());
|
||||
}
|
||||
|
||||
std::optional<std::set<std::uint64_t>> selectedPrograms() {
|
||||
const char* value = std::getenv("APS5_DUMP_SHADERS");
|
||||
if (value == nullptr || std::string_view(value) == "1") return std::nullopt;
|
||||
@@ -32,6 +50,46 @@ std::optional<std::set<std::uint64_t>> selectedPrograms() {
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<const ShaderRecompiler::SourceHandle> PrepareShaderWithDiagnostics(const ShaderRecompiler::RecompileRequest& request, ShaderRecompiler::ShaderPreparationContext* preparation) {
|
||||
std::exception_ptr failure;
|
||||
std::string dump;
|
||||
static const bool dumpInputs = std::getenv("APS5_DUMP_PREPARE_INPUTS") != nullptr;
|
||||
std::string inputDump;
|
||||
if (dumpInputs) {
|
||||
try {
|
||||
static const auto session = captureSession();
|
||||
static std::atomic<std::uint64_t> next{0};
|
||||
const auto suffix = ".input-" + session + "-" + std::to_string(next.fetch_add(1)) + ".prepare";
|
||||
inputDump = Driver::dumpRequest(request.shader.codeAddress, request, suffix);
|
||||
if (!inputDump.empty()) {
|
||||
std::fprintf(stderr, "[prepare-input] begin %s\n", inputDump.c_str());
|
||||
std::fflush(stderr);
|
||||
}
|
||||
} catch (const std::exception& error) {
|
||||
std::fprintf(stderr, "[prepare-input] capture failed: %s\n", error.what());
|
||||
}
|
||||
}
|
||||
try {
|
||||
auto handle = ShaderRecompiler::PrepareShader(request, preparation);
|
||||
if (!inputDump.empty()) std::fprintf(stderr, "[prepare-input] end %s\n", inputDump.c_str());
|
||||
return handle;
|
||||
} catch (...) {
|
||||
failure = std::current_exception();
|
||||
try {
|
||||
if (std::getenv("APS5_DUMP_SHADERS") != nullptr) dump = Driver::dumpRequest(request.shader.codeAddress, request, ".prepare");
|
||||
} catch (...) {}
|
||||
}
|
||||
try {
|
||||
std::rethrow_exception(failure);
|
||||
} catch (const std::exception& error) {
|
||||
std::ostringstream where;
|
||||
where << "shader 0x" << std::hex << request.shader.codeAddress << " stage " << static_cast<unsigned>(request.shader.stage);
|
||||
if (!dump.empty()) where << " (" << dump << ")";
|
||||
where << ": ";
|
||||
throw std::runtime_error(where.str() + error.what());
|
||||
}
|
||||
}
|
||||
|
||||
void Driver::reportSkip(const char* kind, const std::string& what) {
|
||||
static AgcDriver::Mutex reportedMutex;
|
||||
static std::set<std::size_t> reported;
|
||||
@@ -96,14 +154,17 @@ std::string Driver::dumpRequest(std::uint64_t address, const ShaderRecompiler::R
|
||||
if (written != text.size() || closed != 0) {
|
||||
dumped.erase(name);
|
||||
std::fprintf(stderr, "[gpu] incomplete write to dump file %s (%zu of %zu bytes, close status %d)\n", name.c_str(), written, text.size(), closed);
|
||||
return {};
|
||||
}
|
||||
} else {
|
||||
dumped.erase(name);
|
||||
std::fprintf(stderr, "[gpu] could not open dump file %s for writing\n", name.c_str());
|
||||
return {};
|
||||
}
|
||||
} catch (const std::exception& error) {
|
||||
dumped.erase(name);
|
||||
std::fprintf(stderr, "[gpu] could not serialize request for 0x%llx: %s\n", static_cast<unsigned long long>(address), error.what());
|
||||
return {};
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -60,41 +60,18 @@
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
|
||||
std::shared_ptr<const ShaderRecompiler::SourceHandle> PrepareShaderWithDiagnostics(const ShaderRecompiler::RecompileRequest& request, ShaderRecompiler::ShaderPreparationContext* preparation) {
|
||||
std::exception_ptr failure;
|
||||
std::string dump;
|
||||
try {
|
||||
auto handle = ShaderRecompiler::PrepareShader(request, preparation);
|
||||
return handle;
|
||||
} catch (...) {
|
||||
failure = std::current_exception();
|
||||
try {
|
||||
if (std::getenv("APS5_DUMP_SHADERS") != nullptr) dump = Driver::dumpRequest(request.shader.codeAddress, request, ".prepare");
|
||||
} catch (...) {}
|
||||
}
|
||||
try {
|
||||
std::rethrow_exception(failure);
|
||||
} catch (const std::exception& error) {
|
||||
std::ostringstream where;
|
||||
where << "shader 0x" << std::hex << request.shader.codeAddress << " stage " << static_cast<unsigned>(request.shader.stage);
|
||||
if (!dump.empty()) where << " (" << dump << ")";
|
||||
where << ": ";
|
||||
throw std::runtime_error(where.str() + error.what());
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<const ShaderSnapshot> ReadRawShader(std::uint64_t address) {
|
||||
std::shared_ptr<const ShaderSnapshot> ReadRawShader(std::uint64_t address, const std::shared_ptr<const ShaderSnapshot>& retained) {
|
||||
const auto drain = [](std::uint64_t first, std::size_t bytes) {
|
||||
if (!DrawPipeline::Active()) return;
|
||||
auto& pipeline = DrawPipeline::Queue0();
|
||||
if (pipeline.Busy() && pipeline.Overlaps(first, bytes)) pipeline.Drain(DrawPipeline::DrainReason::Capture);
|
||||
};
|
||||
GuestMemory::CheckRange(reinterpret_cast<const void*>(address), sizeof(std::uint32_t), 256);
|
||||
static std::mutex cacheMutex;
|
||||
static std::list<std::shared_ptr<const ShaderSnapshot>> cache;
|
||||
static std::size_t cacheBytes = 0;
|
||||
std::shared_ptr<const ShaderSnapshot> cached;
|
||||
{
|
||||
std::shared_ptr<const ShaderSnapshot> cached = retained != nullptr && retained->codeAddress == address && retained->header.empty() && !retained->code.empty() ? retained : nullptr;
|
||||
if (cached == nullptr) {
|
||||
std::lock_guard lock(cacheMutex);
|
||||
const auto found = std::find_if(cache.begin(), cache.end(), [address](const auto& entry) { return entry->codeAddress == address; });
|
||||
if (found != cache.end()) cached = *found;
|
||||
@@ -110,6 +87,7 @@ std::shared_ptr<const ShaderSnapshot> ReadRawShader(std::uint64_t address) {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
GuestMemory::CheckRange(reinterpret_cast<const void*>(address), sizeof(std::uint32_t), 256);
|
||||
constexpr std::size_t limit = 1024 * 1024;
|
||||
const auto ranges = GuestMemory::CommittedRanges(address, limit);
|
||||
std::uint64_t end = address;
|
||||
@@ -124,7 +102,7 @@ std::shared_ptr<const ShaderSnapshot> ReadRawShader(std::uint64_t address) {
|
||||
snapshot.code.resize(std::min(available, std::max<std::size_t>(64, previous * 2)));
|
||||
drain(address + previous * sizeof(std::uint32_t), (snapshot.code.size() - previous) * sizeof(std::uint32_t));
|
||||
GuestMemory::Read(address + previous * sizeof(std::uint32_t),
|
||||
std::as_writable_bytes(std::span(snapshot.code).subspan(previous)), alignof(std::uint32_t));
|
||||
std::as_writable_bytes(std::span(snapshot.code.Mutable()).subspan(previous)), alignof(std::uint32_t));
|
||||
try {
|
||||
const auto decoded = ShaderRecompiler::RdnaInstructionDecoder{}.Decode(snapshot.code);
|
||||
if (const auto tail = ShaderRecompiler::FindUserDataTail(decoded, 0u, 106u)) snapshot.userDataTailRegister = tail->userDataRegister;
|
||||
@@ -902,6 +880,10 @@ void ReportPreparedAtUse(const ShaderSnapshot& snapshot, const ShaderRecompiler:
|
||||
APS5_LOG_OUT_DEBUG("Shader 0x%llx samples a converted image; preparing its converted-sample variant at use", static_cast<unsigned long long>(request.shader.codeAddress));
|
||||
return;
|
||||
}
|
||||
if (request.context.layerRowSamples) {
|
||||
APS5_LOG_OUT_DEBUG("Shader 0x%llx samples a 1D array past maxImageArrayLayers; preparing its layer-row variant at use", static_cast<unsigned long long>(request.shader.codeAddress));
|
||||
return;
|
||||
}
|
||||
if (snapshot.codeAddress == NullPixelProgramAddress() && request.shader.stage == ShaderRecompiler::ShaderStage::Fragment && request.context.waveSize == 32u) {
|
||||
APS5_LOG_ERR("The null pixel program has no wave%u artifact for this draw; preparing it at draw", request.context.waveSize);
|
||||
return;
|
||||
@@ -969,8 +951,16 @@ ShaderRecompiler::RectListShaders DrawRectangle(const ShaderSnapshot& front, con
|
||||
return PreparedRectangle(front, vertexId, fragmentId);
|
||||
}
|
||||
|
||||
struct UserDataCallSites {
|
||||
ShaderRecompiler::RdnaProgram program;
|
||||
std::vector<ShaderRecompiler::UserDataCall> calls;
|
||||
std::vector<ShaderRecompiler::TableCall> tableCalls;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr std::size_t UserDataLinksPerProgram = 8u;
|
||||
|
||||
std::vector<std::uint32_t> LinkGraphicsUserDataTail(const ShaderRecompiler::RecompileRequest& request, const ShaderSnapshot& snapshot) {
|
||||
using Stage = ShaderRecompiler::ShaderStage;
|
||||
if ((request.shader.stage != Stage::Vertex && request.shader.stage != Stage::Fragment) || !request.shader.header.empty() || !snapshot.userDataTailRegister) return {};
|
||||
@@ -987,13 +977,13 @@ std::string hexText(std::uint64_t value) {
|
||||
return text;
|
||||
}
|
||||
|
||||
std::vector<std::uint32_t> ReadUserDataCallee(std::uint64_t address, std::uint32_t linkRegister) {
|
||||
std::vector<std::uint32_t> ReadUserDataCallee(std::uint64_t address, std::uint32_t linkRegister, bool allowGetpc = false) {
|
||||
constexpr std::uint64_t page = 4096u;
|
||||
constexpr std::size_t limitWords = 1024u * 1024u / 4u;
|
||||
if (address % 4u != 0u) throw std::runtime_error("its callee address " + hexText(address) + " is not dword aligned");
|
||||
std::vector<std::uint32_t> words;
|
||||
const auto finish = [&] {
|
||||
const auto length = ShaderRecompiler::UserDataCalleeLength(words, linkRegister);
|
||||
const auto length = ShaderRecompiler::UserDataCalleeLength(words, linkRegister, allowGetpc);
|
||||
if (length) words.resize(*length);
|
||||
return length.has_value();
|
||||
};
|
||||
@@ -1044,24 +1034,72 @@ std::vector<ShaderRecompiler::TableCallee> ReadTableCallees(const ShaderRecompil
|
||||
}
|
||||
if (targets.size() > limitCallees) throw std::runtime_error("its call table holds " + std::to_string(targets.size()) + " distinct targets; at most " + std::to_string(limitCallees) + " are linked");
|
||||
std::vector<ShaderRecompiler::TableCallee> callees;
|
||||
for (const auto target : targets) callees.push_back({target, ReadUserDataCallee(target, call.linkRegister)});
|
||||
for (const auto target : targets) callees.push_back({target, ReadUserDataCallee(target, call.linkRegister, true)});
|
||||
return callees;
|
||||
}
|
||||
|
||||
ShaderRecompiler::LinkedCalls LinkUserDataCallees(const ShaderRecompiler::RecompileRequest& request) {
|
||||
std::shared_ptr<const ShaderRecompiler::LinkedCalls> LinkUserDataCallees(const ShaderRecompiler::RecompileRequest& request, const ShaderSnapshot& snapshot, std::size_t codeOffset) {
|
||||
const bool gcnVertex = ShaderRecompiler::GcnGuestShaders() && request.shader.stage == ShaderRecompiler::ShaderStage::Vertex;
|
||||
if (request.shader.stage != ShaderRecompiler::ShaderStage::Compute && !gcnVertex) return {};
|
||||
if (request.shader.stage != ShaderRecompiler::ShaderStage::Compute && !gcnVertex) return nullptr;
|
||||
const auto code = request.shader.code;
|
||||
if (std::none_of(code.begin(), code.end(), [](std::uint32_t word) { return (word & 0xff80ff00u) == 0xbe802100u; })) return {};
|
||||
const auto program = ShaderRecompiler::RdnaInstructionDecoder{}.Decode(code);
|
||||
if (std::none_of(code.begin(), code.end(), [](std::uint32_t word) { return (word & 0xff80ff00u) == 0xbe802100u; })) return nullptr;
|
||||
const ShaderRecompiler::SwappcInfo swappc{false, request.context.userDataBaseRegister, static_cast<std::uint32_t>(request.context.userData.size()), request.context.waveSize};
|
||||
const auto calls = ShaderRecompiler::FindUserDataCalls(program, swappc);
|
||||
const auto tableCalls = ShaderRecompiler::FindTableCalls(program, swappc);
|
||||
if (calls.empty() && tableCalls.empty()) return {};
|
||||
const auto addressOf = [&](const ShaderRecompiler::UserDataCall& call) {
|
||||
const auto slot = call.userDataRegister - swappc.userDataBaseRegister;
|
||||
return static_cast<std::uint64_t>(request.context.userData[slot]) | static_cast<std::uint64_t>(request.context.userData[slot + 1u]) << 32u;
|
||||
};
|
||||
const auto sameProgram = [&](const PreparedShaderState::UserDataLink& link) {
|
||||
return link.codeOffset == codeOffset && link.userDataBaseRegister == swappc.userDataBaseRegister && link.userDataCount == swappc.userDataCount && link.waveSize == swappc.waveSize;
|
||||
};
|
||||
std::vector<std::uint32_t> current;
|
||||
const auto unchanged = [&](const PreparedShaderState::UserDataLink& link) {
|
||||
for (std::size_t index = 0; index < link.callees.size(); ++index) {
|
||||
const auto address = addressOf(link.sites->calls[index]);
|
||||
const auto& words = link.code[index];
|
||||
if (address != link.callees[index] || !GuestMemory::Accessible(reinterpret_cast<const void*>(static_cast<std::uintptr_t>(address)), words.size() * 4u)) return false;
|
||||
current.resize(words.size());
|
||||
GuestMemory::Read(address, std::as_writable_bytes(std::span(current)));
|
||||
if (current != words) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
auto& prepared = *snapshot.prepared;
|
||||
std::vector<PreparedShaderState::UserDataLink> candidates;
|
||||
{
|
||||
std::lock_guard lock(prepared.mutex);
|
||||
std::copy_if(prepared.userDataLinks.begin(), prepared.userDataLinks.end(), std::back_inserter(candidates), sameProgram);
|
||||
}
|
||||
std::shared_ptr<const UserDataCallSites> sites;
|
||||
for (auto candidate = candidates.rbegin(); candidate != candidates.rend(); ++candidate) {
|
||||
sites = candidate->sites;
|
||||
if (candidate->linked != nullptr && unchanged(*candidate)) return candidate->linked;
|
||||
}
|
||||
if (sites == nullptr) {
|
||||
auto found = std::make_shared<UserDataCallSites>();
|
||||
found->program = ShaderRecompiler::RdnaInstructionDecoder{}.Decode(code);
|
||||
found->calls = ShaderRecompiler::FindUserDataCalls(found->program, swappc);
|
||||
found->tableCalls = ShaderRecompiler::FindTableCalls(found->program, swappc);
|
||||
sites = std::move(found);
|
||||
}
|
||||
const auto& program = sites->program;
|
||||
const auto& calls = sites->calls;
|
||||
const auto& tableCalls = sites->tableCalls;
|
||||
PreparedShaderState::UserDataLink link{codeOffset, swappc.userDataBaseRegister, swappc.userDataCount, swappc.waveSize, sites, {}, {}, nullptr};
|
||||
const auto remember = [&] {
|
||||
std::lock_guard lock(prepared.mutex);
|
||||
auto& links = prepared.userDataLinks;
|
||||
if (link.linked == nullptr && std::any_of(links.begin(), links.end(), sameProgram)) return;
|
||||
if (std::count_if(links.begin(), links.end(), sameProgram) >= static_cast<std::ptrdiff_t>(UserDataLinksPerProgram)) links.erase(std::find_if(links.begin(), links.end(), sameProgram));
|
||||
links.push_back(link);
|
||||
};
|
||||
if (calls.empty() && tableCalls.empty()) {
|
||||
link.linked = std::make_shared<const ShaderRecompiler::LinkedCalls>();
|
||||
remember();
|
||||
return link.linked;
|
||||
}
|
||||
std::vector<std::vector<std::uint32_t>> callees;
|
||||
for (const auto& call : calls) {
|
||||
const auto slot = call.userDataRegister - swappc.userDataBaseRegister;
|
||||
const auto address = static_cast<std::uint64_t>(request.context.userData[slot]) | static_cast<std::uint64_t>(request.context.userData[slot + 1u]) << 32u;
|
||||
const auto address = addressOf(call);
|
||||
try {
|
||||
callees.push_back(ReadUserDataCallee(address, call.linkRegister));
|
||||
} catch (const std::exception& error) {
|
||||
@@ -1077,7 +1115,16 @@ ShaderRecompiler::LinkedCalls LinkUserDataCallees(const ShaderRecompiler::Recomp
|
||||
throw std::runtime_error("AGC driver: compute shader " + hexText(request.shader.codeAddress) + " calls a target loaded from a table at program counter " + hexText(call.programCounter) + ", but " + error.what());
|
||||
}
|
||||
}
|
||||
return ShaderRecompiler::LinkCalls(program, calls, callees, tableCalls, tableCallees);
|
||||
auto linked = std::make_shared<const ShaderRecompiler::LinkedCalls>(ShaderRecompiler::LinkCalls(program, calls, callees, tableCalls, tableCallees));
|
||||
if (!tableCalls.empty()) {
|
||||
remember();
|
||||
return linked;
|
||||
}
|
||||
for (const auto& call : calls) link.callees.push_back(addressOf(call));
|
||||
link.code = std::move(callees);
|
||||
link.linked = linked;
|
||||
remember();
|
||||
return linked;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1086,8 +1133,10 @@ ShaderRecompiler::PreparedShaderInvocation InvocationFor(const ShaderSnapshot& s
|
||||
require(codeOffset < snapshot.code.size(), "prepared shader code offset is outside the snapshot");
|
||||
const auto code = std::span(snapshot.code).subspan(codeOffset);
|
||||
require(request.shader.code.data() == code.data() && request.shader.code.size() == code.size(), "prepared invocation does not refer to registered code");
|
||||
auto linked = LinkUserDataCallees(request);
|
||||
if (linked.code.empty()) linked.code = LinkGraphicsUserDataTail(request, snapshot);
|
||||
const auto shared = LinkUserDataCallees(request, snapshot, codeOffset);
|
||||
ShaderRecompiler::LinkedCalls tail;
|
||||
if (shared == nullptr || shared->code.empty()) tail.code = LinkGraphicsUserDataTail(request, snapshot);
|
||||
const auto& linked = shared != nullptr && tail.code.empty() ? *shared : tail;
|
||||
auto source = request;
|
||||
if (!linked.code.empty()) {
|
||||
source.shader.code = linked.code;
|
||||
@@ -1096,6 +1145,7 @@ ShaderRecompiler::PreparedShaderInvocation InvocationFor(const ShaderSnapshot& s
|
||||
std::unique_lock lock(snapshot.prepared->mutex);
|
||||
AwaitRegisteredPreparation(*snapshot.prepared, lock);
|
||||
if (std::ranges::find(snapshot.prepared->convertedSamples, codeOffset) != snapshot.prepared->convertedSamples.end()) source.context.convertedSamples = true;
|
||||
if (std::ranges::find(snapshot.prepared->layerRowSamples, codeOffset) != snapshot.prepared->layerRowSamples.end()) source.context.layerRowSamples = true;
|
||||
auto invocationRequest = source;
|
||||
struct PreparedKeyStorage {};
|
||||
auto& key = HostThreadLocal<std::vector<std::uint64_t>, PreparedKeyStorage>();
|
||||
@@ -1123,22 +1173,27 @@ ShaderRecompiler::PreparedShaderInvocation InvocationFor(const ShaderSnapshot& s
|
||||
}
|
||||
|
||||
std::shared_ptr<const ShaderRecompiler::ResourceCapture> CaptureInvocation(ShaderMemory& memory, const ShaderSnapshot& snapshot, std::size_t codeOffset, const ShaderRecompiler::RecompileRequest& request, ShaderRecompiler::PreparedShaderInvocation& invocation) {
|
||||
try {
|
||||
return memory.Capture(invocation);
|
||||
} catch (const ShaderRecompiler::ConvertedSampleRequired&) {
|
||||
if (invocation.Request().context.convertedSamples) throw;
|
||||
}
|
||||
{
|
||||
const auto record = [&](std::vector<std::size_t>& offsets) {
|
||||
std::lock_guard lock(snapshot.prepared->mutex);
|
||||
auto& offsets = snapshot.prepared->convertedSamples;
|
||||
if (std::ranges::find(offsets, codeOffset) == offsets.end()) offsets.push_back(codeOffset);
|
||||
};
|
||||
while (true) {
|
||||
try {
|
||||
return memory.Capture(invocation);
|
||||
} catch (const ShaderRecompiler::ConvertedSampleRequired&) {
|
||||
if (invocation.Request().context.convertedSamples) throw;
|
||||
record(snapshot.prepared->convertedSamples);
|
||||
} catch (const ShaderRecompiler::LayerRowSamplesRequired&) {
|
||||
if (invocation.Request().context.layerRowSamples) throw;
|
||||
record(snapshot.prepared->layerRowSamples);
|
||||
}
|
||||
invocation = InvocationFor(snapshot, codeOffset, request);
|
||||
}
|
||||
invocation = InvocationFor(snapshot, codeOffset, request);
|
||||
return memory.Capture(invocation);
|
||||
}
|
||||
namespace {
|
||||
|
||||
std::optional<ShaderRecompiler::ShaderFloatMode> DecodeFloatMode(const Registers& registers, std::uint8_t type) {
|
||||
template<typename TRegisters>
|
||||
std::optional<ShaderRecompiler::ShaderFloatMode> DecodeFloatMode(const TRegisters& registers, std::uint8_t type) {
|
||||
std::uint32_t rsrc1;
|
||||
std::uint32_t fp16OverflowBit;
|
||||
switch (type) {
|
||||
@@ -1186,7 +1241,7 @@ Shader ReadHeader(const ShaderSnapshot& snapshot) {
|
||||
return header;
|
||||
}
|
||||
|
||||
RegisteredShaderState DecodeRegisteredState(const ShaderSnapshot& snapshot, RegisteredShaderState state = {{}, InitialContextRegisters(), {{0x24a, 0}, {0x24b, 0}}}) {
|
||||
DecodedShaderState DecodeRegisteredState(const ShaderSnapshot& snapshot, DecodedShaderState state = {{}, InitialContextRegisters(), {{0x24a, 0}, {0x24b, 0}}}) {
|
||||
const auto header = ReadHeader(snapshot);
|
||||
for (const auto reg : ReadHeaderArray(snapshot, header.sh_registers, header.num_sh_registers)) {
|
||||
state.shader.insert_or_assign(reg.offset, reg.value);
|
||||
@@ -1434,9 +1489,9 @@ PreparedAtUse PrepareDeferredAbis(const ShaderSnapshot& snapshot, std::unique_lo
|
||||
const auto device = abi.device.lock();
|
||||
if (device == nullptr || snapshot.registeredState == nullptr) continue;
|
||||
QueueState state{};
|
||||
state.shader = snapshot.registeredState->shader;
|
||||
state.context = snapshot.registeredState->context;
|
||||
state.userConfig = snapshot.registeredState->userConfig;
|
||||
state.shader = snapshot.registeredState->shader.Expand();
|
||||
state.context = snapshot.registeredState->context.Expand();
|
||||
state.userConfig = snapshot.registeredState->userConfig.Expand();
|
||||
for (const auto& [offset, value] : abi.context) state.context[offset] = value;
|
||||
for (const auto& [offset, value] : abi.primitive) state.userConfig[offset] = value;
|
||||
try {
|
||||
@@ -2142,9 +2197,9 @@ void Driver::ResolveShaderAbi(const Shader* shader, std::span<const ShaderRegist
|
||||
}
|
||||
require(snapshot->registeredState != nullptr, "registered shader state is missing");
|
||||
QueueState state{};
|
||||
state.shader = snapshot->registeredState->shader;
|
||||
state.context = snapshot->registeredState->context;
|
||||
state.userConfig = snapshot->registeredState->userConfig;
|
||||
state.shader = snapshot->registeredState->shader.Expand();
|
||||
state.context = snapshot->registeredState->context.Expand();
|
||||
state.userConfig = snapshot->registeredState->userConfig.Expand();
|
||||
for (const auto reg : context) state.context[reg.offset] = reg.value;
|
||||
for (const auto reg : primitive) state.userConfig[reg.offset] = reg.value;
|
||||
const auto localDevice = device.Load();
|
||||
@@ -2395,9 +2450,9 @@ ShaderSnapshot PrepareNullPixelProgram(const VulkanDevice& device) {
|
||||
nullRegisteredState.context.insert_or_assign(0x1b4u, 0x2u);
|
||||
null.registeredState = std::make_shared<const RegisteredShaderState>(std::move(nullRegisteredState));
|
||||
QueueState nullState{};
|
||||
nullState.shader = null.registeredState->shader;
|
||||
nullState.context = null.registeredState->context;
|
||||
nullState.userConfig = null.registeredState->userConfig;
|
||||
nullState.shader = null.registeredState->shader.Expand();
|
||||
nullState.context = null.registeredState->context.Expand();
|
||||
nullState.userConfig = null.registeredState->userConfig.Expand();
|
||||
null.prepared->entries = PrepareRegistered(null, device, nullState, true);
|
||||
return null;
|
||||
}
|
||||
@@ -2444,7 +2499,7 @@ void Driver::RegisterShader(const Shader* shader) {
|
||||
require(!RawGraphicsDrawnIn(reinterpret_cast<std::uintptr_t>(code), reinterpret_cast<std::uintptr_t>(code) + fields.shader_size), "a shader was registered over a graphics program that was drawn without registration");
|
||||
ShaderSnapshot snapshot{reinterpret_cast<std::uintptr_t>(code), reinterpret_cast<std::uintptr_t>(shader), fields.type, {}, {}};
|
||||
snapshot.code.resize(fields.shader_size / sizeof(std::uint32_t));
|
||||
std::memcpy(snapshot.code.data(), code, fields.shader_size);
|
||||
std::memcpy(snapshot.code.Mutable().data(), code, fields.shader_size);
|
||||
snapshot.header.resize(fields.header_size);
|
||||
std::memcpy(snapshot.header.data(), static_cast<const void*>(shader), fields.header_size);
|
||||
|
||||
@@ -2479,7 +2534,9 @@ void Driver::RegisterShader(const Shader* shader) {
|
||||
if (shaders != nullptr) {
|
||||
if (const auto found = shaders->find(snapshot.codeAddress); found != shaders->end()) {
|
||||
for (const auto& current : found->second) {
|
||||
if (current->registeredState == nullptr || current->type != snapshot.type || current->code != snapshot.code || *current->registeredState != *snapshot.registeredState) continue;
|
||||
if (current->code != snapshot.code) continue;
|
||||
snapshot.code = current->code;
|
||||
if (current->registeredState == nullptr || current->type != snapshot.type || *current->registeredState != *snapshot.registeredState) continue;
|
||||
snapshot.registeredState = current->registeredState;
|
||||
break;
|
||||
}
|
||||
@@ -2487,9 +2544,9 @@ void Driver::RegisterShader(const Shader* shader) {
|
||||
}
|
||||
}
|
||||
QueueState registered{};
|
||||
registered.shader = snapshot.registeredState->shader;
|
||||
registered.context = snapshot.registeredState->context;
|
||||
registered.userConfig = snapshot.registeredState->userConfig;
|
||||
registered.shader = snapshot.registeredState->shader.Expand();
|
||||
registered.context = snapshot.registeredState->context.Expand();
|
||||
registered.userConfig = snapshot.registeredState->userConfig.Expand();
|
||||
std::shared_ptr<RegisteredPreparation> preparation;
|
||||
if (LazyShaderPreparation()) {
|
||||
static_cast<void>(PlanRegistered(snapshot, *localDevice, registered, true, &snapshot.prepared->deferred));
|
||||
|
||||
@@ -189,6 +189,45 @@ bool Driver::recordQueuedLabelsAfterCapture(std::uint32_t queue, std::span<const
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::atomic<void (*)()> captureCheckHook{nullptr};
|
||||
|
||||
bool& recapturing() {
|
||||
static thread_local bool active = false;
|
||||
return active;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Driver::SetCaptureCheckHook(void (*hook)()) {
|
||||
captureCheckHook.store(hook, std::memory_order_release);
|
||||
}
|
||||
|
||||
void Driver::runCaptureCheckHook() {
|
||||
if (const auto hook = captureCheckHook.load(std::memory_order_acquire)) hook();
|
||||
}
|
||||
|
||||
bool Driver::capturedMemoryChanged(std::span<const ShaderRecompiler::MemoryRegion> regions, std::span<Graphics::GuestMemorySnapshot> compared) {
|
||||
if (recapturing()) return false;
|
||||
const bool mark = compared.size() == regions.size();
|
||||
for (std::size_t i = 0; i < regions.size(); ++i) {
|
||||
const auto outcome = GuestMemory::CompareMapped(regions[i].guestAddress, regions[i].bytes);
|
||||
if (outcome == GuestMemory::Compare::Differs) return true;
|
||||
if (mark && outcome == GuestMemory::Compare::Equal) compared[i].compared = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Driver::RecaptureScope::RecaptureScope() {
|
||||
recapturing() = true;
|
||||
++captureChangeRetries;
|
||||
}
|
||||
|
||||
Driver::RecaptureScope::~RecaptureScope() {
|
||||
recapturing() = false;
|
||||
}
|
||||
|
||||
void Driver::noteQueuedLabels(std::uint32_t queue) {
|
||||
static const bool installed = (Graphics::Recorder::SetQueuedLabelRecorder(&Driver::recordQueuedLabelsFromHook), true);
|
||||
(void)installed;
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ std::atomic<std::uint64_t> labelFallbacks[5] = {};
|
||||
|
||||
std::atomic<std::uint64_t> queuedLabels{0}, labelGroups{0}, immediateLabels{0};
|
||||
|
||||
std::atomic<std::uint64_t> packetLockRecords{0}, packetLockSubmits{0}, packetLockDeferred{0}, packetSubmitDeferred{0}, captureTryRecords{0}, captureRetries{0}, suspendPoints{0};
|
||||
std::atomic<std::uint64_t> packetLockRecords{0}, packetLockSubmits{0}, packetLockDeferred{0}, packetSubmitDeferred{0}, captureTryRecords{0}, captureRetries{0}, captureChangeRetries{0}, suspendPoints{0};
|
||||
|
||||
std::atomic<std::uint64_t> recordTriesSkipped{0};
|
||||
|
||||
|
||||
@@ -285,6 +285,8 @@ void FrameRecorder::record(FrameCall call, bool prologueCall, std::span<const Sh
|
||||
void FrameRecorder::recordLocked(FrameCall call, bool prologueCall, std::span<const Shader* const> shaders) {
|
||||
if (state == State::Waiting) {
|
||||
if (!prologueCall) return;
|
||||
std::set<std::uint64_t> blocks;
|
||||
collectShaderPages(shaders, blocks, prologueHostPages);
|
||||
call.ordinal = ++ordinal;
|
||||
prologue.push_back(std::move(call));
|
||||
return;
|
||||
@@ -361,9 +363,7 @@ std::vector<FrameRecorder::Range> FrameRecorder::newRanges() {
|
||||
return added;
|
||||
}
|
||||
|
||||
void FrameRecorder::emitShaderDelta(std::span<const Shader* const> shaders) {
|
||||
std::set<std::uint64_t> blocks;
|
||||
std::set<std::uint64_t> hostPages;
|
||||
void FrameRecorder::collectShaderPages(std::span<const Shader* const> shaders, std::set<std::uint64_t>& blocks, std::set<std::uint64_t>& hostPages) {
|
||||
std::uintptr_t arenaBase = 0;
|
||||
std::size_t arenaBytes = 0;
|
||||
GuestArena::GuestArenaRange_nid_postfix(&arenaBase, &arenaBytes);
|
||||
@@ -391,6 +391,12 @@ void FrameRecorder::emitShaderDelta(std::span<const Shader* const> shaders) {
|
||||
note(shader->user_data->direct_resource_offset);
|
||||
for (const auto* sharps : shader->user_data->sharp_resource_offset) note(sharps);
|
||||
}
|
||||
}
|
||||
|
||||
void FrameRecorder::emitShaderDelta(std::span<const Shader* const> shaders) {
|
||||
std::set<std::uint64_t> blocks;
|
||||
std::set<std::uint64_t> hostPages;
|
||||
collectShaderPages(shaders, blocks, hostPages);
|
||||
if (blocks.empty() && hostPages.empty()) return;
|
||||
const auto mark = GuestMemory::WriteGeneration();
|
||||
std::vector<Span> spans;
|
||||
@@ -538,6 +544,21 @@ void FrameRecorder::start() {
|
||||
snapshot(range);
|
||||
if (!writer) return;
|
||||
}
|
||||
for (const auto page : prologueHostPages) {
|
||||
const auto* address = reinterpret_cast<const void*>(static_cast<std::uintptr_t>(page));
|
||||
if (!GuestMemory::Accessible(address, HostPageBytes)) continue;
|
||||
const bool covered = std::ranges::any_of(ranges, [&](const auto& range) {
|
||||
return range.readable && range.address <= page && page - range.address <= range.bytes && HostPageBytes <= range.bytes - (page - range.address);
|
||||
});
|
||||
if (covered) continue;
|
||||
const bool writable = GuestMemory::Accessible(address, HostPageBytes, true);
|
||||
Range range{page, HostPageBytes, FrameRangeKind::Host, writable ? 0x04u : 0x02u,
|
||||
FrameRangeAccess::Readable | (writable ? FrameRangeAccess::Writable : 0u), true};
|
||||
snapshot(range);
|
||||
if (!writer) return;
|
||||
ranges.push_back(range);
|
||||
}
|
||||
prologueHostPages.clear();
|
||||
for (const auto& call : prologue) writer->WriteCall(call);
|
||||
std::uintptr_t ringBase = 0;
|
||||
std::uint32_t ringSize = 0;
|
||||
|
||||
@@ -49,13 +49,20 @@
|
||||
#include <cstdint>
|
||||
#include <fcntl.h>
|
||||
#include <fstream>
|
||||
#ifndef __APPLE__
|
||||
#include <link.h>
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <sstream>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
#include "prx/libc/include/specifics/linux/HostMapping.hpp"
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_vm.h>
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace AgcDriver::GuestMemory {
|
||||
@@ -375,6 +382,7 @@ namespace {
|
||||
// callback), and address-based builds verify every image section on each build, so without the table
|
||||
// each of those verifications was a VirtualQuery. APS5_NO_IMAGE_PAGE_CACHE=1 leaves the image uncached.
|
||||
constexpr std::size_t PageBytes = 4096;
|
||||
constexpr std::size_t BlockPages = 64;
|
||||
constexpr std::uint8_t PageReadable = 1;
|
||||
constexpr std::uint8_t PageWritable = 2;
|
||||
constexpr std::uint8_t PageInaccessible = 4;
|
||||
@@ -384,36 +392,48 @@ struct PageSpan {
|
||||
std::size_t size = 0;
|
||||
// Per page: access flags, zero while unknown.
|
||||
std::uint8_t* pages = nullptr;
|
||||
std::uint8_t* blocks = nullptr;
|
||||
static constexpr std::size_t ChunkEntries = 65536;
|
||||
struct alignas(8) Chunk { std::array<std::uint8_t, ChunkEntries> entries{}; };
|
||||
struct alignas(8) Chunk {
|
||||
std::array<std::uint8_t, ChunkEntries> entries{};
|
||||
std::array<std::uint8_t, ChunkEntries / BlockPages> blocks{};
|
||||
};
|
||||
std::atomic<Chunk*>* chunks = nullptr;
|
||||
|
||||
std::uint8_t* chunkData(std::size_t index, bool create) const {
|
||||
Chunk* chunkAt(std::size_t index, bool create) const {
|
||||
auto* chunk = chunks[index].load(std::memory_order_acquire);
|
||||
if (chunk == nullptr && create) {
|
||||
auto fresh = std::unique_ptr<Chunk>(new (std::nothrow) Chunk{});
|
||||
if (fresh != nullptr && chunks[index].compare_exchange_strong(chunk, fresh.get(), std::memory_order_acq_rel, std::memory_order_acquire)) chunk = fresh.release();
|
||||
}
|
||||
return chunk == nullptr ? nullptr : chunk->entries.data();
|
||||
return chunk;
|
||||
}
|
||||
|
||||
std::uint8_t* entry(std::size_t index, bool create) const {
|
||||
if (chunks == nullptr) return pages + index;
|
||||
auto* data = chunkData(index / ChunkEntries, create);
|
||||
return data == nullptr ? nullptr : data + index % ChunkEntries;
|
||||
auto* chunk = chunkAt(index / ChunkEntries, create);
|
||||
return chunk == nullptr ? nullptr : chunk->entries.data() + index % ChunkEntries;
|
||||
}
|
||||
|
||||
std::uint8_t* blockEntry(std::size_t block, bool create) const {
|
||||
if (chunks == nullptr) return blocks + block;
|
||||
auto* chunk = chunkAt(block * BlockPages / ChunkEntries, create);
|
||||
return chunk == nullptr ? nullptr : chunk->blocks.data() + block % (ChunkEntries / BlockPages);
|
||||
}
|
||||
|
||||
bool allocate() {
|
||||
if (size == 0) return false;
|
||||
const auto count = (size / PageBytes + 8) & ~static_cast<std::size_t>(7);
|
||||
const auto count = (size / PageBytes + BlockPages) & ~(BlockPages - 1);
|
||||
#ifdef _WIN32
|
||||
const auto chunkCount = (count + ChunkEntries - 1) / ChunkEntries;
|
||||
chunks = new (std::nothrow) std::atomic<Chunk*>[chunkCount]{};
|
||||
if (chunks == nullptr) size = 0;
|
||||
return chunks != nullptr;
|
||||
#else
|
||||
pages = static_cast<std::uint8_t*>(std::calloc(count, 1));
|
||||
const auto blockCount = (count / BlockPages + 8) & ~static_cast<std::size_t>(7);
|
||||
pages = static_cast<std::uint8_t*>(std::calloc(count + blockCount, 1));
|
||||
if (pages == nullptr) size = 0;
|
||||
else blocks = pages + count;
|
||||
return pages != nullptr;
|
||||
#endif
|
||||
}
|
||||
@@ -422,24 +442,63 @@ struct PageSpan {
|
||||
return size != 0 && address >= base && address - base < size;
|
||||
}
|
||||
|
||||
static std::uint8_t loadByte(const std::uint8_t* at) {
|
||||
return std::atomic_ref<std::uint8_t>(*const_cast<std::uint8_t*>(at)).load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
static void storeByte(std::uint8_t* at, std::uint8_t value) {
|
||||
std::atomic_ref<std::uint8_t>(*at).store(value, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
static std::uint64_t loadWide(const std::uint8_t* at) {
|
||||
return std::atomic_ref<std::uint64_t>(*reinterpret_cast<std::uint64_t*>(const_cast<std::uint8_t*>(at))).load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
std::uint8_t load(std::uintptr_t address) const {
|
||||
auto* value = entry((address - base) / PageBytes, false);
|
||||
return value == nullptr ? 0 : std::atomic_ref<std::uint8_t>(*value).load(std::memory_order_relaxed);
|
||||
return value == nullptr ? 0 : loadByte(value);
|
||||
}
|
||||
|
||||
std::uint8_t common(std::size_t block) const {
|
||||
const auto* at = entry(block * BlockPages, false);
|
||||
if (at == nullptr) return 0;
|
||||
const auto value = loadByte(at);
|
||||
const std::uint64_t wide = 0x0101010101010101ull * value;
|
||||
for (std::size_t offset = 0; offset < BlockPages; offset += 8) {
|
||||
if (loadWide(at + offset) != wide) return 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void settle(std::size_t first, std::size_t last) {
|
||||
std::atomic_thread_fence(std::memory_order_seq_cst);
|
||||
for (auto block = first / BlockPages; block <= (last - 1) / BlockPages; ++block) {
|
||||
const auto value = common(block);
|
||||
auto* summary = blockEntry(block, false);
|
||||
if (summary == nullptr || loadByte(summary) == value) continue;
|
||||
storeByte(summary, value);
|
||||
if (value == 0) continue;
|
||||
std::atomic_thread_fence(std::memory_order_seq_cst);
|
||||
if (common(block) != value) storeByte(summary, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void store(std::uintptr_t address, std::uint8_t value) {
|
||||
if (auto* at = entry((address - base) / PageBytes, value != 0 && value != PageInaccessible)) std::atomic_ref<std::uint8_t>(*at).store(value, std::memory_order_relaxed);
|
||||
store(address, address + PageBytes, value);
|
||||
}
|
||||
|
||||
void store(std::uintptr_t first, std::uintptr_t last, std::uint8_t value) {
|
||||
auto index = (first - base) / PageBytes;
|
||||
const auto stop = (last - 1 - base) / PageBytes + 1;
|
||||
while (index < stop) {
|
||||
const auto next = std::min(stop, (index / ChunkEntries + 1) * ChunkEntries);
|
||||
if (first >= last) return;
|
||||
const auto begin = (first - base) / PageBytes;
|
||||
const auto end = (last - 1 - base) / PageBytes + 1;
|
||||
auto index = begin;
|
||||
while (index < end) {
|
||||
const auto next = std::min(end, (index / ChunkEntries + 1) * ChunkEntries);
|
||||
if (auto* at = entry(index, value != 0 && value != PageInaccessible)) {
|
||||
for (; index < next; ++index, ++at) std::atomic_ref<std::uint8_t>(*at).store(value, std::memory_order_relaxed);
|
||||
for (; index < next; ++index, ++at) storeByte(at, value);
|
||||
} else index = next;
|
||||
}
|
||||
settle(begin, end);
|
||||
}
|
||||
|
||||
// End of the run of pages equal to `value` that starts at `address`, at most `limit`.
|
||||
@@ -454,11 +513,23 @@ struct PageSpan {
|
||||
index = std::min(stop, (index / ChunkEntries + 1) * ChunkEntries);
|
||||
continue;
|
||||
}
|
||||
if (index % 8 == 0 && index + 8 <= stop && std::atomic_ref<std::uint64_t>(*reinterpret_cast<std::uint64_t*>(at)).load(std::memory_order_relaxed) == wide) {
|
||||
if (index % BlockPages == 0) {
|
||||
const auto block = index / BlockPages;
|
||||
const auto* summary = blockEntry(block, false);
|
||||
if (block % 8 == 0 && index + 8 * BlockPages <= stop && loadWide(summary) == wide) {
|
||||
index += 8 * BlockPages;
|
||||
continue;
|
||||
}
|
||||
if (index + BlockPages <= stop && loadByte(summary) == value) {
|
||||
index += BlockPages;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (index % 8 == 0 && index + 8 <= stop && loadWide(at) == wide) {
|
||||
index += 8;
|
||||
continue;
|
||||
}
|
||||
if (std::atomic_ref<std::uint8_t>(*at).load(std::memory_order_relaxed) != value) break;
|
||||
if (loadByte(at) != value) break;
|
||||
++index;
|
||||
}
|
||||
return std::min(limit, base + index * PageBytes);
|
||||
@@ -509,7 +580,7 @@ struct PageStates {
|
||||
if (span->size == 0 || bytes == 0 || address >= span->base + span->size || address + bytes <= span->base) continue;
|
||||
const auto last = std::min(address + bytes, span->base + span->size);
|
||||
for (auto at = std::max(address, span->base) & ~static_cast<std::uintptr_t>(PageBytes - 1); at < last; at += PageBytes) {
|
||||
if (span->load(at) == PageInaccessible) span->store(at, 0);
|
||||
if (span->load(at) == PageInaccessible) span->store(at, at + PageBytes, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -703,6 +774,41 @@ bool describePages(std::uintptr_t address, std::size_t bytes, Emit&& emit) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
{
|
||||
mach_vm_address_t region = cursor;
|
||||
mach_vm_size_t regionSize = 0;
|
||||
vm_region_basic_info_data_64_t info{};
|
||||
mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
|
||||
mach_port_t object = MACH_PORT_NULL;
|
||||
const auto status = mach_vm_region(mach_task_self(), ®ion, ®ionSize, VM_REGION_BASIC_INFO_64, reinterpret_cast<vm_region_info_t>(&info), &count, &object);
|
||||
if (status == KERN_INVALID_ADDRESS) {
|
||||
static_cast<void>(emit(PageRun{cursor, end, false, false}));
|
||||
return true;
|
||||
}
|
||||
if (status != KERN_SUCCESS || regionSize == 0) return false;
|
||||
if (region > cursor) {
|
||||
const auto gapEnd = std::min<std::uintptr_t>(end, region);
|
||||
if (!emit(PageRun{cursor, gapEnd, false, false})) return true;
|
||||
cursor = gapEnd;
|
||||
continue;
|
||||
}
|
||||
bool readable = (info.protection & VM_PROT_READ) != 0;
|
||||
bool writable = readable && (info.protection & VM_PROT_WRITE) != 0;
|
||||
auto next = std::min<std::uintptr_t>(end, region + regionSize);
|
||||
std::uintptr_t watchedEnd = next;
|
||||
const int logical = GuestWriteWatch::GuestWriteWatchProtection_nid_postfix(cursor, next, &watchedEnd);
|
||||
if (logical >= 0) {
|
||||
readable = readable && (logical & PROT_READ) != 0;
|
||||
writable = readable && (logical & PROT_WRITE) != 0;
|
||||
}
|
||||
if (watchedEnd > cursor && watchedEnd < next) next = watchedEnd;
|
||||
recordRun(next, readable, writable);
|
||||
if (!emit(PageRun{cursor, next, readable, writable})) return true;
|
||||
cursor = next;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
std::ifstream maps("/proc/self/maps");
|
||||
if (!maps.is_open()) return false;
|
||||
std::string line;
|
||||
@@ -752,6 +858,10 @@ bool onOwnLiveStack(std::uintptr_t address, std::size_t bytes) {
|
||||
GetCurrentThreadStackLimits(&lowLimit, &highLimit);
|
||||
low = static_cast<std::uintptr_t>(lowLimit);
|
||||
high = static_cast<std::uintptr_t>(highLimit);
|
||||
#elif defined(__APPLE__)
|
||||
const auto self = pthread_self();
|
||||
high = reinterpret_cast<std::uintptr_t>(pthread_get_stackaddr_np(self));
|
||||
low = high - pthread_get_stacksize_np(self);
|
||||
#else
|
||||
pthread_attr_t attributes;
|
||||
if (pthread_getattr_np(pthread_self(), &attributes) != 0) return;
|
||||
@@ -947,11 +1057,11 @@ struct WriteTracker {
|
||||
static constexpr std::size_t CoarseBlocks = 64;
|
||||
static constexpr std::size_t LeafBlocks = std::size_t{1} << 16;
|
||||
struct Leaf {
|
||||
std::array<std::uint32_t, LeafBlocks> blocks{};
|
||||
std::array<std::uint32_t, LeafBlocks> cpuBlocks{};
|
||||
std::array<std::uint32_t, LeafBlocks / CoarseBlocks> coarseBlocks{};
|
||||
std::array<std::uint64_t, LeafBlocks> blocks{};
|
||||
std::array<std::uint64_t, LeafBlocks> cpuBlocks{};
|
||||
std::array<std::uint64_t, LeafBlocks / CoarseBlocks> coarseBlocks{};
|
||||
#ifdef _WIN32
|
||||
std::array<std::uint32_t, LeafBlocks> hintBlocks{};
|
||||
std::array<std::uint64_t, LeafBlocks> hintBlocks{};
|
||||
#endif
|
||||
};
|
||||
std::vector<std::unique_ptr<Leaf>> leaves;
|
||||
@@ -966,8 +1076,8 @@ struct WriteTracker {
|
||||
// stamp still happen under it): a hit must return the current value, including MarkWritten
|
||||
// bumps, or an image refreshed after a stamp would keep failing UnchangedSince until the next
|
||||
// walk of its range and re-upload at every use of the epoch.
|
||||
std::atomic<std::uint32_t> generation{1};
|
||||
std::atomic<std::uint32_t> stable{1};
|
||||
std::atomic<std::uint64_t> generation{1};
|
||||
std::atomic<std::uint64_t> stable{1};
|
||||
std::vector<void*> pages;
|
||||
// Collect memo: page-rounded ranges walked during the current epoch (see BumpCollectEpoch). A
|
||||
// collect fully inside one skips GetWriteWatch, whose cost is proportional to the range's pages,
|
||||
@@ -1050,24 +1160,24 @@ struct WriteTracker {
|
||||
return !GuestArena::GuestArenaHostRegionOverlaps_nid_postfix(static_cast<std::uintptr_t>(first), static_cast<std::size_t>(stop - first));
|
||||
}
|
||||
|
||||
std::uint32_t newestHint(std::uint64_t first, std::uint64_t stop) const {
|
||||
std::uint32_t newest = 0;
|
||||
std::uint64_t newestHint(std::uint64_t first, std::uint64_t stop) const {
|
||||
std::uint64_t newest = 0;
|
||||
for (auto block = blockOf(first); block <= blockOf(stop - 1); ++block) newest = std::max(newest, hintOf(block));
|
||||
return newest;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct DriverPiece {
|
||||
std::uint32_t generation = 0;
|
||||
std::uint64_t generation = 0;
|
||||
std::uint32_t begin = 0;
|
||||
std::uint32_t end = 0;
|
||||
};
|
||||
struct DriverPieces {
|
||||
std::uint32_t whole = 0;
|
||||
std::uint32_t dropped = 0;
|
||||
std::uint64_t whole = 0;
|
||||
std::uint64_t dropped = 0;
|
||||
std::array<DriverPiece, 4> pieces{};
|
||||
std::uint32_t possibleWhole = 0;
|
||||
std::uint32_t possibleDropped = 0;
|
||||
std::uint64_t possibleWhole = 0;
|
||||
std::uint64_t possibleDropped = 0;
|
||||
std::array<DriverPiece, 4> possiblePieces{};
|
||||
|
||||
bool covers(std::uint32_t begin, std::uint32_t end, std::uint64_t generation) const {
|
||||
@@ -1087,21 +1197,21 @@ struct WriteTracker {
|
||||
std::unordered_map<std::uint64_t, DriverPieces> driverPieces;
|
||||
|
||||
struct CpuPages {
|
||||
std::array<std::uint32_t, WritePagesPerBlock> pages{};
|
||||
std::array<std::uint64_t, WritePagesPerBlock> pages{};
|
||||
};
|
||||
std::unordered_map<std::uint64_t, CpuPages> cpuPages;
|
||||
std::unordered_map<std::uint64_t, CpuPages> walkPages;
|
||||
std::map<std::uint64_t, std::uint32_t> refused;
|
||||
std::map<std::uint64_t, std::uint64_t> refused;
|
||||
|
||||
void noteCpuStore(std::uint64_t begin, std::uint64_t end, std::uint32_t stampGeneration) {
|
||||
void noteCpuStore(std::uint64_t begin, std::uint64_t end, std::uint64_t stampGeneration) {
|
||||
notePages(cpuPages, begin, end, stampGeneration);
|
||||
}
|
||||
|
||||
void noteWalkStore(std::uint64_t begin, std::uint64_t end, std::uint32_t stampGeneration) {
|
||||
void noteWalkStore(std::uint64_t begin, std::uint64_t end, std::uint64_t stampGeneration) {
|
||||
notePages(walkPages, begin, end, stampGeneration);
|
||||
}
|
||||
|
||||
void notePages(std::unordered_map<std::uint64_t, CpuPages>& pages, std::uint64_t begin, std::uint64_t end, std::uint32_t stampGeneration) {
|
||||
void notePages(std::unordered_map<std::uint64_t, CpuPages>& pages, std::uint64_t begin, std::uint64_t end, std::uint64_t stampGeneration) {
|
||||
for (auto block = blockOf(begin); block <= blockOf(end - 1); ++block) {
|
||||
const auto blockStart = blockBegin(block);
|
||||
const auto from = std::max(begin, blockStart) - blockStart;
|
||||
@@ -1125,7 +1235,7 @@ struct WriteTracker {
|
||||
#endif
|
||||
}
|
||||
|
||||
void stampWatchedPart(std::uint64_t address, std::uint64_t end, std::uint32_t stampGeneration, bool complete) {
|
||||
void stampWatchedPart(std::uint64_t address, std::uint64_t end, std::uint64_t stampGeneration, bool complete) {
|
||||
#ifdef _WIN32
|
||||
address = std::max<std::uint64_t>(address, base);
|
||||
end = std::min<std::uint64_t>(end, base + size);
|
||||
@@ -1143,7 +1253,7 @@ struct WriteTracker {
|
||||
}
|
||||
}
|
||||
|
||||
void noteDriverStore(std::uint64_t block, std::uint64_t address, std::uint64_t end, std::uint32_t stampGeneration, bool complete) {
|
||||
void noteDriverStore(std::uint64_t block, std::uint64_t address, std::uint64_t end, std::uint64_t stampGeneration, bool complete) {
|
||||
const auto begin = blockBegin(block);
|
||||
const auto from = static_cast<std::uint32_t>(std::max(address, begin) - begin);
|
||||
const auto to = static_cast<std::uint32_t>(std::min<std::uint64_t>(end, begin + WriteBlockBytes) - begin);
|
||||
@@ -1191,19 +1301,19 @@ struct WriteTracker {
|
||||
leafFor(block).hintBlocks[block % LeafBlocks] = generation;
|
||||
}
|
||||
|
||||
std::uint32_t hintOf(std::uint64_t block) const {
|
||||
std::uint64_t hintOf(std::uint64_t block) const {
|
||||
const auto& leaf = leaves[block / LeafBlocks];
|
||||
return leaf != nullptr ? leaf->hintBlocks[block % LeafBlocks] : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::uint32_t stampOf(std::uint64_t block) const {
|
||||
std::uint64_t stampOf(std::uint64_t block) const {
|
||||
const auto& leaf = leaves[block / LeafBlocks];
|
||||
return leaf != nullptr ? leaf->blocks[block % LeafBlocks] : 0;
|
||||
}
|
||||
|
||||
static constexpr std::size_t UnstampedSlots = 1u << 16;
|
||||
std::vector<std::uint32_t> unstampedStores;
|
||||
std::vector<std::uint64_t> unstampedStores;
|
||||
|
||||
void noteUnstampedStore(std::uint64_t address, std::uint64_t end) {
|
||||
if (unstampedStores.empty()) unstampedStores.assign(UnstampedSlots, 0);
|
||||
@@ -1216,8 +1326,8 @@ struct WriteTracker {
|
||||
for (auto block = first; block <= last; ++block) unstampedStores[block % UnstampedSlots] = generation;
|
||||
}
|
||||
|
||||
std::uint32_t newestStamp(std::uint64_t address, std::uint64_t end) const {
|
||||
std::uint32_t newest = 0;
|
||||
std::uint64_t newestStamp(std::uint64_t address, std::uint64_t end) const {
|
||||
std::uint64_t newest = 0;
|
||||
if (!unstampedStores.empty()) {
|
||||
const auto first = address / WriteBlockBytes;
|
||||
const auto last = (end - 1) / WriteBlockBytes;
|
||||
@@ -1236,14 +1346,14 @@ struct WriteTracker {
|
||||
return newest;
|
||||
}
|
||||
|
||||
std::uint32_t coarseStampOf(std::uint64_t block) const {
|
||||
std::uint64_t coarseStampOf(std::uint64_t block) const {
|
||||
const auto& leaf = leaves[block / LeafBlocks];
|
||||
return leaf != nullptr ? leaf->coarseBlocks[(block % LeafBlocks) / CoarseBlocks] : 0;
|
||||
}
|
||||
|
||||
bool unchanged(std::uint64_t first, std::uint64_t last, std::uint64_t since) const {
|
||||
if (first == last) return stampOf(first) <= since;
|
||||
const auto newer = [since](std::uint32_t stamp) { return stamp > since; };
|
||||
const auto newer = [since](std::uint64_t stamp) { return stamp > since; };
|
||||
while (first <= last) {
|
||||
const auto& leaf = leaves[first / LeafBlocks];
|
||||
if (leaf == nullptr) {
|
||||
@@ -1260,7 +1370,7 @@ struct WriteTracker {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::uint32_t cpuStampOf(std::uint64_t block) const {
|
||||
std::uint64_t cpuStampOf(std::uint64_t block) const {
|
||||
const auto& leaf = leaves[block / LeafBlocks];
|
||||
return leaf != nullptr ? leaf->cpuBlocks[block % LeafBlocks] : 0;
|
||||
}
|
||||
@@ -1312,7 +1422,7 @@ struct WriteTracker {
|
||||
return unchanged(blockOf(address), blockOf(address + bytes - 1), since) || !storedOver(address, address + bytes, since, true);
|
||||
}
|
||||
|
||||
void stamp(std::uint64_t block, std::uint32_t stampGeneration, StampKind kind) {
|
||||
void stamp(std::uint64_t block, std::uint64_t stampGeneration, StampKind kind) {
|
||||
const bool cpu = kind == StampKind::Cpu || kind == StampKind::ImportWindow;
|
||||
const bool stored = kind != StampKind::ImportWindow;
|
||||
auto& leaf = leafFor(block);
|
||||
@@ -1365,6 +1475,23 @@ public:
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
class Suspension {
|
||||
public:
|
||||
explicit Suspension(TrackerLock& owner) : owner(owner) {
|
||||
owner.Suspend();
|
||||
}
|
||||
|
||||
~Suspension() {
|
||||
owner.Resume();
|
||||
}
|
||||
|
||||
Suspension(const Suspension&) = delete;
|
||||
Suspension& operator=(const Suspension&) = delete;
|
||||
|
||||
private:
|
||||
TrackerLock& owner;
|
||||
};
|
||||
|
||||
private:
|
||||
void publish() {
|
||||
const auto current = tracker.generation.load(std::memory_order_relaxed);
|
||||
@@ -1389,7 +1516,7 @@ void watchPrivateMapping(std::uintptr_t address, std::size_t bytes, std::uint64_
|
||||
tracker.noteCpuStore(address, address + bytes, tracker.generation);
|
||||
for (auto block = tracker.blockOf(address); block <= tracker.blockOf(address + bytes - 1); ++block) {
|
||||
if (const auto& leaf = tracker.leaves[block / WriteTracker::LeafBlocks]; leaf != nullptr) leaf->hintBlocks[block % WriteTracker::LeafBlocks] = 0;
|
||||
if (const auto found = tracker.driverPieces.find(block); found != tracker.driverPieces.end()) found->second.dropped = std::max<std::uint32_t>(found->second.dropped, tracker.generation);
|
||||
if (const auto found = tracker.driverPieces.find(block); found != tracker.driverPieces.end()) found->second.dropped = std::max<std::uint64_t>(found->second.dropped, tracker.generation);
|
||||
tracker.stamp(block, tracker.generation, StampKind::Cpu);
|
||||
}
|
||||
unwatchSerial.fetch_add(1, std::memory_order_release);
|
||||
@@ -1466,7 +1593,7 @@ struct StampRuns {
|
||||
std::vector<std::pair<std::uint64_t, std::uint64_t>> windowRuns;
|
||||
};
|
||||
|
||||
void noteWrittenRun(StampRuns& runs, std::uintptr_t begin, std::uintptr_t end, std::uint32_t generation) {
|
||||
void noteWrittenRun(StampRuns& runs, std::uintptr_t begin, std::uintptr_t end, std::uint64_t generation) {
|
||||
if (runs.kind != StampKind::Driver) runs.tracker.noteCpuStore(begin, end, generation);
|
||||
else runs.tracker.noteWalkStore(begin, end, generation);
|
||||
}
|
||||
@@ -1766,6 +1893,10 @@ namespace {
|
||||
|
||||
std::atomic<void (*)(std::uint64_t, std::size_t)> unwatchHook{nullptr};
|
||||
|
||||
thread_local bool unwatchWritesProven = true;
|
||||
std::atomic<int> importWalkFailureForTest{0};
|
||||
std::atomic<std::uint64_t> importWalkFailureSpanForTest{0};
|
||||
|
||||
void beforeUnwatch(std::uint64_t address, std::size_t bytes) {
|
||||
const auto hook = unwatchHook.load(std::memory_order_acquire);
|
||||
if (hook == nullptr) return;
|
||||
@@ -1784,6 +1915,16 @@ void beforeUnwatch(std::uint64_t address, std::size_t bytes) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void beforeUnwatchUnproven(std::uint64_t address, std::size_t bytes) {
|
||||
struct Unproven {
|
||||
Unproven() { unwatchWritesProven = false; }
|
||||
~Unproven() { unwatchWritesProven = true; }
|
||||
Unproven(const Unproven&) = delete;
|
||||
Unproven& operator=(const Unproven&) = delete;
|
||||
} unproven;
|
||||
beforeUnwatch(address, bytes);
|
||||
}
|
||||
|
||||
void unwatchLocked(WriteTracker& tracker, std::uint64_t address, std::size_t bytes) {
|
||||
if (!tracker.watched) return;
|
||||
#ifdef _WIN32
|
||||
@@ -1800,6 +1941,15 @@ void SetUnwatchHook(void (*hook)(std::uint64_t, std::size_t)) {
|
||||
unwatchHook.store(hook, std::memory_order_release);
|
||||
}
|
||||
|
||||
bool UnwatchWritesProven() {
|
||||
return unwatchWritesProven;
|
||||
}
|
||||
|
||||
void SetImportWalkFailureForTest(int walk, std::uint64_t span) {
|
||||
importWalkFailureSpanForTest.store(span, std::memory_order_release);
|
||||
importWalkFailureForTest.store(walk, std::memory_order_release);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void SetFreshCollectHook(FreshCollectHook hook) {
|
||||
freshCollectHook.store(hook, std::memory_order_release);
|
||||
@@ -1892,29 +2042,39 @@ bool ImportWatched(std::uint64_t address, std::size_t bytes, const std::function
|
||||
std::vector<std::uint64_t> hashes(static_cast<std::size_t>((stop - first) / page), 0);
|
||||
for (const auto& [begin, end] : spans) CheckRange(reinterpret_cast<const void*>(begin), static_cast<std::size_t>(end - begin), 1, false);
|
||||
HashPages(first, spans, hashes);
|
||||
const auto saveBytes = [&](std::uint64_t begin, std::uint64_t end) {
|
||||
lock.Suspend();
|
||||
beforeUnwatch(begin, static_cast<std::size_t>(end - begin));
|
||||
lock.Resume();
|
||||
const auto failWalk = importWalkFailureForTest.load(std::memory_order_acquire);
|
||||
const auto failSpan = importWalkFailureSpanForTest.load(std::memory_order_acquire);
|
||||
const auto failsWalk = [&](int walk, std::uint64_t begin, std::uint64_t end) {
|
||||
return failWalk == walk && (failSpan == 0 || (begin <= failSpan && failSpan < end));
|
||||
};
|
||||
const auto leave = [&](const std::vector<std::pair<std::uint64_t, std::uint64_t>>& ranges) {
|
||||
if (ranges.empty()) return;
|
||||
const TrackerLock::Suspension suspended{lock};
|
||||
for (const auto& [begin, end] : ranges) beforeUnwatchUnproven(begin, static_cast<std::size_t>(end - begin));
|
||||
};
|
||||
std::vector<std::pair<std::uint64_t, std::uint64_t>> leaving;
|
||||
std::erase_if(spans, [&](const auto& span) {
|
||||
if (walkWrites(tracker, span.first, span.second, StampKind::Cpu, true)) return false;
|
||||
if (!failsWalk(1, span.first, span.second) && walkWrites(tracker, span.first, span.second, StampKind::Cpu, true)) return false;
|
||||
leaving.push_back(span);
|
||||
return true;
|
||||
});
|
||||
for (const auto& [begin, end] : leaving) saveBytes(begin, end);
|
||||
leave(leaving);
|
||||
if (!runImport()) return false;
|
||||
const WindowCopy window{first, hashes};
|
||||
auto unwatchedFrom = first;
|
||||
for (const auto& [begin, end] : spans) {
|
||||
if (!walkWrites(tracker, begin, end, StampKind::Cpu, true, &window)) {
|
||||
saveBytes(begin, end);
|
||||
continue;
|
||||
leaving.clear();
|
||||
std::erase_if(spans, [&](const auto& span) {
|
||||
if (failsWalk(2, span.first, span.second) || !walkWrites(tracker, span.first, span.second, StampKind::Cpu, true, &window)) {
|
||||
leaving.push_back(span);
|
||||
return true;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
GuestArena::GuestArenaCompareResidentWhenShared_nid_no_patch(static_cast<std::uintptr_t>(begin), static_cast<std::size_t>(end - begin));
|
||||
GuestArena::GuestArenaCompareResidentWhenShared_nid_no_patch(static_cast<std::uintptr_t>(span.first), static_cast<std::size_t>(span.second - span.first));
|
||||
#endif
|
||||
return false;
|
||||
});
|
||||
leave(leaving);
|
||||
auto unwatchedFrom = first;
|
||||
for (const auto& [begin, end] : spans) {
|
||||
if (unwatchedFrom < begin) unwatchLocked(tracker, unwatchedFrom, static_cast<std::size_t>(begin - unwatchedFrom));
|
||||
unwatchedFrom = end;
|
||||
}
|
||||
@@ -2066,9 +2226,10 @@ static std::uint64_t markWritten(std::uint64_t address, std::size_t bytes, bool
|
||||
const bool collected = GuestWriteWatch::GuestWriteWatchCollectFresh_nid_postfix(static_cast<std::uintptr_t>(blockFirst), static_cast<std::size_t>(blockStop - blockFirst), &stampWrittenRun, &runs);
|
||||
#endif
|
||||
if (!collected) {
|
||||
lock.Suspend();
|
||||
beforeUnwatch(blockFirst, static_cast<std::size_t>(blockStop - blockFirst));
|
||||
lock.Resume();
|
||||
{
|
||||
const TrackerLock::Suspension suspended{lock};
|
||||
beforeUnwatchUnproven(blockFirst, static_cast<std::size_t>(blockStop - blockFirst));
|
||||
}
|
||||
unwatchLocked(tracker, blockFirst, static_cast<std::size_t>(blockStop - blockFirst));
|
||||
tracker.noteUnstampedStore(address, address + bytes);
|
||||
return 0;
|
||||
@@ -2138,6 +2299,12 @@ std::uint64_t TrackerGeneration() {
|
||||
return tracker.generation;
|
||||
}
|
||||
|
||||
void AdvanceTrackerGenerationForTest(std::uint64_t generation) {
|
||||
auto& tracker = Tracker();
|
||||
const auto lock = lockTracker(tracker);
|
||||
if (generation > tracker.generation.load(std::memory_order_relaxed)) tracker.generation.store(generation, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
std::uint64_t NewestStamp(std::uint64_t address, std::size_t bytes) {
|
||||
auto& tracker = Tracker();
|
||||
const auto lock = lockTracker(tracker);
|
||||
@@ -2614,8 +2781,13 @@ std::uint32_t GpuLockThreadTag() {
|
||||
}
|
||||
|
||||
GpuMutexType& GpuMutex() {
|
||||
#ifdef __APPLE__
|
||||
static auto* mutex = new GpuMutexType;
|
||||
return *mutex;
|
||||
#else
|
||||
static GpuMutexType mutex;
|
||||
return mutex;
|
||||
#endif
|
||||
}
|
||||
|
||||
void TagGpuLockThread(std::uint32_t queue) {
|
||||
@@ -2858,7 +3030,7 @@ void WriteChanged(std::uint64_t address, std::span<const std::byte> current, std
|
||||
WriteChanged(address, current, original, ChangedByteStoreLimit());
|
||||
}
|
||||
|
||||
void WriteChanged(std::uint64_t address, std::span<const std::byte> current, std::span<const std::byte> original, std::uint32_t byteStoreLimit) {
|
||||
static void writeChanged(std::uint64_t address, std::span<const std::byte> current, std::span<const std::byte> original, std::uint32_t byteStoreLimit, bool keepGuest) {
|
||||
require(current.size() == original.size(), "write-back snapshot sizes differ");
|
||||
BreakProofs();
|
||||
if (current.empty()) return;
|
||||
@@ -2878,7 +3050,9 @@ void WriteChanged(std::uint64_t address, std::span<const std::byte> current, std
|
||||
std::size_t at = 0;
|
||||
for (; at + 16 <= size; at += 16) {
|
||||
const auto bytes = _mm_loadu_si128(reinterpret_cast<const __m128i*>(current.data() + at));
|
||||
const auto same = _mm_cmpeq_epi8(bytes, _mm_loadu_si128(reinterpret_cast<const __m128i*>(original.data() + at)));
|
||||
const auto uploaded = _mm_loadu_si128(reinterpret_cast<const __m128i*>(original.data() + at));
|
||||
auto same = _mm_cmpeq_epi8(bytes, uploaded);
|
||||
if (keepGuest) same = _mm_or_si128(same, _mm_xor_si128(_mm_cmpeq_epi8(_mm_loadu_si128(reinterpret_cast<const __m128i*>(destination + at)), uploaded), _mm_set1_epi8(-1)));
|
||||
const auto equal = static_cast<std::uint32_t>(_mm_movemask_epi8(same));
|
||||
if (equal == 0xffffu) continue;
|
||||
const auto changed = ~equal & 0xffffu;
|
||||
@@ -2897,7 +3071,7 @@ void WriteChanged(std::uint64_t address, std::span<const std::byte> current, std
|
||||
}
|
||||
if (masked) _mm_sfence();
|
||||
for (; at < size; ++at) {
|
||||
if (current[at] == original[at]) continue;
|
||||
if (current[at] == original[at] || (keepGuest && destination[at] != original[at])) continue;
|
||||
destination[at] = current[at];
|
||||
firstChanged = std::min(firstChanged, at);
|
||||
lastChanged = std::max(lastChanged, at + 1);
|
||||
@@ -2906,6 +3080,14 @@ void WriteChanged(std::uint64_t address, std::span<const std::byte> current, std
|
||||
});
|
||||
}
|
||||
|
||||
void WriteChanged(std::uint64_t address, std::span<const std::byte> current, std::span<const std::byte> original, std::uint32_t byteStoreLimit) {
|
||||
writeChanged(address, current, original, byteStoreLimit, false);
|
||||
}
|
||||
|
||||
void WriteChangedKeepingGuest(std::uint64_t address, std::span<const std::byte> current, std::span<const std::byte> original) {
|
||||
writeChanged(address, current, original, ChangedByteStoreLimit(), true);
|
||||
}
|
||||
|
||||
void Write(std::uint64_t address, std::span<const std::byte> source, std::size_t alignment) {
|
||||
if (source.empty()) return;
|
||||
// A store, as in WriteChanged.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <cerrno>
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
extern char** environ;
|
||||
#endif
|
||||
|
||||
namespace AgcDriver {
|
||||
|
||||
Loaded 100 of 1599 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user