Compare commits
224 Commits
Canary-1.2
...
5c54ce9114
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c54ce9114 | ||
|
|
3b5f6170d1 | ||
|
|
9b6afa0ea2 | ||
|
|
3541e282ea | ||
|
|
1ce37ec317 | ||
|
|
c06f16c5e6 | ||
|
|
7829fd8ee7 | ||
|
|
33079422fe | ||
|
|
f81cb093fc | ||
|
|
dc0c7a2912 | ||
|
|
1fbee5a584 | ||
|
|
428b1e5cea | ||
|
|
c140e9b23c | ||
|
|
9c8055440e | ||
|
|
c03cd50fa3 | ||
|
|
069f630776 | ||
|
|
13d411e4de | ||
|
|
9f53b07491 | ||
|
|
cd8113dadf | ||
|
|
9089c4ffe5 | ||
|
|
fe9d8d05bd | ||
|
|
880a8ae748 | ||
|
|
11531dacb6 | ||
|
|
3974739ed3 | ||
|
|
440a3447fb | ||
|
|
65374ed6cb | ||
|
|
789d6ab959 | ||
|
|
182db31343 | ||
|
|
ea296b134d | ||
|
|
bf584442b2 | ||
|
|
cb7c294dbf | ||
|
|
eaf1e7efd2 | ||
|
|
471e7ed2e4 | ||
|
|
ad3e80b383 | ||
|
|
ed64a63094 | ||
|
|
8df7ba2d56 | ||
|
|
e743d78115 | ||
|
|
04ba762710 | ||
|
|
f42b2ed59d | ||
|
|
e6f7d6e1d5 | ||
|
|
0ad5def417 | ||
|
|
f012c3fbef | ||
|
|
b69b432b4c | ||
|
|
d135385cab | ||
|
|
b360f4e721 | ||
|
|
a1c0c70ec2 | ||
|
|
290ac405ac | ||
|
|
bbd64fd5f0 | ||
|
|
09446fd80e | ||
|
|
4f014a89cf | ||
|
|
6482e566ab | ||
|
|
7fcd9b792e | ||
|
|
e676fd8b17 | ||
|
|
dd16e3cee1 | ||
|
|
31e5f74e05 | ||
|
|
f2f099bddb | ||
|
|
2616dc57fb | ||
|
|
0cdf7cfe21 | ||
|
|
2ecf999569 | ||
|
|
b612fc5155 | ||
|
|
25eb545409 | ||
|
|
52269964b6 | ||
|
|
ccdddac8fc | ||
|
|
1bc30bf3ba | ||
|
|
4868fface8 | ||
|
|
6fca4492d0 | ||
|
|
ade2f256e0 | ||
|
|
580b150c9a | ||
|
|
e6bad52945 | ||
|
|
beda3206e0 | ||
|
|
2f93a0f706 | ||
|
|
80f44d9547 | ||
|
|
b08e5db6d8 | ||
|
|
6a291d4116 | ||
|
|
6fc827fe67 | ||
|
|
6cd4866d76 | ||
|
|
4d7ca5c0f0 | ||
|
|
a375faecc1 | ||
|
|
1728b0f20c | ||
|
|
5aa071c59b | ||
|
|
1018c9db8b | ||
|
|
01ccd18726 | ||
|
|
abfbc6f4bc | ||
|
|
6a4bc02d7a | ||
|
|
814c0526d2 | ||
|
|
a5a4ef38e6 | ||
|
|
c17e3bfcdf | ||
|
|
017f46f318 | ||
|
|
fd4d801bfd | ||
|
|
f1dee50275 | ||
|
|
c2ae49eb47 | ||
|
|
47c71966d0 | ||
|
|
f9e8f4bc29 | ||
|
|
7694c8c046 | ||
|
|
0dd789e8a5 | ||
|
|
4e0aafd005 | ||
|
|
c5091f499e | ||
|
|
41c8fd8194 | ||
|
|
d4a7ee25ea | ||
|
|
3141c560fb | ||
|
|
de341b285b | ||
|
|
cc95e80ee9 | ||
|
|
d75ce52bd4 | ||
|
|
4a4ea557de | ||
|
|
33f42adb11 | ||
|
|
918ec1bde3 | ||
|
|
cca429d46a | ||
|
|
845c86f545 | ||
|
|
27993b789f | ||
|
|
bdd890cf6f | ||
|
|
c5574b41a1 | ||
|
|
292e27f0da | ||
|
|
606e149bd3 | ||
|
|
a8c3407d11 | ||
|
|
daa8168985 | ||
|
|
f580521e99 | ||
|
|
2226521f6c | ||
|
|
384416953d | ||
|
|
1343fabe41 | ||
|
|
1e52af5e29 | ||
|
|
672f5df0f9 | ||
|
|
804d9c1efe | ||
|
|
9270b35648 | ||
|
|
5a6d01db3c | ||
|
|
ef9c1416ec | ||
|
|
5efa7d5dfa | ||
|
|
a82569d615 | ||
|
|
ed5832ca73 | ||
|
|
574aa9ff9c | ||
|
|
8a29428de2 | ||
|
|
f4272b05fa | ||
|
|
d8265f7772 | ||
|
|
259526430c | ||
|
|
b5fafb6394 | ||
|
|
323c356d9c | ||
|
|
30b22ce6ba | ||
|
|
9acecc9eb2 | ||
|
|
4193a37a91 | ||
|
|
c4cc657b89 | ||
|
|
9726b0feb0 | ||
|
|
159ff828a1 | ||
|
|
6fa2bfc736 | ||
|
|
2c24df0247 | ||
|
|
13efc3e544 | ||
|
|
845dd9a8db | ||
|
|
b661bdd997 | ||
|
|
cc84041270 | ||
|
|
987ab9be41 | ||
|
|
8a2bc3957a | ||
|
|
850df38f1e | ||
|
|
c8d598d5ac | ||
|
|
3e5b2bda38 | ||
|
|
9bb50fc6dd | ||
|
|
e956864697 | ||
|
|
f43442f774 | ||
|
|
88d11d3d8d | ||
|
|
391f57bdd2 | ||
|
|
fd2b5a7fc1 | ||
|
|
37c165e9fc | ||
|
|
003a6d322b | ||
|
|
978d2c132b | ||
|
|
5d63706cea | ||
|
|
732aafd3bb | ||
|
|
3fa714bb72 | ||
|
|
7c01633f13 | ||
|
|
27c5cba10b | ||
|
|
3525d5ecd4 | ||
|
|
6286501550 | ||
|
|
61ae427a4d | ||
|
|
19d2883a35 | ||
|
|
617c03119f | ||
|
|
e43d899e1d | ||
|
|
0cd09ea0c5 | ||
|
|
4135d74e4d | ||
|
|
bd29f658b1 | ||
|
|
df150f0788 | ||
|
|
e50198b37d | ||
|
|
f426945fec | ||
|
|
172869bfba | ||
|
|
b6f88514f9 | ||
|
|
e92f52e56c | ||
|
|
318498eab0 | ||
|
|
a5cde8e006 | ||
|
|
d0a344d632 | ||
|
|
ca66298817 | ||
|
|
9ae1c4380d | ||
|
|
c88518bce2 | ||
|
|
a3888ed7cf | ||
|
|
7cbbd02973 | ||
|
|
b2e1e553e4 | ||
|
|
699e1962b1 | ||
|
|
e486b902b1 | ||
|
|
0ab5b41c4b | ||
|
|
d10a478cce | ||
|
|
ec1020b165 | ||
|
|
4082ebad1a | ||
|
|
da8ea06074 | ||
|
|
7f9dccb293 | ||
|
|
8e4a77aba0 | ||
|
|
8fd8a776c9 | ||
|
|
eec92c242c | ||
|
|
42a739d34c | ||
|
|
f362bef43d | ||
|
|
f5ce539de9 | ||
|
|
4f699afe7a | ||
|
|
6caab1aa37 | ||
|
|
9baaa2b8f8 | ||
|
|
7f376b4f45 | ||
|
|
32cdccde12 | ||
|
|
cbd851d00e | ||
|
|
f463ea1c5d | ||
|
|
1dd69912b1 | ||
|
|
1fbb0d8e7d | ||
|
|
9ee3f1ff36 | ||
|
|
d052d74ac4 | ||
|
|
df91c4c57a | ||
|
|
2aaaa7872f | ||
|
|
b5999583d6 | ||
|
|
8b3a945b5f | ||
|
|
09107b67ff | ||
|
|
12b264af44 | ||
|
|
0c21b07f19 | ||
|
|
18625cf775 | ||
|
|
77a9246825 |
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -22,7 +22,7 @@ body:
|
||||
id: log
|
||||
attributes:
|
||||
label: Log file
|
||||
description: A log file will help our developers to better diagnose and fix the issue.
|
||||
description: "A log file will help our developers to better diagnose and fix the issue. UPLOAD THE FILE. DO NOT COPY AND PASTE THE FILE'S CONTENT."
|
||||
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste).
|
||||
validations:
|
||||
required: true
|
||||
|
||||
4
.github/labeler.yml
vendored
4
.github/labeler.yml
vendored
@@ -18,6 +18,10 @@ gpu:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**']
|
||||
|
||||
'graphics-backend:metal':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Metal/**', 'src/Ryujinx.Graphics.Metal.SharpMetalExtensions/**']
|
||||
|
||||
gui:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**']
|
||||
|
||||
27
.github/workflows/build.yml
vendored
27
.github/workflows/build.yml
vendored
@@ -64,14 +64,9 @@ jobs:
|
||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained
|
||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
||||
|
||||
- name: Publish Ryujinx.Headless.SDL2
|
||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained
|
||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
||||
|
||||
- name: Set executable bit
|
||||
run: |
|
||||
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
||||
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
|
||||
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
|
||||
|
||||
- name: Build AppImage
|
||||
@@ -119,13 +114,6 @@ jobs:
|
||||
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}-AppImage
|
||||
path: publish_appimage
|
||||
|
||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nogui-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
|
||||
path: publish_sdl2_headless
|
||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
||||
|
||||
build_macos:
|
||||
name: macOS Universal (${{ matrix.configuration }})
|
||||
runs-on: ubuntu-latest
|
||||
@@ -141,11 +129,11 @@ jobs:
|
||||
with:
|
||||
global-json-file: global.json
|
||||
|
||||
- name: Setup LLVM 14
|
||||
- name: Setup LLVM 17
|
||||
run: |
|
||||
wget https://apt.llvm.org/llvm.sh
|
||||
chmod +x llvm.sh
|
||||
sudo ./llvm.sh 14
|
||||
sudo ./llvm.sh 17
|
||||
|
||||
- name: Install rcodesign
|
||||
run: |
|
||||
@@ -171,20 +159,9 @@ jobs:
|
||||
run: |
|
||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp publish ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
||||
|
||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
||||
run: |
|
||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
||||
|
||||
- name: Upload Ryujinx artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
||||
path: "publish/*.tar.gz"
|
||||
if: github.event_name == 'pull_request'
|
||||
|
||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nogui-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
||||
path: "publish_headless/*.tar.gz"
|
||||
if: github.event_name == 'pull_request'
|
||||
|
||||
101
.github/workflows/canary.yml
vendored
101
.github/workflows/canary.yml
vendored
@@ -108,6 +108,7 @@ jobs:
|
||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||
sed -r --in-place '/^Name=Ryujinx$/s/Name=Ryujinx/Name=Ryujinx-Canary/' distribution/linux/Ryujinx.desktop
|
||||
shell: bash
|
||||
|
||||
- name: Create output dir
|
||||
@@ -115,83 +116,69 @@ jobs:
|
||||
|
||||
- name: Publish
|
||||
run: |
|
||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained
|
||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
||||
|
||||
- name: Packing Windows builds
|
||||
if: matrix.platform.os == 'windows-latest'
|
||||
run: |
|
||||
pushd publish_ava
|
||||
rm publish/libarmeilleure-jitsupport.dylib
|
||||
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
||||
popd
|
||||
|
||||
pushd publish_sdl2_headless
|
||||
rm publish/libarmeilleure-jitsupport.dylib
|
||||
7z a ../release_output/nogui-ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
||||
pushd publish
|
||||
rm libarmeilleure-jitsupport.dylib
|
||||
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||
popd
|
||||
shell: bash
|
||||
|
||||
- name: Packing Linux builds
|
||||
if: matrix.platform.os == 'ubuntu-latest'
|
||||
run: |
|
||||
pushd publish_ava
|
||||
rm publish/libarmeilleure-jitsupport.dylib
|
||||
chmod +x publish/Ryujinx.sh publish/Ryujinx
|
||||
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
||||
popd
|
||||
|
||||
pushd publish_sdl2_headless
|
||||
rm publish/libarmeilleure-jitsupport.dylib
|
||||
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
|
||||
tar -czvf ../release_output/nogui-ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
||||
pushd publish
|
||||
rm libarmeilleure-jitsupport.dylib
|
||||
chmod +x Ryujinx.sh Ryujinx
|
||||
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||
popd
|
||||
shell: bash
|
||||
|
||||
#- name: Build AppImage (Linux)
|
||||
# if: matrix.platform.os == 'ubuntu-latest'
|
||||
# run: |
|
||||
# BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||
# PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||
- name: Build AppImage (Linux)
|
||||
if: matrix.platform.os == 'ubuntu-latest'
|
||||
run: |
|
||||
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||
PLATFORM_NAME="${{ matrix.platform.name }}"
|
||||
|
||||
# sudo apt install -y zsync desktop-file-utils appstream
|
||||
sudo apt install -y zsync desktop-file-utils appstream
|
||||
|
||||
# mkdir -p tools
|
||||
# export PATH="$PATH:$(readlink -f tools)"
|
||||
mkdir -p tools
|
||||
export PATH="$PATH:$(readlink -f tools)"
|
||||
|
||||
# Setup appimagetool
|
||||
# wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||
# chmod +x tools/appimagetool
|
||||
# chmod +x distribution/linux/appimage/build-appimage.sh
|
||||
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||
chmod +x tools/appimagetool
|
||||
chmod +x distribution/linux/appimage/build-appimage.sh
|
||||
|
||||
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
||||
# if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
||||
# ARCH_NAME=x64
|
||||
# export ARCH=x86_64
|
||||
# elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
||||
# ARCH_NAME=arm64
|
||||
# export ARCH=aarch64
|
||||
# else
|
||||
# echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
||||
# exit 1
|
||||
# fi
|
||||
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
||||
ARCH_NAME=x64
|
||||
export ARCH=x86_64
|
||||
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
||||
ARCH_NAME=arm64
|
||||
export ARCH=aarch64
|
||||
else
|
||||
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||
# BUILDDIR=publish_ava OUTDIR=publish_ava_appimage distribution/linux/appimage/build-appimage.sh
|
||||
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|Canary-Releases|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||
|
||||
# Add to release output
|
||||
# pushd publish_ava_appimage
|
||||
# mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||
# mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||
# popd
|
||||
# shell: bash
|
||||
pushd publish_appimage
|
||||
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||
popd
|
||||
shell: bash
|
||||
|
||||
- name: Pushing new release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
name: ${{ steps.version_info.outputs.build_version }}
|
||||
artifacts: "release_output/*.tar.gz,release_output/*.zip"
|
||||
#artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*"
|
||||
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
|
||||
tag: ${{ steps.version_info.outputs.build_version }}
|
||||
body: |
|
||||
# Canary builds:
|
||||
@@ -215,7 +202,7 @@ jobs:
|
||||
|
||||
macos_release:
|
||||
name: Release MacOS universal
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -223,11 +210,11 @@ jobs:
|
||||
with:
|
||||
global-json-file: global.json
|
||||
|
||||
- name: Setup LLVM 15
|
||||
- name: Setup LLVM 17
|
||||
run: |
|
||||
wget https://apt.llvm.org/llvm.sh
|
||||
chmod +x llvm.sh
|
||||
sudo ./llvm.sh 15
|
||||
sudo ./llvm.sh 17
|
||||
|
||||
- name: Install rcodesign
|
||||
run: |
|
||||
@@ -262,15 +249,11 @@ jobs:
|
||||
run: |
|
||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
||||
|
||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
||||
run: |
|
||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
||||
|
||||
- name: Pushing new release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
name: "Canary ${{ steps.version_info.outputs.build_version }}"
|
||||
artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
|
||||
artifacts: "publish_ava/*.tar.gz"
|
||||
tag: ${{ steps.version_info.outputs.build_version }}
|
||||
body: ""
|
||||
omitBodyDuringUpdate: true
|
||||
|
||||
9
.github/workflows/nightly_pr_comment.yml
vendored
9
.github/workflows/nightly_pr_comment.yml
vendored
@@ -38,21 +38,16 @@ jobs:
|
||||
return core.error(`No artifacts found`);
|
||||
}
|
||||
let body = `Download the artifacts for this pull request:\n`;
|
||||
let hidden_headless_artifacts = `\n\n <details><summary>GUI-less</summary>\n`;
|
||||
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
||||
for (const art of artifacts) {
|
||||
var url = `https://github.com/Ryubing/Ryujinx/actions/runs/${run_id}/artifacts/${art_id}`;
|
||||
if(art.name.includes('Debug')) {
|
||||
const url = `https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip`;
|
||||
if (art.name.includes('Debug')) {
|
||||
hidden_debug_artifacts += `\n* [${art.name}](${url})`;
|
||||
} else if(art.name.includes('nogui-ryujinx')) {
|
||||
hidden_headless_artifacts += `\n* [${art.name}](${url})`;
|
||||
} else {
|
||||
body += `\n* [${art.name}](${url})`;
|
||||
}
|
||||
}
|
||||
hidden_headless_artifacts += `\n</details>`;
|
||||
hidden_debug_artifacts += `\n</details>`;
|
||||
body += hidden_headless_artifacts;
|
||||
body += hidden_debug_artifacts;
|
||||
|
||||
const {data: comments} = await github.rest.issues.listComments({repo, owner, issue_number});
|
||||
|
||||
47
.github/workflows/release.yml
vendored
47
.github/workflows/release.yml
vendored
@@ -3,16 +3,6 @@ name: Release job
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
push:
|
||||
branches: [ release ]
|
||||
paths-ignore:
|
||||
- '.github/**'
|
||||
- 'docs/**'
|
||||
- 'assets/**'
|
||||
- '*.yml'
|
||||
- '*.json'
|
||||
- '*.config'
|
||||
- '*.md'
|
||||
|
||||
concurrency: release
|
||||
|
||||
@@ -112,7 +102,6 @@ jobs:
|
||||
- name: Publish
|
||||
run: |
|
||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained
|
||||
|
||||
- name: Packing Windows builds
|
||||
if: matrix.platform.os == 'windows-latest'
|
||||
@@ -121,10 +110,14 @@ jobs:
|
||||
rm libarmeilleure-jitsupport.dylib
|
||||
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||
popd
|
||||
shell: bash
|
||||
|
||||
pushd publish_sdl2_headless
|
||||
rm libarmeilleure-jitsupport.dylib
|
||||
7z a ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||
- name: Packing Linux builds
|
||||
if: matrix.platform.os == 'ubuntu-latest'
|
||||
run: |
|
||||
pushd publish
|
||||
chmod +x Ryujinx.sh Ryujinx
|
||||
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||
popd
|
||||
shell: bash
|
||||
|
||||
@@ -163,20 +156,6 @@ jobs:
|
||||
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||
popd
|
||||
shell: bash
|
||||
|
||||
- name: Packing Linux builds
|
||||
if: matrix.platform.os == 'ubuntu-latest'
|
||||
run: |
|
||||
pushd publish
|
||||
chmod +x Ryujinx.sh Ryujinx
|
||||
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||
popd
|
||||
|
||||
pushd publish_sdl2_headless
|
||||
chmod +x Ryujinx.sh Ryujinx.Headless.SDL2
|
||||
tar -czvf ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||
popd
|
||||
shell: bash
|
||||
|
||||
- name: Pushing new release
|
||||
@@ -204,7 +183,7 @@ jobs:
|
||||
|
||||
macos_release:
|
||||
name: Release MacOS universal
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -212,11 +191,11 @@ jobs:
|
||||
with:
|
||||
global-json-file: global.json
|
||||
|
||||
- name: Setup LLVM 15
|
||||
- name: Setup LLVM 17
|
||||
run: |
|
||||
wget https://apt.llvm.org/llvm.sh
|
||||
chmod +x llvm.sh
|
||||
sudo ./llvm.sh 15
|
||||
sudo ./llvm.sh 17
|
||||
|
||||
- name: Install rcodesign
|
||||
run: |
|
||||
@@ -251,15 +230,11 @@ jobs:
|
||||
run: |
|
||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
||||
|
||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
||||
run: |
|
||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
||||
|
||||
- name: Pushing new release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
name: ${{ steps.version_info.outputs.build_version }}
|
||||
artifacts: "publish/*.tar.gz, publish_headless/*.tar.gz"
|
||||
artifacts: "publish/*.tar.gz"
|
||||
tag: ${{ steps.version_info.outputs.build_version }}
|
||||
body: ""
|
||||
omitBodyDuringUpdate: true
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Avalonia" Version="11.0.10" />
|
||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.10" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="11.0.10" />
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.10" />
|
||||
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.10" />
|
||||
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.18" />
|
||||
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.18" />
|
||||
<PackageVersion Include="Avalonia" Version="11.0.13" />
|
||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.13" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="11.0.13" />
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.13" />
|
||||
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.13" />
|
||||
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.19" />
|
||||
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.19" />
|
||||
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
||||
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
@@ -17,7 +17,8 @@
|
||||
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
||||
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||
<PackageVersion Include="Concentus" Version="2.2.0" />
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
|
||||
<PackageVersion Include="Concentus" Version="2.2.2" />
|
||||
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
||||
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
||||
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
|
||||
@@ -25,7 +26,7 @@
|
||||
<PackageVersion Include="LibHac" Version="0.19.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
|
||||
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.1.2" />
|
||||
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.3.0" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
|
||||
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
|
||||
@@ -41,16 +42,17 @@
|
||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||
<PackageVersion Include="Gommon" Version="2.6.8" />
|
||||
<PackageVersion Include="Gommon" Version="2.7.1" />
|
||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||
<PackageVersion Include="SharpMetal" Version="1.0.0-preview21" />
|
||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.21.0" />
|
||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.21.0" />
|
||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.21.0" />
|
||||
<PackageVersion Include="SkiaSharp" Version="2.88.7" />
|
||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" />
|
||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
|
||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" />
|
||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.22.0" />
|
||||
<PackageVersion Include="SkiaSharp" Version="2.88.9" />
|
||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
||||
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
||||
<PackageVersion Include="System.IO.Hashing" Version="9.0.0" />
|
||||
<PackageVersion Include="System.Management" Version="9.0.0" />
|
||||
|
||||
@@ -54,12 +54,13 @@ failing to meet this requirement may result in a poor gameplay experience or une
|
||||
|
||||
## Latest build
|
||||
|
||||
Stable builds are made every so often onto a separate "release" branch that then gets put into the releases you know and love.
|
||||
Stable builds are made every so often, based on the `master` branch, that then gets put into the releases you know and love.
|
||||
These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
|
||||
They are released every month or so, to ensure consistent updates, while not being an annoying amount of individual updates to download over the course of that month.
|
||||
|
||||
You can find the latest stable release [here](https://github.com/GreemDev/Ryujinx/releases/latest).
|
||||
|
||||
Canary builds are compiled automatically for each commit on the master branch.
|
||||
Canary builds are compiled automatically for each commit on the `master` branch.
|
||||
While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**.
|
||||
These canary builds are only recommended for experienced users.
|
||||
|
||||
@@ -109,7 +110,7 @@ If you are planning to contribute or just want to learn more about this project
|
||||
- **Configuration**
|
||||
|
||||
The emulator has settings for enabling or disabling some logging, remapping controllers, and more.
|
||||
You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the user folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
|
||||
You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the Ryujinx data folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
17
Ryujinx.sln
17
Ryujinx.sln
@@ -57,14 +57,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "src\
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Headless.SDL2", "src\Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}"
|
||||
@@ -213,10 +209,6 @@ Global
|
||||
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -225,10 +217,6 @@ Global
|
||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -261,13 +249,12 @@ Global
|
||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
||||
@@ -6,14 +6,14 @@ cd "$ROOTDIR"
|
||||
|
||||
BUILDDIR=${BUILDDIR:-publish}
|
||||
OUTDIR=${OUTDIR:-publish_appimage}
|
||||
UFLAG=${UFLAG:-"gh-releases-zsync|GreemDev|ryujinx|latest|*-x64.AppImage.zsync"}
|
||||
UFLAG=${UFLAG:-"gh-releases-zsync|Ryubing|ryujinx|latest|*-x64.AppImage.zsync"}
|
||||
|
||||
rm -rf AppDir
|
||||
mkdir -p AppDir/usr/bin
|
||||
|
||||
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
|
||||
cp distribution/linux/appimage/AppRun AppDir/AppRun
|
||||
cp src/Ryujinx.UI.Common/Resources/Logo_Ryujinx.png AppDir/Ryujinx.svg
|
||||
cp distribution/misc/Logo.svg AppDir/Ryujinx.svg
|
||||
|
||||
|
||||
cp -r "$BUILDDIR"/* AppDir/usr/bin/
|
||||
|
||||
@@ -19,7 +19,7 @@ if platform.system() == "Darwin":
|
||||
else:
|
||||
OTOOL = shutil.which("llvm-otool")
|
||||
if OTOOL is None:
|
||||
for llvm_ver in [15, 14, 13]:
|
||||
for llvm_ver in [17, 16, 15, 14, 13]:
|
||||
otool_path = shutil.which(f"llvm-otool-{llvm_ver}")
|
||||
if otool_path is not None:
|
||||
OTOOL = otool_path
|
||||
|
||||
@@ -26,7 +26,7 @@ else:
|
||||
LIPO = shutil.which("llvm-lipo")
|
||||
|
||||
if LIPO is None:
|
||||
for llvm_ver in [15, 14, 13]:
|
||||
for llvm_ver in [17, 16, 15, 14, 13]:
|
||||
lipo_path = shutil.which(f"llvm-lipo-{llvm_ver}")
|
||||
if lipo_path is not None:
|
||||
LIPO = lipo_path
|
||||
|
||||
@@ -67,11 +67,11 @@ python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_APP_
|
||||
|
||||
if ! [ -x "$(command -v lipo)" ];
|
||||
then
|
||||
if ! [ -x "$(command -v llvm-lipo-14)" ];
|
||||
if ! [ -x "$(command -v llvm-lipo-17)" ];
|
||||
then
|
||||
LIPO=llvm-lipo
|
||||
else
|
||||
LIPO=llvm-lipo-14
|
||||
LIPO=llvm-lipo-17
|
||||
fi
|
||||
else
|
||||
LIPO=lipo
|
||||
|
||||
@@ -62,11 +62,11 @@ python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTP
|
||||
|
||||
if ! [ -x "$(command -v lipo)" ];
|
||||
then
|
||||
if ! [ -x "$(command -v llvm-lipo-14)" ];
|
||||
if ! [ -x "$(command -v llvm-lipo-17)" ];
|
||||
then
|
||||
LIPO=llvm-lipo
|
||||
else
|
||||
LIPO=llvm-lipo-14
|
||||
LIPO=llvm-lipo-17
|
||||
fi
|
||||
else
|
||||
LIPO=lipo
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2018 - 2023 Ryujinx Team and Contributors.</string>
|
||||
<string>Copyright © 2018 - 2025 Ryujinx Team and Contributors.</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
3425
docs/compatibility.csv
Normal file
3425
docs/compatibility.csv
Normal file
File diff suppressed because it is too large
Load Diff
@@ -406,7 +406,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2);
|
||||
|
||||
return EmitUnaryMathCall(context, nameof(Math.Abs), res);
|
||||
return EmitUnaryMathCall(context, nameof(MathHelper.Abs), res);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -451,7 +451,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2);
|
||||
|
||||
return EmitUnaryMathCall(context, nameof(Math.Abs), res);
|
||||
return EmitUnaryMathCall(context, nameof(MathHelper.Abs), res);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -483,7 +483,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
EmitScalarUnaryOpF(context, (op1) =>
|
||||
{
|
||||
return EmitUnaryMathCall(context, nameof(Math.Abs), op1);
|
||||
return EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -522,7 +522,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
EmitVectorUnaryOpF(context, (op1) =>
|
||||
{
|
||||
return EmitUnaryMathCall(context, nameof(Math.Abs), op1);
|
||||
return EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2246,7 +2246,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
EmitScalarUnaryOpF(context, (op1) =>
|
||||
{
|
||||
return EmitUnaryMathCall(context, nameof(Math.Floor), op1);
|
||||
return EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2265,7 +2265,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
EmitVectorUnaryOpF(context, (op1) =>
|
||||
{
|
||||
return EmitUnaryMathCall(context, nameof(Math.Floor), op1);
|
||||
return EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2322,7 +2322,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
EmitScalarUnaryOpF(context, (op1) =>
|
||||
{
|
||||
return EmitUnaryMathCall(context, nameof(Math.Ceiling), op1);
|
||||
return EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2341,7 +2341,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
EmitVectorUnaryOpF(context, (op1) =>
|
||||
{
|
||||
return EmitUnaryMathCall(context, nameof(Math.Ceiling), op1);
|
||||
return EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2390,7 +2390,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
EmitScalarUnaryOpF(context, (op1) =>
|
||||
{
|
||||
return EmitUnaryMathCall(context, nameof(Math.Truncate), op1);
|
||||
return EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op1);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2409,7 +2409,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
EmitVectorUnaryOpF(context, (op1) =>
|
||||
{
|
||||
return EmitUnaryMathCall(context, nameof(Math.Truncate), op1);
|
||||
return EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Abs), op1));
|
||||
EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Abs), op1));
|
||||
EmitVectorUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -726,8 +726,8 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
if (absolute)
|
||||
{
|
||||
ne = EmitUnaryMathCall(context, nameof(Math.Abs), ne);
|
||||
me = EmitUnaryMathCall(context, nameof(Math.Abs), me);
|
||||
ne = EmitUnaryMathCall(context, nameof(MathHelper.Abs), ne);
|
||||
me = EmitUnaryMathCall(context, nameof(MathHelper.Abs), me);
|
||||
}
|
||||
|
||||
Operand e = EmitSoftFloatCall(context, name, ne, me);
|
||||
|
||||
@@ -333,7 +333,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1));
|
||||
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitFcvt(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1), signed: true, scalar: false);
|
||||
EmitFcvt(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1), signed: true, scalar: false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1));
|
||||
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -538,7 +538,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Ceiling), op1));
|
||||
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,7 +554,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Ceiling), op1));
|
||||
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -357,10 +357,10 @@ namespace ARMeilleure.Instructions
|
||||
toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert);
|
||||
break;
|
||||
case 0b10: // Towards positive infinity
|
||||
toConvert = EmitUnaryMathCall(context, nameof(Math.Ceiling), toConvert);
|
||||
toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), toConvert);
|
||||
break;
|
||||
case 0b11: // Towards negative infinity
|
||||
toConvert = EmitUnaryMathCall(context, nameof(Math.Floor), toConvert);
|
||||
toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Floor), toConvert);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -494,10 +494,10 @@ namespace ARMeilleure.Instructions
|
||||
toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert);
|
||||
break;
|
||||
case 0b10: // Towards positive infinity
|
||||
toConvert = EmitUnaryMathCall(context, nameof(Math.Ceiling), toConvert);
|
||||
toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), toConvert);
|
||||
break;
|
||||
case 0b11: // Towards negative infinity
|
||||
toConvert = EmitUnaryMathCall(context, nameof(Math.Floor), toConvert);
|
||||
toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Floor), toConvert);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -534,7 +534,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(Math.Floor), m));
|
||||
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), m));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(Math.Ceiling), m));
|
||||
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), m));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,7 +613,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Truncate), op1));
|
||||
EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -460,8 +460,8 @@ namespace ARMeilleure.Instructions
|
||||
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||
|
||||
MethodInfo info = (op.Size & 1) == 0
|
||||
? typeof(MathF).GetMethod(name, new Type[] { typeof(float) })
|
||||
: typeof(Math).GetMethod(name, new Type[] { typeof(double) });
|
||||
? typeof(MathHelperF).GetMethod(name, new Type[] { typeof(float) })
|
||||
: typeof(MathHelper).GetMethod(name, new Type[] { typeof(double) });
|
||||
|
||||
return context.Call(info, n);
|
||||
}
|
||||
@@ -470,11 +470,11 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||
|
||||
string name = nameof(Math.Round);
|
||||
string name = nameof(MathHelper.Round);
|
||||
|
||||
MethodInfo info = (op.Size & 1) == 0
|
||||
? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) })
|
||||
: typeof(Math).GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) });
|
||||
? typeof(MathHelperF).GetMethod(name, new Type[] { typeof(float), typeof(int) })
|
||||
: typeof(MathHelper).GetMethod(name, new Type[] { typeof(double), typeof(int) });
|
||||
|
||||
return context.Call(info, n, Const((int)roundMode));
|
||||
}
|
||||
@@ -510,16 +510,16 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
context.MarkLabel(lbl1);
|
||||
context.BranchIf(lbl2, rMode, rP, Comparison.NotEqual);
|
||||
context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Ceiling), op));
|
||||
context.Copy(res, EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lbl2);
|
||||
context.BranchIf(lbl3, rMode, rM, Comparison.NotEqual);
|
||||
context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Floor), op));
|
||||
context.Copy(res, EmitUnaryMathCall(context, nameof(MathHelper.Floor), op));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lbl3);
|
||||
context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Truncate), op));
|
||||
context.Copy(res, EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
71
src/ARMeilleure/Instructions/MathHelper.cs
Normal file
71
src/ARMeilleure/Instructions/MathHelper.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
static class MathHelper
|
||||
{
|
||||
[UnmanagedCallersOnly]
|
||||
public static double Abs(double value)
|
||||
{
|
||||
return Math.Abs(value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double Ceiling(double value)
|
||||
{
|
||||
return Math.Ceiling(value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double Floor(double value)
|
||||
{
|
||||
return Math.Floor(value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double Round(double value, int mode)
|
||||
{
|
||||
return Math.Round(value, (MidpointRounding)mode);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double Truncate(double value)
|
||||
{
|
||||
return Math.Truncate(value);
|
||||
}
|
||||
}
|
||||
|
||||
static class MathHelperF
|
||||
{
|
||||
[UnmanagedCallersOnly]
|
||||
public static float Abs(float value)
|
||||
{
|
||||
return MathF.Abs(value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float Ceiling(float value)
|
||||
{
|
||||
return MathF.Ceiling(value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float Floor(float value)
|
||||
{
|
||||
return MathF.Floor(value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float Round(float value, int mode)
|
||||
{
|
||||
return MathF.Round(value, (MidpointRounding)mode);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float Truncate(float value)
|
||||
{
|
||||
return MathF.Truncate(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
@@ -34,6 +35,7 @@ namespace ARMeilleure.Instructions
|
||||
Context = null;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void Break(ulong address, int imm)
|
||||
{
|
||||
Statistics.PauseTimer();
|
||||
@@ -43,6 +45,7 @@ namespace ARMeilleure.Instructions
|
||||
Statistics.ResumeTimer();
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void SupervisorCall(ulong address, int imm)
|
||||
{
|
||||
Statistics.PauseTimer();
|
||||
@@ -52,6 +55,7 @@ namespace ARMeilleure.Instructions
|
||||
Statistics.ResumeTimer();
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void Undefined(ulong address, int opCode)
|
||||
{
|
||||
Statistics.PauseTimer();
|
||||
@@ -62,26 +66,31 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
|
||||
#region "System registers"
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong GetCtrEl0()
|
||||
{
|
||||
return GetContext().CtrEl0;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong GetDczidEl0()
|
||||
{
|
||||
return GetContext().DczidEl0;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong GetCntfrqEl0()
|
||||
{
|
||||
return GetContext().CntfrqEl0;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong GetCntpctEl0()
|
||||
{
|
||||
return GetContext().CntpctEl0;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong GetCntvctEl0()
|
||||
{
|
||||
return GetContext().CntvctEl0;
|
||||
@@ -89,26 +98,31 @@ namespace ARMeilleure.Instructions
|
||||
#endregion
|
||||
|
||||
#region "Read"
|
||||
[UnmanagedCallersOnly]
|
||||
public static byte ReadByte(ulong address)
|
||||
{
|
||||
return GetMemoryManager().ReadGuest<byte>(address);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ushort ReadUInt16(ulong address)
|
||||
{
|
||||
return GetMemoryManager().ReadGuest<ushort>(address);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint ReadUInt32(ulong address)
|
||||
{
|
||||
return GetMemoryManager().ReadGuest<uint>(address);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong ReadUInt64(ulong address)
|
||||
{
|
||||
return GetMemoryManager().ReadGuest<ulong>(address);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 ReadVector128(ulong address)
|
||||
{
|
||||
return GetMemoryManager().ReadGuest<V128>(address);
|
||||
@@ -116,47 +130,56 @@ namespace ARMeilleure.Instructions
|
||||
#endregion
|
||||
|
||||
#region "Write"
|
||||
[UnmanagedCallersOnly]
|
||||
public static void WriteByte(ulong address, byte value)
|
||||
{
|
||||
GetMemoryManager().WriteGuest(address, value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void WriteUInt16(ulong address, ushort value)
|
||||
{
|
||||
GetMemoryManager().WriteGuest(address, value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void WriteUInt32(ulong address, uint value)
|
||||
{
|
||||
GetMemoryManager().WriteGuest(address, value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void WriteUInt64(ulong address, ulong value)
|
||||
{
|
||||
GetMemoryManager().WriteGuest(address, value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void WriteVector128(ulong address, V128 value)
|
||||
{
|
||||
GetMemoryManager().WriteGuest(address, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void EnqueueForRejit(ulong address)
|
||||
{
|
||||
Context.Translator.EnqueueForRejit(address, GetContext().ExecutionMode);
|
||||
}
|
||||
|
||||
public static void SignalMemoryTracking(ulong address, ulong size, bool write)
|
||||
[UnmanagedCallersOnly]
|
||||
public static void SignalMemoryTracking(ulong address, ulong size, byte write)
|
||||
{
|
||||
GetMemoryManager().SignalMemoryTracking(address, size, write);
|
||||
GetMemoryManager().SignalMemoryTracking(address, size, write == 1);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void ThrowInvalidMemoryAccess(ulong address)
|
||||
{
|
||||
throw new InvalidAccessException(address);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong GetFunctionAddress(ulong address)
|
||||
{
|
||||
TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
|
||||
@@ -164,12 +187,14 @@ namespace ARMeilleure.Instructions
|
||||
return (ulong)function.FuncPointer.ToInt64();
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static void InvalidateCacheLine(ulong address)
|
||||
{
|
||||
Context.Translator.InvalidateJitCacheRegion(address, InstEmit.DczSizeInBytes);
|
||||
}
|
||||
|
||||
public static bool CheckSynchronization()
|
||||
[UnmanagedCallersOnly]
|
||||
public static byte CheckSynchronization()
|
||||
{
|
||||
Statistics.PauseTimer();
|
||||
|
||||
@@ -179,7 +204,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Statistics.ResumeTimer();
|
||||
|
||||
return context.Running;
|
||||
return (byte)(context.Running ? 1 : 0);
|
||||
}
|
||||
|
||||
public static ExecutionContext GetContext()
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
static class SoftFallback
|
||||
{
|
||||
#region "ShrImm64"
|
||||
[UnmanagedCallersOnly]
|
||||
public static long SignedShrImm64(long value, long roundConst, int shift)
|
||||
{
|
||||
if (roundConst == 0L)
|
||||
@@ -48,6 +50,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift)
|
||||
{
|
||||
if (roundConst == 0L)
|
||||
@@ -92,6 +95,7 @@ namespace ARMeilleure.Instructions
|
||||
#endregion
|
||||
|
||||
#region "Saturation"
|
||||
[UnmanagedCallersOnly]
|
||||
public static int SatF32ToS32(float value)
|
||||
{
|
||||
if (float.IsNaN(value))
|
||||
@@ -103,6 +107,7 @@ namespace ARMeilleure.Instructions
|
||||
value <= int.MinValue ? int.MinValue : (int)value;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static long SatF32ToS64(float value)
|
||||
{
|
||||
if (float.IsNaN(value))
|
||||
@@ -114,6 +119,7 @@ namespace ARMeilleure.Instructions
|
||||
value <= long.MinValue ? long.MinValue : (long)value;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint SatF32ToU32(float value)
|
||||
{
|
||||
if (float.IsNaN(value))
|
||||
@@ -125,6 +131,7 @@ namespace ARMeilleure.Instructions
|
||||
value <= uint.MinValue ? uint.MinValue : (uint)value;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong SatF32ToU64(float value)
|
||||
{
|
||||
if (float.IsNaN(value))
|
||||
@@ -136,6 +143,7 @@ namespace ARMeilleure.Instructions
|
||||
value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static int SatF64ToS32(double value)
|
||||
{
|
||||
if (double.IsNaN(value))
|
||||
@@ -147,6 +155,7 @@ namespace ARMeilleure.Instructions
|
||||
value <= int.MinValue ? int.MinValue : (int)value;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static long SatF64ToS64(double value)
|
||||
{
|
||||
if (double.IsNaN(value))
|
||||
@@ -158,6 +167,7 @@ namespace ARMeilleure.Instructions
|
||||
value <= long.MinValue ? long.MinValue : (long)value;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint SatF64ToU32(double value)
|
||||
{
|
||||
if (double.IsNaN(value))
|
||||
@@ -169,6 +179,7 @@ namespace ARMeilleure.Instructions
|
||||
value <= uint.MinValue ? uint.MinValue : (uint)value;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong SatF64ToU64(double value)
|
||||
{
|
||||
if (double.IsNaN(value))
|
||||
@@ -182,6 +193,7 @@ namespace ARMeilleure.Instructions
|
||||
#endregion
|
||||
|
||||
#region "Count"
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
||||
{
|
||||
value ^= value >> 1;
|
||||
@@ -201,6 +213,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
private static ReadOnlySpan<byte> ClzNibbleTbl => new byte[] { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
||||
{
|
||||
if (value == 0ul)
|
||||
@@ -224,41 +237,49 @@ namespace ARMeilleure.Instructions
|
||||
#endregion
|
||||
|
||||
#region "Table"
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Tbl1(V128 vector, int bytes, V128 tb0)
|
||||
{
|
||||
return TblOrTbx(default, vector, bytes, tb0);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Tbl2(V128 vector, int bytes, V128 tb0, V128 tb1)
|
||||
{
|
||||
return TblOrTbx(default, vector, bytes, tb0, tb1);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Tbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
|
||||
{
|
||||
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Tbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
|
||||
{
|
||||
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2, tb3);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Tbx1(V128 dest, V128 vector, int bytes, V128 tb0)
|
||||
{
|
||||
return TblOrTbx(dest, vector, bytes, tb0);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Tbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1)
|
||||
{
|
||||
return TblOrTbx(dest, vector, bytes, tb0, tb1);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Tbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
|
||||
{
|
||||
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Tbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
|
||||
{
|
||||
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3);
|
||||
@@ -300,14 +321,22 @@ namespace ARMeilleure.Instructions
|
||||
private const uint Crc32RevPoly = 0xedb88320;
|
||||
private const uint Crc32cRevPoly = 0x82f63b78;
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint Crc32b(uint crc, byte value) => Crc32(crc, Crc32RevPoly, value);
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value);
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value);
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value);
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint Crc32cb(uint crc, byte value) => Crc32(crc, Crc32cRevPoly, value);
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value);
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value);
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value);
|
||||
|
||||
private static uint Crc32h(uint crc, uint poly, ushort val)
|
||||
@@ -358,21 +387,25 @@ namespace ARMeilleure.Instructions
|
||||
#endregion
|
||||
|
||||
#region "Aes"
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Decrypt(V128 value, V128 roundKey)
|
||||
{
|
||||
return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey));
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Encrypt(V128 value, V128 roundKey)
|
||||
{
|
||||
return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(value ^ roundKey));
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 InverseMixColumns(V128 value)
|
||||
{
|
||||
return CryptoHelper.AesInvMixColumns(value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 MixColumns(V128 value)
|
||||
{
|
||||
return CryptoHelper.AesMixColumns(value);
|
||||
@@ -380,6 +413,7 @@ namespace ARMeilleure.Instructions
|
||||
#endregion
|
||||
|
||||
#region "Sha1"
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 HashChoose(V128 hash_abcd, uint hash_e, V128 wk)
|
||||
{
|
||||
for (int e = 0; e <= 3; e++)
|
||||
@@ -400,11 +434,13 @@ namespace ARMeilleure.Instructions
|
||||
return hash_abcd;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static uint FixedRotate(uint hash_e)
|
||||
{
|
||||
return hash_e.Rol(30);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 HashMajority(V128 hash_abcd, uint hash_e, V128 wk)
|
||||
{
|
||||
for (int e = 0; e <= 3; e++)
|
||||
@@ -425,6 +461,7 @@ namespace ARMeilleure.Instructions
|
||||
return hash_abcd;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 HashParity(V128 hash_abcd, uint hash_e, V128 wk)
|
||||
{
|
||||
for (int e = 0; e <= 3; e++)
|
||||
@@ -445,6 +482,7 @@ namespace ARMeilleure.Instructions
|
||||
return hash_abcd;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Sha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11)
|
||||
{
|
||||
ulong t2 = w4_7.Extract<ulong>(0);
|
||||
@@ -455,6 +493,7 @@ namespace ARMeilleure.Instructions
|
||||
return result ^ (w0_3 ^ w8_11);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Sha1SchedulePart2(V128 tw0_3, V128 w12_15)
|
||||
{
|
||||
V128 t = tw0_3 ^ (w12_15 >> 32);
|
||||
@@ -499,16 +538,19 @@ namespace ARMeilleure.Instructions
|
||||
#endregion
|
||||
|
||||
#region "Sha256"
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 HashLower(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
||||
{
|
||||
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk)
|
||||
{
|
||||
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7)
|
||||
{
|
||||
V128 result = new();
|
||||
@@ -527,6 +569,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 Sha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15)
|
||||
{
|
||||
V128 result = new();
|
||||
@@ -628,6 +671,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
#endregion
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static V128 PolynomialMult64_128(ulong op1, ulong op2)
|
||||
{
|
||||
V128 result = V128.Zero;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
@@ -312,6 +313,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
static class SoftFloat16_32
|
||||
{
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPConvert(ushort valueBits)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -487,6 +489,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
static class SoftFloat16_64
|
||||
{
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPConvert(ushort valueBits)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -662,6 +665,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
static class SoftFloat32_16
|
||||
{
|
||||
[UnmanagedCallersOnly]
|
||||
public static ushort FPConvert(float value)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -781,12 +785,19 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
static class SoftFloat32
|
||||
{
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPAdd(float value1, float value2)
|
||||
{
|
||||
return FPAddFpscr(value1, value2, false);
|
||||
return FPAddFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPAddFpscr(float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPAddFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPAddFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static float FPAddFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -837,7 +848,8 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int FPCompare(float value1, float value2, bool signalNaNs)
|
||||
[UnmanagedCallersOnly]
|
||||
public static int FPCompare(float value1, float value2, byte signalNaNs)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = context.Fpcr;
|
||||
@@ -851,7 +863,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
result = 0b0011;
|
||||
|
||||
if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs)
|
||||
if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs == 1)
|
||||
{
|
||||
SoftFloat.FPProcessException(FPException.InvalidOp, context, fpcr);
|
||||
}
|
||||
@@ -875,12 +887,13 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPCompareEQ(float value1, float value2)
|
||||
{
|
||||
return FPCompareEQFpscr(value1, value2, false);
|
||||
return FPCompareEQFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPCompareEQFpscr(float value1, float value2, bool standardFpscr)
|
||||
private static float FPCompareEQFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -907,12 +920,25 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
public static float FPCompareGE(float value1, float value2)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPCompareEQFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPCompareGEFpscr(value1, value2, false);
|
||||
return FPCompareEQFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
public static float FPCompareGEFpscr(float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPCompareGE(float value1, float value2)
|
||||
{
|
||||
return FPCompareGEFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPCompareGEFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPCompareGEFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static float FPCompareGEFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -936,12 +962,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPCompareGT(float value1, float value2)
|
||||
{
|
||||
return FPCompareGTFpscr(value1, value2, false);
|
||||
return FPCompareGTFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPCompareGTFpscr(float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPCompareGTFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPCompareGTFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static float FPCompareGTFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -965,26 +998,31 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPCompareLE(float value1, float value2)
|
||||
{
|
||||
return FPCompareGE(value2, value1);
|
||||
return FPCompareGEFpscrImpl(value2, value1, false);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPCompareLT(float value1, float value2)
|
||||
{
|
||||
return FPCompareGT(value2, value1);
|
||||
return FPCompareGTFpscrImpl(value2, value1, false);
|
||||
}
|
||||
|
||||
public static float FPCompareLEFpscr(float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPCompareLEFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPCompareGEFpscr(value2, value1, standardFpscr);
|
||||
return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
|
||||
}
|
||||
|
||||
public static float FPCompareLTFpscr(float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPCompareLTFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPCompareGTFpscr(value2, value1, standardFpscr);
|
||||
return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPDiv(float value1, float value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -1037,12 +1075,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMax(float value1, float value2)
|
||||
{
|
||||
return FPMaxFpscr(value1, value2, false);
|
||||
return FPMaxFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPMaxFpscr(float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMaxFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static float FPMaxFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -1103,12 +1148,13 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMaxNum(float value1, float value2)
|
||||
{
|
||||
return FPMaxNumFpscr(value1, value2, false);
|
||||
return FPMaxNumFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPMaxNumFpscr(float value1, float value2, bool standardFpscr)
|
||||
private static float FPMaxNumFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -1125,15 +1171,28 @@ namespace ARMeilleure.Instructions
|
||||
value2 = FPInfinity(true);
|
||||
}
|
||||
|
||||
return FPMaxFpscr(value1, value2, standardFpscr);
|
||||
return FPMaxFpscrImpl(value1, value2, standardFpscr);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMaxNumFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPMaxNumFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMin(float value1, float value2)
|
||||
{
|
||||
return FPMinFpscr(value1, value2, false);
|
||||
return FPMinFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPMinFpscr(float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMinFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPMinFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static float FPMinFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -1194,12 +1253,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMinNum(float value1, float value2)
|
||||
{
|
||||
return FPMinNumFpscr(value1, value2, false);
|
||||
return FPMinNumFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPMinNumFpscr(float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMinNumFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPMinNumFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static float FPMinNumFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -1216,15 +1282,22 @@ namespace ARMeilleure.Instructions
|
||||
value2 = FPInfinity(false);
|
||||
}
|
||||
|
||||
return FPMinFpscr(value1, value2, standardFpscr);
|
||||
return FPMinFpscrImpl(value1, value2, standardFpscr);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMul(float value1, float value2)
|
||||
{
|
||||
return FPMulFpscr(value1, value2, false);
|
||||
return FPMulFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPMulFpscr(float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMulFpscr(float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPMulFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static float FPMulFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -1271,12 +1344,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMulAdd(float valueA, float value1, float value2)
|
||||
{
|
||||
return FPMulAddFpscr(valueA, value1, value2, false);
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPMulAddFpscr(float valueA, float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMulAddFpscr(float valueA, float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static float FPMulAddFpscrImpl(float valueA, float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -1342,20 +1422,23 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMulSub(float valueA, float value1, float value2)
|
||||
{
|
||||
value1 = value1.FPNeg();
|
||||
|
||||
return FPMulAdd(valueA, value1, value2);
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPMulSubFpscr(float valueA, float value1, float value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMulSubFpscr(float valueA, float value1, float value2, byte standardFpscr)
|
||||
{
|
||||
value1 = value1.FPNeg();
|
||||
|
||||
return FPMulAddFpscr(valueA, value1, value2, standardFpscr);
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPMulX(float value1, float value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -1401,27 +1484,36 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPNegMulAdd(float valueA, float value1, float value2)
|
||||
{
|
||||
valueA = valueA.FPNeg();
|
||||
value1 = value1.FPNeg();
|
||||
|
||||
return FPMulAdd(valueA, value1, value2);
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPNegMulSub(float valueA, float value1, float value2)
|
||||
{
|
||||
valueA = valueA.FPNeg();
|
||||
|
||||
return FPMulAdd(valueA, value1, value2);
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPRecipEstimate(float value)
|
||||
{
|
||||
return FPRecipEstimateFpscr(value, false);
|
||||
return FPRecipEstimateFpscrImpl(value, false);
|
||||
}
|
||||
|
||||
public static float FPRecipEstimateFpscr(float value, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPRecipEstimateFpscr(float value, byte standardFpscr)
|
||||
{
|
||||
return FPRecipEstimateFpscrImpl(value, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static float FPRecipEstimateFpscrImpl(float value, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -1508,6 +1600,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPRecipStep(float value1, float value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -1533,15 +1626,16 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
product = FPMulFpscr(value1, value2, true);
|
||||
product = FPMulFpscrImpl(value1, value2, true);
|
||||
}
|
||||
|
||||
result = FPSubFpscr(FPTwo(false), product, true);
|
||||
result = FPSubFpscrImpl(FPTwo(false), product, true);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPRecipStepFused(float value1, float value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -1585,6 +1679,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPRecpX(float value)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -1610,12 +1705,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPRSqrtEstimate(float value)
|
||||
{
|
||||
return FPRSqrtEstimateFpscr(value, false);
|
||||
return FPRSqrtEstimateFpscrImpl(value, false);
|
||||
}
|
||||
|
||||
public static float FPRSqrtEstimateFpscr(float value, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPRSqrtEstimateFpscr(float value, byte standardFpscr)
|
||||
{
|
||||
return FPRSqrtEstimateFpscrImpl(value, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static float FPRSqrtEstimateFpscrImpl(float value, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -1729,6 +1831,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPRSqrtStep(float value1, float value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -1754,7 +1857,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
product = FPMulFpscr(value1, value2, true);
|
||||
product = FPMulFpscrImpl(value1, value2, true);
|
||||
}
|
||||
|
||||
result = FPHalvedSub(FPThree(false), product, context, fpcr);
|
||||
@@ -1763,6 +1866,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPRSqrtStepFused(float value1, float value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -1806,6 +1910,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPSqrt(float value)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -1848,12 +1953,13 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static float FPSub(float value1, float value2)
|
||||
{
|
||||
return FPSubFpscr(value1, value2, false);
|
||||
return FPSubFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static float FPSubFpscr(float value1, float value2, bool standardFpscr)
|
||||
private static float FPSubFpscrImpl(float value1, float value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2094,6 +2200,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
static class SoftFloat64_16
|
||||
{
|
||||
[UnmanagedCallersOnly]
|
||||
public static ushort FPConvert(double value)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -2213,12 +2320,19 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
static class SoftFloat64
|
||||
{
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPAdd(double value1, double value2)
|
||||
{
|
||||
return FPAddFpscr(value1, value2, false);
|
||||
return FPAddFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPAddFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPAddFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPAddFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPAddFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2269,7 +2383,8 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int FPCompare(double value1, double value2, bool signalNaNs)
|
||||
[UnmanagedCallersOnly]
|
||||
public static int FPCompare(double value1, double value2, byte signalNaNs)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = context.Fpcr;
|
||||
@@ -2283,7 +2398,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
result = 0b0011;
|
||||
|
||||
if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs)
|
||||
if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs == 1)
|
||||
{
|
||||
SoftFloat.FPProcessException(FPException.InvalidOp, context, fpcr);
|
||||
}
|
||||
@@ -2307,12 +2422,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPCompareEQ(double value1, double value2)
|
||||
{
|
||||
return FPCompareEQFpscr(value1, value2, false);
|
||||
return FPCompareEQFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPCompareEQFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPCompareEQFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPCompareEQFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPCompareEQFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2339,12 +2461,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPCompareGE(double value1, double value2)
|
||||
{
|
||||
return FPCompareGEFpscr(value1, value2, false);
|
||||
return FPCompareGEFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPCompareGEFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPCompareGEFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPCompareGEFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPCompareGEFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2368,12 +2497,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPCompareGT(double value1, double value2)
|
||||
{
|
||||
return FPCompareGTFpscr(value1, value2, false);
|
||||
return FPCompareGTFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPCompareGTFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPCompareGTFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPCompareGTFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPCompareGTFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2397,26 +2533,31 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPCompareLE(double value1, double value2)
|
||||
{
|
||||
return FPCompareGE(value2, value1);
|
||||
return FPCompareGEFpscrImpl(value2, value1, false);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPCompareLT(double value1, double value2)
|
||||
{
|
||||
return FPCompareGT(value2, value1);
|
||||
return FPCompareGTFpscrImpl(value2, value1, false);
|
||||
}
|
||||
|
||||
public static double FPCompareLEFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPCompareLEFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPCompareGEFpscr(value2, value1, standardFpscr);
|
||||
return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
|
||||
}
|
||||
|
||||
public static double FPCompareLTFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPCompareLTFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPCompareGTFpscr(value2, value1, standardFpscr);
|
||||
return FPCompareGTFpscrImpl(value2, value1, standardFpscr == 1);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPDiv(double value1, double value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -2469,12 +2610,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMax(double value1, double value2)
|
||||
{
|
||||
return FPMaxFpscr(value1, value2, false);
|
||||
return FPMaxFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPMaxFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMaxFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPMaxFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2535,12 +2683,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMaxNum(double value1, double value2)
|
||||
{
|
||||
return FPMaxNumFpscr(value1, value2, false);
|
||||
return FPMaxNumFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPMaxNumFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMaxNumFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPMaxNumFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPMaxNumFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2557,15 +2712,22 @@ namespace ARMeilleure.Instructions
|
||||
value2 = FPInfinity(true);
|
||||
}
|
||||
|
||||
return FPMaxFpscr(value1, value2, standardFpscr);
|
||||
return FPMaxFpscrImpl(value1, value2, standardFpscr);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMin(double value1, double value2)
|
||||
{
|
||||
return FPMinFpscr(value1, value2, false);
|
||||
return FPMinFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPMinFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMinFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPMinFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPMinFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2626,12 +2788,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMinNum(double value1, double value2)
|
||||
{
|
||||
return FPMinNumFpscr(value1, value2, false);
|
||||
return FPMinNumFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPMinNumFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMinNumFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPMinNumFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPMinNumFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2648,15 +2817,22 @@ namespace ARMeilleure.Instructions
|
||||
value2 = FPInfinity(false);
|
||||
}
|
||||
|
||||
return FPMinFpscr(value1, value2, standardFpscr);
|
||||
return FPMinFpscrImpl(value1, value2, standardFpscr);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMul(double value1, double value2)
|
||||
{
|
||||
return FPMulFpscr(value1, value2, false);
|
||||
return FPMulFpscrImpl(value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPMulFpscr(double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMulFpscr(double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPMulFpscrImpl(value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPMulFpscrImpl(double value1, double value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2703,12 +2879,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMulAdd(double valueA, double value1, double value2)
|
||||
{
|
||||
return FPMulAddFpscr(valueA, value1, value2, false);
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPMulAddFpscr(double valueA, double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMulAddFpscr(double valueA, double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPMulAddFpscrImpl(double valueA, double value1, double value2, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2774,20 +2957,23 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMulSub(double valueA, double value1, double value2)
|
||||
{
|
||||
value1 = value1.FPNeg();
|
||||
|
||||
return FPMulAdd(valueA, value1, value2);
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||
}
|
||||
|
||||
public static double FPMulSubFpscr(double valueA, double value1, double value2, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMulSubFpscr(double valueA, double value1, double value2, byte standardFpscr)
|
||||
{
|
||||
value1 = value1.FPNeg();
|
||||
|
||||
return FPMulAddFpscr(valueA, value1, value2, standardFpscr);
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPMulX(double value1, double value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -2833,27 +3019,36 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPNegMulAdd(double valueA, double value1, double value2)
|
||||
{
|
||||
valueA = valueA.FPNeg();
|
||||
value1 = value1.FPNeg();
|
||||
|
||||
return FPMulAdd(valueA, value1, value2);
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPNegMulSub(double valueA, double value1, double value2)
|
||||
{
|
||||
valueA = valueA.FPNeg();
|
||||
|
||||
return FPMulAdd(valueA, value1, value2);
|
||||
return FPMulAddFpscrImpl(valueA, value1, value2, false);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPRecipEstimate(double value)
|
||||
{
|
||||
return FPRecipEstimateFpscr(value, false);
|
||||
return FPRecipEstimateFpscrImpl(value, false);
|
||||
}
|
||||
|
||||
public static double FPRecipEstimateFpscr(double value, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPRecipEstimateFpscr(double value, byte standardFpscr)
|
||||
{
|
||||
return FPRecipEstimateFpscrImpl(value, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPRecipEstimateFpscrImpl(double value, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -2940,6 +3135,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPRecipStep(double value1, double value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -2965,7 +3161,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
product = FPMulFpscr(value1, value2, true);
|
||||
product = FPMulFpscrImpl(value1, value2, true);
|
||||
}
|
||||
|
||||
result = FPSubFpscr(FPTwo(false), product, true);
|
||||
@@ -2974,6 +3170,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPRecipStepFused(double value1, double value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -3017,6 +3214,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPRecpX(double value)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -3042,12 +3240,19 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPRSqrtEstimate(double value)
|
||||
{
|
||||
return FPRSqrtEstimateFpscr(value, false);
|
||||
return FPRSqrtEstimateFpscrImpl(value, false);
|
||||
}
|
||||
|
||||
public static double FPRSqrtEstimateFpscr(double value, bool standardFpscr)
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPRSqrtEstimateFpscr(double value, byte standardFpscr)
|
||||
{
|
||||
return FPRSqrtEstimateFpscrImpl(value, standardFpscr == 1);
|
||||
}
|
||||
|
||||
private static double FPRSqrtEstimateFpscrImpl(double value, bool standardFpscr)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
|
||||
@@ -3161,6 +3366,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPRSqrtStep(double value1, double value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -3186,7 +3392,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
product = FPMulFpscr(value1, value2, true);
|
||||
product = FPMulFpscrImpl(value1, value2, true);
|
||||
}
|
||||
|
||||
result = FPHalvedSub(FPThree(false), product, context, fpcr);
|
||||
@@ -3195,6 +3401,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPRSqrtStepFused(double value1, double value2)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -3238,6 +3445,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPSqrt(double value)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
@@ -3280,6 +3488,7 @@ namespace ARMeilleure.Instructions
|
||||
return result;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
public static double FPSub(double value1, double value2)
|
||||
{
|
||||
return FPSubFpscr(value1, value2, false);
|
||||
|
||||
@@ -4,15 +4,9 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
class DelegateInfo
|
||||
{
|
||||
#pragma warning disable IDE0052 // Remove unread private member
|
||||
private readonly Delegate _dlg; // Ensure that this delegate will not be garbage collected.
|
||||
#pragma warning restore IDE0052
|
||||
|
||||
public nint FuncPtr { get; }
|
||||
|
||||
public DelegateInfo(Delegate dlg, nint funcPtr)
|
||||
public nint FuncPtr { get; private set; }
|
||||
public DelegateInfo(nint funcPtr)
|
||||
{
|
||||
_dlg = dlg;
|
||||
FuncPtr = funcPtr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using ARMeilleure.Instructions;
|
||||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
{
|
||||
@@ -34,21 +32,7 @@ namespace ARMeilleure.Translation
|
||||
|
||||
return _delegates.Values[index].FuncPtr; // O(1).
|
||||
}
|
||||
|
||||
public static nint GetDelegateFuncPtr(MethodInfo info)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(info);
|
||||
|
||||
string key = GetKey(info);
|
||||
|
||||
if (!_delegates.TryGetValue(key, out DelegateInfo dlgInfo)) // O(log(n)).
|
||||
{
|
||||
throw new KeyNotFoundException($"({nameof(key)} = {key})");
|
||||
}
|
||||
|
||||
return dlgInfo.FuncPtr;
|
||||
}
|
||||
|
||||
|
||||
public static int GetDelegateIndex(MethodInfo info)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(info);
|
||||
@@ -64,12 +48,12 @@ namespace ARMeilleure.Translation
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
private static void SetDelegateInfo(Delegate dlg, nint funcPtr)
|
||||
|
||||
private static void SetDelegateInfo(MethodInfo method)
|
||||
{
|
||||
string key = GetKey(dlg.Method);
|
||||
string key = GetKey(method);
|
||||
|
||||
_delegates.Add(key, new DelegateInfo(dlg, funcPtr)); // ArgumentException (key).
|
||||
_delegates.Add(key, new DelegateInfo(method.MethodHandle.GetFunctionPointer())); // ArgumentException (key).
|
||||
}
|
||||
|
||||
private static string GetKey(MethodInfo info)
|
||||
@@ -83,528 +67,179 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
_delegates = new SortedList<string, DelegateInfo>();
|
||||
|
||||
var dlgMathAbs = new MathAbs(Math.Abs);
|
||||
var dlgMathCeiling = new MathCeiling(Math.Ceiling);
|
||||
var dlgMathFloor = new MathFloor(Math.Floor);
|
||||
var dlgMathRound = new MathRound(Math.Round);
|
||||
var dlgMathTruncate = new MathTruncate(Math.Truncate);
|
||||
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Abs)));
|
||||
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Ceiling)));
|
||||
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Floor)));
|
||||
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Round)));
|
||||
SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Truncate)));
|
||||
|
||||
var dlgMathFAbs = new MathFAbs(MathF.Abs);
|
||||
var dlgMathFCeiling = new MathFCeiling(MathF.Ceiling);
|
||||
var dlgMathFFloor = new MathFFloor(MathF.Floor);
|
||||
var dlgMathFRound = new MathFRound(MathF.Round);
|
||||
var dlgMathFTruncate = new MathFTruncate(MathF.Truncate);
|
||||
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Abs)));
|
||||
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Ceiling)));
|
||||
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Floor)));
|
||||
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Round)));
|
||||
SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Truncate)));
|
||||
|
||||
var dlgNativeInterfaceBreak = new NativeInterfaceBreak(NativeInterface.Break);
|
||||
var dlgNativeInterfaceCheckSynchronization = new NativeInterfaceCheckSynchronization(NativeInterface.CheckSynchronization);
|
||||
var dlgNativeInterfaceEnqueueForRejit = new NativeInterfaceEnqueueForRejit(NativeInterface.EnqueueForRejit);
|
||||
var dlgNativeInterfaceGetCntfrqEl0 = new NativeInterfaceGetCntfrqEl0(NativeInterface.GetCntfrqEl0);
|
||||
var dlgNativeInterfaceGetCntpctEl0 = new NativeInterfaceGetCntpctEl0(NativeInterface.GetCntpctEl0);
|
||||
var dlgNativeInterfaceGetCntvctEl0 = new NativeInterfaceGetCntvctEl0(NativeInterface.GetCntvctEl0);
|
||||
var dlgNativeInterfaceGetCtrEl0 = new NativeInterfaceGetCtrEl0(NativeInterface.GetCtrEl0);
|
||||
var dlgNativeInterfaceGetDczidEl0 = new NativeInterfaceGetDczidEl0(NativeInterface.GetDczidEl0);
|
||||
var dlgNativeInterfaceGetFunctionAddress = new NativeInterfaceGetFunctionAddress(NativeInterface.GetFunctionAddress);
|
||||
var dlgNativeInterfaceInvalidateCacheLine = new NativeInterfaceInvalidateCacheLine(NativeInterface.InvalidateCacheLine);
|
||||
var dlgNativeInterfaceReadByte = new NativeInterfaceReadByte(NativeInterface.ReadByte);
|
||||
var dlgNativeInterfaceReadUInt16 = new NativeInterfaceReadUInt16(NativeInterface.ReadUInt16);
|
||||
var dlgNativeInterfaceReadUInt32 = new NativeInterfaceReadUInt32(NativeInterface.ReadUInt32);
|
||||
var dlgNativeInterfaceReadUInt64 = new NativeInterfaceReadUInt64(NativeInterface.ReadUInt64);
|
||||
var dlgNativeInterfaceReadVector128 = new NativeInterfaceReadVector128(NativeInterface.ReadVector128);
|
||||
var dlgNativeInterfaceSignalMemoryTracking = new NativeInterfaceSignalMemoryTracking(NativeInterface.SignalMemoryTracking);
|
||||
var dlgNativeInterfaceSupervisorCall = new NativeInterfaceSupervisorCall(NativeInterface.SupervisorCall);
|
||||
var dlgNativeInterfaceThrowInvalidMemoryAccess = new NativeInterfaceThrowInvalidMemoryAccess(NativeInterface.ThrowInvalidMemoryAccess);
|
||||
var dlgNativeInterfaceUndefined = new NativeInterfaceUndefined(NativeInterface.Undefined);
|
||||
var dlgNativeInterfaceWriteByte = new NativeInterfaceWriteByte(NativeInterface.WriteByte);
|
||||
var dlgNativeInterfaceWriteUInt16 = new NativeInterfaceWriteUInt16(NativeInterface.WriteUInt16);
|
||||
var dlgNativeInterfaceWriteUInt32 = new NativeInterfaceWriteUInt32(NativeInterface.WriteUInt32);
|
||||
var dlgNativeInterfaceWriteUInt64 = new NativeInterfaceWriteUInt64(NativeInterface.WriteUInt64);
|
||||
var dlgNativeInterfaceWriteVector128 = new NativeInterfaceWriteVector128(NativeInterface.WriteVector128);
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Break)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Undefined)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)));
|
||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)));
|
||||
|
||||
var dlgSoftFallbackCountLeadingSigns = new SoftFallbackCountLeadingSigns(SoftFallback.CountLeadingSigns);
|
||||
var dlgSoftFallbackCountLeadingZeros = new SoftFallbackCountLeadingZeros(SoftFallback.CountLeadingZeros);
|
||||
var dlgSoftFallbackCrc32b = new SoftFallbackCrc32b(SoftFallback.Crc32b);
|
||||
var dlgSoftFallbackCrc32cb = new SoftFallbackCrc32cb(SoftFallback.Crc32cb);
|
||||
var dlgSoftFallbackCrc32ch = new SoftFallbackCrc32ch(SoftFallback.Crc32ch);
|
||||
var dlgSoftFallbackCrc32cw = new SoftFallbackCrc32cw(SoftFallback.Crc32cw);
|
||||
var dlgSoftFallbackCrc32cx = new SoftFallbackCrc32cx(SoftFallback.Crc32cx);
|
||||
var dlgSoftFallbackCrc32h = new SoftFallbackCrc32h(SoftFallback.Crc32h);
|
||||
var dlgSoftFallbackCrc32w = new SoftFallbackCrc32w(SoftFallback.Crc32w);
|
||||
var dlgSoftFallbackCrc32x = new SoftFallbackCrc32x(SoftFallback.Crc32x);
|
||||
var dlgSoftFallbackDecrypt = new SoftFallbackDecrypt(SoftFallback.Decrypt);
|
||||
var dlgSoftFallbackEncrypt = new SoftFallbackEncrypt(SoftFallback.Encrypt);
|
||||
var dlgSoftFallbackFixedRotate = new SoftFallbackFixedRotate(SoftFallback.FixedRotate);
|
||||
var dlgSoftFallbackHashChoose = new SoftFallbackHashChoose(SoftFallback.HashChoose);
|
||||
var dlgSoftFallbackHashLower = new SoftFallbackHashLower(SoftFallback.HashLower);
|
||||
var dlgSoftFallbackHashMajority = new SoftFallbackHashMajority(SoftFallback.HashMajority);
|
||||
var dlgSoftFallbackHashParity = new SoftFallbackHashParity(SoftFallback.HashParity);
|
||||
var dlgSoftFallbackHashUpper = new SoftFallbackHashUpper(SoftFallback.HashUpper);
|
||||
var dlgSoftFallbackInverseMixColumns = new SoftFallbackInverseMixColumns(SoftFallback.InverseMixColumns);
|
||||
var dlgSoftFallbackMixColumns = new SoftFallbackMixColumns(SoftFallback.MixColumns);
|
||||
var dlgSoftFallbackPolynomialMult64_128 = new SoftFallbackPolynomialMult64_128(SoftFallback.PolynomialMult64_128);
|
||||
var dlgSoftFallbackSatF32ToS32 = new SoftFallbackSatF32ToS32(SoftFallback.SatF32ToS32);
|
||||
var dlgSoftFallbackSatF32ToS64 = new SoftFallbackSatF32ToS64(SoftFallback.SatF32ToS64);
|
||||
var dlgSoftFallbackSatF32ToU32 = new SoftFallbackSatF32ToU32(SoftFallback.SatF32ToU32);
|
||||
var dlgSoftFallbackSatF32ToU64 = new SoftFallbackSatF32ToU64(SoftFallback.SatF32ToU64);
|
||||
var dlgSoftFallbackSatF64ToS32 = new SoftFallbackSatF64ToS32(SoftFallback.SatF64ToS32);
|
||||
var dlgSoftFallbackSatF64ToS64 = new SoftFallbackSatF64ToS64(SoftFallback.SatF64ToS64);
|
||||
var dlgSoftFallbackSatF64ToU32 = new SoftFallbackSatF64ToU32(SoftFallback.SatF64ToU32);
|
||||
var dlgSoftFallbackSatF64ToU64 = new SoftFallbackSatF64ToU64(SoftFallback.SatF64ToU64);
|
||||
var dlgSoftFallbackSha1SchedulePart1 = new SoftFallbackSha1SchedulePart1(SoftFallback.Sha1SchedulePart1);
|
||||
var dlgSoftFallbackSha1SchedulePart2 = new SoftFallbackSha1SchedulePart2(SoftFallback.Sha1SchedulePart2);
|
||||
var dlgSoftFallbackSha256SchedulePart1 = new SoftFallbackSha256SchedulePart1(SoftFallback.Sha256SchedulePart1);
|
||||
var dlgSoftFallbackSha256SchedulePart2 = new SoftFallbackSha256SchedulePart2(SoftFallback.Sha256SchedulePart2);
|
||||
var dlgSoftFallbackSignedShrImm64 = new SoftFallbackSignedShrImm64(SoftFallback.SignedShrImm64);
|
||||
var dlgSoftFallbackTbl1 = new SoftFallbackTbl1(SoftFallback.Tbl1);
|
||||
var dlgSoftFallbackTbl2 = new SoftFallbackTbl2(SoftFallback.Tbl2);
|
||||
var dlgSoftFallbackTbl3 = new SoftFallbackTbl3(SoftFallback.Tbl3);
|
||||
var dlgSoftFallbackTbl4 = new SoftFallbackTbl4(SoftFallback.Tbl4);
|
||||
var dlgSoftFallbackTbx1 = new SoftFallbackTbx1(SoftFallback.Tbx1);
|
||||
var dlgSoftFallbackTbx2 = new SoftFallbackTbx2(SoftFallback.Tbx2);
|
||||
var dlgSoftFallbackTbx3 = new SoftFallbackTbx3(SoftFallback.Tbx3);
|
||||
var dlgSoftFallbackTbx4 = new SoftFallbackTbx4(SoftFallback.Tbx4);
|
||||
var dlgSoftFallbackUnsignedShrImm64 = new SoftFallbackUnsignedShrImm64(SoftFallback.UnsignedShrImm64);
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32b)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cb)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32ch)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cw)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cx)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32h)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32w)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32x)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.FixedRotate)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashChoose)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashMajority)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashParity)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.PolynomialMult64_128)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS64)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU64)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS32)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS64)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU32)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU64)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart1)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart2)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl4)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx1)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
|
||||
|
||||
var dlgSoftFloat16_32FPConvert = new SoftFloat16_32FPConvert(SoftFloat16_32.FPConvert);
|
||||
var dlgSoftFloat16_64FPConvert = new SoftFloat16_64FPConvert(SoftFloat16_64.FPConvert);
|
||||
SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)));
|
||||
SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)));
|
||||
|
||||
var dlgSoftFloat32FPAdd = new SoftFloat32FPAdd(SoftFloat32.FPAdd);
|
||||
var dlgSoftFloat32FPAddFpscr = new SoftFloat32FPAddFpscr(SoftFloat32.FPAddFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPCompare = new SoftFloat32FPCompare(SoftFloat32.FPCompare);
|
||||
var dlgSoftFloat32FPCompareEQ = new SoftFloat32FPCompareEQ(SoftFloat32.FPCompareEQ);
|
||||
var dlgSoftFloat32FPCompareEQFpscr = new SoftFloat32FPCompareEQFpscr(SoftFloat32.FPCompareEQFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPCompareGE = new SoftFloat32FPCompareGE(SoftFloat32.FPCompareGE);
|
||||
var dlgSoftFloat32FPCompareGEFpscr = new SoftFloat32FPCompareGEFpscr(SoftFloat32.FPCompareGEFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPCompareGT = new SoftFloat32FPCompareGT(SoftFloat32.FPCompareGT);
|
||||
var dlgSoftFloat32FPCompareGTFpscr = new SoftFloat32FPCompareGTFpscr(SoftFloat32.FPCompareGTFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPCompareLE = new SoftFloat32FPCompareLE(SoftFloat32.FPCompareLE);
|
||||
var dlgSoftFloat32FPCompareLEFpscr = new SoftFloat32FPCompareLEFpscr(SoftFloat32.FPCompareLEFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPCompareLT = new SoftFloat32FPCompareLT(SoftFloat32.FPCompareLT);
|
||||
var dlgSoftFloat32FPCompareLTFpscr = new SoftFloat32FPCompareLTFpscr(SoftFloat32.FPCompareLTFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPDiv = new SoftFloat32FPDiv(SoftFloat32.FPDiv);
|
||||
var dlgSoftFloat32FPMax = new SoftFloat32FPMax(SoftFloat32.FPMax);
|
||||
var dlgSoftFloat32FPMaxFpscr = new SoftFloat32FPMaxFpscr(SoftFloat32.FPMaxFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPMaxNum = new SoftFloat32FPMaxNum(SoftFloat32.FPMaxNum);
|
||||
var dlgSoftFloat32FPMaxNumFpscr = new SoftFloat32FPMaxNumFpscr(SoftFloat32.FPMaxNumFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPMin = new SoftFloat32FPMin(SoftFloat32.FPMin);
|
||||
var dlgSoftFloat32FPMinFpscr = new SoftFloat32FPMinFpscr(SoftFloat32.FPMinFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPMinNum = new SoftFloat32FPMinNum(SoftFloat32.FPMinNum);
|
||||
var dlgSoftFloat32FPMinNumFpscr = new SoftFloat32FPMinNumFpscr(SoftFloat32.FPMinNumFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPMul = new SoftFloat32FPMul(SoftFloat32.FPMul);
|
||||
var dlgSoftFloat32FPMulFpscr = new SoftFloat32FPMulFpscr(SoftFloat32.FPMulFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPMulAdd = new SoftFloat32FPMulAdd(SoftFloat32.FPMulAdd);
|
||||
var dlgSoftFloat32FPMulAddFpscr = new SoftFloat32FPMulAddFpscr(SoftFloat32.FPMulAddFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPMulSub = new SoftFloat32FPMulSub(SoftFloat32.FPMulSub);
|
||||
var dlgSoftFloat32FPMulSubFpscr = new SoftFloat32FPMulSubFpscr(SoftFloat32.FPMulSubFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPMulX = new SoftFloat32FPMulX(SoftFloat32.FPMulX);
|
||||
var dlgSoftFloat32FPNegMulAdd = new SoftFloat32FPNegMulAdd(SoftFloat32.FPNegMulAdd);
|
||||
var dlgSoftFloat32FPNegMulSub = new SoftFloat32FPNegMulSub(SoftFloat32.FPNegMulSub);
|
||||
var dlgSoftFloat32FPRecipEstimate = new SoftFloat32FPRecipEstimate(SoftFloat32.FPRecipEstimate);
|
||||
var dlgSoftFloat32FPRecipEstimateFpscr = new SoftFloat32FPRecipEstimateFpscr(SoftFloat32.FPRecipEstimateFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPRecipStep = new SoftFloat32FPRecipStep(SoftFloat32.FPRecipStep); // A32 only.
|
||||
var dlgSoftFloat32FPRecipStepFused = new SoftFloat32FPRecipStepFused(SoftFloat32.FPRecipStepFused);
|
||||
var dlgSoftFloat32FPRecpX = new SoftFloat32FPRecpX(SoftFloat32.FPRecpX);
|
||||
var dlgSoftFloat32FPRSqrtEstimate = new SoftFloat32FPRSqrtEstimate(SoftFloat32.FPRSqrtEstimate);
|
||||
var dlgSoftFloat32FPRSqrtEstimateFpscr = new SoftFloat32FPRSqrtEstimateFpscr(SoftFloat32.FPRSqrtEstimateFpscr); // A32 only.
|
||||
var dlgSoftFloat32FPRSqrtStep = new SoftFloat32FPRSqrtStep(SoftFloat32.FPRSqrtStep); // A32 only.
|
||||
var dlgSoftFloat32FPRSqrtStepFused = new SoftFloat32FPRSqrtStepFused(SoftFloat32.FPRSqrtStepFused);
|
||||
var dlgSoftFloat32FPSqrt = new SoftFloat32FPSqrt(SoftFloat32.FPSqrt);
|
||||
var dlgSoftFloat32FPSub = new SoftFloat32FPSub(SoftFloat32.FPSub);
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAdd)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAddFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompare)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQ)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGE)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGEFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGT)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGTFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLE)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLEFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLT)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLTFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPDiv)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMax)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNum)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNumFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMin)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNum)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNumFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMul)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAdd)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAddFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSub)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSubFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulX)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulAdd)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulSub)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimate)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimateFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStep))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStepFused)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecpX)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimate)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimateFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStep))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStepFused)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSqrt)));
|
||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSub)));
|
||||
|
||||
var dlgSoftFloat32_16FPConvert = new SoftFloat32_16FPConvert(SoftFloat32_16.FPConvert);
|
||||
SetDelegateInfo(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert)));
|
||||
|
||||
var dlgSoftFloat64FPAdd = new SoftFloat64FPAdd(SoftFloat64.FPAdd);
|
||||
var dlgSoftFloat64FPAddFpscr = new SoftFloat64FPAddFpscr(SoftFloat64.FPAddFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPCompare = new SoftFloat64FPCompare(SoftFloat64.FPCompare);
|
||||
var dlgSoftFloat64FPCompareEQ = new SoftFloat64FPCompareEQ(SoftFloat64.FPCompareEQ);
|
||||
var dlgSoftFloat64FPCompareEQFpscr = new SoftFloat64FPCompareEQFpscr(SoftFloat64.FPCompareEQFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPCompareGE = new SoftFloat64FPCompareGE(SoftFloat64.FPCompareGE);
|
||||
var dlgSoftFloat64FPCompareGEFpscr = new SoftFloat64FPCompareGEFpscr(SoftFloat64.FPCompareGEFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPCompareGT = new SoftFloat64FPCompareGT(SoftFloat64.FPCompareGT);
|
||||
var dlgSoftFloat64FPCompareGTFpscr = new SoftFloat64FPCompareGTFpscr(SoftFloat64.FPCompareGTFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPCompareLE = new SoftFloat64FPCompareLE(SoftFloat64.FPCompareLE);
|
||||
var dlgSoftFloat64FPCompareLEFpscr = new SoftFloat64FPCompareLEFpscr(SoftFloat64.FPCompareLEFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPCompareLT = new SoftFloat64FPCompareLT(SoftFloat64.FPCompareLT);
|
||||
var dlgSoftFloat64FPCompareLTFpscr = new SoftFloat64FPCompareLTFpscr(SoftFloat64.FPCompareLTFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPDiv = new SoftFloat64FPDiv(SoftFloat64.FPDiv);
|
||||
var dlgSoftFloat64FPMax = new SoftFloat64FPMax(SoftFloat64.FPMax);
|
||||
var dlgSoftFloat64FPMaxFpscr = new SoftFloat64FPMaxFpscr(SoftFloat64.FPMaxFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPMaxNum = new SoftFloat64FPMaxNum(SoftFloat64.FPMaxNum);
|
||||
var dlgSoftFloat64FPMaxNumFpscr = new SoftFloat64FPMaxNumFpscr(SoftFloat64.FPMaxNumFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPMin = new SoftFloat64FPMin(SoftFloat64.FPMin);
|
||||
var dlgSoftFloat64FPMinFpscr = new SoftFloat64FPMinFpscr(SoftFloat64.FPMinFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPMinNum = new SoftFloat64FPMinNum(SoftFloat64.FPMinNum);
|
||||
var dlgSoftFloat64FPMinNumFpscr = new SoftFloat64FPMinNumFpscr(SoftFloat64.FPMinNumFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPMul = new SoftFloat64FPMul(SoftFloat64.FPMul);
|
||||
var dlgSoftFloat64FPMulFpscr = new SoftFloat64FPMulFpscr(SoftFloat64.FPMulFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPMulAdd = new SoftFloat64FPMulAdd(SoftFloat64.FPMulAdd);
|
||||
var dlgSoftFloat64FPMulAddFpscr = new SoftFloat64FPMulAddFpscr(SoftFloat64.FPMulAddFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPMulSub = new SoftFloat64FPMulSub(SoftFloat64.FPMulSub);
|
||||
var dlgSoftFloat64FPMulSubFpscr = new SoftFloat64FPMulSubFpscr(SoftFloat64.FPMulSubFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPMulX = new SoftFloat64FPMulX(SoftFloat64.FPMulX);
|
||||
var dlgSoftFloat64FPNegMulAdd = new SoftFloat64FPNegMulAdd(SoftFloat64.FPNegMulAdd);
|
||||
var dlgSoftFloat64FPNegMulSub = new SoftFloat64FPNegMulSub(SoftFloat64.FPNegMulSub);
|
||||
var dlgSoftFloat64FPRecipEstimate = new SoftFloat64FPRecipEstimate(SoftFloat64.FPRecipEstimate);
|
||||
var dlgSoftFloat64FPRecipEstimateFpscr = new SoftFloat64FPRecipEstimateFpscr(SoftFloat64.FPRecipEstimateFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPRecipStep = new SoftFloat64FPRecipStep(SoftFloat64.FPRecipStep); // A32 only.
|
||||
var dlgSoftFloat64FPRecipStepFused = new SoftFloat64FPRecipStepFused(SoftFloat64.FPRecipStepFused);
|
||||
var dlgSoftFloat64FPRecpX = new SoftFloat64FPRecpX(SoftFloat64.FPRecpX);
|
||||
var dlgSoftFloat64FPRSqrtEstimate = new SoftFloat64FPRSqrtEstimate(SoftFloat64.FPRSqrtEstimate);
|
||||
var dlgSoftFloat64FPRSqrtEstimateFpscr = new SoftFloat64FPRSqrtEstimateFpscr(SoftFloat64.FPRSqrtEstimateFpscr); // A32 only.
|
||||
var dlgSoftFloat64FPRSqrtStep = new SoftFloat64FPRSqrtStep(SoftFloat64.FPRSqrtStep); // A32 only.
|
||||
var dlgSoftFloat64FPRSqrtStepFused = new SoftFloat64FPRSqrtStepFused(SoftFloat64.FPRSqrtStepFused);
|
||||
var dlgSoftFloat64FPSqrt = new SoftFloat64FPSqrt(SoftFloat64.FPSqrt);
|
||||
var dlgSoftFloat64FPSub = new SoftFloat64FPSub(SoftFloat64.FPSub);
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAdd)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAddFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompare)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQ)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGE)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGEFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGT)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGTFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLE)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLEFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLT)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLTFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPDiv)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMax)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNum)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNumFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMin)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNum)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNumFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMul)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAdd)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAddFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSub)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSubFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulX)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulAdd)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulSub)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimate)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimateFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStep))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStepFused)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecpX)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimate)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimateFpscr))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStep))); // A32 only.
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStepFused)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSqrt)));
|
||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSub)));
|
||||
|
||||
var dlgSoftFloat64_16FPConvert = new SoftFloat64_16FPConvert(SoftFloat64_16.FPConvert);
|
||||
|
||||
SetDelegateInfo(dlgMathAbs, Marshal.GetFunctionPointerForDelegate<MathAbs>(dlgMathAbs));
|
||||
SetDelegateInfo(dlgMathCeiling, Marshal.GetFunctionPointerForDelegate<MathCeiling>(dlgMathCeiling));
|
||||
SetDelegateInfo(dlgMathFloor, Marshal.GetFunctionPointerForDelegate<MathFloor>(dlgMathFloor));
|
||||
SetDelegateInfo(dlgMathRound, Marshal.GetFunctionPointerForDelegate<MathRound>(dlgMathRound));
|
||||
SetDelegateInfo(dlgMathTruncate, Marshal.GetFunctionPointerForDelegate<MathTruncate>(dlgMathTruncate));
|
||||
|
||||
SetDelegateInfo(dlgMathFAbs, Marshal.GetFunctionPointerForDelegate<MathFAbs>(dlgMathFAbs));
|
||||
SetDelegateInfo(dlgMathFCeiling, Marshal.GetFunctionPointerForDelegate<MathFCeiling>(dlgMathFCeiling));
|
||||
SetDelegateInfo(dlgMathFFloor, Marshal.GetFunctionPointerForDelegate<MathFFloor>(dlgMathFFloor));
|
||||
SetDelegateInfo(dlgMathFRound, Marshal.GetFunctionPointerForDelegate<MathFRound>(dlgMathFRound));
|
||||
SetDelegateInfo(dlgMathFTruncate, Marshal.GetFunctionPointerForDelegate<MathFTruncate>(dlgMathFTruncate));
|
||||
|
||||
SetDelegateInfo(dlgNativeInterfaceBreak, Marshal.GetFunctionPointerForDelegate<NativeInterfaceBreak>(dlgNativeInterfaceBreak));
|
||||
SetDelegateInfo(dlgNativeInterfaceCheckSynchronization, Marshal.GetFunctionPointerForDelegate<NativeInterfaceCheckSynchronization>(dlgNativeInterfaceCheckSynchronization));
|
||||
SetDelegateInfo(dlgNativeInterfaceEnqueueForRejit, Marshal.GetFunctionPointerForDelegate<NativeInterfaceEnqueueForRejit>(dlgNativeInterfaceEnqueueForRejit));
|
||||
SetDelegateInfo(dlgNativeInterfaceGetCntfrqEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntfrqEl0>(dlgNativeInterfaceGetCntfrqEl0));
|
||||
SetDelegateInfo(dlgNativeInterfaceGetCntpctEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntpctEl0>(dlgNativeInterfaceGetCntpctEl0));
|
||||
SetDelegateInfo(dlgNativeInterfaceGetCntvctEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntvctEl0>(dlgNativeInterfaceGetCntvctEl0));
|
||||
SetDelegateInfo(dlgNativeInterfaceGetCtrEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCtrEl0>(dlgNativeInterfaceGetCtrEl0));
|
||||
SetDelegateInfo(dlgNativeInterfaceGetDczidEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetDczidEl0>(dlgNativeInterfaceGetDczidEl0));
|
||||
SetDelegateInfo(dlgNativeInterfaceGetFunctionAddress, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetFunctionAddress>(dlgNativeInterfaceGetFunctionAddress));
|
||||
SetDelegateInfo(dlgNativeInterfaceInvalidateCacheLine, Marshal.GetFunctionPointerForDelegate<NativeInterfaceInvalidateCacheLine>(dlgNativeInterfaceInvalidateCacheLine));
|
||||
SetDelegateInfo(dlgNativeInterfaceReadByte, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadByte>(dlgNativeInterfaceReadByte));
|
||||
SetDelegateInfo(dlgNativeInterfaceReadUInt16, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt16>(dlgNativeInterfaceReadUInt16));
|
||||
SetDelegateInfo(dlgNativeInterfaceReadUInt32, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt32>(dlgNativeInterfaceReadUInt32));
|
||||
SetDelegateInfo(dlgNativeInterfaceReadUInt64, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt64>(dlgNativeInterfaceReadUInt64));
|
||||
SetDelegateInfo(dlgNativeInterfaceReadVector128, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadVector128>(dlgNativeInterfaceReadVector128));
|
||||
SetDelegateInfo(dlgNativeInterfaceSignalMemoryTracking, Marshal.GetFunctionPointerForDelegate<NativeInterfaceSignalMemoryTracking>(dlgNativeInterfaceSignalMemoryTracking));
|
||||
SetDelegateInfo(dlgNativeInterfaceSupervisorCall, Marshal.GetFunctionPointerForDelegate<NativeInterfaceSupervisorCall>(dlgNativeInterfaceSupervisorCall));
|
||||
SetDelegateInfo(dlgNativeInterfaceThrowInvalidMemoryAccess, Marshal.GetFunctionPointerForDelegate<NativeInterfaceThrowInvalidMemoryAccess>(dlgNativeInterfaceThrowInvalidMemoryAccess));
|
||||
SetDelegateInfo(dlgNativeInterfaceUndefined, Marshal.GetFunctionPointerForDelegate<NativeInterfaceUndefined>(dlgNativeInterfaceUndefined));
|
||||
SetDelegateInfo(dlgNativeInterfaceWriteByte, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteByte>(dlgNativeInterfaceWriteByte));
|
||||
SetDelegateInfo(dlgNativeInterfaceWriteUInt16, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt16>(dlgNativeInterfaceWriteUInt16));
|
||||
SetDelegateInfo(dlgNativeInterfaceWriteUInt32, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt32>(dlgNativeInterfaceWriteUInt32));
|
||||
SetDelegateInfo(dlgNativeInterfaceWriteUInt64, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt64>(dlgNativeInterfaceWriteUInt64));
|
||||
SetDelegateInfo(dlgNativeInterfaceWriteVector128, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteVector128>(dlgNativeInterfaceWriteVector128));
|
||||
|
||||
SetDelegateInfo(dlgSoftFallbackCountLeadingSigns, Marshal.GetFunctionPointerForDelegate<SoftFallbackCountLeadingSigns>(dlgSoftFallbackCountLeadingSigns));
|
||||
SetDelegateInfo(dlgSoftFallbackCountLeadingZeros, Marshal.GetFunctionPointerForDelegate<SoftFallbackCountLeadingZeros>(dlgSoftFallbackCountLeadingZeros));
|
||||
SetDelegateInfo(dlgSoftFallbackCrc32b, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32b>(dlgSoftFallbackCrc32b));
|
||||
SetDelegateInfo(dlgSoftFallbackCrc32cb, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cb>(dlgSoftFallbackCrc32cb));
|
||||
SetDelegateInfo(dlgSoftFallbackCrc32ch, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32ch>(dlgSoftFallbackCrc32ch));
|
||||
SetDelegateInfo(dlgSoftFallbackCrc32cw, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cw>(dlgSoftFallbackCrc32cw));
|
||||
SetDelegateInfo(dlgSoftFallbackCrc32cx, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cx>(dlgSoftFallbackCrc32cx));
|
||||
SetDelegateInfo(dlgSoftFallbackCrc32h, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32h>(dlgSoftFallbackCrc32h));
|
||||
SetDelegateInfo(dlgSoftFallbackCrc32w, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32w>(dlgSoftFallbackCrc32w));
|
||||
SetDelegateInfo(dlgSoftFallbackCrc32x, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32x>(dlgSoftFallbackCrc32x));
|
||||
SetDelegateInfo(dlgSoftFallbackDecrypt, Marshal.GetFunctionPointerForDelegate<SoftFallbackDecrypt>(dlgSoftFallbackDecrypt));
|
||||
SetDelegateInfo(dlgSoftFallbackEncrypt, Marshal.GetFunctionPointerForDelegate<SoftFallbackEncrypt>(dlgSoftFallbackEncrypt));
|
||||
SetDelegateInfo(dlgSoftFallbackFixedRotate, Marshal.GetFunctionPointerForDelegate<SoftFallbackFixedRotate>(dlgSoftFallbackFixedRotate));
|
||||
SetDelegateInfo(dlgSoftFallbackHashChoose, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashChoose>(dlgSoftFallbackHashChoose));
|
||||
SetDelegateInfo(dlgSoftFallbackHashLower, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashLower>(dlgSoftFallbackHashLower));
|
||||
SetDelegateInfo(dlgSoftFallbackHashMajority, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashMajority>(dlgSoftFallbackHashMajority));
|
||||
SetDelegateInfo(dlgSoftFallbackHashParity, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashParity>(dlgSoftFallbackHashParity));
|
||||
SetDelegateInfo(dlgSoftFallbackHashUpper, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashUpper>(dlgSoftFallbackHashUpper));
|
||||
SetDelegateInfo(dlgSoftFallbackInverseMixColumns, Marshal.GetFunctionPointerForDelegate<SoftFallbackInverseMixColumns>(dlgSoftFallbackInverseMixColumns));
|
||||
SetDelegateInfo(dlgSoftFallbackMixColumns, Marshal.GetFunctionPointerForDelegate<SoftFallbackMixColumns>(dlgSoftFallbackMixColumns));
|
||||
SetDelegateInfo(dlgSoftFallbackPolynomialMult64_128, Marshal.GetFunctionPointerForDelegate<SoftFallbackPolynomialMult64_128>(dlgSoftFallbackPolynomialMult64_128));
|
||||
SetDelegateInfo(dlgSoftFallbackSatF32ToS32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToS32>(dlgSoftFallbackSatF32ToS32));
|
||||
SetDelegateInfo(dlgSoftFallbackSatF32ToS64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToS64>(dlgSoftFallbackSatF32ToS64));
|
||||
SetDelegateInfo(dlgSoftFallbackSatF32ToU32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToU32>(dlgSoftFallbackSatF32ToU32));
|
||||
SetDelegateInfo(dlgSoftFallbackSatF32ToU64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToU64>(dlgSoftFallbackSatF32ToU64));
|
||||
SetDelegateInfo(dlgSoftFallbackSatF64ToS32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToS32>(dlgSoftFallbackSatF64ToS32));
|
||||
SetDelegateInfo(dlgSoftFallbackSatF64ToS64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToS64>(dlgSoftFallbackSatF64ToS64));
|
||||
SetDelegateInfo(dlgSoftFallbackSatF64ToU32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToU32>(dlgSoftFallbackSatF64ToU32));
|
||||
SetDelegateInfo(dlgSoftFallbackSatF64ToU64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToU64>(dlgSoftFallbackSatF64ToU64));
|
||||
SetDelegateInfo(dlgSoftFallbackSha1SchedulePart1, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha1SchedulePart1>(dlgSoftFallbackSha1SchedulePart1));
|
||||
SetDelegateInfo(dlgSoftFallbackSha1SchedulePart2, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha1SchedulePart2>(dlgSoftFallbackSha1SchedulePart2));
|
||||
SetDelegateInfo(dlgSoftFallbackSha256SchedulePart1, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha256SchedulePart1>(dlgSoftFallbackSha256SchedulePart1));
|
||||
SetDelegateInfo(dlgSoftFallbackSha256SchedulePart2, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha256SchedulePart2>(dlgSoftFallbackSha256SchedulePart2));
|
||||
SetDelegateInfo(dlgSoftFallbackSignedShrImm64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSignedShrImm64>(dlgSoftFallbackSignedShrImm64));
|
||||
SetDelegateInfo(dlgSoftFallbackTbl1, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl1>(dlgSoftFallbackTbl1));
|
||||
SetDelegateInfo(dlgSoftFallbackTbl2, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl2>(dlgSoftFallbackTbl2));
|
||||
SetDelegateInfo(dlgSoftFallbackTbl3, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl3>(dlgSoftFallbackTbl3));
|
||||
SetDelegateInfo(dlgSoftFallbackTbl4, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl4>(dlgSoftFallbackTbl4));
|
||||
SetDelegateInfo(dlgSoftFallbackTbx1, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx1>(dlgSoftFallbackTbx1));
|
||||
SetDelegateInfo(dlgSoftFallbackTbx2, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx2>(dlgSoftFallbackTbx2));
|
||||
SetDelegateInfo(dlgSoftFallbackTbx3, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx3>(dlgSoftFallbackTbx3));
|
||||
SetDelegateInfo(dlgSoftFallbackTbx4, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx4>(dlgSoftFallbackTbx4));
|
||||
SetDelegateInfo(dlgSoftFallbackUnsignedShrImm64, Marshal.GetFunctionPointerForDelegate<SoftFallbackUnsignedShrImm64>(dlgSoftFallbackUnsignedShrImm64));
|
||||
|
||||
SetDelegateInfo(dlgSoftFloat16_32FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat16_32FPConvert>(dlgSoftFloat16_32FPConvert));
|
||||
SetDelegateInfo(dlgSoftFloat16_64FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat16_64FPConvert>(dlgSoftFloat16_64FPConvert));
|
||||
|
||||
SetDelegateInfo(dlgSoftFloat32FPAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPAdd>(dlgSoftFloat32FPAdd));
|
||||
SetDelegateInfo(dlgSoftFloat32FPAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPAddFpscr>(dlgSoftFloat32FPAddFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompare, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompare>(dlgSoftFloat32FPCompare));
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompareEQ, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareEQ>(dlgSoftFloat32FPCompareEQ));
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompareEQFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareEQFpscr>(dlgSoftFloat32FPCompareEQFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompareGE, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGE>(dlgSoftFloat32FPCompareGE));
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompareGEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGEFpscr>(dlgSoftFloat32FPCompareGEFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompareGT, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGT>(dlgSoftFloat32FPCompareGT));
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompareGTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGTFpscr>(dlgSoftFloat32FPCompareGTFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompareLE, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLE>(dlgSoftFloat32FPCompareLE));
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompareLEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLEFpscr>(dlgSoftFloat32FPCompareLEFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompareLT, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLT>(dlgSoftFloat32FPCompareLT));
|
||||
SetDelegateInfo(dlgSoftFloat32FPCompareLTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLTFpscr>(dlgSoftFloat32FPCompareLTFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPDiv, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPDiv>(dlgSoftFloat32FPDiv));
|
||||
SetDelegateInfo(dlgSoftFloat32FPMax, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMax>(dlgSoftFloat32FPMax));
|
||||
SetDelegateInfo(dlgSoftFloat32FPMaxFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxFpscr>(dlgSoftFloat32FPMaxFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPMaxNum, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxNum>(dlgSoftFloat32FPMaxNum));
|
||||
SetDelegateInfo(dlgSoftFloat32FPMaxNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxNumFpscr>(dlgSoftFloat32FPMaxNumFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPMin, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMin>(dlgSoftFloat32FPMin));
|
||||
SetDelegateInfo(dlgSoftFloat32FPMinFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinFpscr>(dlgSoftFloat32FPMinFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPMinNum, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinNum>(dlgSoftFloat32FPMinNum));
|
||||
SetDelegateInfo(dlgSoftFloat32FPMinNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinNumFpscr>(dlgSoftFloat32FPMinNumFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPMul, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMul>(dlgSoftFloat32FPMul));
|
||||
SetDelegateInfo(dlgSoftFloat32FPMulFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulFpscr>(dlgSoftFloat32FPMulFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulAdd>(dlgSoftFloat32FPMulAdd));
|
||||
SetDelegateInfo(dlgSoftFloat32FPMulAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulAddFpscr>(dlgSoftFloat32FPMulAddFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulSub>(dlgSoftFloat32FPMulSub));
|
||||
SetDelegateInfo(dlgSoftFloat32FPMulSubFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulSubFpscr>(dlgSoftFloat32FPMulSubFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPMulX, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulX>(dlgSoftFloat32FPMulX));
|
||||
SetDelegateInfo(dlgSoftFloat32FPNegMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPNegMulAdd>(dlgSoftFloat32FPNegMulAdd));
|
||||
SetDelegateInfo(dlgSoftFloat32FPNegMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPNegMulSub>(dlgSoftFloat32FPNegMulSub));
|
||||
SetDelegateInfo(dlgSoftFloat32FPRecipEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipEstimate>(dlgSoftFloat32FPRecipEstimate));
|
||||
SetDelegateInfo(dlgSoftFloat32FPRecipEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipEstimateFpscr>(dlgSoftFloat32FPRecipEstimateFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPRecipStep, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipStep>(dlgSoftFloat32FPRecipStep)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPRecipStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipStepFused>(dlgSoftFloat32FPRecipStepFused));
|
||||
SetDelegateInfo(dlgSoftFloat32FPRecpX, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecpX>(dlgSoftFloat32FPRecpX));
|
||||
SetDelegateInfo(dlgSoftFloat32FPRSqrtEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtEstimate>(dlgSoftFloat32FPRSqrtEstimate));
|
||||
SetDelegateInfo(dlgSoftFloat32FPRSqrtEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtEstimateFpscr>(dlgSoftFloat32FPRSqrtEstimateFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPRSqrtStep, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtStep>(dlgSoftFloat32FPRSqrtStep)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat32FPRSqrtStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtStepFused>(dlgSoftFloat32FPRSqrtStepFused));
|
||||
SetDelegateInfo(dlgSoftFloat32FPSqrt, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPSqrt>(dlgSoftFloat32FPSqrt));
|
||||
SetDelegateInfo(dlgSoftFloat32FPSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPSub>(dlgSoftFloat32FPSub));
|
||||
|
||||
SetDelegateInfo(dlgSoftFloat32_16FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat32_16FPConvert>(dlgSoftFloat32_16FPConvert));
|
||||
|
||||
SetDelegateInfo(dlgSoftFloat64FPAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPAdd>(dlgSoftFloat64FPAdd));
|
||||
SetDelegateInfo(dlgSoftFloat64FPAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPAddFpscr>(dlgSoftFloat64FPAddFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompare, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompare>(dlgSoftFloat64FPCompare));
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompareEQ, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareEQ>(dlgSoftFloat64FPCompareEQ));
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompareEQFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareEQFpscr>(dlgSoftFloat64FPCompareEQFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompareGE, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGE>(dlgSoftFloat64FPCompareGE));
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompareGEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGEFpscr>(dlgSoftFloat64FPCompareGEFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompareGT, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGT>(dlgSoftFloat64FPCompareGT));
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompareGTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGTFpscr>(dlgSoftFloat64FPCompareGTFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompareLE, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLE>(dlgSoftFloat64FPCompareLE));
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompareLEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLEFpscr>(dlgSoftFloat64FPCompareLEFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompareLT, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLT>(dlgSoftFloat64FPCompareLT));
|
||||
SetDelegateInfo(dlgSoftFloat64FPCompareLTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLTFpscr>(dlgSoftFloat64FPCompareLTFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPDiv, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPDiv>(dlgSoftFloat64FPDiv));
|
||||
SetDelegateInfo(dlgSoftFloat64FPMax, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMax>(dlgSoftFloat64FPMax));
|
||||
SetDelegateInfo(dlgSoftFloat64FPMaxFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxFpscr>(dlgSoftFloat64FPMaxFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPMaxNum, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxNum>(dlgSoftFloat64FPMaxNum));
|
||||
SetDelegateInfo(dlgSoftFloat64FPMaxNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxNumFpscr>(dlgSoftFloat64FPMaxNumFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPMin, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMin>(dlgSoftFloat64FPMin));
|
||||
SetDelegateInfo(dlgSoftFloat64FPMinFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinFpscr>(dlgSoftFloat64FPMinFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPMinNum, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinNum>(dlgSoftFloat64FPMinNum));
|
||||
SetDelegateInfo(dlgSoftFloat64FPMinNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinNumFpscr>(dlgSoftFloat64FPMinNumFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPMul, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMul>(dlgSoftFloat64FPMul));
|
||||
SetDelegateInfo(dlgSoftFloat64FPMulFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulFpscr>(dlgSoftFloat64FPMulFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulAdd>(dlgSoftFloat64FPMulAdd));
|
||||
SetDelegateInfo(dlgSoftFloat64FPMulAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulAddFpscr>(dlgSoftFloat64FPMulAddFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulSub>(dlgSoftFloat64FPMulSub));
|
||||
SetDelegateInfo(dlgSoftFloat64FPMulSubFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulSubFpscr>(dlgSoftFloat64FPMulSubFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPMulX, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulX>(dlgSoftFloat64FPMulX));
|
||||
SetDelegateInfo(dlgSoftFloat64FPNegMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPNegMulAdd>(dlgSoftFloat64FPNegMulAdd));
|
||||
SetDelegateInfo(dlgSoftFloat64FPNegMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPNegMulSub>(dlgSoftFloat64FPNegMulSub));
|
||||
SetDelegateInfo(dlgSoftFloat64FPRecipEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipEstimate>(dlgSoftFloat64FPRecipEstimate));
|
||||
SetDelegateInfo(dlgSoftFloat64FPRecipEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipEstimateFpscr>(dlgSoftFloat64FPRecipEstimateFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPRecipStep, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipStep>(dlgSoftFloat64FPRecipStep)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPRecipStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipStepFused>(dlgSoftFloat64FPRecipStepFused));
|
||||
SetDelegateInfo(dlgSoftFloat64FPRecpX, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecpX>(dlgSoftFloat64FPRecpX));
|
||||
SetDelegateInfo(dlgSoftFloat64FPRSqrtEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtEstimate>(dlgSoftFloat64FPRSqrtEstimate));
|
||||
SetDelegateInfo(dlgSoftFloat64FPRSqrtEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtEstimateFpscr>(dlgSoftFloat64FPRSqrtEstimateFpscr)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPRSqrtStep, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtStep>(dlgSoftFloat64FPRSqrtStep)); // A32 only.
|
||||
SetDelegateInfo(dlgSoftFloat64FPRSqrtStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtStepFused>(dlgSoftFloat64FPRSqrtStepFused));
|
||||
SetDelegateInfo(dlgSoftFloat64FPSqrt, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPSqrt>(dlgSoftFloat64FPSqrt));
|
||||
SetDelegateInfo(dlgSoftFloat64FPSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPSub>(dlgSoftFloat64FPSub));
|
||||
|
||||
SetDelegateInfo(dlgSoftFloat64_16FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat64_16FPConvert>(dlgSoftFloat64_16FPConvert));
|
||||
SetDelegateInfo(typeof(SoftFloat64_16).GetMethod(nameof(SoftFloat64_16.FPConvert)));
|
||||
}
|
||||
|
||||
private delegate double MathAbs(double value);
|
||||
private delegate double MathCeiling(double a);
|
||||
private delegate double MathFloor(double d);
|
||||
private delegate double MathRound(double value, MidpointRounding mode);
|
||||
private delegate double MathTruncate(double d);
|
||||
|
||||
private delegate float MathFAbs(float x);
|
||||
private delegate float MathFCeiling(float x);
|
||||
private delegate float MathFFloor(float x);
|
||||
private delegate float MathFRound(float x, MidpointRounding mode);
|
||||
private delegate float MathFTruncate(float x);
|
||||
|
||||
private delegate void NativeInterfaceBreak(ulong address, int imm);
|
||||
private delegate bool NativeInterfaceCheckSynchronization();
|
||||
private delegate void NativeInterfaceEnqueueForRejit(ulong address);
|
||||
private delegate ulong NativeInterfaceGetCntfrqEl0();
|
||||
private delegate ulong NativeInterfaceGetCntpctEl0();
|
||||
private delegate ulong NativeInterfaceGetCntvctEl0();
|
||||
private delegate ulong NativeInterfaceGetCtrEl0();
|
||||
private delegate ulong NativeInterfaceGetDczidEl0();
|
||||
private delegate ulong NativeInterfaceGetFunctionAddress(ulong address);
|
||||
private delegate void NativeInterfaceInvalidateCacheLine(ulong address);
|
||||
private delegate byte NativeInterfaceReadByte(ulong address);
|
||||
private delegate ushort NativeInterfaceReadUInt16(ulong address);
|
||||
private delegate uint NativeInterfaceReadUInt32(ulong address);
|
||||
private delegate ulong NativeInterfaceReadUInt64(ulong address);
|
||||
private delegate V128 NativeInterfaceReadVector128(ulong address);
|
||||
private delegate void NativeInterfaceSignalMemoryTracking(ulong address, ulong size, bool write);
|
||||
private delegate void NativeInterfaceSupervisorCall(ulong address, int imm);
|
||||
private delegate void NativeInterfaceThrowInvalidMemoryAccess(ulong address);
|
||||
private delegate void NativeInterfaceUndefined(ulong address, int opCode);
|
||||
private delegate void NativeInterfaceWriteByte(ulong address, byte value);
|
||||
private delegate void NativeInterfaceWriteUInt16(ulong address, ushort value);
|
||||
private delegate void NativeInterfaceWriteUInt32(ulong address, uint value);
|
||||
private delegate void NativeInterfaceWriteUInt64(ulong address, ulong value);
|
||||
private delegate void NativeInterfaceWriteVector128(ulong address, V128 value);
|
||||
|
||||
private delegate ulong SoftFallbackCountLeadingSigns(ulong value, int size);
|
||||
private delegate ulong SoftFallbackCountLeadingZeros(ulong value, int size);
|
||||
private delegate uint SoftFallbackCrc32b(uint crc, byte value);
|
||||
private delegate uint SoftFallbackCrc32cb(uint crc, byte value);
|
||||
private delegate uint SoftFallbackCrc32ch(uint crc, ushort value);
|
||||
private delegate uint SoftFallbackCrc32cw(uint crc, uint value);
|
||||
private delegate uint SoftFallbackCrc32cx(uint crc, ulong value);
|
||||
private delegate uint SoftFallbackCrc32h(uint crc, ushort value);
|
||||
private delegate uint SoftFallbackCrc32w(uint crc, uint value);
|
||||
private delegate uint SoftFallbackCrc32x(uint crc, ulong value);
|
||||
private delegate V128 SoftFallbackDecrypt(V128 value, V128 roundKey);
|
||||
private delegate V128 SoftFallbackEncrypt(V128 value, V128 roundKey);
|
||||
private delegate uint SoftFallbackFixedRotate(uint hash_e);
|
||||
private delegate V128 SoftFallbackHashChoose(V128 hash_abcd, uint hash_e, V128 wk);
|
||||
private delegate V128 SoftFallbackHashLower(V128 hash_abcd, V128 hash_efgh, V128 wk);
|
||||
private delegate V128 SoftFallbackHashMajority(V128 hash_abcd, uint hash_e, V128 wk);
|
||||
private delegate V128 SoftFallbackHashParity(V128 hash_abcd, uint hash_e, V128 wk);
|
||||
private delegate V128 SoftFallbackHashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk);
|
||||
private delegate V128 SoftFallbackInverseMixColumns(V128 value);
|
||||
private delegate V128 SoftFallbackMixColumns(V128 value);
|
||||
private delegate V128 SoftFallbackPolynomialMult64_128(ulong op1, ulong op2);
|
||||
private delegate int SoftFallbackSatF32ToS32(float value);
|
||||
private delegate long SoftFallbackSatF32ToS64(float value);
|
||||
private delegate uint SoftFallbackSatF32ToU32(float value);
|
||||
private delegate ulong SoftFallbackSatF32ToU64(float value);
|
||||
private delegate int SoftFallbackSatF64ToS32(double value);
|
||||
private delegate long SoftFallbackSatF64ToS64(double value);
|
||||
private delegate uint SoftFallbackSatF64ToU32(double value);
|
||||
private delegate ulong SoftFallbackSatF64ToU64(double value);
|
||||
private delegate V128 SoftFallbackSha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11);
|
||||
private delegate V128 SoftFallbackSha1SchedulePart2(V128 tw0_3, V128 w12_15);
|
||||
private delegate V128 SoftFallbackSha256SchedulePart1(V128 w0_3, V128 w4_7);
|
||||
private delegate V128 SoftFallbackSha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15);
|
||||
private delegate long SoftFallbackSignedShrImm64(long value, long roundConst, int shift);
|
||||
private delegate V128 SoftFallbackTbl1(V128 vector, int bytes, V128 tb0);
|
||||
private delegate V128 SoftFallbackTbl2(V128 vector, int bytes, V128 tb0, V128 tb1);
|
||||
private delegate V128 SoftFallbackTbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2);
|
||||
private delegate V128 SoftFallbackTbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3);
|
||||
private delegate V128 SoftFallbackTbx1(V128 dest, V128 vector, int bytes, V128 tb0);
|
||||
private delegate V128 SoftFallbackTbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1);
|
||||
private delegate V128 SoftFallbackTbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2);
|
||||
private delegate V128 SoftFallbackTbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3);
|
||||
private delegate ulong SoftFallbackUnsignedShrImm64(ulong value, long roundConst, int shift);
|
||||
|
||||
private delegate float SoftFloat16_32FPConvert(ushort valueBits);
|
||||
|
||||
private delegate double SoftFloat16_64FPConvert(ushort valueBits);
|
||||
|
||||
private delegate float SoftFloat32FPAdd(float value1, float value2);
|
||||
private delegate float SoftFloat32FPAddFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate int SoftFloat32FPCompare(float value1, float value2, bool signalNaNs);
|
||||
private delegate float SoftFloat32FPCompareEQ(float value1, float value2);
|
||||
private delegate float SoftFloat32FPCompareEQFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPCompareGE(float value1, float value2);
|
||||
private delegate float SoftFloat32FPCompareGEFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPCompareGT(float value1, float value2);
|
||||
private delegate float SoftFloat32FPCompareGTFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPCompareLE(float value1, float value2);
|
||||
private delegate float SoftFloat32FPCompareLEFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPCompareLT(float value1, float value2);
|
||||
private delegate float SoftFloat32FPCompareLTFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPDiv(float value1, float value2);
|
||||
private delegate float SoftFloat32FPMax(float value1, float value2);
|
||||
private delegate float SoftFloat32FPMaxFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPMaxNum(float value1, float value2);
|
||||
private delegate float SoftFloat32FPMaxNumFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPMin(float value1, float value2);
|
||||
private delegate float SoftFloat32FPMinFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPMinNum(float value1, float value2);
|
||||
private delegate float SoftFloat32FPMinNumFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPMul(float value1, float value2);
|
||||
private delegate float SoftFloat32FPMulFpscr(float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPMulAdd(float valueA, float value1, float value2);
|
||||
private delegate float SoftFloat32FPMulAddFpscr(float valueA, float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPMulSub(float valueA, float value1, float value2);
|
||||
private delegate float SoftFloat32FPMulSubFpscr(float valueA, float value1, float value2, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPMulX(float value1, float value2);
|
||||
private delegate float SoftFloat32FPNegMulAdd(float valueA, float value1, float value2);
|
||||
private delegate float SoftFloat32FPNegMulSub(float valueA, float value1, float value2);
|
||||
private delegate float SoftFloat32FPRecipEstimate(float value);
|
||||
private delegate float SoftFloat32FPRecipEstimateFpscr(float value, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPRecipStep(float value1, float value2);
|
||||
private delegate float SoftFloat32FPRecipStepFused(float value1, float value2);
|
||||
private delegate float SoftFloat32FPRecpX(float value);
|
||||
private delegate float SoftFloat32FPRSqrtEstimate(float value);
|
||||
private delegate float SoftFloat32FPRSqrtEstimateFpscr(float value, bool standardFpscr);
|
||||
private delegate float SoftFloat32FPRSqrtStep(float value1, float value2);
|
||||
private delegate float SoftFloat32FPRSqrtStepFused(float value1, float value2);
|
||||
private delegate float SoftFloat32FPSqrt(float value);
|
||||
private delegate float SoftFloat32FPSub(float value1, float value2);
|
||||
|
||||
private delegate ushort SoftFloat32_16FPConvert(float value);
|
||||
|
||||
private delegate double SoftFloat64FPAdd(double value1, double value2);
|
||||
private delegate double SoftFloat64FPAddFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate int SoftFloat64FPCompare(double value1, double value2, bool signalNaNs);
|
||||
private delegate double SoftFloat64FPCompareEQ(double value1, double value2);
|
||||
private delegate double SoftFloat64FPCompareEQFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPCompareGE(double value1, double value2);
|
||||
private delegate double SoftFloat64FPCompareGEFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPCompareGT(double value1, double value2);
|
||||
private delegate double SoftFloat64FPCompareGTFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPCompareLE(double value1, double value2);
|
||||
private delegate double SoftFloat64FPCompareLEFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPCompareLT(double value1, double value2);
|
||||
private delegate double SoftFloat64FPCompareLTFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPDiv(double value1, double value2);
|
||||
private delegate double SoftFloat64FPMax(double value1, double value2);
|
||||
private delegate double SoftFloat64FPMaxFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPMaxNum(double value1, double value2);
|
||||
private delegate double SoftFloat64FPMaxNumFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPMin(double value1, double value2);
|
||||
private delegate double SoftFloat64FPMinFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPMinNum(double value1, double value2);
|
||||
private delegate double SoftFloat64FPMinNumFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPMul(double value1, double value2);
|
||||
private delegate double SoftFloat64FPMulFpscr(double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPMulAdd(double valueA, double value1, double value2);
|
||||
private delegate double SoftFloat64FPMulAddFpscr(double valueA, double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPMulSub(double valueA, double value1, double value2);
|
||||
private delegate double SoftFloat64FPMulSubFpscr(double valueA, double value1, double value2, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPMulX(double value1, double value2);
|
||||
private delegate double SoftFloat64FPNegMulAdd(double valueA, double value1, double value2);
|
||||
private delegate double SoftFloat64FPNegMulSub(double valueA, double value1, double value2);
|
||||
private delegate double SoftFloat64FPRecipEstimate(double value);
|
||||
private delegate double SoftFloat64FPRecipEstimateFpscr(double value, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPRecipStep(double value1, double value2);
|
||||
private delegate double SoftFloat64FPRecipStepFused(double value1, double value2);
|
||||
private delegate double SoftFloat64FPRecpX(double value);
|
||||
private delegate double SoftFloat64FPRSqrtEstimate(double value);
|
||||
private delegate double SoftFloat64FPRSqrtEstimateFpscr(double value, bool standardFpscr);
|
||||
private delegate double SoftFloat64FPRSqrtStep(double value1, double value2);
|
||||
private delegate double SoftFloat64FPRSqrtStepFused(double value1, double value2);
|
||||
private delegate double SoftFloat64FPSqrt(double value);
|
||||
private delegate double SoftFloat64FPSub(double value1, double value2);
|
||||
|
||||
private delegate ushort SoftFloat64_16FPConvert(double value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace ARMeilleure.Translation
|
||||
|
||||
public virtual Operand Call(MethodInfo info, params Operand[] callArgs)
|
||||
{
|
||||
nint funcPtr = Delegates.GetDelegateFuncPtr(info);
|
||||
nint funcPtr = info.MethodHandle.GetFunctionPointer();
|
||||
|
||||
OperandType returnType = GetOperandType(info.ReturnType);
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ namespace ARMeilleure.Translation.PTC
|
||||
{
|
||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||
|
||||
private const uint InternalVersion = 6997; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const uint InternalVersion = 6998; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
|
||||
@@ -9,20 +9,12 @@ namespace Ryujinx.Audio.Backends.Dummy
|
||||
{
|
||||
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
|
||||
{
|
||||
private readonly ManualResetEvent _updateRequiredEvent;
|
||||
private readonly ManualResetEvent _pauseEvent;
|
||||
private readonly ManualResetEvent _updateRequiredEvent = new(false);
|
||||
private readonly ManualResetEvent _pauseEvent = new(true);
|
||||
|
||||
public static bool IsSupported => true;
|
||||
|
||||
public float Volume { get; set; }
|
||||
|
||||
public DummyHardwareDeviceDriver()
|
||||
{
|
||||
_updateRequiredEvent = new ManualResetEvent(false);
|
||||
_pauseEvent = new ManualResetEvent(true);
|
||||
|
||||
Volume = 1f;
|
||||
}
|
||||
public float Volume { get; set; } = 1f;
|
||||
|
||||
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
|
||||
{
|
||||
@@ -60,7 +52,7 @@ namespace Ryujinx.Audio.Backends.Dummy
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
|
||||
7
src/Ryujinx.BuildValidationTasks/IValidationTask.cs
Normal file
7
src/Ryujinx.BuildValidationTasks/IValidationTask.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Ryujinx.BuildValidationTasks
|
||||
{
|
||||
public interface IValidationTask
|
||||
{
|
||||
public bool Execute(string projectPath, bool isGitRunner);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.Build.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.Build.Framework;
|
||||
|
||||
namespace Ryujinx.BuildValidationTasks
|
||||
{
|
||||
public class LocaleValidationTask : Task
|
||||
{
|
||||
public override bool Execute()
|
||||
{
|
||||
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
||||
|
||||
if (path.Split(["src"], StringSplitOptions.None).Length == 1)
|
||||
{
|
||||
//i assume that we are in a build directory in the solution dir
|
||||
path = new FileInfo(path).Directory!.Parent!.GetDirectories("src")[0].GetDirectories("Ryujinx")[0].GetDirectories("Assets")[0].GetFiles("locales.json")[0].FullName;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = path.Split(["src"], StringSplitOptions.None)[0];
|
||||
path = new FileInfo(path).Directory!.GetDirectories("src")[0].GetDirectories("Ryujinx")[0].GetDirectories("Assets")[0].GetFiles("locales.json")[0].FullName;
|
||||
}
|
||||
|
||||
string data;
|
||||
|
||||
using (StreamReader sr = new(path))
|
||||
{
|
||||
data = sr.ReadToEnd();
|
||||
}
|
||||
|
||||
LocalesJson json = JsonConvert.DeserializeObject<LocalesJson>(data);
|
||||
|
||||
for (int i = 0; i < json.Locales.Count; i++)
|
||||
{
|
||||
LocalesEntry locale = json.Locales[i];
|
||||
|
||||
foreach (string langCode in json.Languages.Where(it => !locale.Translations.ContainsKey(it)))
|
||||
{
|
||||
locale.Translations.Add(langCode, string.Empty);
|
||||
Log.LogMessage(MessageImportance.High, $"Added '{langCode}' to Locale '{locale.ID}'");
|
||||
}
|
||||
|
||||
locale.Translations = locale.Translations.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||
json.Locales[i] = locale;
|
||||
}
|
||||
|
||||
string jsonString = JsonConvert.SerializeObject(json, Formatting.Indented);
|
||||
|
||||
using (StreamWriter sw = new(path))
|
||||
{
|
||||
sw.Write(jsonString);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct LocalesJson
|
||||
{
|
||||
public List<string> Languages { get; set; }
|
||||
public List<LocalesEntry> Locales { get; set; }
|
||||
}
|
||||
|
||||
struct LocalesEntry
|
||||
{
|
||||
public string ID { get; set; }
|
||||
public Dictionary<string, string> Translations { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
117
src/Ryujinx.BuildValidationTasks/LocalesValidationTask.cs
Normal file
117
src/Ryujinx.BuildValidationTasks/LocalesValidationTask.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Text.Encodings.Web;
|
||||
|
||||
namespace Ryujinx.BuildValidationTasks
|
||||
{
|
||||
public class LocalesValidationTask : IValidationTask
|
||||
{
|
||||
public LocalesValidationTask() { }
|
||||
|
||||
public bool Execute(string projectPath, bool isGitRunner)
|
||||
{
|
||||
Console.WriteLine("Running Locale Validation Task...");
|
||||
|
||||
string path = projectPath + "src/Ryujinx/Assets/locales.json";
|
||||
string data;
|
||||
|
||||
using (StreamReader sr = new(path))
|
||||
{
|
||||
data = sr.ReadToEnd();
|
||||
}
|
||||
|
||||
LocalesJson json;
|
||||
|
||||
if (isGitRunner && data.Contains("\r\n"))
|
||||
throw new FormatException("locales.json is using CRLF line endings! It should be using LF line endings, build locally to fix...");
|
||||
|
||||
try
|
||||
{
|
||||
json = JsonSerializer.Deserialize<LocalesJson>(data);
|
||||
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
throw new JsonException(e.Message); //shorter and easier stacktrace
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool encounteredIssue = false;
|
||||
|
||||
for (int i = 0; i < json.Locales.Count; i++)
|
||||
{
|
||||
LocalesEntry locale = json.Locales[i];
|
||||
|
||||
foreach (string langCode in json.Languages.Where(lang => !locale.Translations.ContainsKey(lang)))
|
||||
{
|
||||
encounteredIssue = true;
|
||||
|
||||
if (!isGitRunner)
|
||||
{
|
||||
locale.Translations.Add(langCode, string.Empty);
|
||||
Console.WriteLine($"Added '{langCode}' to Locale '{locale.ID}'");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Missing '{langCode}' in Locale '{locale.ID}'!");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string langCode in json.Languages.Where(lang => locale.Translations.ContainsKey(lang) && lang != "en_US" && locale.Translations[lang] == locale.Translations["en_US"]))
|
||||
{
|
||||
encounteredIssue = true;
|
||||
|
||||
if (!isGitRunner)
|
||||
{
|
||||
locale.Translations[langCode] = string.Empty;
|
||||
Console.WriteLine($"Lanugage '{langCode}' is a duplicate of en_US in Locale '{locale.ID}'! Resetting it...");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Lanugage '{langCode}' is a duplicate of en_US in Locale '{locale.ID}'!");
|
||||
}
|
||||
}
|
||||
|
||||
locale.Translations = locale.Translations.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||
json.Locales[i] = locale;
|
||||
}
|
||||
|
||||
if (isGitRunner && encounteredIssue)
|
||||
throw new JsonException("1 or more locales are invalid!");
|
||||
|
||||
JsonSerializerOptions jsonOptions = new JsonSerializerOptions()
|
||||
{
|
||||
WriteIndented = true,
|
||||
NewLine = "\n",
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
};
|
||||
|
||||
string jsonString = JsonSerializer.Serialize(json, jsonOptions);
|
||||
|
||||
using (StreamWriter sw = new(path))
|
||||
{
|
||||
sw.Write(jsonString);
|
||||
}
|
||||
|
||||
Console.WriteLine("Finished Locale Validation Task!");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct LocalesJson
|
||||
{
|
||||
public List<string> Languages { get; set; }
|
||||
public List<LocalesEntry> Locales { get; set; }
|
||||
}
|
||||
|
||||
struct LocalesEntry
|
||||
{
|
||||
public string ID { get; set; }
|
||||
public Dictionary<string, string> Translations { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
37
src/Ryujinx.BuildValidationTasks/Program.cs
Normal file
37
src/Ryujinx.BuildValidationTasks/Program.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.BuildValidationTasks
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// Display the number of command line arguments.
|
||||
if (args.Length == 0)
|
||||
throw new ArgumentException("Error: too few arguments!");
|
||||
|
||||
string path = args[0];
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
throw new ArgumentException("Error: path is null or empty!");
|
||||
|
||||
if (!Path.Exists(path))
|
||||
throw new FileLoadException($"path {{{path}}} does not exist!");
|
||||
|
||||
path = Path.GetFullPath(path);
|
||||
|
||||
if (!Directory.GetDirectories(path).Contains($"{path}src"))
|
||||
throw new FileLoadException($"path {{{path}}} is not a valid ryujinx project!");
|
||||
|
||||
bool isGitRunner = path.Contains("runner") || path.Contains("D:\\a\\Ryujinx\\Ryujinx");
|
||||
if (isGitRunner)
|
||||
Console.WriteLine("Is Git Runner!");
|
||||
|
||||
// Run tasks
|
||||
// Pass extra info needed in the task constructors
|
||||
new LocalesValidationTask().Execute(path, isGitRunner);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" />
|
||||
<PackageReference Include="Newtonsoft.Json" />
|
||||
</ItemGroup>
|
||||
<Target Name="PostBuildTarget" AfterTargets="AfterBuild">
|
||||
<Message Text="Running Validation Project" Importance="high" />
|
||||
|
||||
<UsingTask TaskName="Ryujinx.BuildValidationTasks.LocaleValidationTask" TaskFactory="TaskHostFactory" AssemblyFile="$(OutDir)Ryujinx.BuildValidationTasks.dll" />
|
||||
|
||||
<Target Name="LocalesJsonValidation" AfterTargets="AfterRebuild">
|
||||
<LocaleValidationTask />
|
||||
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
|
||||
Command="dotnet Ryujinx.BuildValidationTasks.dll "$(ProjectDir)..\..\\""
|
||||
ConsoleToMsBuild="true"
|
||||
Condition="'$(RuntimeIdentifier)' == ''"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -35,6 +35,8 @@ namespace Ryujinx.Common.Configuration
|
||||
#pragma warning restore IDE0055
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static float ToFloatY(this AspectRatio aspectRatio)
|
||||
{
|
||||
|
||||
60
src/Ryujinx.Common/Configuration/DirtyHack.cs
Normal file
60
src/Ryujinx.Common/Configuration/DirtyHack.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using Gommon;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[Flags]
|
||||
public enum DirtyHack : byte
|
||||
{
|
||||
Xc2MenuSoftlockFix = 1,
|
||||
ShaderTranslationDelay = 2
|
||||
}
|
||||
|
||||
public readonly struct EnabledDirtyHack(DirtyHack hack, int value)
|
||||
{
|
||||
public DirtyHack Hack => hack;
|
||||
public int Value => value;
|
||||
|
||||
|
||||
|
||||
public ulong Pack() => Raw.PackBitFields(PackedFormat);
|
||||
|
||||
public static EnabledDirtyHack Unpack(ulong packedHack)
|
||||
{
|
||||
var unpackedFields = packedHack.UnpackBitFields(PackedFormat);
|
||||
if (unpackedFields is not [var hack, var value])
|
||||
throw new Exception("The unpack operation on the integer resulted in an invalid unpacked result.");
|
||||
|
||||
return new EnabledDirtyHack((DirtyHack)hack, (int)value);
|
||||
}
|
||||
|
||||
private uint[] Raw => [(uint)Hack, (uint)Value.CoerceAtLeast(0)];
|
||||
|
||||
public static readonly byte[] PackedFormat = [8, 32];
|
||||
}
|
||||
|
||||
public class DirtyHacks : Dictionary<DirtyHack, int>
|
||||
{
|
||||
public DirtyHacks(IEnumerable<EnabledDirtyHack> hacks)
|
||||
=> hacks.ForEach(edh => Add(edh.Hack, edh.Value));
|
||||
|
||||
public DirtyHacks(ulong[] packedHacks) : this(packedHacks.Select(EnabledDirtyHack.Unpack)) {}
|
||||
|
||||
public ulong[] PackEntries()
|
||||
=> Entries.Select(it => it.Pack()).ToArray();
|
||||
|
||||
public EnabledDirtyHack[] Entries
|
||||
=> this
|
||||
.Select(it => new EnabledDirtyHack(it.Key, it.Value))
|
||||
.ToArray();
|
||||
|
||||
public static implicit operator DirtyHacks(EnabledDirtyHack[] hacks) => new(hacks);
|
||||
public static implicit operator DirtyHacks(ulong[] packedHacks) => new(packedHacks);
|
||||
|
||||
public new int this[DirtyHack hack] => TryGetValue(hack, out var value) ? value : -1;
|
||||
|
||||
public bool IsEnabled(DirtyHack hack) => ContainsKey(hack);
|
||||
}
|
||||
}
|
||||
@@ -78,5 +78,10 @@ namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
/// Controller Rumble Settings
|
||||
/// </summary>
|
||||
public RumbleConfigController Rumble { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controller LED Settings
|
||||
/// </summary>
|
||||
public LedConfigController Led { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
{
|
||||
public class LedConfigController
|
||||
{
|
||||
/// <summary>
|
||||
/// Enable LED color changing by the emulator
|
||||
/// </summary>
|
||||
public bool EnableLed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ignores the color and disables the LED entirely.
|
||||
/// </summary>
|
||||
public bool TurnOffLed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ignores the color and uses the rainbow color functionality for the LED.
|
||||
/// </summary>
|
||||
public bool UseRainbow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Packed RGB int of the color
|
||||
/// </summary>
|
||||
public uint LedColor { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,6 @@ namespace Ryujinx.Common.Configuration
|
||||
Bilinear,
|
||||
Nearest,
|
||||
Fsr,
|
||||
Area,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ namespace Ryujinx.Common
|
||||
public static class StreamExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes a <see cref="ReadOnlySpan{int}" /> to this stream.
|
||||
/// Writes an int span to this stream.
|
||||
///
|
||||
/// This default implementation converts each buffer value to a stack-allocated
|
||||
/// byte array, then writes it to the Stream using <cref="System.Stream.Write(byte[])" />.
|
||||
/// byte array, then writes it to the Stream using <see cref="Stream.Write(ReadOnlySpan{byte})" />.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to be written to</param>
|
||||
/// <param name="buffer">The buffer of values to be written</param>
|
||||
|
||||
@@ -3,7 +3,7 @@ using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Ryujinx.UI.Common.Helper
|
||||
namespace Ryujinx.Common.Helper
|
||||
{
|
||||
public static partial class ConsoleHelper
|
||||
{
|
||||
@@ -8,7 +8,7 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Ryujinx.UI.Common.Helper
|
||||
namespace Ryujinx.Common.Helper
|
||||
{
|
||||
public static partial class FileAssociationHelper
|
||||
{
|
||||
@@ -132,7 +132,7 @@ namespace Ryujinx.UI.Common.Helper
|
||||
|
||||
if (uninstall)
|
||||
{
|
||||
// If the types don't already exist, there's nothing to do and we can call this operation successful.
|
||||
// If the types don't already exist, there's nothing to do, and we can call this operation successful.
|
||||
if (!AreMimeTypesRegisteredWindows())
|
||||
{
|
||||
return true;
|
||||
@@ -3,7 +3,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Ryujinx.UI.Common.Helper
|
||||
namespace Ryujinx.Common.Helper
|
||||
{
|
||||
[SupportedOSPlatform("linux")]
|
||||
public static class LinuxHelper
|
||||
@@ -2,7 +2,7 @@ using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Ryujinx.UI.Common.Helper
|
||||
namespace Ryujinx.Common.Helper
|
||||
{
|
||||
[SupportedOSPlatform("macos")]
|
||||
public static partial class ObjectiveC
|
||||
@@ -5,7 +5,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.UI.Common.Helper
|
||||
namespace Ryujinx.Common.Helper
|
||||
{
|
||||
public static partial class OpenHelper
|
||||
{
|
||||
23
src/Ryujinx.Common/Helpers/RunningPlatform.cs
Normal file
23
src/Ryujinx.Common/Helpers/RunningPlatform.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace Ryujinx.Common.Helper
|
||||
{
|
||||
public static class RunningPlatform
|
||||
{
|
||||
public static bool IsMacOS => OperatingSystem.IsMacOS();
|
||||
public static bool IsWindows => OperatingSystem.IsWindows();
|
||||
public static bool IsLinux => OperatingSystem.IsLinux();
|
||||
|
||||
public static bool IsIntelMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.X64;
|
||||
public static bool IsArmMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.Arm64;
|
||||
|
||||
public static bool IsX64Windows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.X64);
|
||||
public static bool IsArmWindows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
|
||||
|
||||
public static bool IsX64Linux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.X64);
|
||||
public static bool IsArmLinux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
@@ -157,21 +158,16 @@ namespace Ryujinx.Common.Logging
|
||||
_time.Restart();
|
||||
}
|
||||
|
||||
private static ILogTarget GetTarget(string targetName)
|
||||
{
|
||||
foreach (var target in _logTargets)
|
||||
{
|
||||
if (target.Name.Equals(targetName))
|
||||
{
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private static ILogTarget GetTarget(string targetName)
|
||||
=> _logTargets.FirstOrDefault(target => target.Name.Equals(targetName));
|
||||
|
||||
public static void AddTarget(ILogTarget target)
|
||||
{
|
||||
if (_logTargets.Any(t => t.Name == target.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_logTargets.Add(target);
|
||||
|
||||
Updated += target.Log;
|
||||
|
||||
@@ -27,11 +27,7 @@ namespace Ryujinx.Common.Logging.Targets
|
||||
|
||||
private readonly int _overflowTimeout;
|
||||
|
||||
string ILogTarget.Name { get => _target.Name; }
|
||||
|
||||
public AsyncLogTargetWrapper(ILogTarget target)
|
||||
: this(target, -1)
|
||||
{ }
|
||||
string ILogTarget.Name => _target.Name;
|
||||
|
||||
public AsyncLogTargetWrapper(ILogTarget target, int queueLimit = -1, AsyncLogTargetOverflowAction overflowAction = AsyncLogTargetOverflowAction.Block)
|
||||
{
|
||||
|
||||
@@ -53,6 +53,9 @@ namespace Ryujinx.Common
|
||||
{
|
||||
public static void LogValueChange<T>(LogClass logClass, ReactiveEventArgs<T> eventArgs, string valueName)
|
||||
{
|
||||
if (eventArgs.AreValuesEqual)
|
||||
return;
|
||||
|
||||
string message = string.Create(CultureInfo.InvariantCulture, $"{valueName} set to: {eventArgs.NewValue}");
|
||||
|
||||
Logger.Info?.Print(logClass, message);
|
||||
@@ -65,5 +68,22 @@ namespace Ryujinx.Common
|
||||
{
|
||||
public T OldValue { get; } = oldValue;
|
||||
public T NewValue { get; } = newValue;
|
||||
|
||||
public bool AreValuesEqual
|
||||
{
|
||||
get
|
||||
{
|
||||
if (OldValue == null && NewValue == null)
|
||||
return true;
|
||||
|
||||
if (OldValue == null && NewValue != null)
|
||||
return false;
|
||||
|
||||
if (OldValue != null && NewValue == null)
|
||||
return false;
|
||||
|
||||
return OldValue!.Equals(NewValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
src/Ryujinx.Common/RyujinxException.cs
Normal file
10
src/Ryujinx.Common/RyujinxException.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Common
|
||||
{
|
||||
public class RyujinxException : Exception
|
||||
{
|
||||
public RyujinxException(string message) : base(message)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Gommon;
|
||||
using Gommon;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Helper;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -8,17 +9,20 @@ namespace Ryujinx.Common
|
||||
{
|
||||
public static class TitleIDs
|
||||
{
|
||||
public static ReactiveObject<Optional<string>> CurrentApplication { get; } = new();
|
||||
|
||||
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
|
||||
{
|
||||
switch (currentBackend)
|
||||
{
|
||||
case GraphicsBackend.Metal when !OperatingSystem.IsMacOS():
|
||||
case GraphicsBackend.OpenGl when OperatingSystem.IsMacOS():
|
||||
return GraphicsBackend.Vulkan;
|
||||
case GraphicsBackend.Vulkan or GraphicsBackend.OpenGl or GraphicsBackend.Metal:
|
||||
return currentBackend;
|
||||
}
|
||||
|
||||
if (!(OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture is Architecture.Arm64))
|
||||
if (!RunningPlatform.IsArmMac)
|
||||
return GraphicsBackend.Vulkan;
|
||||
|
||||
return GreatMetalTitles.ContainsIgnoreCase(titleId) ? GraphicsBackend.Metal : GraphicsBackend.Vulkan;
|
||||
@@ -26,16 +30,28 @@ namespace Ryujinx.Common
|
||||
|
||||
public static readonly string[] GreatMetalTitles =
|
||||
[
|
||||
"01006f8002326000", // Animal Crossings: New Horizons
|
||||
"01009bf0072d4000", // Captain Toad: Treasure Tracker
|
||||
"010076f0049a2000", // Bayonetta
|
||||
"0100a5c00d162000", // Cuphead
|
||||
"010023800d64a000", // Deltarune
|
||||
"01003a30012c0000", // LEGO City Undercover
|
||||
"010028600EBDA000", // Mario 3D World
|
||||
"0100152000022000", // Mario Kart 8 Deluxe
|
||||
"01005CA01580E000", // Persona 5
|
||||
"010075a016a3a000", // Persona 4 Arena Ultimax
|
||||
"0100187003A36000", // Pokémon: Let's Go, Eevee!
|
||||
"010003f003a34000", // Pokémon: Let's Go, Pikachu!
|
||||
"01008C0016544000", // Sea of Stars
|
||||
"01006A800016E000", // Smash Ultimate
|
||||
"0100000000010000", // Super Mario Odyessy
|
||||
"01006bb00c6f0000", // The Legend of Zelda: Link's Awakening
|
||||
|
||||
// These ones have small issues, but those happen on Vulkan as well:
|
||||
"01006f8002326000", // Animal Crossings: New Horizons
|
||||
"01009bf0072d4000", // Captain Toad: Treasure Tracker
|
||||
"01009510001ca000", // Fast RMX
|
||||
"01005CA01580E000", // Persona 5 Royale
|
||||
"0100000000010000", // Super Mario Odyssey
|
||||
|
||||
//Isaac claims it has a issue in level 2, but I am not able to replicate it on my M3. More testing would be appreciated:
|
||||
"010015100b514000", // Super Mario Bros. Wonder
|
||||
];
|
||||
|
||||
public static string GetDiscordGameAsset(string titleId)
|
||||
@@ -43,93 +59,117 @@ namespace Ryujinx.Common
|
||||
|
||||
public static readonly string[] DiscordGameAssetKeys =
|
||||
[
|
||||
"010055d009f78000", // Fire Emblem: Three Houses
|
||||
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
||||
//All games are in Alphabetical order by Game name.
|
||||
|
||||
//Dragon Quest Franchise
|
||||
"010008900705c000", // Dragon Quest Builders
|
||||
"010042000a986000", // Dragon Quest Builders 2
|
||||
|
||||
//Fire Emblem Franchise
|
||||
"0100a6301214e000", // Fire Emblem Engage
|
||||
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
||||
"010055d009f78000", // Fire Emblem: Three Houses
|
||||
"0100f15003e64000", // Fire Emblem Warriors
|
||||
"010071f0143ea000", // Fire Emblem Warriors: Three Hopes
|
||||
|
||||
"01007e3006dda000", // Kirby Star Allies
|
||||
|
||||
//Kirby Franchise
|
||||
"01004d300c5ae000", // Kirby and the Forgotten Land
|
||||
"01006b601380e000", // Kirby's Return to Dream Land Deluxe
|
||||
"01003fb00c5a8000", // Super Kirby Clash
|
||||
"0100227010460000", // Kirby Fighters 2
|
||||
"0100a8e016236000", // Kirby's Dream Buffet
|
||||
|
||||
"0100227010460000", // Kirby Fighters 2
|
||||
"01006b601380e000", // Kirby's Return to Dream Land Deluxe
|
||||
"01007e3006dda000", // Kirby Star Allies
|
||||
"01003fb00c5a8000", // Super Kirby Clash
|
||||
|
||||
|
||||
//The Zelda Franchise
|
||||
"01000b900d8b0000", // Cadence of Hyrule
|
||||
"0100ae00096ea000", // Hyrule Warriors: Definitive Edition
|
||||
"01002b00111a2000", // Hyrule Warriors: Age of Calamity
|
||||
"01007ef00011e000", // The Legend of Zelda: Breath of the Wild
|
||||
"01006bb00c6f0000", // The Legend of Zelda: Link's Awakening
|
||||
"01002da013484000", // The Legend of Zelda: Skyward Sword HD
|
||||
"0100f2c0115b6000", // The Legend of Zelda: Tears of the Kingdom
|
||||
"01008cf01baac000", // The Legend of Zelda: Echoes of Wisdom
|
||||
"01000b900d8b0000", // Cadence of Hyrule
|
||||
"0100ae00096ea000", // Hyrule Warriors: Definitive Edition
|
||||
"01002b00111a2000", // Hyrule Warriors: Age of Calamity
|
||||
|
||||
|
||||
//Luigi Franchise
|
||||
"010048701995e000", // Luigi's Mansion 2 HD
|
||||
"0100dca0064a6000", // Luigi's Mansion 3
|
||||
|
||||
//Metroid Franchise
|
||||
"010093801237c000", // Metroid Dread
|
||||
"010012101468c000", // Metroid Prime Remastered
|
||||
|
||||
"0100000000010000", // SUPER MARIO ODYSSEY
|
||||
"0100ea80032ea000", // Super Mario Bros. U Deluxe
|
||||
"01009b90006dc000", // Super Mario Maker 2
|
||||
"010049900f546000", // Super Mario 3D All-Stars
|
||||
"010049900F546001", // ^ 64
|
||||
"010049900F546002", // ^ Sunshine
|
||||
"010049900F546003", // ^ Galaxy
|
||||
"010028600ebda000", // Super Mario 3D World + Bowser's Fury
|
||||
"010015100b514000", // Super Mario Bros. Wonder
|
||||
"0100152000022000", // Mario Kart 8 Deluxe
|
||||
"010036b0034e4000", // Super Mario Party
|
||||
"01006fe013472000", // Mario Party Superstars
|
||||
"0100965017338000", // Super Mario Party Jamboree
|
||||
//Monster Hunter Franchise
|
||||
"0100770008dd8000", // Monster Hunter Generations Ultimate
|
||||
"0100b04011742000", // Monster Hunter Rise
|
||||
|
||||
//Mario Franchise
|
||||
"01006d0017f7a000", // Mario & Luigi: Brothership
|
||||
"010003000e146000", // Mario & Sonic at the Olympic Games Tokyo 2020
|
||||
"010067300059a000", // Mario + Rabbids: Kingdom Battle
|
||||
"0100317013770000", // Mario + Rabbids: Sparks of Hope
|
||||
"0100c9c00e25c000", // Mario Golf: Super Rush
|
||||
"0100152000022000", // Mario Kart 8 Deluxe
|
||||
"01006fe013472000", // Mario Party Superstars
|
||||
"010019401051c000", // Mario Strikers: Battle League
|
||||
"0100bde00862a000", // Mario Tennis Aces
|
||||
"0100b99019412000", // Mario vs. Donkey Kong
|
||||
"010049900f546000", // Super Mario 3D All-Stars
|
||||
"010028600ebda000", // Super Mario 3D World + Bowser's Fury
|
||||
"010049900F546001", // Super Mario 64
|
||||
"0100ea80032ea000", // Super Mario Bros. U Deluxe
|
||||
"010015100b514000", // Super Mario Bros. Wonder
|
||||
"010049900F546003", // Super Mario Galaxy
|
||||
"01009b90006dc000", // Super Mario Maker 2
|
||||
"0100000000010000", // SUPER MARIO ODYSSEY
|
||||
"010036b0034e4000", // Super Mario Party
|
||||
"0100965017338000", // Super Mario Party Jamboree
|
||||
"0100bc0018138000", // Super Mario RPG
|
||||
"010049900F546002", // Super Mario Sunshine
|
||||
"0100a3900c3e2000", // Paper Mario: The Origami King
|
||||
"0100ecd018ebe000", // Paper Mario: The Thousand-Year Door
|
||||
"0100bc0018138000", // Super Mario RPG
|
||||
"0100bde00862a000", // Mario Tennis Aces
|
||||
"0100c9c00e25c000", // Mario Golf: Super Rush
|
||||
"010019401051c000", // Mario Strikers: Battle League
|
||||
"010003000e146000", // Mario & Sonic at the Olympic Games Tokyo 2020
|
||||
"0100b99019412000", // Mario vs. Donkey Kong
|
||||
|
||||
//Pikmin Franchise
|
||||
"0100aa80194b0000", // Pikmin 1
|
||||
"0100d680194b2000", // Pikmin 2
|
||||
"0100f4c009322000", // Pikmin 3 Deluxe
|
||||
"0100b7c00933a000", // Pikmin 4
|
||||
|
||||
"010003f003a34000", // Pokémon: Let's Go Pikachu!
|
||||
"0100187003a36000", // Pokémon: Let's Go Eevee!
|
||||
"0100abf008968000", // Pokémon Sword
|
||||
"01008db008c2c000", // Pokémon Shield
|
||||
//The Pokémon Franchise
|
||||
"0100f4300bf2c000", // New Pokémon Snap
|
||||
"0100000011d90000", // Pokémon Brilliant Diamond
|
||||
"010018e011d92000", // Pokémon Shining Pearl
|
||||
"01001f5010dfa000", // Pokémon Legends: Arceus
|
||||
"01003d200baa2000", // Pokémon Mystery Dungeon - Rescue Team DX
|
||||
"0100a3d008c5c000", // Pokémon Scarlet
|
||||
"01008db008c2c000", // Pokémon Shield
|
||||
"010018e011d92000", // Pokémon Shining Pearl
|
||||
"0100abf008968000", // Pokémon Sword
|
||||
"01008f6008c5e000", // Pokémon Violet
|
||||
"0100b3f000be2000", // Pokkén Tournament DX
|
||||
"0100f4300bf2c000", // New Pokémon Snap
|
||||
"0100187003a36000", // Pokémon: Let's Go Eevee!
|
||||
"010003f003a34000", // Pokémon: Let's Go Pikachu!
|
||||
|
||||
"01003bc0000a0000", // Splatoon 2 (US)
|
||||
//Splatoon Franchise
|
||||
"0100f8f0000a2000", // Splatoon 2 (EU)
|
||||
"01003c700009c000", // Splatoon 2 (JP)
|
||||
"01003bc0000a0000", // Splatoon 2 (US)
|
||||
"0100c2500fc20000", // Splatoon 3
|
||||
"0100ba0018500000", // Splatoon 3: Splatfest World Premiere
|
||||
|
||||
"010040600c5ce000", // Tetris 99
|
||||
"0100277011f1a000", // Super Mario Bros. 35
|
||||
"0100ad9012510000", // PAC-MAN 99
|
||||
//NSO Membership games
|
||||
"0100ccf019c8c000", // F-ZERO 99
|
||||
"0100d870045b6000", // NES - Nintendo Switch Online
|
||||
"01008d300c50c000", // SNES - Nintendo Switch Online
|
||||
"0100c9a00ece6000", // N64 - Nintendo Switch Online
|
||||
"0100e0601c632000", // N64 - Nintendo Switch Online 18+
|
||||
"0100c62011050000", // GB - Nintendo Switch Online
|
||||
"010012f017576000", // GBA - Nintendo Switch Online
|
||||
"0100c9a00ece6000", // N64 - Nintendo Switch Online
|
||||
"0100e0601c632000", // N64 - Nintendo Switch Online 18+
|
||||
"0100d870045b6000", // NES - Nintendo Switch Online
|
||||
"0100ad9012510000", // PAC-MAN 99
|
||||
"010040600c5ce000", // Tetris 99
|
||||
"01008d300c50c000", // SNES - Nintendo Switch Online
|
||||
"0100277011f1a000", // Super Mario Bros. 35
|
||||
|
||||
//Misc Nintendo 1st party games
|
||||
"01000320000cc000", // 1-2 Switch
|
||||
"0100300012f2a000", // Advance Wars 1+2: Re-Boot Camp
|
||||
"01006f8002326000", // Animal Crossing: New Horizons
|
||||
@@ -144,32 +184,44 @@ namespace Ryujinx.Common
|
||||
"01006a800016e000", // Super Smash Bros. Ultimate
|
||||
"0100a9400c9c2000", // Tokyo Mirage Sessions #FE Encore
|
||||
|
||||
//Bayonetta Franchise
|
||||
"010076f0049a2000", // Bayonetta
|
||||
"01007960049a0000", // Bayonetta 2
|
||||
"01004a4010fea000", // Bayonetta 3
|
||||
"0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon
|
||||
|
||||
//Persona Franchise
|
||||
"0100dcd01525a000", // Persona 3 Portable
|
||||
"010062b01525c000", // Persona 4 Golden
|
||||
"010075a016a3a000", // Persona 4 Arena Ultimax
|
||||
"010062b01525c000", // Persona 4 Golden
|
||||
"01005ca01580e000", // Persona 5 Royal
|
||||
"0100801011c3e000", // Persona 5 Strikers
|
||||
"010087701b092000", // Persona 5 Tactica
|
||||
|
||||
"01009aa000faa000", // Sonic Mania
|
||||
//Sonic Franchise
|
||||
"01004ad014bf0000", // Sonic Frontiers
|
||||
"01009aa000faa000", // Sonic Mania
|
||||
"01005ea01c0fc000", // SONIC X SHADOW GENERATIONS
|
||||
"01005ea01c0fc001", // ^
|
||||
|
||||
//Xenoblade Franchise
|
||||
"0100ff500e34a000", // Xenoblade Chronicles - Definitive Edition
|
||||
"0100e95004038000", // Xenoblade Chronicles 2
|
||||
"010074f013262000", // Xenoblade Chronicles 3
|
||||
|
||||
//Misc Games
|
||||
"010056e00853a000", // A Hat in Time
|
||||
"0100fd1014726000", // Baldurs Gate: Dark Alliance
|
||||
"0100dbf01000a000", // Burnout Paradise Remastered
|
||||
"0100744001588000", // Cars 3: Driven to Win
|
||||
"0100b41013c82000", // Cruis'n Blast
|
||||
"010085900337e000", // Death Squared
|
||||
"01001b300b9be000", // Diablo III: Eternal Collection
|
||||
"01008c8012920000", // Dying Light Platinum Edition
|
||||
"01001cc01b2d4000", // Goat Simulator 3
|
||||
"01003620068ea000", // Hand of Fate 2
|
||||
"010085500130a000", // Lego City: Undercover
|
||||
"010073c01af34000", // LEGO Horizon Adventures
|
||||
"0100770008dd8000", // Monster Hunter Generations Ultimate
|
||||
"0100b04011742000", // Monster Hunter Rise
|
||||
"0100853015e86000", // No Man's Sky
|
||||
"01007bb017812000", // Portal
|
||||
"0100abd01785c000", // Portal 2
|
||||
@@ -185,6 +237,8 @@ namespace Ryujinx.Common
|
||||
"01000a10041ea000", // The Elder Scrolls V: Skyrim
|
||||
"010057a01e4d4000", // TSUKIHIME -A piece of blue glass moon-
|
||||
"010080b00ad66000", // Undertale
|
||||
"010069401adb8000", // Unicorn Overlord
|
||||
"0100534009ff2000", // Yonder - The cloud catcher chronicles
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Ryujinx.UI.Common
|
||||
namespace Ryujinx.Common.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Represent a common error that could be reported to the user by the emulator.
|
||||
@@ -40,5 +40,35 @@ namespace Ryujinx.Common
|
||||
|
||||
return (value >> 32) | (value << 32);
|
||||
}
|
||||
|
||||
// Never actually written bit packing logic before, so I looked it up.
|
||||
// This code is from https://gist.github.com/Alan-FGR/04938e93e2bffdf5802ceb218a37c195
|
||||
|
||||
public static ulong PackBitFields(this uint[] values, byte[] bitFields)
|
||||
{
|
||||
ulong retVal = values[0]; //we set the first value right away
|
||||
for (int f = 1; f < values.Length; f++)
|
||||
{
|
||||
retVal <<= bitFields[f]; // we shift the previous value
|
||||
retVal += values[f];// and add our current value
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static uint[] UnpackBitFields(this ulong packed, byte[] bitFields)
|
||||
{
|
||||
int fields = bitFields.Length - 1; // number of fields to unpack
|
||||
uint[] retArr = new uint[fields + 1]; // init return array
|
||||
int curPos = 0; // current field bit position (start)
|
||||
int lastEnd; // position where last field ended
|
||||
for (int f = fields; f >= 0; f--) // loop from last
|
||||
{
|
||||
lastEnd = curPos; // we store where the last value ended
|
||||
curPos += bitFields[f]; // we get where the current value starts
|
||||
int leftShift = 64 - curPos; // we figure how much left shift we gotta apply for the other numbers to overflow into oblivion
|
||||
retArr[f] = (uint)((packed << leftShift) >> leftShift + lastEnd); // we do magic
|
||||
}
|
||||
return retArr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
110
src/Ryujinx.Common/Utilities/Rainbow.cs
Normal file
110
src/Ryujinx.Common/Utilities/Rainbow.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using Gommon;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Common.Utilities
|
||||
{
|
||||
public static class Rainbow
|
||||
{
|
||||
public static bool CyclingEnabled { get; set; }
|
||||
|
||||
public static void Enable()
|
||||
{
|
||||
if (!CyclingEnabled)
|
||||
{
|
||||
CyclingEnabled = true;
|
||||
Executor.ExecuteBackgroundAsync(async () =>
|
||||
{
|
||||
while (CyclingEnabled)
|
||||
{
|
||||
await Task.Delay(15);
|
||||
Tick();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void Disable()
|
||||
{
|
||||
CyclingEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
public static float Speed { get; set; } = 1;
|
||||
|
||||
public static Color Color { get; private set; } = Color.Blue;
|
||||
|
||||
public static void Tick()
|
||||
{
|
||||
Color = HsbToRgb((Color.GetHue() + Speed) / 360);
|
||||
|
||||
UpdatedHandler.Call(Color.ToArgb());
|
||||
}
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
Color = Color.Blue;
|
||||
UpdatedHandler.Clear();
|
||||
}
|
||||
|
||||
public static event Action<int> Updated
|
||||
{
|
||||
add => UpdatedHandler.Add(value);
|
||||
remove => UpdatedHandler.Remove(value);
|
||||
}
|
||||
|
||||
internal static Event<int> UpdatedHandler = new();
|
||||
|
||||
private static Color HsbToRgb(float hue, float saturation = 1, float brightness = 1)
|
||||
{
|
||||
int r = 0, g = 0, b = 0;
|
||||
if (saturation == 0)
|
||||
{
|
||||
r = g = b = (int)(brightness * 255.0f + 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
float h = (hue - (float)Math.Floor(hue)) * 6.0f;
|
||||
float f = h - (float)Math.Floor(h);
|
||||
float p = brightness * (1.0f - saturation);
|
||||
float q = brightness * (1.0f - saturation * f);
|
||||
float t = brightness * (1.0f - (saturation * (1.0f - f)));
|
||||
switch ((int)h)
|
||||
{
|
||||
case 0:
|
||||
r = (int)(brightness * 255.0f + 0.5f);
|
||||
g = (int)(t * 255.0f + 0.5f);
|
||||
b = (int)(p * 255.0f + 0.5f);
|
||||
break;
|
||||
case 1:
|
||||
r = (int)(q * 255.0f + 0.5f);
|
||||
g = (int)(brightness * 255.0f + 0.5f);
|
||||
b = (int)(p * 255.0f + 0.5f);
|
||||
break;
|
||||
case 2:
|
||||
r = (int)(p * 255.0f + 0.5f);
|
||||
g = (int)(brightness * 255.0f + 0.5f);
|
||||
b = (int)(t * 255.0f + 0.5f);
|
||||
break;
|
||||
case 3:
|
||||
r = (int)(p * 255.0f + 0.5f);
|
||||
g = (int)(q * 255.0f + 0.5f);
|
||||
b = (int)(brightness * 255.0f + 0.5f);
|
||||
break;
|
||||
case 4:
|
||||
r = (int)(t * 255.0f + 0.5f);
|
||||
g = (int)(p * 255.0f + 0.5f);
|
||||
b = (int)(brightness * 255.0f + 0.5f);
|
||||
break;
|
||||
case 5:
|
||||
r = (int)(brightness * 255.0f + 0.5f);
|
||||
g = (int)(p * 255.0f + 0.5f);
|
||||
b = (int)(q * 255.0f + 0.5f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Color.FromArgb(Convert.ToByte(255), Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace Ryujinx.Graphics.GAL
|
||||
{
|
||||
public enum AntiAliasing
|
||||
{
|
||||
None,
|
||||
Fxaa,
|
||||
SmaaLow,
|
||||
SmaaMedium,
|
||||
SmaaHigh,
|
||||
SmaaUltra,
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Ryujinx.Graphics.GAL
|
||||
{
|
||||
public enum ScalingFilter
|
||||
{
|
||||
Bilinear,
|
||||
Nearest,
|
||||
Fsr,
|
||||
Area,
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Graphics.Device;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
||||
@@ -90,6 +91,13 @@ namespace Ryujinx.Graphics.Gpu
|
||||
/// Support buffer updater.
|
||||
/// </summary>
|
||||
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Enabled dirty hacks.
|
||||
/// Used for workarounds to emulator bugs we can't fix/don't know how to fix yet.
|
||||
/// </summary>
|
||||
internal DirtyHacks DirtyHacks { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Host hardware capabilities.
|
||||
@@ -113,7 +121,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||
/// Creates a new instance of the GPU emulation context.
|
||||
/// </summary>
|
||||
/// <param name="renderer">Host renderer</param>
|
||||
public GpuContext(IRenderer renderer)
|
||||
public GpuContext(IRenderer renderer, DirtyHacks hacks)
|
||||
{
|
||||
Renderer = renderer;
|
||||
|
||||
@@ -136,6 +144,8 @@ namespace Ryujinx.Graphics.Gpu
|
||||
|
||||
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
||||
|
||||
DirtyHacks = hacks;
|
||||
|
||||
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||
/// Enables or disables high-level emulation of common GPU Macro code.
|
||||
/// </summary>
|
||||
public static bool EnableMacroHLE = true;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Title id of the current running game.
|
||||
/// Used by the shader cache.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
@@ -366,6 +367,9 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_context.Capabilities.Api == TargetApi.Metal && _context.DirtyHacks.IsEnabled(DirtyHack.ShaderTranslationDelay))
|
||||
Thread.Sleep(_context.DirtyHacks[DirtyHack.ShaderTranslationDelay]);
|
||||
|
||||
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
||||
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
@@ -117,7 +118,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||
private static string GetDiskCachePath()
|
||||
{
|
||||
return GraphicsConfig.EnableShaderCache && GraphicsConfig.TitleId != null
|
||||
? Path.Combine(AppDataManager.GamesDirPath, GraphicsConfig.TitleId, "cache", "shader")
|
||||
? Path.Combine(AppDataManager.GamesDirPath, GraphicsConfig.TitleId.ToLower(), "cache", "shader")
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,10 @@ using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Metal.Effects;
|
||||
using Ryujinx.Graphics.Metal.SharpMetalExtensions;
|
||||
using SharpMetal.ObjectiveCCore;
|
||||
using SharpMetal.QuartzCore;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
using AntiAliasing = Ryujinx.Graphics.GAL.AntiAliasing;
|
||||
using ScalingFilter = Ryujinx.Graphics.GAL.ScalingFilter;
|
||||
|
||||
namespace Ryujinx.Graphics.Metal
|
||||
{
|
||||
@@ -25,13 +22,15 @@ namespace Ryujinx.Graphics.Metal
|
||||
|
||||
private int _requestedWidth;
|
||||
private int _requestedHeight;
|
||||
|
||||
// private bool _vsyncEnabled;
|
||||
|
||||
private AntiAliasing _currentAntiAliasing;
|
||||
private bool _updateEffect;
|
||||
private IPostProcessingEffect _effect;
|
||||
private IScalingFilter _scalingFilter;
|
||||
private bool _isLinear;
|
||||
|
||||
public bool IsVSyncEnabled => _metalLayer.DisplaySyncEnabled;
|
||||
|
||||
// private float _scalingFilterLevel;
|
||||
private bool _updateScalingFilter;
|
||||
private ScalingFilter _currentScalingFilter;
|
||||
@@ -43,7 +42,7 @@ namespace Ryujinx.Graphics.Metal
|
||||
_metalLayer = metalLayer;
|
||||
}
|
||||
|
||||
private unsafe void ResizeIfNeeded()
|
||||
private void ResizeIfNeeded()
|
||||
{
|
||||
if (_requestedWidth != 0 && _requestedHeight != 0)
|
||||
{
|
||||
@@ -57,7 +56,7 @@ namespace Ryujinx.Graphics.Metal
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
||||
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
||||
{
|
||||
if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex)
|
||||
{
|
||||
@@ -144,15 +143,7 @@ namespace Ryujinx.Graphics.Metal
|
||||
|
||||
public void ChangeVSyncMode(VSyncMode vSyncMode)
|
||||
{
|
||||
switch (vSyncMode)
|
||||
{
|
||||
case VSyncMode.Unbounded:
|
||||
_metalLayer.DisplaySyncEnabled = false;
|
||||
break;
|
||||
case VSyncMode.Switch:
|
||||
_metalLayer.DisplaySyncEnabled = true;
|
||||
break;
|
||||
}
|
||||
_metalLayer.DisplaySyncEnabled = vSyncMode is VSyncMode.Switch;
|
||||
}
|
||||
|
||||
public void SetAntiAliasing(AntiAliasing effect)
|
||||
|
||||
@@ -2,8 +2,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal enum BitDepth
|
||||
{
|
||||
Bits8 = 8, /**< 8 bits */
|
||||
Bits10 = 10, /**< 10 bits */
|
||||
Bits12 = 12, /**< 12 bits */
|
||||
Bits8 = 8, // < 8 bits
|
||||
Bits10 = 10, // < 10 bits
|
||||
Bits12 = 12, // < 12 bits
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +1,75 @@
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal enum CodecErr
|
||||
{
|
||||
/*!\brief Operation completed without error */
|
||||
CodecOk,
|
||||
/// <summary>
|
||||
/// Operation completed without error
|
||||
/// </summary>
|
||||
Ok,
|
||||
|
||||
/*!\brief Unspecified error */
|
||||
CodecError,
|
||||
/// <summary>
|
||||
/// Unspecified error
|
||||
/// </summary>
|
||||
Error,
|
||||
|
||||
/*!\brief Memory operation failed */
|
||||
CodecMemError,
|
||||
/// <summary>
|
||||
/// Memory operation failed
|
||||
/// </summary>
|
||||
MemError,
|
||||
|
||||
/*!\brief ABI version mismatch */
|
||||
CodecAbiMismatch,
|
||||
/// <summary>
|
||||
/// ABI version mismatch
|
||||
/// </summary>
|
||||
AbiMismatch,
|
||||
|
||||
/*!\brief Algorithm does not have required capability */
|
||||
CodecIncapable,
|
||||
/// <summary>
|
||||
/// Algorithm does not have required capability
|
||||
/// </summary>
|
||||
Incapable,
|
||||
|
||||
/*!\brief The given bitstream is not supported.
|
||||
*
|
||||
* The bitstream was unable to be parsed at the highest level. The decoder
|
||||
* is unable to proceed. This error \ref SHOULD be treated as fatal to the
|
||||
* stream. */
|
||||
CodecUnsupBitstream,
|
||||
/// <summary>
|
||||
/// The given bitstream is not supported.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The bitstream was unable to be parsed at the highest level.<br/>
|
||||
/// The decoder is unable to proceed.<br/>
|
||||
/// This error SHOULD be treated as fatal to the stream.
|
||||
/// </remarks>
|
||||
UnsupBitstream,
|
||||
|
||||
/*!\brief Encoded bitstream uses an unsupported feature
|
||||
*
|
||||
* The decoder does not implement a feature required by the encoder. This
|
||||
* return code should only be used for features that prevent future
|
||||
* pictures from being properly decoded. This error \ref MAY be treated as
|
||||
* fatal to the stream or \ref MAY be treated as fatal to the current GOP.
|
||||
*/
|
||||
CodecUnsupFeature,
|
||||
/// <summary>
|
||||
/// Encoded bitstream uses an unsupported feature
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The decoder does not implement a feature required by the encoder.<br/>
|
||||
/// This return code should only be used for features that prevent future
|
||||
/// pictures from being properly decoded.<br/>
|
||||
/// <br/>
|
||||
/// This error MAY be treated as fatal to the stream or MAY be treated as fatal to the current GOP.
|
||||
/// </remarks>
|
||||
UnsupFeature,
|
||||
|
||||
/*!\brief The coded data for this stream is corrupt or incomplete
|
||||
*
|
||||
* There was a problem decoding the current frame. This return code
|
||||
* should only be used for failures that prevent future pictures from
|
||||
* being properly decoded. This error \ref MAY be treated as fatal to the
|
||||
* stream or \ref MAY be treated as fatal to the current GOP. If decoding
|
||||
* is continued for the current GOP, artifacts may be present.
|
||||
*/
|
||||
CodecCorruptFrame,
|
||||
/// <summary>
|
||||
/// The coded data for this stream is corrupt or incomplete.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There was a problem decoding the current frame.<br/>
|
||||
/// This return code should only be used
|
||||
/// for failures that prevent future pictures from being properly decoded.<br/>
|
||||
/// <br/>
|
||||
/// This error MAY be treated as fatal to the stream or MAY be treated as fatal to the current GOP.<br/>
|
||||
/// If decoding is continued for the current GOP, artifacts may be present.
|
||||
/// </remarks>
|
||||
CorruptFrame,
|
||||
|
||||
/*!\brief An application-supplied parameter is not valid.
|
||||
*
|
||||
*/
|
||||
CodecInvalidParam,
|
||||
/// <summary>
|
||||
/// An application-supplied parameter is not valid.
|
||||
/// </summary>
|
||||
InvalidParam,
|
||||
|
||||
/*!\brief An iterator reached the end of list.
|
||||
*
|
||||
*/
|
||||
CodecListEnd,
|
||||
/// <summary>
|
||||
/// An iterator reached the end of list.
|
||||
/// </summary>
|
||||
ListEnd
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte ClipPixel(int val)
|
||||
{
|
||||
return (byte)((val > 255) ? 255 : (val < 0) ? 0 : val);
|
||||
return (byte)(val > 255 ? 255 : val < 0 ? 0 : val);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -56,4 +56,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
||||
return numValues > 0 ? GetMsb(numValues) + 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
||||
{
|
||||
Marshal.FreeHGlobal(item.Pointer);
|
||||
}
|
||||
|
||||
item.Pointer = ptr;
|
||||
item.Length = lengthInBytes;
|
||||
break;
|
||||
@@ -58,7 +59,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayPtr<T>(ptr, length);
|
||||
ArrayPtr<T> allocation = new ArrayPtr<T>(ptr, length);
|
||||
|
||||
allocation.AsSpan().Fill(default);
|
||||
|
||||
return allocation;
|
||||
}
|
||||
|
||||
public unsafe void Free<T>(ArrayPtr<T> arr) where T : unmanaged
|
||||
|
||||
@@ -20,4 +20,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Common
|
||||
new Span<T>(ptr, length).Fill(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class Constants
|
||||
{
|
||||
public const int Vp9InterpExtend = 4;
|
||||
public const int InterpExtend = 4;
|
||||
|
||||
public const int MaxMbPlane = 3;
|
||||
|
||||
@@ -25,6 +27,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
/* Segment Feature Masks */
|
||||
public const int MaxMvRefCandidates = 2;
|
||||
|
||||
public const int IntraInterContexts = 4;
|
||||
public const int CompInterContexts = 5;
|
||||
public const int RefContexts = 5;
|
||||
|
||||
@@ -32,12 +35,26 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
public const int EightTapSmooth = 1;
|
||||
public const int EightTapSharp = 2;
|
||||
public const int SwitchableFilters = 3; /* Number of switchable filters */
|
||||
|
||||
public const int Bilinear = 3;
|
||||
public const int Switchable = 4; /* should be the last one */
|
||||
|
||||
// The codec can operate in four possible inter prediction filter mode:
|
||||
// 8-tap, 8-tap-smooth, 8-tap-sharp, and switching between the three.
|
||||
public const int SwitchableFilterContexts = SwitchableFilters + 1;
|
||||
public const int Switchable = 4; /* Should be the last one */
|
||||
|
||||
// Frame
|
||||
public const int RefsPerFrame = 3;
|
||||
|
||||
public const int RefFramesLog2 = 3;
|
||||
public const int RefFrames = 1 << RefFramesLog2;
|
||||
|
||||
// 1 scratch frame for the new frame, 3 for scaled references on the encoder.
|
||||
public const int FrameBuffers = RefFrames + 4;
|
||||
|
||||
public const int FrameContextsLog2 = 2;
|
||||
public const int FrameContexts = 1 << FrameContextsLog2;
|
||||
|
||||
public const int NumPingPongBuffers = 2;
|
||||
|
||||
public const int Class0Bits = 1; /* bits at integer precision for class 0 */
|
||||
@@ -48,9 +65,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
public const int MvLow = -(1 << MvInUseBits);
|
||||
|
||||
// Coefficient token alphabet
|
||||
public const int ZeroToken = 0; // 0 Extra Bits 0+0
|
||||
public const int OneToken = 1; // 1 Extra Bits 0+1
|
||||
public const int TwoToken = 2; // 2 Extra Bits 0+1
|
||||
public const int ZeroToken = 0; // 0 Extra Bits 0+0
|
||||
public const int OneToken = 1; // 1 Extra Bits 0+1
|
||||
public const int TwoToken = 2; // 2 Extra Bits 0+1
|
||||
|
||||
public const int PivotNode = 2;
|
||||
|
||||
@@ -65,5 +82,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
public const int SegmentAbsData = 1;
|
||||
public const int MaxSegments = 8;
|
||||
|
||||
public const int PartitionTypes = (int)PartitionType.PartitionTypes;
|
||||
|
||||
public const int PartitionPlOffset = 4; // Number of probability models per block size
|
||||
public const int PartitionContexts = 4 * PartitionPlOffset;
|
||||
|
||||
public const int PlaneTypes = (int)PlaneType.PlaneTypes;
|
||||
|
||||
public const int IntraModes = (int)PredictionMode.TmPred + 1;
|
||||
|
||||
public const int InterModes = 1 + (int)PredictionMode.NewMv - (int)PredictionMode.NearestMv;
|
||||
|
||||
public const int SkipContexts = 3;
|
||||
public const int InterModeContexts = 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/Ryujinx.Graphics.Nvdec.Vp9/DSubExp.cs
Normal file
47
src/Ryujinx.Graphics.Nvdec.Vp9/DSubExp.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class DSubExp
|
||||
{
|
||||
public static int InvRecenterNonneg(int v, int m)
|
||||
{
|
||||
if (v > 2 * m)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
return (v & 1) != 0 ? m - ((v + 1) >> 1) : m + (v >> 1);
|
||||
}
|
||||
|
||||
private static readonly byte[] InvMapTable =
|
||||
{
|
||||
7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176, 189, 202, 215, 228, 241, 254, 1, 2, 3, 4,
|
||||
5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34,
|
||||
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62,
|
||||
63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90,
|
||||
91, 92, 93, 94, 95, 96, 97, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114,
|
||||
115, 116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
|
||||
138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157, 158, 159,
|
||||
160, 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
|
||||
183, 184, 185, 186, 187, 188, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205,
|
||||
206, 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
|
||||
229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250,
|
||||
251, 252, 253, 253
|
||||
};
|
||||
|
||||
public static int InvRemapProb(int v, int m)
|
||||
{
|
||||
Debug.Assert(v < InvMapTable.Length / sizeof(byte));
|
||||
|
||||
v = InvMapTable[v];
|
||||
m--;
|
||||
if (m << 1 <= Prob.MaxProb)
|
||||
{
|
||||
return 1 + InvRecenterNonneg(v, m);
|
||||
}
|
||||
|
||||
return Prob.MaxProb - InvRecenterNonneg(v, Prob.MaxProb - 1 - m);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Dsp;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
@@ -10,11 +10,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class DecodeMv
|
||||
{
|
||||
private const int MvrefNeighbours = 8;
|
||||
private const int RefNeighbours = 8;
|
||||
|
||||
private static PredictionMode ReadIntraMode(ref Reader r, ReadOnlySpan<byte> p)
|
||||
{
|
||||
return (PredictionMode)r.ReadTree(Luts.Vp9IntraModeTree, p);
|
||||
return (PredictionMode)r.ReadTree(Luts.IntraModeTree, p);
|
||||
}
|
||||
|
||||
private static PredictionMode ReadIntraModeY(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r, int sizeGroup)
|
||||
@@ -41,7 +41,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private static PredictionMode ReadInterMode(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r, int ctx)
|
||||
{
|
||||
int mode = r.ReadTree(Luts.Vp9InterModeTree, cm.Fc.Value.InterModeProb[ctx].AsSpan());
|
||||
int mode = r.ReadTree(Luts.InterModeTree, cm.Fc.Value.InterModeProb[ctx].AsSpan());
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
++xd.Counts.Value.InterMode[ctx][mode];
|
||||
@@ -52,22 +52,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private static int ReadSegmentId(ref Reader r, ref Array7<byte> segTreeProbs)
|
||||
{
|
||||
return r.ReadTree(Luts.Vp9SegmentTree, segTreeProbs.AsSpan());
|
||||
return r.ReadTree(Luts.SegmentTree, segTreeProbs.AsSpan());
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> GetTxProbs(ref Vp9EntropyProbs fc, TxSize maxTxSize, int ctx)
|
||||
{
|
||||
switch (maxTxSize)
|
||||
{
|
||||
case TxSize.Tx8x8:
|
||||
return fc.Tx8x8Prob[ctx].AsSpan();
|
||||
case TxSize.Tx16x16:
|
||||
return fc.Tx16x16Prob[ctx].AsSpan();
|
||||
case TxSize.Tx32x32:
|
||||
return fc.Tx32x32Prob[ctx].AsSpan();
|
||||
case TxSize.Tx8x8: return fc.Tx8x8Prob[ctx].AsSpan();
|
||||
case TxSize.Tx16x16: return fc.Tx16x16Prob[ctx].AsSpan();
|
||||
case TxSize.Tx32x32: return fc.Tx32x32Prob[ctx].AsSpan();
|
||||
default:
|
||||
Debug.Assert(false, "Invalid maxTxSize.");
|
||||
|
||||
return ReadOnlySpan<byte>.Empty;
|
||||
}
|
||||
}
|
||||
@@ -76,15 +72,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
switch (maxTxSize)
|
||||
{
|
||||
case TxSize.Tx8x8:
|
||||
return counts.Tx8x8[ctx].AsSpan();
|
||||
case TxSize.Tx16x16:
|
||||
return counts.Tx16x16[ctx].AsSpan();
|
||||
case TxSize.Tx32x32:
|
||||
return counts.Tx32x32[ctx].AsSpan();
|
||||
case TxSize.Tx8x8: return counts.Tx8x8[ctx].AsSpan();
|
||||
case TxSize.Tx16x16: return counts.Tx16x16[ctx].AsSpan();
|
||||
case TxSize.Tx32x32: return counts.Tx32x32[ctx].AsSpan();
|
||||
default:
|
||||
Debug.Assert(false, "Invalid maxTxSize.");
|
||||
|
||||
return Span<uint>.Empty;
|
||||
}
|
||||
}
|
||||
@@ -124,34 +116,32 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return (TxSize)Math.Min((int)maxTxSize, (int)Luts.TxModeToBiggestTxSize[(int)txMode]);
|
||||
}
|
||||
|
||||
private static int DecGetSegmentId(ref Vp9Common cm, ArrayPtr<byte> segmentIds, int miOffset, int xMis, int yMis)
|
||||
private static int DecGetSegmentId(ref Vp9Common cm, ArrayPtr<byte> segmentIds, int miOffset, int xMis,
|
||||
int yMis)
|
||||
{
|
||||
int x, y, segmentId = int.MaxValue;
|
||||
int segmentId = int.MaxValue;
|
||||
|
||||
for (y = 0; y < yMis; y++)
|
||||
for (int y = 0; y < yMis; y++)
|
||||
{
|
||||
for (x = 0; x < xMis; x++)
|
||||
for (int x = 0; x < xMis; x++)
|
||||
{
|
||||
segmentId = Math.Min(segmentId, segmentIds[miOffset + y * cm.MiCols + x]);
|
||||
segmentId = Math.Min(segmentId, segmentIds[miOffset + (y * cm.MiCols) + x]);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Assert(segmentId >= 0 && segmentId < Constants.MaxSegments);
|
||||
|
||||
return segmentId;
|
||||
}
|
||||
|
||||
private static void SetSegmentId(ref Vp9Common cm, int miOffset, int xMis, int yMis, int segmentId)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
Debug.Assert(segmentId >= 0 && segmentId < Constants.MaxSegments);
|
||||
|
||||
for (y = 0; y < yMis; y++)
|
||||
for (int y = 0; y < yMis; y++)
|
||||
{
|
||||
for (x = 0; x < xMis; x++)
|
||||
for (int x = 0; x < xMis; x++)
|
||||
{
|
||||
cm.CurrentFrameSegMap[miOffset + y * cm.MiCols + x] = (byte)segmentId;
|
||||
cm.CurrentFrameSegMap[miOffset + (y * cm.MiCols) + x] = (byte)segmentId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,13 +154,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int xMis,
|
||||
int yMis)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < yMis; y++)
|
||||
for (int y = 0; y < yMis; y++)
|
||||
{
|
||||
for (x = 0; x < xMis; x++)
|
||||
for (int x = 0; x < xMis; x++)
|
||||
{
|
||||
currentSegmentIds[miOffset + y * cm.MiCols + x] = (byte)(!lastSegmentIds.IsNull ? lastSegmentIds[miOffset + y * cm.MiCols + x] : 0);
|
||||
currentSegmentIds[miOffset + (y * cm.MiCols) + x] = (byte)(!lastSegmentIds.IsNull
|
||||
? lastSegmentIds[miOffset + (y * cm.MiCols) + x]
|
||||
: 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,13 +178,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (!seg.UpdateMap)
|
||||
{
|
||||
CopySegmentId(ref cm, cm.LastFrameSegMap, cm.CurrentFrameSegMap, miOffset, xMis, yMis);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
segmentId = ReadSegmentId(ref r, ref cm.Fc.Value.SegTreeProb);
|
||||
SetSegmentId(ref cm, miOffset, xMis, yMis, segmentId);
|
||||
|
||||
return segmentId;
|
||||
}
|
||||
|
||||
@@ -210,7 +198,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Segmentation seg = ref cm.Seg;
|
||||
ref ModeInfo mi = ref xd.Mi[0].Value;
|
||||
int predictedSegmentId, segmentId;
|
||||
int miOffset = miRow * cm.MiCols + miCol;
|
||||
int miOffset = (miRow * cm.MiCols) + miCol;
|
||||
|
||||
if (!seg.Enabled)
|
||||
{
|
||||
@@ -224,7 +212,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (!seg.UpdateMap)
|
||||
{
|
||||
CopySegmentId(ref cm, cm.LastFrameSegMap, cm.CurrentFrameSegMap, miOffset, xMis, yMis);
|
||||
|
||||
return predictedSegmentId;
|
||||
}
|
||||
|
||||
@@ -232,20 +219,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
byte predProb = Segmentation.GetPredProbSegId(ref cm.Fc.Value.SegPredProb, ref xd);
|
||||
mi.SegIdPredicted = (sbyte)r.Read(predProb);
|
||||
segmentId = mi.SegIdPredicted != 0 ? predictedSegmentId : ReadSegmentId(ref r, ref cm.Fc.Value.SegTreeProb);
|
||||
segmentId = mi.SegIdPredicted != 0
|
||||
? predictedSegmentId
|
||||
: ReadSegmentId(ref r, ref cm.Fc.Value.SegTreeProb);
|
||||
}
|
||||
else
|
||||
{
|
||||
segmentId = ReadSegmentId(ref r, ref cm.Fc.Value.SegTreeProb);
|
||||
}
|
||||
SetSegmentId(ref cm, miOffset, xMis, yMis, segmentId);
|
||||
|
||||
SetSegmentId(ref cm, miOffset, xMis, yMis, segmentId);
|
||||
return segmentId;
|
||||
}
|
||||
|
||||
private static int ReadSkip(ref Vp9Common cm, ref MacroBlockD xd, int segmentId, ref Reader r)
|
||||
{
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.SegLvlSkip) != 0)
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.Skip) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -260,12 +249,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return skip;
|
||||
}
|
||||
|
||||
private static int ReadMvComponent(ref Reader r, ref Vp9EntropyProbs fc, int mvcomp, bool usehp)
|
||||
private static int ReadComponent(ref Reader r, ref Vp9EntropyProbs fc, int mvcomp, bool usehp)
|
||||
{
|
||||
int mag, d, fr, hp;
|
||||
bool sign = r.Read(fc.Sign[mvcomp]) != 0;
|
||||
MvClassType mvClass = (MvClassType)r.ReadTree(Luts.Vp9MvClassTree, fc.Classes[mvcomp].AsSpan());
|
||||
bool class0 = mvClass == MvClassType.MvClass0;
|
||||
MvClassType mvClass = (MvClassType)r.ReadTree(Luts.MvClassTree, fc.Classes[mvcomp].AsSpan());
|
||||
bool class0 = mvClass == MvClassType.Class0;
|
||||
|
||||
// Integer part
|
||||
if (class0)
|
||||
@@ -275,11 +264,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
int n = (int)mvClass + Constants.Class0Bits - 1; // Number of bits
|
||||
|
||||
d = 0;
|
||||
for (i = 0; i < n; ++i)
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
d |= r.Read(fc.Bits[mvcomp][i]) << i;
|
||||
}
|
||||
@@ -288,40 +276,39 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
// Fractional part
|
||||
fr = r.ReadTree(Luts.Vp9MvFPTree, class0 ? fc.Class0Fp[mvcomp][d].AsSpan() : fc.Fp[mvcomp].AsSpan());
|
||||
fr = r.ReadTree(Luts.MvFPTree, class0 ? fc.Class0Fp[mvcomp][d].AsSpan() : fc.Fp[mvcomp].AsSpan());
|
||||
|
||||
// High precision part (if hp is not used, the default value of the hp is 1)
|
||||
hp = usehp ? r.Read(class0 ? fc.Class0Hp[mvcomp] : fc.Hp[mvcomp]) : 1;
|
||||
|
||||
// Result
|
||||
mag += ((d << 3) | (fr << 1) | hp) + 1;
|
||||
|
||||
return sign ? -mag : mag;
|
||||
}
|
||||
|
||||
private static void ReadMv(
|
||||
private static void Read(
|
||||
ref Reader r,
|
||||
ref Mv mv,
|
||||
ref Mv refr,
|
||||
ref Vp9EntropyProbs fc,
|
||||
Ptr<Vp9BackwardUpdates> counts,
|
||||
bool allowHP)
|
||||
bool allowHp)
|
||||
{
|
||||
MvJointType jointType = (MvJointType)r.ReadTree(Luts.Vp9MvJointTree, fc.Joints.AsSpan());
|
||||
bool useHP = allowHP && refr.UseMvHp();
|
||||
MvJointType jointType = (MvJointType)r.ReadTree(Luts.MvJointTree, fc.Joints.AsSpan());
|
||||
bool useHp = allowHp && refr.UseHp();
|
||||
Mv diff = new();
|
||||
|
||||
if (Mv.MvJointVertical(jointType))
|
||||
if (Mv.JointVertical(jointType))
|
||||
{
|
||||
diff.Row = (short)ReadMvComponent(ref r, ref fc, 0, useHP);
|
||||
diff.Row = (short)ReadComponent(ref r, ref fc, 0, useHp);
|
||||
}
|
||||
|
||||
if (Mv.MvJointHorizontal(jointType))
|
||||
if (Mv.JointHorizontal(jointType))
|
||||
{
|
||||
diff.Col = (short)ReadMvComponent(ref r, ref fc, 1, useHP);
|
||||
diff.Col = (short)ReadComponent(ref r, ref fc, 1, useHp);
|
||||
}
|
||||
|
||||
diff.IncMv(counts);
|
||||
diff.Inc(counts);
|
||||
|
||||
mv.Row = (short)(refr.Row + diff.Row);
|
||||
mv.Col = (short)(refr.Col + diff.Col);
|
||||
@@ -329,7 +316,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private static ReferenceMode ReadBlockReferenceMode(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r)
|
||||
{
|
||||
if (cm.ReferenceMode == ReferenceMode.ReferenceModeSelect)
|
||||
if (cm.ReferenceMode == ReferenceMode.Select)
|
||||
{
|
||||
int ctx = PredCommon.GetReferenceModeContext(ref cm, ref xd);
|
||||
ReferenceMode mode = (ReferenceMode)r.Read(cm.Fc.Value.CompInterProb[ctx]);
|
||||
@@ -354,15 +341,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
ref Vp9EntropyProbs fc = ref cm.Fc.Value;
|
||||
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.SegLvlRefFrame) != 0)
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.RefFrame) != 0)
|
||||
{
|
||||
refFrame[0] = (sbyte)cm.Seg.GetSegData(segmentId, SegLvlFeatures.SegLvlRefFrame);
|
||||
refFrame[0] = (sbyte)cm.Seg.GetSegData(segmentId, SegLvlFeatures.RefFrame);
|
||||
refFrame[1] = Constants.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReferenceMode mode = ReadBlockReferenceMode(ref cm, ref xd, ref r);
|
||||
if (mode == ReferenceMode.CompoundReference)
|
||||
if (mode == ReferenceMode.Compound)
|
||||
{
|
||||
int idx = cm.RefFrameSignBias[cm.CompFixedRef];
|
||||
int ctx = PredCommon.GetPredContextCompRefP(ref cm, ref xd);
|
||||
@@ -375,7 +362,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
refFrame[idx] = cm.CompFixedRef;
|
||||
refFrame[idx == 0 ? 1 : 0] = cm.CompVarRef[bit];
|
||||
}
|
||||
else if (mode == ReferenceMode.SingleReference)
|
||||
else if (mode == ReferenceMode.Single)
|
||||
{
|
||||
int ctx0 = PredCommon.GetPredContextSingleRefP1(ref xd);
|
||||
int bit0 = r.Read(fc.SingleRefProb[ctx0][0]);
|
||||
@@ -412,7 +399,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
private static byte ReadSwitchableInterpFilter(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r)
|
||||
{
|
||||
int ctx = xd.GetPredContextSwitchableInterp();
|
||||
byte type = (byte)r.ReadTree(Luts.Vp9SwitchableInterpTree, cm.Fc.Value.SwitchableInterpProb[ctx].AsSpan());
|
||||
byte type = (byte)r.ReadTree(Luts.SwitchableInterpTree, cm.Fc.Value.SwitchableInterpProb[ctx].AsSpan());
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
++xd.Counts.Value.SwitchableInterp[ctx][type];
|
||||
@@ -424,12 +411,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
private static void ReadIntraBlockModeInfo(ref Vp9Common cm, ref MacroBlockD xd, ref ModeInfo mi, ref Reader r)
|
||||
{
|
||||
BlockSize bsize = mi.SbType;
|
||||
int i;
|
||||
|
||||
|
||||
switch (bsize)
|
||||
{
|
||||
case BlockSize.Block4x4:
|
||||
for (i = 0; i < 4; ++i)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
mi.Bmi[i].Mode = ReadIntraModeY(ref cm, ref xd, ref r, 0);
|
||||
}
|
||||
@@ -459,27 +446,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
mi.RefFrame[1] = Constants.None;
|
||||
}
|
||||
|
||||
private static bool IsMvValid(ref Mv mv)
|
||||
{
|
||||
return mv.Row > Constants.MvLow &&
|
||||
mv.Row < Constants.MvUpp &&
|
||||
mv.Col > Constants.MvLow &&
|
||||
mv.Col < Constants.MvUpp;
|
||||
}
|
||||
|
||||
private static void CopyMvPair(ref Array2<Mv> dst, ref Array2<Mv> src)
|
||||
private static void CopyPair(ref Array2<Mv> dst, ref Array2<Mv> src)
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
}
|
||||
|
||||
private static void ZeroMvPair(ref Array2<Mv> dst)
|
||||
private static void ZeroPair(ref Array2<Mv> dst)
|
||||
{
|
||||
dst[0] = new Mv();
|
||||
dst[1] = new Mv();
|
||||
}
|
||||
|
||||
private static bool AssignMv(
|
||||
private static bool Assign(
|
||||
ref Vp9Common cm,
|
||||
ref MacroBlockD xd,
|
||||
PredictionMode mode,
|
||||
@@ -487,45 +466,45 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Array2<Mv> refMv,
|
||||
ref Array2<Mv> nearNearestMv,
|
||||
int isCompound,
|
||||
bool allowHP,
|
||||
bool allowHp,
|
||||
ref Reader r)
|
||||
{
|
||||
int i;
|
||||
bool ret = true;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case PredictionMode.NewMv:
|
||||
{
|
||||
for (i = 0; i < 1 + isCompound; ++i)
|
||||
for (int i = 0; i < 1 + isCompound; ++i)
|
||||
{
|
||||
ReadMv(ref r, ref mv[i], ref refMv[i], ref cm.Fc.Value, xd.Counts, allowHP);
|
||||
ret = ret && IsMvValid(ref mv[i]);
|
||||
Read(ref r, ref mv[i], ref refMv[i], ref cm.Fc.Value, xd.Counts, allowHp);
|
||||
ret = ret && mv[i].IsValid();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PredictionMode.NearMv:
|
||||
case PredictionMode.NearestMv:
|
||||
{
|
||||
CopyMvPair(ref mv, ref nearNearestMv);
|
||||
CopyPair(ref mv, ref nearNearestMv);
|
||||
break;
|
||||
}
|
||||
case PredictionMode.ZeroMv:
|
||||
{
|
||||
ZeroMvPair(ref mv);
|
||||
ZeroPair(ref mv);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static bool ReadIsInterBlock(ref Vp9Common cm, ref MacroBlockD xd, int segmentId, ref Reader r)
|
||||
{
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.SegLvlRefFrame) != 0)
|
||||
if (cm.Seg.IsSegFeatureActive(segmentId, SegLvlFeatures.RefFrame) != 0)
|
||||
{
|
||||
return cm.Seg.GetSegData(segmentId, SegLvlFeatures.SegLvlRefFrame) != Constants.IntraFrame;
|
||||
return cm.Seg.GetSegData(segmentId, SegLvlFeatures.RefFrame) != Constants.IntraFrame;
|
||||
}
|
||||
|
||||
int ctx = xd.GetIntraInterContext();
|
||||
@@ -538,33 +517,30 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return isInter;
|
||||
}
|
||||
|
||||
private static void DecFindBestRefMvs(bool allowHP, Span<Mv> mvlist, ref Mv bestMv, int refmvCount)
|
||||
private static void DecFindBestRefs(bool allowHp, Span<Mv> mvlist, ref Mv bestMv, int refmvCount)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Make sure all the candidates are properly clamped etc
|
||||
for (i = 0; i < refmvCount; ++i)
|
||||
for (int i = 0; i < refmvCount; ++i)
|
||||
{
|
||||
mvlist[i].LowerMvPrecision(allowHP);
|
||||
mvlist[i].LowerPrecision(allowHp);
|
||||
bestMv = mvlist[i];
|
||||
}
|
||||
}
|
||||
|
||||
private static bool AddMvRefListEb(Mv mv, ref int refMvCount, Span<Mv> mvRefList, bool earlyBreak)
|
||||
private static bool AddRefListEb(Mv mv, ref int refCount, Span<Mv> mvRefList, bool earlyBreak)
|
||||
{
|
||||
if (refMvCount != 0)
|
||||
if (refCount != 0)
|
||||
{
|
||||
if (Unsafe.As<Mv, int>(ref mv) != Unsafe.As<Mv, int>(ref mvRefList[0]))
|
||||
{
|
||||
mvRefList[refMvCount] = mv;
|
||||
refMvCount++;
|
||||
|
||||
mvRefList[refCount] = mv;
|
||||
refCount++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mvRefList[refMvCount++] = mv;
|
||||
mvRefList[refCount++] = mv;
|
||||
if (earlyBreak)
|
||||
{
|
||||
return true;
|
||||
@@ -574,19 +550,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return false;
|
||||
}
|
||||
|
||||
// Performs mv sign inversion if indicated by the reference frame combination.
|
||||
private static Mv ScaleMv(ref ModeInfo mi, int refr, sbyte thisRefFrame, ref Array4<sbyte> refSignBias)
|
||||
{
|
||||
Mv mv = mi.Mv[refr];
|
||||
if (refSignBias[mi.RefFrame[refr]] != refSignBias[thisRefFrame])
|
||||
{
|
||||
mv.Row *= -1;
|
||||
mv.Col *= -1;
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
|
||||
private static bool IsDiffRefFrameAddMvEb(
|
||||
private static bool IsDiffRefFrameAddEb(
|
||||
ref ModeInfo mbmi,
|
||||
sbyte refFrame,
|
||||
ref Array4<sbyte> refSignBias,
|
||||
@@ -598,26 +562,30 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
if (mbmi.RefFrame[0] != refFrame)
|
||||
{
|
||||
if (AddMvRefListEb(ScaleMv(ref mbmi, 0, refFrame, ref refSignBias), ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (mbmi.HasSecondRef() && mbmi.RefFrame[1] != refFrame && Unsafe.As<Mv, int>(ref mbmi.Mv[1]) != Unsafe.As<Mv, int>(ref mbmi.Mv[0]))
|
||||
{
|
||||
if (AddMvRefListEb(ScaleMv(ref mbmi, 1, refFrame, ref refSignBias), ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddRefListEb(mbmi.ScaleMv(0, refFrame, ref refSignBias), ref refmvCount, mvRefList,
|
||||
earlyBreak))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mbmi.HasSecondRef() && mbmi.RefFrame[1] != refFrame &&
|
||||
Unsafe.As<Mv, int>(ref mbmi.Mv[1]) != Unsafe.As<Mv, int>(ref mbmi.Mv[0]))
|
||||
{
|
||||
if (AddRefListEb(mbmi.ScaleMv(1, refFrame, ref refSignBias), ref refmvCount, mvRefList,
|
||||
earlyBreak))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function searches the neighborhood of a given MB/SB
|
||||
// to try and find candidate reference vectors.
|
||||
private static int DecFindMvRefs(
|
||||
private static int DecFindRefs(
|
||||
ref Vp9Common cm,
|
||||
ref MacroBlockD xd,
|
||||
PredictionMode mode,
|
||||
@@ -627,22 +595,24 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int miRow,
|
||||
int miCol,
|
||||
int block,
|
||||
int isSub8X8)
|
||||
int isSub8x8)
|
||||
{
|
||||
ref Array4<sbyte> refSignBias = ref cm.RefFrameSignBias;
|
||||
int i, refmvCount = 0;
|
||||
bool differentRefFound = false;
|
||||
Ptr<MvRef> prevFrameMvs = cm.UsePrevFrameMvs ? new Ptr<MvRef>(ref cm.PrevFrameMvs[miRow * cm.MiCols + miCol]) : Ptr<MvRef>.Null;
|
||||
Ptr<MvRef> prevFrameMvs = cm.UsePrevFrameMvs
|
||||
? new Ptr<MvRef>(ref cm.PrevFrameMvs[(miRow * cm.MiCols) + miCol])
|
||||
: Ptr<MvRef>.Null;
|
||||
ref TileInfo tile = ref xd.Tile;
|
||||
// If mode is nearestmv or newmv (uses nearestmv as a reference) then stop
|
||||
// searching after the first mv is found.
|
||||
bool earlyBreak = mode != PredictionMode.NearMv;
|
||||
|
||||
// Blank the reference vector list
|
||||
mvRefList[..Constants.MaxMvRefCandidates].Clear();
|
||||
mvRefList.Slice(0, Constants.MaxMvRefCandidates).Fill(new Mv());
|
||||
|
||||
i = 0;
|
||||
if (isSub8X8 != 0)
|
||||
if (isSub8x8 != 0)
|
||||
{
|
||||
// If the size < 8x8 we get the mv from the bmi substructure for the
|
||||
// nearest two blocks.
|
||||
@@ -651,19 +621,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Position mvRef = ref mvRefSearch[i];
|
||||
if (tile.IsInside(miCol, miRow, cm.MiRows, ref mvRef))
|
||||
{
|
||||
ref ModeInfo candidateMi = ref xd.Mi[mvRef.Col + mvRef.Row * xd.MiStride].Value;
|
||||
ref ModeInfo candidateMi = ref xd.Mi[mvRef.Col + (mvRef.Row * xd.MiStride)].Value;
|
||||
differentRefFound = true;
|
||||
|
||||
if (candidateMi.RefFrame[0] == refFrame)
|
||||
{
|
||||
if (AddMvRefListEb(candidateMi.GetSubBlockMv(0, mvRef.Col, block), ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddRefListEb(candidateMi.GetSubBlockMv(0, mvRef.Col, block), ref refmvCount,
|
||||
mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
else if (candidateMi.RefFrame[1] == refFrame)
|
||||
{
|
||||
if (AddMvRefListEb(candidateMi.GetSubBlockMv(1, mvRef.Col, block), ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddRefListEb(candidateMi.GetSubBlockMv(1, mvRef.Col, block), ref refmvCount,
|
||||
mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -675,24 +647,24 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// Check the rest of the neighbors in much the same way
|
||||
// as before except we don't need to keep track of sub blocks or
|
||||
// mode counts.
|
||||
for (; i < MvrefNeighbours; ++i)
|
||||
for (; i < RefNeighbours; ++i)
|
||||
{
|
||||
ref Position mvRef = ref mvRefSearch[i];
|
||||
if (tile.IsInside(miCol, miRow, cm.MiRows, ref mvRef))
|
||||
{
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + mvRef.Row * xd.MiStride].Value;
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + (mvRef.Row * xd.MiStride)].Value;
|
||||
differentRefFound = true;
|
||||
|
||||
if (candidate.RefFrame[0] == refFrame)
|
||||
{
|
||||
if (AddMvRefListEb(candidate.Mv[0], ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddRefListEb(candidate.Mv[0], ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
else if (candidate.RefFrame[1] == refFrame)
|
||||
{
|
||||
if (AddMvRefListEb(candidate.Mv[1], ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddRefListEb(candidate.Mv[1], ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -705,14 +677,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
if (prevFrameMvs.Value.RefFrame[0] == refFrame)
|
||||
{
|
||||
if (AddMvRefListEb(prevFrameMvs.Value.Mv[0], ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddRefListEb(prevFrameMvs.Value.Mv[0], ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
else if (prevFrameMvs.Value.RefFrame[1] == refFrame)
|
||||
{
|
||||
if (AddMvRefListEb(prevFrameMvs.Value.Mv[1], ref refmvCount, mvRefList, earlyBreak))
|
||||
if (AddRefListEb(prevFrameMvs.Value.Mv[1], ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -724,15 +696,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// different reference frames.
|
||||
if (differentRefFound)
|
||||
{
|
||||
for (i = 0; i < MvrefNeighbours; ++i)
|
||||
for (i = 0; i < RefNeighbours; ++i)
|
||||
{
|
||||
ref Position mvRef = ref mvRefSearch[i];
|
||||
if (tile.IsInside(miCol, miRow, cm.MiRows, ref mvRef))
|
||||
{
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + mvRef.Row * xd.MiStride].Value;
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + (mvRef.Row * xd.MiStride)].Value;
|
||||
|
||||
// If the candidate is Intra we don't want to consider its mv.
|
||||
if (IsDiffRefFrameAddMvEb(ref candidate, refFrame, ref refSignBias, ref refmvCount, mvRefList, earlyBreak))
|
||||
if (IsDiffRefFrameAddEb(ref candidate, refFrame, ref refSignBias, ref refmvCount, mvRefList,
|
||||
earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -751,7 +724,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
mv.Row *= -1;
|
||||
mv.Col *= -1;
|
||||
}
|
||||
if (AddMvRefListEb(mv, ref refmvCount, mvRefList, earlyBreak))
|
||||
|
||||
if (AddRefListEb(mv, ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -759,7 +733,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
if (prevFrameMvs.Value.RefFrame[1] > Constants.IntraFrame &&
|
||||
prevFrameMvs.Value.RefFrame[1] != refFrame &&
|
||||
Unsafe.As<Mv, int>(ref prevFrameMvs.Value.Mv[1]) != Unsafe.As<Mv, int>(ref prevFrameMvs.Value.Mv[0]))
|
||||
Unsafe.As<Mv, int>(ref prevFrameMvs.Value.Mv[1]) !=
|
||||
Unsafe.As<Mv, int>(ref prevFrameMvs.Value.Mv[0]))
|
||||
{
|
||||
Mv mv = prevFrameMvs.Value.Mv[1];
|
||||
if (refSignBias[prevFrameMvs.Value.RefFrame[1]] != refSignBias[refFrame])
|
||||
@@ -767,7 +742,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
mv.Row *= -1;
|
||||
mv.Col *= -1;
|
||||
}
|
||||
if (AddMvRefListEb(mv, ref refmvCount, mvRefList, earlyBreak))
|
||||
|
||||
if (AddRefListEb(mv, ref refmvCount, mvRefList, earlyBreak))
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
@@ -784,17 +760,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
refmvCount = 1;
|
||||
}
|
||||
|
||||
Done:
|
||||
Done:
|
||||
// Clamp vectors
|
||||
for (i = 0; i < refmvCount; ++i)
|
||||
{
|
||||
mvRefList[i].ClampMvRef(ref xd);
|
||||
mvRefList[i].ClampRef(ref xd);
|
||||
}
|
||||
|
||||
return refmvCount;
|
||||
}
|
||||
|
||||
private static void AppendSub8x8MvsForIdx(
|
||||
private static void AppendSub8x8ForIdx(
|
||||
ref Vp9Common cm,
|
||||
ref MacroBlockD xd,
|
||||
Span<Position> mvRefSearch,
|
||||
@@ -808,12 +784,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
Span<Mv> mvList = stackalloc Mv[Constants.MaxMvRefCandidates];
|
||||
ref ModeInfo mi = ref xd.Mi[0].Value;
|
||||
ref Array4<BModeInfo> bmi = ref mi.Bmi;
|
||||
int n;
|
||||
int refmvCount;
|
||||
|
||||
Debug.Assert(Constants.MaxMvRefCandidates == 2);
|
||||
|
||||
refmvCount = DecFindMvRefs(ref cm, ref xd, bMode, mi.RefFrame[refr], mvRefSearch, mvList, miRow, miCol, block, 1);
|
||||
refmvCount = DecFindRefs(ref cm, ref xd, bMode, mi.RefFrame[refr], mvRefSearch, mvList, miRow, miCol,
|
||||
block, 1);
|
||||
|
||||
switch (block)
|
||||
{
|
||||
@@ -829,7 +805,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
else
|
||||
{
|
||||
bestSub8x8 = new Mv();
|
||||
for (n = 0; n < refmvCount; ++n)
|
||||
for (int n = 0; n < refmvCount; ++n)
|
||||
{
|
||||
if (Unsafe.As<Mv, int>(ref bmi[0].Mv[refr]) != Unsafe.As<Mv, int>(ref mvList[n]))
|
||||
{
|
||||
@@ -838,6 +814,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 3:
|
||||
if (bMode == PredictionMode.NearestMv)
|
||||
@@ -852,7 +829,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
candidates[2] = mvList[0];
|
||||
candidates[3] = mvList[1];
|
||||
bestSub8x8 = new Mv();
|
||||
for (n = 0; n < 2 + Constants.MaxMvRefCandidates; ++n)
|
||||
for (int n = 0; n < 2 + Constants.MaxMvRefCandidates; ++n)
|
||||
{
|
||||
if (Unsafe.As<Mv, int>(ref bmi[2].Mv[refr]) != Unsafe.As<Mv, int>(ref candidates[n]))
|
||||
{
|
||||
@@ -861,6 +838,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Invalid block index.");
|
||||
@@ -868,19 +846,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static byte GetModeContext(ref Vp9Common cm, ref MacroBlockD xd, Span<Position> mvRefSearch, int miRow, int miCol)
|
||||
private static byte GetModeContext(ref Vp9Common cm, ref MacroBlockD xd, Span<Position> mvRefSearch, int miRow,
|
||||
int miCol)
|
||||
{
|
||||
int i;
|
||||
int contextCounter = 0;
|
||||
ref TileInfo tile = ref xd.Tile;
|
||||
|
||||
// Get mode count from nearest 2 blocks
|
||||
for (i = 0; i < 2; ++i)
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
ref Position mvRef = ref mvRefSearch[i];
|
||||
if (tile.IsInside(miCol, miRow, cm.MiRows, ref mvRef))
|
||||
{
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + mvRef.Row * xd.MiStride].Value;
|
||||
ref ModeInfo candidate = ref xd.Mi[mvRef.Col + (mvRef.Row * xd.MiStride)].Value;
|
||||
// Keep counts for entropy encoding.
|
||||
contextCounter += Luts.Mode2Counter[(int)candidate.Mode];
|
||||
}
|
||||
@@ -898,7 +876,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Reader r)
|
||||
{
|
||||
BlockSize bsize = mi.SbType;
|
||||
bool allowHP = cm.AllowHighPrecisionMv;
|
||||
bool allowHp = cm.AllowHighPrecisionMv;
|
||||
Array2<Mv> bestRefMvs = new();
|
||||
int refr, isCompound;
|
||||
byte interModeCtx;
|
||||
@@ -908,13 +886,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
isCompound = mi.HasSecondRef() ? 1 : 0;
|
||||
interModeCtx = GetModeContext(ref cm, ref xd, mvRefSearch, miRow, miCol);
|
||||
|
||||
if (cm.Seg.IsSegFeatureActive(mi.SegmentId, SegLvlFeatures.SegLvlSkip) != 0)
|
||||
if (cm.Seg.IsSegFeatureActive(mi.SegmentId, SegLvlFeatures.Skip) != 0)
|
||||
{
|
||||
mi.Mode = PredictionMode.ZeroMv;
|
||||
if (bsize < BlockSize.Block8x8)
|
||||
{
|
||||
xd.ErrorInfo.Value.InternalError(CodecErr.CodecUnsupBitstream, "Invalid usage of segement feature on small blocks");
|
||||
|
||||
xd.ErrorInfo.Value.InternalError(CodecErr.UnsupBitstream,
|
||||
"Invalid usage of segement feature on small blocks");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -942,53 +920,58 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
sbyte frame = mi.RefFrame[refr];
|
||||
int refmvCount;
|
||||
|
||||
refmvCount = DecFindMvRefs(ref cm, ref xd, mi.Mode, frame, mvRefSearch, tmpMvs, miRow, miCol, -1, 0);
|
||||
refmvCount = DecFindRefs(ref cm, ref xd, mi.Mode, frame, mvRefSearch, tmpMvs, miRow, miCol,
|
||||
-1, 0);
|
||||
|
||||
DecFindBestRefMvs(allowHP, tmpMvs, ref bestRefMvs[refr], refmvCount);
|
||||
DecFindBestRefs(allowHp, tmpMvs, ref bestRefMvs[refr], refmvCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mi.InterpFilter = (cm.InterpFilter == Constants.Switchable) ? ReadSwitchableInterpFilter(ref cm, ref xd, ref r) : cm.InterpFilter;
|
||||
mi.InterpFilter = cm.InterpFilter == Constants.Switchable
|
||||
? ReadSwitchableInterpFilter(ref cm, ref xd, ref r)
|
||||
: cm.InterpFilter;
|
||||
|
||||
if (bsize < BlockSize.Block8x8)
|
||||
{
|
||||
int num4X4W = 1 << xd.BmodeBlocksWl;
|
||||
int num4X4H = 1 << xd.BmodeBlocksHl;
|
||||
int num4x4W = 1 << xd.BmodeBlocksWl;
|
||||
int num4x4H = 1 << xd.BmodeBlocksHl;
|
||||
int idx, idy;
|
||||
PredictionMode bMode = 0;
|
||||
Array2<Mv> bestSub8x8 = new();
|
||||
const uint InvalidMv = 0x80008000;
|
||||
const uint invalidMv = 0x80008000;
|
||||
// Initialize the 2nd element as even though it won't be used meaningfully
|
||||
// if isCompound is false.
|
||||
Unsafe.As<Mv, uint>(ref bestSub8x8[1]) = InvalidMv;
|
||||
for (idy = 0; idy < 2; idy += num4X4H)
|
||||
Unsafe.As<Mv, uint>(ref bestSub8x8[1]) = invalidMv;
|
||||
for (idy = 0; idy < 2; idy += num4x4H)
|
||||
{
|
||||
for (idx = 0; idx < 2; idx += num4X4W)
|
||||
for (idx = 0; idx < 2; idx += num4x4W)
|
||||
{
|
||||
int j = idy * 2 + idx;
|
||||
int j = (idy * 2) + idx;
|
||||
bMode = ReadInterMode(ref cm, ref xd, ref r, interModeCtx);
|
||||
|
||||
if (bMode == PredictionMode.NearestMv || bMode == PredictionMode.NearMv)
|
||||
{
|
||||
for (refr = 0; refr < 1 + isCompound; ++refr)
|
||||
{
|
||||
AppendSub8x8MvsForIdx(ref cm, ref xd, mvRefSearch, bMode, j, refr, miRow, miCol, ref bestSub8x8[refr]);
|
||||
AppendSub8x8ForIdx(ref cm, ref xd, mvRefSearch, bMode, j, refr, miRow, miCol,
|
||||
ref bestSub8x8[refr]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!AssignMv(ref cm, ref xd, bMode, ref mi.Bmi[j].Mv, ref bestRefMvs, ref bestSub8x8, isCompound, allowHP, ref r))
|
||||
if (!Assign(ref cm, ref xd, bMode, ref mi.Bmi[j].Mv, ref bestRefMvs, ref bestSub8x8,
|
||||
isCompound, allowHp, ref r))
|
||||
{
|
||||
xd.Corrupted |= true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (num4X4H == 2)
|
||||
if (num4x4H == 2)
|
||||
{
|
||||
mi.Bmi[j + 2] = mi.Bmi[j];
|
||||
}
|
||||
|
||||
if (num4X4W == 2)
|
||||
if (num4x4W == 2)
|
||||
{
|
||||
mi.Bmi[j + 1] = mi.Bmi[j];
|
||||
}
|
||||
@@ -997,11 +980,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
mi.Mode = bMode;
|
||||
|
||||
CopyMvPair(ref mi.Mv, ref mi.Bmi[3].Mv);
|
||||
CopyPair(ref mi.Mv, ref mi.Bmi[3].Mv);
|
||||
}
|
||||
else
|
||||
{
|
||||
xd.Corrupted |= !AssignMv(ref cm, ref xd, mi.Mode, ref mi.Mv, ref bestRefMvs, ref bestRefMvs, isCompound, allowHP, ref r);
|
||||
xd.Corrupted |= !Assign(ref cm, ref xd, mi.Mode, ref mi.Mv, ref bestRefMvs, ref bestRefMvs,
|
||||
isCompound, allowHp, ref r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1045,7 +1029,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
Debug.Assert(b == 1 || b == 3);
|
||||
|
||||
return curMi.Value.Bmi[b - 1].Mode;
|
||||
}
|
||||
|
||||
@@ -1062,7 +1045,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
Debug.Assert(b == 2 || b == 3);
|
||||
|
||||
return curMi.Value.Bmi[b - 2].Mode;
|
||||
}
|
||||
|
||||
@@ -1075,7 +1057,6 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
PredictionMode above = AboveBlockMode(mi, aboveMi, block);
|
||||
PredictionMode left = LeftBlockMode(mi, leftMi, block);
|
||||
|
||||
return fc.KfYModeProb[(int)above][(int)left].AsSpan();
|
||||
}
|
||||
|
||||
@@ -1092,8 +1073,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
Ptr<ModeInfo> aboveMi = xd.AboveMi;
|
||||
Ptr<ModeInfo> leftMi = xd.LeftMi;
|
||||
BlockSize bsize = mi.Value.SbType;
|
||||
int i;
|
||||
int miOffset = miRow * cm.MiCols + miCol;
|
||||
|
||||
int miOffset = (miRow * cm.MiCols) + miCol;
|
||||
|
||||
mi.Value.SegmentId = (sbyte)ReadIntraSegmentId(ref cm, miOffset, xMis, yMis, ref r);
|
||||
mi.Value.Skip = (sbyte)ReadSkip(ref cm, ref xd, mi.Value.SegmentId, ref r);
|
||||
@@ -1104,7 +1085,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
switch (bsize)
|
||||
{
|
||||
case BlockSize.Block4x4:
|
||||
for (i = 0; i < 4; ++i)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
mi.Value.Bmi[i].Mode =
|
||||
ReadIntraMode(ref r, GetYModeProbs(ref cm.Fc.Value, mi, aboveMi, leftMi, i));
|
||||
@@ -1149,8 +1130,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Reader r = ref twd.BitReader;
|
||||
ref MacroBlockD xd = ref twd.Xd;
|
||||
ref ModeInfo mi = ref xd.Mi[0].Value;
|
||||
ArrayPtr<MvRef> frameMvs = cm.CurFrameMvs.Slice(miRow * cm.MiCols + miCol);
|
||||
int w, h;
|
||||
ArrayPtr<MvRef> frameMvs = cm.CurFrameMvs.Slice((miRow * cm.MiCols) + miCol);
|
||||
|
||||
if (cm.FrameIsIntraOnly())
|
||||
{
|
||||
@@ -1160,17 +1140,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
ReadInterFrameModeInfo(ref cm, ref xd, miRow, miCol, ref r, xMis, yMis);
|
||||
|
||||
for (h = 0; h < yMis; ++h)
|
||||
for (int h = 0; h < yMis; ++h)
|
||||
{
|
||||
for (w = 0; w < xMis; ++w)
|
||||
for (int w = 0; w < xMis; ++w)
|
||||
{
|
||||
ref MvRef mv = ref frameMvs[w];
|
||||
CopyRefFramePair(ref mv.RefFrame, ref mi.RefFrame);
|
||||
CopyMvPair(ref mv.Mv, ref mi.Mv);
|
||||
CopyPair(ref mv.Mv, ref mi.Mv);
|
||||
}
|
||||
|
||||
frameMvs = frameMvs.Slice(cm.MiCols);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
@@ -12,14 +12,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private readonly MemoryAllocator _allocator = new();
|
||||
|
||||
public ISurface CreateSurface(int width, int height) => new Surface(width, height);
|
||||
public ISurface CreateSurface(int width, int height)
|
||||
{
|
||||
return new Surface(width, height);
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> LiteralToFilter => new byte[]
|
||||
{
|
||||
Constants.EightTapSmooth,
|
||||
Constants.EightTap,
|
||||
Constants.EightTapSharp,
|
||||
Constants.Bilinear,
|
||||
Constants.EightTapSmooth, Constants.EightTap, Constants.EightTapSharp, Constants.Bilinear
|
||||
};
|
||||
|
||||
public unsafe bool Decode(
|
||||
@@ -29,25 +29,24 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ReadOnlySpan<Vp9MvRef> mvsIn,
|
||||
Span<Vp9MvRef> mvsOut)
|
||||
{
|
||||
Vp9Common cm = new()
|
||||
{
|
||||
FrameType = pictureInfo.IsKeyFrame ? FrameType.KeyFrame : FrameType.InterFrame,
|
||||
IntraOnly = pictureInfo.IntraOnly,
|
||||
Vp9Common cm = new();
|
||||
|
||||
Width = output.Width,
|
||||
Height = output.Height,
|
||||
SubsamplingX = 1,
|
||||
SubsamplingY = 1,
|
||||
cm.FrameType = pictureInfo.IsKeyFrame ? FrameType.KeyFrame : FrameType.InterFrame;
|
||||
cm.IntraOnly = pictureInfo.IntraOnly;
|
||||
|
||||
UsePrevFrameMvs = pictureInfo.UsePrevInFindMvRefs,
|
||||
cm.Width = output.Width;
|
||||
cm.Height = output.Height;
|
||||
cm.SubsamplingX = 1;
|
||||
cm.SubsamplingY = 1;
|
||||
|
||||
RefFrameSignBias = pictureInfo.RefFrameSignBias,
|
||||
cm.UsePrevFrameMvs = pictureInfo.UsePrevInFindMvRefs;
|
||||
|
||||
BaseQindex = pictureInfo.BaseQIndex,
|
||||
YDcDeltaQ = pictureInfo.YDcDeltaQ,
|
||||
UvAcDeltaQ = pictureInfo.UvAcDeltaQ,
|
||||
UvDcDeltaQ = pictureInfo.UvDcDeltaQ,
|
||||
};
|
||||
cm.RefFrameSignBias = pictureInfo.RefFrameSignBias;
|
||||
|
||||
cm.BaseQindex = pictureInfo.BaseQIndex;
|
||||
cm.YDcDeltaQ = pictureInfo.YDcDeltaQ;
|
||||
cm.UvAcDeltaQ = pictureInfo.UvAcDeltaQ;
|
||||
cm.UvDcDeltaQ = pictureInfo.UvDcDeltaQ;
|
||||
|
||||
cm.Mb.Lossless = pictureInfo.Lossless;
|
||||
cm.Mb.Bd = 8;
|
||||
@@ -68,6 +67,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
cm.CompFixedRef = pictureInfo.CompFixedRef;
|
||||
cm.CompVarRef = pictureInfo.CompVarRef;
|
||||
|
||||
cm.BitDepth = BitDepth.Bits8;
|
||||
|
||||
cm.Log2TileCols = pictureInfo.Log2TileCols;
|
||||
cm.Log2TileRows = pictureInfo.Log2TileRows;
|
||||
|
||||
@@ -78,6 +79,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
cm.Seg.FeatureMask = pictureInfo.SegmentFeatureEnable;
|
||||
cm.Seg.FeatureData = pictureInfo.SegmentFeatureData;
|
||||
|
||||
cm.Lf.FilterLevel = pictureInfo.LoopFilterLevel;
|
||||
cm.Lf.SharpnessLevel = pictureInfo.LoopFilterSharpnessLevel;
|
||||
cm.Lf.ModeRefDeltaEnabled = pictureInfo.ModeRefDeltaEnabled;
|
||||
cm.Lf.RefDeltas = pictureInfo.RefDeltas;
|
||||
cm.Lf.ModeDeltas = pictureInfo.ModeDeltas;
|
||||
@@ -105,7 +108,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
cm.SetupSegmentationDequant();
|
||||
cm.SetupScaleFactors();
|
||||
|
||||
SetMvs(ref cm, mvsIn);
|
||||
cm.SetMvs(mvsIn);
|
||||
|
||||
if (cm.Lf.FilterLevel != 0 && cm.SkipLoopFilter == 0)
|
||||
{
|
||||
LoopFilter.LoopFilterFrameInit(ref cm, cm.Lf.FilterLevel);
|
||||
}
|
||||
|
||||
fixed (byte* dataPtr = bitstream)
|
||||
{
|
||||
@@ -114,10 +122,27 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (maxThreads > 1 && tileRows == 1 && tileCols > 1)
|
||||
{
|
||||
DecodeFrame.DecodeTilesMt(ref cm, new ArrayPtr<byte>(dataPtr, bitstream.Length), maxThreads);
|
||||
|
||||
LoopFilter.LoopFilterFrameMt(
|
||||
ref cm.Mb.CurBuf,
|
||||
ref cm,
|
||||
ref cm.Mb,
|
||||
cm.Lf.FilterLevel,
|
||||
false,
|
||||
false,
|
||||
maxThreads);
|
||||
}
|
||||
else
|
||||
{
|
||||
DecodeFrame.DecodeTiles(ref cm, new ArrayPtr<byte>(dataPtr, bitstream.Length));
|
||||
|
||||
LoopFilter.LoopFilterFrame(
|
||||
ref cm.Mb.CurBuf,
|
||||
ref cm,
|
||||
ref cm.Mb,
|
||||
cm.Lf.FilterLevel,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
}
|
||||
catch (InternalErrorException)
|
||||
@@ -126,7 +151,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
GetMvs(ref cm, mvsOut);
|
||||
cm.GetMvs(mvsOut);
|
||||
|
||||
cm.FreeTileWorkerData(_allocator);
|
||||
cm.FreeContextBuffers(_allocator);
|
||||
@@ -134,48 +159,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void SetMvs(ref Vp9Common cm, ReadOnlySpan<Vp9MvRef> mvs)
|
||||
public void Dispose()
|
||||
{
|
||||
if (mvs.Length > cm.PrevFrameMvs.Length)
|
||||
{
|
||||
throw new ArgumentException($"Size mismatch, expected: {cm.PrevFrameMvs.Length}, but got: {mvs.Length}.");
|
||||
}
|
||||
|
||||
for (int i = 0; i < mvs.Length; i++)
|
||||
{
|
||||
ref var mv = ref cm.PrevFrameMvs[i];
|
||||
|
||||
mv.Mv[0].Row = mvs[i].Mvs[0].Row;
|
||||
mv.Mv[0].Col = mvs[i].Mvs[0].Col;
|
||||
mv.Mv[1].Row = mvs[i].Mvs[1].Row;
|
||||
mv.Mv[1].Col = mvs[i].Mvs[1].Col;
|
||||
|
||||
mv.RefFrame[0] = (sbyte)mvs[i].RefFrames[0];
|
||||
mv.RefFrame[1] = (sbyte)mvs[i].RefFrames[1];
|
||||
}
|
||||
_allocator.Dispose();
|
||||
}
|
||||
|
||||
private static void GetMvs(ref Vp9Common cm, Span<Vp9MvRef> mvs)
|
||||
{
|
||||
if (mvs.Length > cm.CurFrameMvs.Length)
|
||||
{
|
||||
throw new ArgumentException($"Size mismatch, expected: {cm.CurFrameMvs.Length}, but got: {mvs.Length}.");
|
||||
}
|
||||
|
||||
for (int i = 0; i < mvs.Length; i++)
|
||||
{
|
||||
ref var mv = ref cm.CurFrameMvs[i];
|
||||
|
||||
mvs[i].Mvs[0].Row = mv.Mv[0].Row;
|
||||
mvs[i].Mvs[0].Col = mv.Mv[0].Col;
|
||||
mvs[i].Mvs[1].Row = mv.Mv[1].Row;
|
||||
mvs[i].Mvs[1].Col = mv.Mv[1].Col;
|
||||
|
||||
mvs[i].RefFrames[0] = mv.RefFrame[0];
|
||||
mvs[i].RefFrames[1] = mv.RefFrame[1];
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() => _allocator.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Dsp;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
@@ -17,26 +17,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private static int GetCoefContext(ReadOnlySpan<short> neighbors, ReadOnlySpan<byte> tokenCache, int c)
|
||||
{
|
||||
const int MaxNeighbors = 2;
|
||||
const int maxNeighbors = 2;
|
||||
|
||||
return (1 + tokenCache[neighbors[MaxNeighbors * c + 0]] + tokenCache[neighbors[MaxNeighbors * c + 1]]) >> 1;
|
||||
}
|
||||
|
||||
private static int ReadCoeff(
|
||||
ref Reader r,
|
||||
ReadOnlySpan<byte> probs,
|
||||
int n,
|
||||
ref ulong value,
|
||||
ref int count,
|
||||
ref uint range)
|
||||
{
|
||||
int i, val = 0;
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
val = (val << 1) | r.ReadBool(probs[i], ref value, ref count, ref range);
|
||||
}
|
||||
|
||||
return val;
|
||||
return (1 + tokenCache[neighbors[(maxNeighbors * c) + 0]] +
|
||||
tokenCache[neighbors[(maxNeighbors * c) + 1]]) >> 1;
|
||||
}
|
||||
|
||||
private static int DecodeCoefs(
|
||||
@@ -58,13 +42,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref Array6<Array6<Array3<byte>>> coefProbs = ref fc.CoefProbs[(int)txSize][(int)type][refr];
|
||||
Span<byte> tokenCache = stackalloc byte[32 * 32];
|
||||
ReadOnlySpan<byte> bandTranslate = Luts.GetBandTranslate(txSize);
|
||||
int dqShift = (txSize == TxSize.Tx32x32) ? 1 : 0;
|
||||
int dqShift = txSize == TxSize.Tx32x32 ? 1 : 0;
|
||||
int v;
|
||||
short dqv = dq[0];
|
||||
ReadOnlySpan<byte> cat6Prob = (xd.Bd == 12)
|
||||
? Luts.Vp9Cat6ProbHigh12
|
||||
: (xd.Bd == 10) ? Luts.Vp9Cat6ProbHigh12[2..] : Luts.Vp9Cat6Prob;
|
||||
int cat6Bits = (xd.Bd == 12) ? 18 : (xd.Bd == 10) ? 16 : 14;
|
||||
ReadOnlySpan<byte> cat6Prob = xd.Bd == 12
|
||||
? Luts.Cat6ProbHigh12
|
||||
: xd.Bd == 10
|
||||
? Luts.Cat6ProbHigh12.Slice(2)
|
||||
: Luts.Cat6Prob;
|
||||
int cat6Bits = xd.Bd == 12 ? 18 : xd.Bd == 10 ? 16 : 14;
|
||||
// Keep value, range, and count as locals. The compiler produces better
|
||||
// results with the locals than using r directly.
|
||||
ulong value = r.Value;
|
||||
@@ -75,7 +61,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
int val = -1;
|
||||
band = bandTranslate[0];
|
||||
bandTranslate = bandTranslate[1..];
|
||||
bandTranslate = bandTranslate.Slice(1);
|
||||
ref Array3<byte> prob = ref coefProbs[band][ctx];
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
@@ -107,18 +93,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
r.Value = value;
|
||||
r.Range = range;
|
||||
r.Count = count;
|
||||
|
||||
return c; // Zero tokens at the end (no eob token)
|
||||
}
|
||||
|
||||
ctx = GetCoefContext(nb, tokenCache, c);
|
||||
band = bandTranslate[0];
|
||||
bandTranslate = bandTranslate[1..];
|
||||
bandTranslate = bandTranslate.Slice(1);
|
||||
prob = ref coefProbs[band][ctx];
|
||||
}
|
||||
|
||||
if (r.ReadBool(prob[OneContextNode], ref value, ref count, ref range) != 0)
|
||||
{
|
||||
ReadOnlySpan<byte> p = Luts.Vp9Pareto8Full[prob[Constants.PivotNode] - 1];
|
||||
ReadOnlySpan<byte> p = Luts.Pareto8Full[prob[Constants.PivotNode] - 1];
|
||||
if (!xd.Counts.IsNull)
|
||||
{
|
||||
++counts.Coef[(int)txSize][(int)type][refr][band][ctx][Constants.TwoToken];
|
||||
@@ -133,20 +119,24 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
if (r.ReadBool(p[7], ref value, ref count, ref range) != 0)
|
||||
{
|
||||
val = Constants.Cat6MinVal + ReadCoeff(ref r, cat6Prob, cat6Bits, ref value, ref count, ref range);
|
||||
val = Constants.Cat6MinVal + r.ReadCoeff(cat6Prob, cat6Bits, ref value,
|
||||
ref count, ref range);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Constants.Cat5MinVal + ReadCoeff(ref r, Luts.Vp9Cat5Prob, 5, ref value, ref count, ref range);
|
||||
val = Constants.Cat5MinVal + r.ReadCoeff(Luts.Cat5Prob, 5, ref value,
|
||||
ref count, ref range);
|
||||
}
|
||||
}
|
||||
else if (r.ReadBool(p[6], ref value, ref count, ref range) != 0)
|
||||
{
|
||||
val = Constants.Cat4MinVal + ReadCoeff(ref r, Luts.Vp9Cat4Prob, 4, ref value, ref count, ref range);
|
||||
val = Constants.Cat4MinVal + r.ReadCoeff(Luts.Cat4Prob, 4, ref value, ref count,
|
||||
ref range);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Constants.Cat3MinVal + ReadCoeff(ref r, Luts.Vp9Cat3Prob, 3, ref value, ref count, ref range);
|
||||
val = Constants.Cat3MinVal + r.ReadCoeff(Luts.Cat3Prob, 3, ref value, ref count,
|
||||
ref range);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -154,13 +144,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
tokenCache[scan[c]] = 4;
|
||||
if (r.ReadBool(p[4], ref value, ref count, ref range) != 0)
|
||||
{
|
||||
val = Constants.Cat2MinVal + ReadCoeff(ref r, Luts.Vp9Cat2Prob, 2, ref value, ref count, ref range);
|
||||
val = Constants.Cat2MinVal + r.ReadCoeff(Luts.Cat2Prob, 2, ref value, ref count,
|
||||
ref range);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Constants.Cat1MinVal + ReadCoeff(ref r, Luts.Vp9Cat1Prob, 1, ref value, ref count, ref range);
|
||||
val = Constants.Cat1MinVal + r.ReadCoeff(Luts.Cat1Prob, 1, ref value, ref count,
|
||||
ref range);
|
||||
}
|
||||
}
|
||||
|
||||
// Val may use 18-bits
|
||||
v = (int)(((long)val * dqv) >> dqShift);
|
||||
}
|
||||
@@ -188,7 +181,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
tokenCache[scan[c]] = 1;
|
||||
v = dqv >> dqShift;
|
||||
}
|
||||
dqcoeff[scan[c]] = (int)HighbdCheckRange(r.ReadBool(128, ref value, ref count, ref range) != 0 ? -v : v, xd.Bd);
|
||||
|
||||
dqcoeff[scan[c]] = (int)HighbdCheckRange(r.ReadBool(128, ref value, ref count, ref range) != 0 ? -v : v,
|
||||
xd.Bd);
|
||||
++c;
|
||||
ctx = GetCoefContext(nb, tokenCache, c);
|
||||
dqv = dq[1];
|
||||
@@ -197,11 +192,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
r.Value = value;
|
||||
r.Range = range;
|
||||
r.Count = count;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private static void GetCtxShift(ref MacroBlockD xd, ref int ctxShiftA, ref int ctxShiftL, int x, int y, uint txSizeInBlocks)
|
||||
private static void GetCtxShift(ref MacroBlockD xd, ref int ctxShiftA, ref int ctxShiftL, int x, int y,
|
||||
uint txSizeInBlocks)
|
||||
{
|
||||
if (xd.MaxBlocksWide != 0)
|
||||
{
|
||||
@@ -210,6 +205,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ctxShiftA = (int)(txSizeInBlocks - (xd.MaxBlocksWide - x)) * 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (xd.MaxBlocksHigh != 0)
|
||||
{
|
||||
if (txSizeInBlocks + y > xd.MaxBlocksHigh)
|
||||
@@ -238,8 +234,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
ref MacroBlockDPlane pd = ref xd.Plane[plane];
|
||||
ref Array2<short> dequant = ref pd.SegDequant[segId];
|
||||
int eob;
|
||||
Span<sbyte> a = pd.AboveContext.AsSpan()[x..];
|
||||
Span<sbyte> l = pd.LeftContext.AsSpan()[y..];
|
||||
Span<sbyte> a = pd.AboveContext.AsSpan().Slice(x);
|
||||
Span<sbyte> l = pd.LeftContext.AsSpan().Slice(y);
|
||||
int ctx;
|
||||
int ctxShiftA = 0;
|
||||
int ctxShiftL = 0;
|
||||
@@ -324,4 +320,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
return eob;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -75,17 +75,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Vector128<int> zero = Vector128<int>.Zero;
|
||||
Vector128<int> const64 = Vector128.Create(64);
|
||||
|
||||
ulong x, y;
|
||||
src -= SubpelTaps / 2 - 1;
|
||||
src -= (SubpelTaps / 2) - 1;
|
||||
|
||||
fixed (Array8<short>* xFilter = xFilters)
|
||||
{
|
||||
Vector128<short> vfilter = Sse2.LoadVector128((short*)xFilter + (uint)(x0Q4 & SubpelMask) * 8);
|
||||
Vector128<short> vfilter = Sse2.LoadVector128((short*)xFilter + ((uint)(x0Q4 & SubpelMask) * 8));
|
||||
|
||||
for (y = 0; y < (uint)h; ++y)
|
||||
for (ulong y = 0; y < (uint)h; ++y)
|
||||
{
|
||||
ulong srcOffset = (uint)x0Q4 >> SubpelBits;
|
||||
for (x = 0; x < (uint)w; x += 4)
|
||||
for (ulong x = 0; x < (uint)w; x += 4)
|
||||
{
|
||||
Vector128<short> vsrc0 = Sse41.ConvertToVector128Int16(&src[srcOffset + x]);
|
||||
Vector128<short> vsrc1 = Sse41.ConvertToVector128Int16(&src[srcOffset + x + 1]);
|
||||
@@ -94,8 +93,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
Vector128<int> sum0123 = MultiplyAddAdjacent(vsrc0, vsrc1, vsrc2, vsrc3, vfilter, zero);
|
||||
|
||||
Sse.StoreScalar((float*)&dst[x], PackUnsignedSaturate(RoundShift(sum0123, const64), zero).AsSingle());
|
||||
Sse.StoreScalar((float*)&dst[x],
|
||||
PackUnsignedSaturate(RoundShift(sum0123, const64), zero).AsSingle());
|
||||
}
|
||||
|
||||
src += srcStride;
|
||||
dst += dstStride;
|
||||
}
|
||||
@@ -117,22 +118,20 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
if (Sse41.IsSupported && UseIntrinsics && xStepQ4 == 1 << SubpelBits)
|
||||
{
|
||||
ConvolveHorizSse41(src, srcStride, dst, dstStride, xFilters, x0Q4, w, h);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
src -= SubpelTaps / 2 - 1;
|
||||
src -= (SubpelTaps / 2) - 1;
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
int xQ4 = x0Q4;
|
||||
for (x = 0; x < w; ++x)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
byte* srcX = &src[xQ4 >> SubpelBits];
|
||||
ref Array8<short> xFilter = ref xFilters[xQ4 & SubpelMask];
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcX[k] * xFilter[k];
|
||||
}
|
||||
@@ -140,6 +139,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[x] = BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits));
|
||||
xQ4 += xStepQ4;
|
||||
}
|
||||
|
||||
src += srcStride;
|
||||
dst += dstStride;
|
||||
}
|
||||
@@ -156,25 +156,26 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
int x, y;
|
||||
src -= SubpelTaps / 2 - 1;
|
||||
src -= (SubpelTaps / 2) - 1;
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
int xQ4 = x0Q4;
|
||||
for (x = 0; x < w; ++x)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
byte* srcX = &src[xQ4 >> SubpelBits];
|
||||
ref Array8<short> xFilter = ref xFilters[xQ4 & SubpelMask];
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcX[k] * xFilter[k];
|
||||
}
|
||||
|
||||
dst[x] = (byte)BitUtils.RoundPowerOfTwo(dst[x] + BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits)), 1);
|
||||
dst[x] = (byte)BitUtils.RoundPowerOfTwo(
|
||||
dst[x] + BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits)), 1);
|
||||
xQ4 += xStepQ4;
|
||||
}
|
||||
|
||||
src += srcStride;
|
||||
dst += dstStride;
|
||||
}
|
||||
@@ -203,18 +204,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
srcStride * 6,
|
||||
srcStride * 7);
|
||||
|
||||
ulong x, y;
|
||||
src -= srcStride * (SubpelTaps / 2 - 1);
|
||||
src -= srcStride * ((SubpelTaps / 2) - 1);
|
||||
|
||||
fixed (Array8<short>* yFilter = yFilters)
|
||||
{
|
||||
Vector128<short> vfilter = Sse2.LoadVector128((short*)yFilter + (uint)(y0Q4 & SubpelMask) * 8);
|
||||
Vector128<short> vfilter = Sse2.LoadVector128((short*)yFilter + ((uint)(y0Q4 & SubpelMask) * 8));
|
||||
|
||||
ulong srcBaseY = (uint)y0Q4 >> SubpelBits;
|
||||
for (y = 0; y < (uint)h; ++y)
|
||||
for (ulong y = 0; y < (uint)h; ++y)
|
||||
{
|
||||
ulong srcOffset = (srcBaseY + y) * (uint)srcStride;
|
||||
for (x = 0; x < (uint)w; x += 4)
|
||||
for (ulong x = 0; x < (uint)w; x += 4)
|
||||
{
|
||||
Vector256<int> vsrc = Avx2.GatherVector256((uint*)&src[srcOffset + x], indices, 1).AsInt32();
|
||||
|
||||
@@ -240,8 +240,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
Vector128<int> sum0123 = MultiplyAddAdjacent(vsrc0, vsrc1, vsrc2, vsrc3, vfilter, zero);
|
||||
|
||||
Sse.StoreScalar((float*)&dst[x], PackUnsignedSaturate(RoundShift(sum0123, const64), zero).AsSingle());
|
||||
Sse.StoreScalar((float*)&dst[x],
|
||||
PackUnsignedSaturate(RoundShift(sum0123, const64), zero).AsSingle());
|
||||
}
|
||||
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
||||
@@ -262,22 +264,20 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
if (Avx2.IsSupported && UseIntrinsics && yStepQ4 == 1 << SubpelBits)
|
||||
{
|
||||
ConvolveVertAvx2(src, srcStride, dst, dstStride, yFilters, y0Q4, w, h);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
src -= srcStride * (SubpelTaps / 2 - 1);
|
||||
src -= srcStride * ((SubpelTaps / 2) - 1);
|
||||
|
||||
for (x = 0; x < w; ++x)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
int yQ4 = y0Q4;
|
||||
for (y = 0; y < h; ++y)
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
byte* srcY = &src[(yQ4 >> SubpelBits) * srcStride];
|
||||
ref Array8<short> yFilter = ref yFilters[yQ4 & SubpelMask];
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcY[k * srcStride] * yFilter[k];
|
||||
}
|
||||
@@ -285,6 +285,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[y * dstStride] = BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits));
|
||||
yQ4 += yStepQ4;
|
||||
}
|
||||
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
@@ -301,18 +302,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
int x, y;
|
||||
src -= srcStride * (SubpelTaps / 2 - 1);
|
||||
src -= srcStride * ((SubpelTaps / 2) - 1);
|
||||
|
||||
for (x = 0; x < w; ++x)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
int yQ4 = y0Q4;
|
||||
for (y = 0; y < h; ++y)
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
byte* srcY = &src[(yQ4 >> SubpelBits) * srcStride];
|
||||
ref Array8<short> yFilter = ref yFilters[yQ4 & SubpelMask];
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcY[k * srcStride] * yFilter[k];
|
||||
}
|
||||
@@ -321,6 +321,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[y * dstStride] + BitUtils.ClipPixel(BitUtils.RoundPowerOfTwo(sum, FilterBits)), 1);
|
||||
yQ4 += yStepQ4;
|
||||
}
|
||||
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
@@ -420,15 +421,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
// ==> yStepQ4 = 64. Since w and h are at most 16, the temp buffer is still
|
||||
// big enough.
|
||||
byte* temp = stackalloc byte[64 * 135];
|
||||
int intermediateHeight = (((h - 1) * yStepQ4 + y0Q4) >> SubpelBits) + SubpelTaps;
|
||||
int intermediateHeight = ((((h - 1) * yStepQ4) + y0Q4) >> SubpelBits) + SubpelTaps;
|
||||
|
||||
Debug.Assert(w <= 64);
|
||||
Debug.Assert(h <= 64);
|
||||
Debug.Assert(yStepQ4 <= 32 || (yStepQ4 <= 64 && h <= 32));
|
||||
Debug.Assert(xStepQ4 <= 64);
|
||||
|
||||
ConvolveHoriz(src - srcStride * (SubpelTaps / 2 - 1), srcStride, temp, 64, filter, x0Q4, xStepQ4, w, intermediateHeight);
|
||||
ConvolveVert(temp + 64 * (SubpelTaps / 2 - 1), 64, dst, dstStride, filter, y0Q4, yStepQ4, w, h);
|
||||
ConvolveHoriz(src - (srcStride * ((SubpelTaps / 2) - 1)), srcStride, temp, 64, filter, x0Q4, xStepQ4, w,
|
||||
intermediateHeight);
|
||||
ConvolveVert(temp + (64 * ((SubpelTaps / 2) - 1)), 64, dst, dstStride, filter, y0Q4, yStepQ4, w, h);
|
||||
}
|
||||
|
||||
public static unsafe void Convolve8Avg(
|
||||
@@ -489,11 +491,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
for (x = 0; x < w; ++x)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
dst[x] = (byte)BitUtils.RoundPowerOfTwo(dst[x] + src[x], 1);
|
||||
}
|
||||
@@ -611,18 +611,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int h,
|
||||
int bd)
|
||||
{
|
||||
int x, y;
|
||||
src -= SubpelTaps / 2 - 1;
|
||||
src -= (SubpelTaps / 2) - 1;
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
int xQ4 = x0Q4;
|
||||
for (x = 0; x < w; ++x)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
ushort* srcX = &src[xQ4 >> SubpelBits];
|
||||
ref Array8<short> xFilter = ref xFilters[xQ4 & SubpelMask];
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcX[k] * xFilter[k];
|
||||
}
|
||||
@@ -630,6 +629,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[x] = BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd);
|
||||
xQ4 += xStepQ4;
|
||||
}
|
||||
|
||||
src += srcStride;
|
||||
dst += dstStride;
|
||||
}
|
||||
@@ -647,25 +647,26 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int h,
|
||||
int bd)
|
||||
{
|
||||
int x, y;
|
||||
src -= SubpelTaps / 2 - 1;
|
||||
src -= (SubpelTaps / 2) - 1;
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
int xQ4 = x0Q4;
|
||||
for (x = 0; x < w; ++x)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
ushort* srcX = &src[xQ4 >> SubpelBits];
|
||||
ref Array8<short> xFilter = ref xFilters[xQ4 & SubpelMask];
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcX[k] * xFilter[k];
|
||||
}
|
||||
|
||||
dst[x] = (ushort)BitUtils.RoundPowerOfTwo(dst[x] + BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd), 1);
|
||||
dst[x] = (ushort)BitUtils.RoundPowerOfTwo(
|
||||
dst[x] + BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd), 1);
|
||||
xQ4 += xStepQ4;
|
||||
}
|
||||
|
||||
src += srcStride;
|
||||
dst += dstStride;
|
||||
}
|
||||
@@ -683,18 +684,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int h,
|
||||
int bd)
|
||||
{
|
||||
int x, y;
|
||||
src -= srcStride * (SubpelTaps / 2 - 1);
|
||||
src -= srcStride * ((SubpelTaps / 2) - 1);
|
||||
|
||||
for (x = 0; x < w; ++x)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
int yQ4 = y0Q4;
|
||||
for (y = 0; y < h; ++y)
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
ushort* srcY = &src[(yQ4 >> SubpelBits) * srcStride];
|
||||
ref Array8<short> yFilter = ref yFilters[yQ4 & SubpelMask];
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcY[k * srcStride] * yFilter[k];
|
||||
}
|
||||
@@ -702,6 +702,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[y * dstStride] = BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd);
|
||||
yQ4 += yStepQ4;
|
||||
}
|
||||
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
@@ -719,26 +720,27 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int h,
|
||||
int bd)
|
||||
{
|
||||
int x, y;
|
||||
src -= srcStride * (SubpelTaps / 2 - 1);
|
||||
src -= srcStride * ((SubpelTaps / 2) - 1);
|
||||
|
||||
for (x = 0; x < w; ++x)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
int yQ4 = y0Q4;
|
||||
for (y = 0; y < h; ++y)
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
ushort* srcY = &src[(yQ4 >> SubpelBits) * srcStride];
|
||||
ref Array8<short> yFilter = ref yFilters[yQ4 & SubpelMask];
|
||||
int k, sum = 0;
|
||||
for (k = 0; k < SubpelTaps; ++k)
|
||||
int sum = 0;
|
||||
for (int k = 0; k < SubpelTaps; ++k)
|
||||
{
|
||||
sum += srcY[k * srcStride] * yFilter[k];
|
||||
}
|
||||
|
||||
dst[y * dstStride] = (ushort)BitUtils.RoundPowerOfTwo(
|
||||
dst[y * dstStride] + BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd), 1);
|
||||
dst[y * dstStride] + BitUtils.ClipPixelHighbd(BitUtils.RoundPowerOfTwo(sum, FilterBits), bd),
|
||||
1);
|
||||
yQ4 += yStepQ4;
|
||||
}
|
||||
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
@@ -771,15 +773,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
// --Require an additional SubpelTaps rows for the 8-tap filter tails.
|
||||
// --((64 - 1) * 32 + 15) >> 4 + 8 = 135.
|
||||
ushort* temp = stackalloc ushort[64 * 135];
|
||||
int intermediateHeight = (((h - 1) * yStepQ4 + y0Q4) >> SubpelBits) + SubpelTaps;
|
||||
int intermediateHeight = ((((h - 1) * yStepQ4) + y0Q4) >> SubpelBits) + SubpelTaps;
|
||||
|
||||
Debug.Assert(w <= 64);
|
||||
Debug.Assert(h <= 64);
|
||||
Debug.Assert(yStepQ4 <= 32);
|
||||
Debug.Assert(xStepQ4 <= 32);
|
||||
|
||||
HighbdConvolveHoriz(src - srcStride * (SubpelTaps / 2 - 1), srcStride, temp, 64, filter, x0Q4, xStepQ4, w, intermediateHeight, bd);
|
||||
HighbdConvolveVert(temp + 64 * (SubpelTaps / 2 - 1), 64, dst, dstStride, filter, y0Q4, yStepQ4, w, h, bd);
|
||||
HighbdConvolveHoriz(src - (srcStride * ((SubpelTaps / 2) - 1)), srcStride, temp, 64, filter, x0Q4, xStepQ4,
|
||||
w, intermediateHeight, bd);
|
||||
HighbdConvolveVert(temp + (64 * ((SubpelTaps / 2) - 1)), 64, dst, dstStride, filter, y0Q4, yStepQ4, w, h,
|
||||
bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdConvolve8Horiz(
|
||||
@@ -928,11 +932,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
int h,
|
||||
int bd)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
for (x = 0; x < w; ++x)
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
dst[x] = (ushort)BitUtils.RoundPowerOfTwo(dst[x] + src[x], 1);
|
||||
}
|
||||
@@ -942,4 +944,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
public const int SubpelShifts = 1 << SubpelBits;
|
||||
public const int SubpelTaps = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
@@ -6,22 +6,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
private static unsafe ref byte Dst(byte* dst, int stride, int x, int y)
|
||||
{
|
||||
return ref dst[x + y * stride];
|
||||
return ref dst[x + (y * stride)];
|
||||
}
|
||||
|
||||
private static unsafe ref ushort Dst(ushort* dst, int stride, int x, int y)
|
||||
{
|
||||
return ref dst[x + y * stride];
|
||||
return ref dst[x + (y * stride)];
|
||||
}
|
||||
|
||||
private static byte Avg3(byte a, byte b, byte c)
|
||||
{
|
||||
return (byte)((a + 2 * b + c + 2) >> 2);
|
||||
return (byte)((a + (2 * b) + c + 2) >> 2);
|
||||
}
|
||||
|
||||
private static ushort Avg3(ushort a, ushort b, ushort c)
|
||||
{
|
||||
return (ushort)((a + 2 * b + c + 2) >> 2);
|
||||
return (ushort)((a + (2 * b) + c + 2) >> 2);
|
||||
}
|
||||
|
||||
private static byte Avg2(byte a, byte b)
|
||||
@@ -51,9 +51,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void D207Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r, c;
|
||||
// First column
|
||||
for (r = 0; r < bs - 1; ++r)
|
||||
for (int r = 0; r < bs - 1; ++r)
|
||||
{
|
||||
dst[r * stride] = Avg2(left[r], left[r + 1]);
|
||||
}
|
||||
@@ -62,7 +61,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst++;
|
||||
|
||||
// Second column
|
||||
for (r = 0; r < bs - 2; ++r)
|
||||
for (int r = 0; r < bs - 2; ++r)
|
||||
{
|
||||
dst[r * stride] = Avg3(left[r], left[r + 1], left[r + 2]);
|
||||
}
|
||||
@@ -72,16 +71,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst++;
|
||||
|
||||
// Rest of last row
|
||||
for (c = 0; c < bs - 2; ++c)
|
||||
for (int c = 0; c < bs - 2; ++c)
|
||||
{
|
||||
dst[(bs - 1) * stride + c] = left[bs - 1];
|
||||
dst[((bs - 1) * stride) + c] = left[bs - 1];
|
||||
}
|
||||
|
||||
for (r = bs - 2; r >= 0; --r)
|
||||
for (int r = bs - 2; r >= 0; --r)
|
||||
{
|
||||
for (c = 0; c < bs - 2; ++c)
|
||||
for (int c = 0; c < bs - 2; ++c)
|
||||
{
|
||||
dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
|
||||
dst[(r * stride) + c] = dst[((r + 1) * stride) + c - 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,19 +102,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void D63Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r, c;
|
||||
int size;
|
||||
for (c = 0; c < bs; ++c)
|
||||
for (int c = 0; c < bs; ++c)
|
||||
{
|
||||
dst[c] = Avg2(above[c], above[c + 1]);
|
||||
dst[stride + c] = Avg3(above[c], above[c + 1], above[c + 2]);
|
||||
}
|
||||
for (r = 2, size = bs - 2; r < bs; r += 2, --size)
|
||||
|
||||
for (int r = 2, size = bs - 2; r < bs; r += 2, --size)
|
||||
{
|
||||
MemoryUtil.Copy(dst + (r + 0) * stride, dst + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + (r + 0) * stride + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + (r + 1) * stride, dst + stride + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + (r + 1) * stride + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + ((r + 0) * stride), dst + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + ((r + 0) * stride) + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + ((r + 1) * stride), dst + stride + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + ((r + 1) * stride) + size, above[bs - 1], bs - size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,15 +136,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
byte aboveRight = above[bs - 1];
|
||||
byte* dstRow0 = dst;
|
||||
int x, size;
|
||||
|
||||
for (x = 0; x < bs - 1; ++x)
|
||||
for (int x = 0; x < bs - 1; ++x)
|
||||
{
|
||||
dst[x] = Avg3(above[x], above[x + 1], above[x + 2]);
|
||||
}
|
||||
|
||||
dst[bs - 1] = aboveRight;
|
||||
dst += stride;
|
||||
for (x = 1, size = bs - 2; x < bs; ++x, --size)
|
||||
for (int x = 1, size = bs - 2; x < bs; ++x, --size)
|
||||
{
|
||||
MemoryUtil.Copy(dst, dstRow0 + x, size);
|
||||
MemoryUtil.Fill(dst + size, aboveRight, x + 1);
|
||||
@@ -171,10 +169,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void D117Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r, c;
|
||||
|
||||
// First row
|
||||
for (c = 0; c < bs; c++)
|
||||
for (int c = 0; c < bs; c++)
|
||||
{
|
||||
dst[c] = Avg2(above[c - 1], above[c]);
|
||||
}
|
||||
@@ -183,7 +179,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
// Second row
|
||||
dst[0] = Avg3(left[0], above[-1], above[0]);
|
||||
for (c = 1; c < bs; c++)
|
||||
for (int c = 1; c < bs; c++)
|
||||
{
|
||||
dst[c] = Avg3(above[c - 2], above[c - 1], above[c]);
|
||||
}
|
||||
@@ -192,17 +188,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
// The rest of first col
|
||||
dst[0] = Avg3(above[-1], left[0], left[1]);
|
||||
for (r = 3; r < bs; ++r)
|
||||
for (int r = 3; r < bs; ++r)
|
||||
{
|
||||
dst[(r - 2) * stride] = Avg3(left[r - 3], left[r - 2], left[r - 1]);
|
||||
}
|
||||
|
||||
// The rest of the block
|
||||
for (r = 2; r < bs; ++r)
|
||||
for (int r = 2; r < bs; ++r)
|
||||
{
|
||||
for (c = 1; c < bs; c++)
|
||||
for (int c = 1; c < bs; c++)
|
||||
{
|
||||
dst[c] = dst[-2 * stride + c - 1];
|
||||
dst[c] = dst[(-2 * stride) + c - 1];
|
||||
}
|
||||
|
||||
dst += stride;
|
||||
@@ -226,26 +222,26 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void D135Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int i;
|
||||
byte* border = stackalloc byte[32 + 32 - 1]; // outer border from bottom-left to top-right
|
||||
|
||||
// Dst(dst, stride, bs, bs - 2)[0], i.e., border starting at bottom-left
|
||||
for (i = 0; i < bs - 2; ++i)
|
||||
for (int i = 0; i < bs - 2; ++i)
|
||||
{
|
||||
border[i] = Avg3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]);
|
||||
}
|
||||
|
||||
border[bs - 2] = Avg3(above[-1], left[0], left[1]);
|
||||
border[bs - 1] = Avg3(left[0], above[-1], above[0]);
|
||||
border[bs - 0] = Avg3(above[-1], above[0], above[1]);
|
||||
// dst[0][2, size), i.e., remaining top border ascending
|
||||
for (i = 0; i < bs - 2; ++i)
|
||||
for (int i = 0; i < bs - 2; ++i)
|
||||
{
|
||||
border[bs + 1 + i] = Avg3(above[i], above[i + 1], above[i + 2]);
|
||||
}
|
||||
|
||||
for (i = 0; i < bs; ++i)
|
||||
for (int i = 0; i < bs; ++i)
|
||||
{
|
||||
MemoryUtil.Copy(dst + i * stride, border + bs - 1 - i, bs);
|
||||
MemoryUtil.Copy(dst + (i * stride), border + bs - 1 - i, bs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,9 +262,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void D153Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r, c;
|
||||
dst[0] = Avg2(above[-1], left[0]);
|
||||
for (r = 1; r < bs; r++)
|
||||
for (int r = 1; r < bs; r++)
|
||||
{
|
||||
dst[r * stride] = Avg2(left[r - 1], left[r]);
|
||||
}
|
||||
@@ -277,23 +272,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
dst[0] = Avg3(left[0], above[-1], above[0]);
|
||||
dst[stride] = Avg3(above[-1], left[0], left[1]);
|
||||
for (r = 2; r < bs; r++)
|
||||
for (int r = 2; r < bs; r++)
|
||||
{
|
||||
dst[r * stride] = Avg3(left[r - 2], left[r - 1], left[r]);
|
||||
}
|
||||
|
||||
dst++;
|
||||
|
||||
for (c = 0; c < bs - 2; c++)
|
||||
for (int c = 0; c < bs - 2; c++)
|
||||
{
|
||||
dst[c] = Avg3(above[c - 1], above[c], above[c + 1]);
|
||||
}
|
||||
|
||||
dst += stride;
|
||||
|
||||
for (r = 1; r < bs; ++r)
|
||||
for (int r = 1; r < bs; ++r)
|
||||
{
|
||||
for (c = 0; c < bs - 2; c++)
|
||||
for (int c = 0; c < bs - 2; c++)
|
||||
{
|
||||
dst[c] = dst[-stride + c - 2];
|
||||
}
|
||||
@@ -324,9 +319,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void VPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Copy(dst, above, bs);
|
||||
dst += stride;
|
||||
@@ -355,43 +348,40 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void HPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, left[r], bs);
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void TMPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TmPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TMPredictor(dst, stride, 4, above, left);
|
||||
TmPredictor(dst, stride, 4, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void TMPredictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TmPredictor8x8(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TMPredictor(dst, stride, 8, above, left);
|
||||
TmPredictor(dst, stride, 8, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void TMPredictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TmPredictor16x16(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TMPredictor(dst, stride, 16, above, left);
|
||||
TmPredictor(dst, stride, 16, above, left);
|
||||
}
|
||||
|
||||
public static unsafe void TMPredictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void TmPredictor32x32(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
TMPredictor(dst, stride, 32, above, left);
|
||||
TmPredictor(dst, stride, 32, above, left);
|
||||
}
|
||||
|
||||
private static unsafe void TMPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
private static unsafe void TmPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r, c;
|
||||
int yTopLeft = above[-1];
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
for (c = 0; c < bs; c++)
|
||||
for (int c = 0; c < bs; c++)
|
||||
{
|
||||
dst[c] = BitUtils.ClipPixel(left[r] + above[c] - yTopLeft);
|
||||
}
|
||||
@@ -422,9 +412,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void Dc128Predictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int r;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (byte)128, bs);
|
||||
dst += stride;
|
||||
@@ -453,16 +441,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void DcLeftPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int i, r, expectedDc, sum = 0;
|
||||
int expectedDc, sum = 0;
|
||||
|
||||
for (i = 0; i < bs; i++)
|
||||
for (int i = 0; i < bs; i++)
|
||||
{
|
||||
sum += left[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (byte)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -491,16 +479,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void DcTopPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int i, r, expectedDc, sum = 0;
|
||||
int expectedDc, sum = 0;
|
||||
|
||||
for (i = 0; i < bs; i++)
|
||||
for (int i = 0; i < bs; i++)
|
||||
{
|
||||
sum += above[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (byte)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -529,10 +517,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
private static unsafe void DcPredictor(byte* dst, int stride, int bs, byte* above, byte* left)
|
||||
{
|
||||
int i, r, expectedDc, sum = 0;
|
||||
int expectedDc, sum = 0;
|
||||
int count = 2 * bs;
|
||||
|
||||
for (i = 0; i < bs; i++)
|
||||
for (int i = 0; i < bs; i++)
|
||||
{
|
||||
sum += above[i];
|
||||
sum += left[i];
|
||||
@@ -540,7 +528,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
expectedDc = (sum + (count >> 1)) / count;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (byte)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -555,10 +543,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
byte k = left[2];
|
||||
byte l = left[3];
|
||||
|
||||
MemoryUtil.Fill(dst + stride * 0, Avg3(h, I, j), 4);
|
||||
MemoryUtil.Fill(dst + stride * 1, Avg3(I, j, k), 4);
|
||||
MemoryUtil.Fill(dst + stride * 2, Avg3(j, k, l), 4);
|
||||
MemoryUtil.Fill(dst + stride * 3, Avg3(k, l, l), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 0), Avg3(h, I, j), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 1), Avg3(I, j, k), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 2), Avg3(j, k, l), 4);
|
||||
MemoryUtil.Fill(dst + (stride * 3), Avg3(k, l, l), 4);
|
||||
}
|
||||
|
||||
public static unsafe void VePredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
@@ -574,9 +562,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
dst[1] = Avg3(I, j, k);
|
||||
dst[2] = Avg3(j, k, l);
|
||||
dst[3] = Avg3(k, l, m);
|
||||
MemoryUtil.Copy(dst + stride * 1, dst, 4);
|
||||
MemoryUtil.Copy(dst + stride * 2, dst, 4);
|
||||
MemoryUtil.Copy(dst + stride * 3, dst, 4);
|
||||
MemoryUtil.Copy(dst + (stride * 1), dst, 4);
|
||||
MemoryUtil.Copy(dst + (stride * 2), dst, 4);
|
||||
MemoryUtil.Copy(dst + (stride * 3), dst, 4);
|
||||
}
|
||||
|
||||
public static unsafe void D207Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
@@ -591,7 +579,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 1, 0) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 1, 1) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 1, 2) = Avg3(k, l, l);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 0, 3) = Dst(dst, stride, 1, 3) = Dst(dst, stride, 2, 3) = Dst(dst, stride, 3, 3) = l;
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 0, 3) =
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 2, 3) = Dst(dst, stride, 3, 3) = l;
|
||||
}
|
||||
|
||||
public static unsafe void D63Predictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
@@ -616,7 +605,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 3, 3) = Avg3(e, f, g); // Differs from vp8
|
||||
}
|
||||
|
||||
public static unsafe void D63ePredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D63EPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte a = above[0];
|
||||
byte b = above[1];
|
||||
@@ -652,13 +641,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 0, 0) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 0, 1) = Avg3(b, c, d);
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 2) = Avg3(c, d, e);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 0) =
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 3) = Avg3(e, f, g);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 3) = Avg3(f, g, h);
|
||||
Dst(dst, stride, 3, 3) = h; // differs from vp8
|
||||
}
|
||||
|
||||
public static unsafe void D45ePredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
public static unsafe void D45EPredictor4x4(byte* dst, int stride, byte* above, byte* left)
|
||||
{
|
||||
byte a = above[0];
|
||||
byte b = above[1];
|
||||
@@ -671,7 +661,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 0, 0) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 0, 1) = Avg3(b, c, d);
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 2) = Avg3(c, d, e);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 0) =
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 3) = Avg3(e, f, g);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 3) = Avg3(f, g, h);
|
||||
Dst(dst, stride, 3, 3) = Avg3(g, h, h);
|
||||
@@ -714,7 +705,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 0, 3) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 0, 2) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 2, 3) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 1) = Avg3(x, I, j);
|
||||
Dst(dst, stride, 3, 3) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, I);
|
||||
Dst(dst, stride, 3, 3) =
|
||||
Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, I);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 0) = Avg3(b, a, x);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 0) = Avg3(c, b, a);
|
||||
Dst(dst, stride, 3, 0) = Avg3(d, c, b);
|
||||
@@ -758,38 +750,39 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD207Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD207Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdD207Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int r, c;
|
||||
|
||||
// First column.
|
||||
for (r = 0; r < bs - 1; ++r)
|
||||
for (int r = 0; r < bs - 1; ++r)
|
||||
{
|
||||
dst[r * stride] = Avg2(left[r], left[r + 1]);
|
||||
}
|
||||
|
||||
dst[(bs - 1) * stride] = left[bs - 1];
|
||||
dst++;
|
||||
|
||||
// Second column.
|
||||
for (r = 0; r < bs - 2; ++r)
|
||||
for (int r = 0; r < bs - 2; ++r)
|
||||
{
|
||||
dst[r * stride] = Avg3(left[r], left[r + 1], left[r + 2]);
|
||||
}
|
||||
|
||||
dst[(bs - 2) * stride] = Avg3(left[bs - 2], left[bs - 1], left[bs - 1]);
|
||||
dst[(bs - 1) * stride] = left[bs - 1];
|
||||
dst++;
|
||||
|
||||
// Rest of last row.
|
||||
for (c = 0; c < bs - 2; ++c)
|
||||
for (int c = 0; c < bs - 2; ++c)
|
||||
{
|
||||
dst[(bs - 1) * stride + c] = left[bs - 1];
|
||||
dst[((bs - 1) * stride) + c] = left[bs - 1];
|
||||
}
|
||||
|
||||
for (r = bs - 2; r >= 0; --r)
|
||||
for (int r = bs - 2; r >= 0; --r)
|
||||
{
|
||||
for (c = 0; c < bs - 2; ++c)
|
||||
for (int c = 0; c < bs - 2; ++c)
|
||||
{
|
||||
dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
|
||||
dst[(r * stride) + c] = dst[((r + 1) * stride) + c - 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -809,21 +802,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD63Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD63Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdD63Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int r, c;
|
||||
int size;
|
||||
for (c = 0; c < bs; ++c)
|
||||
for (int c = 0; c < bs; ++c)
|
||||
{
|
||||
dst[c] = Avg2(above[c], above[c + 1]);
|
||||
dst[stride + c] = Avg3(above[c], above[c + 1], above[c + 2]);
|
||||
}
|
||||
for (r = 2, size = bs - 2; r < bs; r += 2, --size)
|
||||
|
||||
for (int r = 2, size = bs - 2; r < bs; r += 2, --size)
|
||||
{
|
||||
MemoryUtil.Copy(dst + (r + 0) * stride, dst + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + (r + 0) * stride + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + (r + 1) * stride, dst + stride + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + (r + 1) * stride + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + ((r + 0) * stride), dst + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + ((r + 0) * stride) + size, above[bs - 1], bs - size);
|
||||
MemoryUtil.Copy(dst + ((r + 1) * stride), dst + stride + (r >> 1), size);
|
||||
MemoryUtil.Fill(dst + ((r + 1) * stride) + size, above[bs - 1], bs - size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -842,19 +835,20 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD45Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD45Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdD45Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
ushort aboveRight = above[bs - 1];
|
||||
ushort* dstRow0 = dst;
|
||||
int x, size;
|
||||
|
||||
for (x = 0; x < bs - 1; ++x)
|
||||
for (int x = 0; x < bs - 1; ++x)
|
||||
{
|
||||
dst[x] = Avg3(above[x], above[x + 1], above[x + 2]);
|
||||
}
|
||||
|
||||
dst[bs - 1] = aboveRight;
|
||||
dst += stride;
|
||||
for (x = 1, size = bs - 2; x < bs; ++x, --size)
|
||||
for (int x = 1, size = bs - 2; x < bs; ++x, --size)
|
||||
{
|
||||
MemoryUtil.Copy(dst, dstRow0 + x, size);
|
||||
MemoryUtil.Fill(dst + size, aboveRight, x + 1);
|
||||
@@ -877,12 +871,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD117Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD117Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdD117Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int r, c;
|
||||
|
||||
// First row
|
||||
for (c = 0; c < bs; c++)
|
||||
for (int c = 0; c < bs; c++)
|
||||
{
|
||||
dst[c] = Avg2(above[c - 1], above[c]);
|
||||
}
|
||||
@@ -891,7 +884,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
// Second row
|
||||
dst[0] = Avg3(left[0], above[-1], above[0]);
|
||||
for (c = 1; c < bs; c++)
|
||||
for (int c = 1; c < bs; c++)
|
||||
{
|
||||
dst[c] = Avg3(above[c - 2], above[c - 1], above[c]);
|
||||
}
|
||||
@@ -900,17 +893,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
// The rest of first col
|
||||
dst[0] = Avg3(above[-1], left[0], left[1]);
|
||||
for (r = 3; r < bs; ++r)
|
||||
for (int r = 3; r < bs; ++r)
|
||||
{
|
||||
dst[(r - 2) * stride] = Avg3(left[r - 3], left[r - 2], left[r - 1]);
|
||||
}
|
||||
|
||||
// The rest of the block
|
||||
for (r = 2; r < bs; ++r)
|
||||
for (int r = 2; r < bs; ++r)
|
||||
{
|
||||
for (c = 1; c < bs; c++)
|
||||
for (int c = 1; c < bs; c++)
|
||||
{
|
||||
dst[c] = dst[-2 * stride + c - 1];
|
||||
dst[c] = dst[(-2 * stride) + c - 1];
|
||||
}
|
||||
|
||||
dst += stride;
|
||||
@@ -932,28 +925,29 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD135Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD135Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdD135Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int i;
|
||||
ushort* border = stackalloc ushort[32 + 32 - 1]; // Outer border from bottom-left to top-right
|
||||
|
||||
// Dst(dst, stride, bs, bs - 2)[0], i.e., border starting at bottom-left
|
||||
for (i = 0; i < bs - 2; ++i)
|
||||
for (int i = 0; i < bs - 2; ++i)
|
||||
{
|
||||
border[i] = Avg3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]);
|
||||
}
|
||||
|
||||
border[bs - 2] = Avg3(above[-1], left[0], left[1]);
|
||||
border[bs - 1] = Avg3(left[0], above[-1], above[0]);
|
||||
border[bs - 0] = Avg3(above[-1], above[0], above[1]);
|
||||
// dst[0][2, size), i.e., remaining top border ascending
|
||||
for (i = 0; i < bs - 2; ++i)
|
||||
for (int i = 0; i < bs - 2; ++i)
|
||||
{
|
||||
border[bs + 1 + i] = Avg3(above[i], above[i + 1], above[i + 2]);
|
||||
}
|
||||
|
||||
for (i = 0; i < bs; ++i)
|
||||
for (int i = 0; i < bs; ++i)
|
||||
{
|
||||
MemoryUtil.Copy(dst + i * stride, border + bs - 1 - i, bs);
|
||||
MemoryUtil.Copy(dst + (i * stride), border + bs - 1 - i, bs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -972,11 +966,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdD153Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdD153Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdD153Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int r, c;
|
||||
dst[0] = Avg2(above[-1], left[0]);
|
||||
for (r = 1; r < bs; r++)
|
||||
for (int r = 1; r < bs; r++)
|
||||
{
|
||||
dst[r * stride] = Avg2(left[r - 1], left[r]);
|
||||
}
|
||||
@@ -985,23 +979,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
dst[0] = Avg3(left[0], above[-1], above[0]);
|
||||
dst[stride] = Avg3(above[-1], left[0], left[1]);
|
||||
for (r = 2; r < bs; r++)
|
||||
for (int r = 2; r < bs; r++)
|
||||
{
|
||||
dst[r * stride] = Avg3(left[r - 2], left[r - 1], left[r]);
|
||||
}
|
||||
|
||||
dst++;
|
||||
|
||||
for (c = 0; c < bs - 2; c++)
|
||||
for (int c = 0; c < bs - 2; c++)
|
||||
{
|
||||
dst[c] = Avg3(above[c - 1], above[c], above[c + 1]);
|
||||
}
|
||||
|
||||
dst += stride;
|
||||
|
||||
for (r = 1; r < bs; ++r)
|
||||
for (int r = 1; r < bs; ++r)
|
||||
{
|
||||
for (c = 0; c < bs - 2; c++)
|
||||
for (int c = 0; c < bs - 2; c++)
|
||||
{
|
||||
dst[c] = dst[-stride + c - 2];
|
||||
}
|
||||
@@ -1030,10 +1024,10 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdVPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdVPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdVPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int r;
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Copy(dst, above, bs);
|
||||
dst += stride;
|
||||
@@ -1060,44 +1054,44 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdHPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdHPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdHPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int r;
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, left[r], bs);
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTMPredictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTmPredictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTMPredictor(dst, stride, 4, above, left, bd);
|
||||
HighbdTmPredictor(dst, stride, 4, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTMPredictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTmPredictor8x8(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTMPredictor(dst, stride, 8, above, left, bd);
|
||||
HighbdTmPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTMPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTmPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTMPredictor(dst, stride, 16, above, left, bd);
|
||||
HighbdTmPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdTMPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdTmPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
{
|
||||
HighbdTMPredictor(dst, stride, 32, above, left, bd);
|
||||
HighbdTmPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdTMPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdTmPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int r, c;
|
||||
int yTopLeft = above[-1];
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
for (c = 0; c < bs; c++)
|
||||
for (int c = 0; c < bs; c++)
|
||||
{
|
||||
dst[c] = BitUtils.ClipPixelHighbd(left[r] + above[c] - yTopLeft, bd);
|
||||
}
|
||||
@@ -1116,21 +1110,22 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdDc128Predictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDc128Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDc128Predictor16x16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDc128Predictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDc128Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDc128Predictor32x32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDc128Predictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdDc128Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdDc128Predictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int r;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (ushort)(128 << (bd - 8)), bs);
|
||||
dst += stride;
|
||||
@@ -1147,28 +1142,31 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdDcLeftPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcLeftPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcLeftPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDcLeftPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcLeftPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcLeftPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDcLeftPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdDcLeftPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdDcLeftPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int i, r, expectedDc, sum = 0;
|
||||
int expectedDc, sum = 0;
|
||||
|
||||
for (i = 0; i < bs; i++)
|
||||
for (int i = 0; i < bs; i++)
|
||||
{
|
||||
sum += left[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (ushort)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -1185,28 +1183,31 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdDcTopPredictor(dst, stride, 8, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcTopPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcTopPredictor16x16(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDcTopPredictor(dst, stride, 16, above, left, bd);
|
||||
}
|
||||
|
||||
public static unsafe void HighbdDcTopPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
public static unsafe void HighbdDcTopPredictor32x32(ushort* dst, int stride, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
HighbdDcTopPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdDcTopPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdDcTopPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int i, r, expectedDc, sum = 0;
|
||||
int expectedDc, sum = 0;
|
||||
|
||||
for (i = 0; i < bs; i++)
|
||||
for (int i = 0; i < bs; i++)
|
||||
{
|
||||
sum += above[i];
|
||||
}
|
||||
|
||||
expectedDc = (sum + (bs >> 1)) / bs;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (ushort)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -1233,12 +1234,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
HighbdDcPredictor(dst, stride, 32, above, left, bd);
|
||||
}
|
||||
|
||||
private static unsafe void HighbdDcPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left, int bd)
|
||||
private static unsafe void HighbdDcPredictor(ushort* dst, int stride, int bs, ushort* above, ushort* left,
|
||||
int bd)
|
||||
{
|
||||
int i, r, expectedDc, sum = 0;
|
||||
int expectedDc, sum = 0;
|
||||
int count = 2 * bs;
|
||||
|
||||
for (i = 0; i < bs; i++)
|
||||
for (int i = 0; i < bs; i++)
|
||||
{
|
||||
sum += above[i];
|
||||
sum += left[i];
|
||||
@@ -1246,7 +1248,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
expectedDc = (sum + (count >> 1)) / count;
|
||||
|
||||
for (r = 0; r < bs; r++)
|
||||
for (int r = 0; r < bs; r++)
|
||||
{
|
||||
MemoryUtil.Fill(dst, (ushort)expectedDc, bs);
|
||||
dst += stride;
|
||||
@@ -1265,7 +1267,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 1, 0) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 1, 1) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 1, 2) = Avg3(k, l, l);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 0, 3) = Dst(dst, stride, 1, 3) = Dst(dst, stride, 2, 3) = Dst(dst, stride, 3, 3) = l;
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 0, 3) =
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 2, 3) = Dst(dst, stride, 3, 3) = l;
|
||||
}
|
||||
|
||||
public static unsafe void HighbdD63Predictor4x4(ushort* dst, int stride, ushort* above, ushort* left, int bd)
|
||||
@@ -1303,7 +1306,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 0, 0) = Avg3(a, b, c);
|
||||
Dst(dst, stride, 1, 0) = Dst(dst, stride, 0, 1) = Avg3(b, c, d);
|
||||
Dst(dst, stride, 2, 0) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 2) = Avg3(c, d, e);
|
||||
Dst(dst, stride, 3, 0) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 0) =
|
||||
Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 3) = Avg3(d, e, f);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 3) = Avg3(e, f, g);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 3) = Avg3(f, g, h);
|
||||
Dst(dst, stride, 3, 3) = h; // Differs from vp8
|
||||
@@ -1346,7 +1350,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 0, 3) = Avg3(j, k, l);
|
||||
Dst(dst, stride, 1, 3) = Dst(dst, stride, 0, 2) = Avg3(I, j, k);
|
||||
Dst(dst, stride, 2, 3) = Dst(dst, stride, 1, 2) = Dst(dst, stride, 0, 1) = Avg3(x, I, j);
|
||||
Dst(dst, stride, 3, 3) = Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, I);
|
||||
Dst(dst, stride, 3, 3) =
|
||||
Dst(dst, stride, 2, 2) = Dst(dst, stride, 1, 1) = Dst(dst, stride, 0, 0) = Avg3(a, x, I);
|
||||
Dst(dst, stride, 3, 2) = Dst(dst, stride, 2, 1) = Dst(dst, stride, 1, 0) = Avg3(b, a, x);
|
||||
Dst(dst, stride, 3, 1) = Dst(dst, stride, 2, 0) = Avg3(c, b, a);
|
||||
Dst(dst, stride, 3, 0) = Avg3(d, c, b);
|
||||
@@ -1376,4 +1381,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Dst(dst, stride, 1, 3) = Avg3(l, k, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
229
src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/LoopFilterAuto.cs
Normal file
229
src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/LoopFilterAuto.cs
Normal file
@@ -0,0 +1,229 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
internal class LoopFilterAuto
|
||||
{
|
||||
public static void LpfHorizontal4(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal4(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal4(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfHorizontal4Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit0,
|
||||
ReadOnlySpan<byte> limit0,
|
||||
ReadOnlySpan<byte> thresh0,
|
||||
ReadOnlySpan<byte> blimit1,
|
||||
ReadOnlySpan<byte> limit1,
|
||||
ReadOnlySpan<byte> thresh1)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal4Dual(s, pitch, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal4Dual(s, pitch, blimit0[0], limit0[0], thresh0[0], blimit1[0], limit1[0],
|
||||
thresh1[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfHorizontal8(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal8(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal8(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfHorizontal8Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit0,
|
||||
ReadOnlySpan<byte> limit0,
|
||||
ReadOnlySpan<byte> thresh0,
|
||||
ReadOnlySpan<byte> blimit1,
|
||||
ReadOnlySpan<byte> limit1,
|
||||
ReadOnlySpan<byte> thresh1)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal8Dual(s, pitch, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal8Dual(s, pitch, blimit0[0], limit0[0], thresh0[0], blimit1[0], limit1[0],
|
||||
thresh1[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfHorizontal16(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal16(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal16(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfHorizontal16Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfHorizontal16Dual(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfHorizontal16Dual(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical4(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical4(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical4(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical4Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit0,
|
||||
ReadOnlySpan<byte> limit0,
|
||||
ReadOnlySpan<byte> thresh0,
|
||||
ReadOnlySpan<byte> blimit1,
|
||||
ReadOnlySpan<byte> limit1,
|
||||
ReadOnlySpan<byte> thresh1)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical4Dual(s, pitch, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical4Dual(s, pitch, blimit0[0], limit0[0], thresh0[0], blimit1[0], limit1[0],
|
||||
thresh1[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical8(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical8(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical8(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical8Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit0,
|
||||
ReadOnlySpan<byte> limit0,
|
||||
ReadOnlySpan<byte> thresh0,
|
||||
ReadOnlySpan<byte> blimit1,
|
||||
ReadOnlySpan<byte> limit1,
|
||||
ReadOnlySpan<byte> thresh1)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical8Dual(s, pitch, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical8Dual(s, pitch, blimit0[0], limit0[0], thresh0[0], blimit1[0], limit1[0],
|
||||
thresh1[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical16(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical16(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical16(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LpfVertical16Dual(
|
||||
ArrayPtr<byte> s,
|
||||
int pitch,
|
||||
ReadOnlySpan<byte> blimit,
|
||||
ReadOnlySpan<byte> limit,
|
||||
ReadOnlySpan<byte> thresh)
|
||||
{
|
||||
if (Sse2.IsSupported)
|
||||
{
|
||||
LoopFilterSse2.LpfVertical16Dual(s, pitch, blimit, limit, thresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopFilterScalar.LpfVertical16Dual(s, pitch, blimit[0], limit[0], thresh[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1093
src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/LoopFilterScalar.cs
Normal file
1093
src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/LoopFilterScalar.cs
Normal file
File diff suppressed because it is too large
Load Diff
1837
src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/LoopFilterSse2.cs
Normal file
1837
src/Ryujinx.Graphics.Nvdec.Vp9/Dsp/LoopFilterSse2.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
@@ -12,10 +12,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
Debug.Assert(den != 0);
|
||||
{
|
||||
int p = (int)(((ulong)num * 256 + (den >> 1)) / den);
|
||||
int p = (int)((((ulong)num * 256) + (den >> 1)) / den);
|
||||
// (p > 255) ? 255 : (p < 1) ? 1 : p;
|
||||
int clippedProb = p | ((255 - p) >> 23) | (p == 0 ? 1 : 0);
|
||||
|
||||
return (byte)clippedProb;
|
||||
}
|
||||
}
|
||||
@@ -23,13 +22,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
/* This function assumes prob1 and prob2 are already within [1,255] range. */
|
||||
public static byte WeightedProb(int prob1, int prob2, int factor)
|
||||
{
|
||||
return (byte)BitUtils.RoundPowerOfTwo(prob1 * (256 - factor) + prob2 * factor, 8);
|
||||
return (byte)BitUtils.RoundPowerOfTwo((prob1 * (256 - factor)) + (prob2 * factor), 8);
|
||||
}
|
||||
|
||||
// MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT;
|
||||
private static readonly uint[] _countToUpdateFactor = {
|
||||
0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64,
|
||||
70, 76, 83, 89, 96, 102, 108, 115, 121, 128,
|
||||
private static readonly uint[] CountToUpdateFactor =
|
||||
{
|
||||
0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64, 70, 76, 83, 89, 96, 102, 108, 115, 121, 128
|
||||
};
|
||||
|
||||
private const int ModeMvCountSat = 20;
|
||||
@@ -41,14 +40,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
return preProb;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint count = Math.Min(den, ModeMvCountSat);
|
||||
uint factor = _countToUpdateFactor[(int)count];
|
||||
byte prob = GetProb(ct0, den);
|
||||
|
||||
return WeightedProb(preProb, prob, (int)factor);
|
||||
}
|
||||
uint count = Math.Min(den, ModeMvCountSat);
|
||||
uint factor = CountToUpdateFactor[(int)count];
|
||||
byte prob = GetProb(ct0, den);
|
||||
return WeightedProb(preProb, prob, (int)factor);
|
||||
}
|
||||
|
||||
private static uint TreeMergeProbsImpl(
|
||||
@@ -59,17 +55,17 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Span<byte> probs)
|
||||
{
|
||||
int l = tree[i];
|
||||
uint leftCount = (l <= 0) ? counts[-l] : TreeMergeProbsImpl((uint)l, tree, preProbs, counts, probs);
|
||||
uint leftCount = l <= 0 ? counts[-l] : TreeMergeProbsImpl((uint)l, tree, preProbs, counts, probs);
|
||||
int r = tree[i + 1];
|
||||
uint rightCount = (r <= 0) ? counts[-r] : TreeMergeProbsImpl((uint)r, tree, preProbs, counts, probs);
|
||||
uint rightCount = r <= 0 ? counts[-r] : TreeMergeProbsImpl((uint)r, tree, preProbs, counts, probs);
|
||||
probs[(int)(i >> 1)] = ModeMvMergeProbs(preProbs[(int)(i >> 1)], leftCount, rightCount);
|
||||
|
||||
return leftCount + rightCount;
|
||||
}
|
||||
|
||||
public static void TreeMergeProbs(sbyte[] tree, ReadOnlySpan<byte> preProbs, ReadOnlySpan<uint> counts, Span<byte> probs)
|
||||
public static void TreeMergeProbs(sbyte[] tree, ReadOnlySpan<byte> preProbs, ReadOnlySpan<uint> counts,
|
||||
Span<byte> probs)
|
||||
{
|
||||
TreeMergeProbsImpl(0, tree, preProbs, counts, probs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
|
||||
@@ -6,18 +7,18 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
internal struct Reader
|
||||
{
|
||||
private static readonly byte[] _norm = {
|
||||
0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
private static readonly byte[] Norm =
|
||||
{
|
||||
0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
private const int BdValueSize = sizeof(ulong) * 8;
|
||||
|
||||
// This is meant to be a large, positive constant that can still be efficiently
|
||||
@@ -36,16 +37,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_buffer = new ArrayPtr<byte>(ref buffer[0], size);
|
||||
Value = 0;
|
||||
Count = -8;
|
||||
Range = 255;
|
||||
Fill();
|
||||
|
||||
return ReadBit() != 0; // Marker bit
|
||||
}
|
||||
_buffer = new ArrayPtr<byte>(ref buffer[0], size);
|
||||
Value = 0;
|
||||
Count = -8;
|
||||
Range = 255;
|
||||
Fill();
|
||||
return ReadBit() != 0; // Marker bit
|
||||
}
|
||||
|
||||
private void Fill()
|
||||
@@ -65,7 +63,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
ulong bigEndianValues = BinaryPrimitives.ReadUInt64BigEndian(buffer);
|
||||
nv = bigEndianValues >> (BdValueSize - bits);
|
||||
count += bits;
|
||||
buffer = buffer[(bits >> 3)..];
|
||||
buffer = buffer.Slice(bits >> 3);
|
||||
value = Value | (nv << (shift & 0x7));
|
||||
}
|
||||
else
|
||||
@@ -84,7 +82,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
{
|
||||
count += 8;
|
||||
value |= (ulong)buffer[0] << shift;
|
||||
buffer = buffer[1..];
|
||||
buffer = buffer.Slice(1);
|
||||
shift -= 8;
|
||||
}
|
||||
}
|
||||
@@ -98,7 +96,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Count = count;
|
||||
}
|
||||
|
||||
public readonly bool HasError()
|
||||
public bool HasError()
|
||||
{
|
||||
// Check if we have reached the end of the buffer.
|
||||
//
|
||||
@@ -124,7 +122,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
ulong bigsplit;
|
||||
int count;
|
||||
uint range;
|
||||
uint split = (Range * (uint)prob + (256 - (uint)prob)) >> 8;
|
||||
uint split = ((Range * (uint)prob) + (256 - (uint)prob)) >> 8;
|
||||
|
||||
if (Count < 0)
|
||||
{
|
||||
@@ -146,7 +144,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
}
|
||||
|
||||
{
|
||||
int shift = _norm[range];
|
||||
int shift = Norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
@@ -188,7 +186,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
public int ReadBool(int prob, ref ulong value, ref int count, ref uint range)
|
||||
{
|
||||
uint split = (range * (uint)prob + (256 - (uint)prob)) >> 8;
|
||||
uint split = ((range * (uint)prob) + (256 - (uint)prob)) >> 8;
|
||||
ulong bigsplit = (ulong)split << (BdValueSize - 8);
|
||||
|
||||
if (count < 0)
|
||||
@@ -202,19 +200,20 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
|
||||
if (value >= bigsplit)
|
||||
{
|
||||
range -= split;
|
||||
value -= bigsplit;
|
||||
range = range - split;
|
||||
value = value - bigsplit;
|
||||
{
|
||||
int shift = _norm[range];
|
||||
int shift = Norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
range = split;
|
||||
{
|
||||
int shift = _norm[range];
|
||||
int shift = Norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
@@ -230,7 +229,82 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
Count -= 8;
|
||||
_buffer = _buffer.Slice(-1);
|
||||
}
|
||||
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
private int DecodeUniform()
|
||||
{
|
||||
const int l = 8;
|
||||
const int m = (1 << l) - 191;
|
||||
int v = ReadLiteral(l - 1);
|
||||
return v < m ? v : (v << 1) - m + ReadBit();
|
||||
}
|
||||
|
||||
public int DecodeTermSubexp()
|
||||
{
|
||||
if (ReadBit() == 0)
|
||||
{
|
||||
return ReadLiteral(4);
|
||||
}
|
||||
|
||||
if (ReadBit() == 0)
|
||||
{
|
||||
return ReadLiteral(4) + 16;
|
||||
}
|
||||
|
||||
if (ReadBit() == 0)
|
||||
{
|
||||
return ReadLiteral(5) + 32;
|
||||
}
|
||||
|
||||
return DecodeUniform() + 64;
|
||||
}
|
||||
|
||||
public TxMode ReadTxMode()
|
||||
{
|
||||
TxMode txMode = (TxMode)ReadLiteral(2);
|
||||
if (txMode == TxMode.Allow32x32)
|
||||
{
|
||||
txMode += ReadBit();
|
||||
}
|
||||
|
||||
return txMode;
|
||||
}
|
||||
|
||||
public int ReadCoeff(
|
||||
ReadOnlySpan<byte> probs,
|
||||
int n,
|
||||
ref ulong value,
|
||||
ref int count,
|
||||
ref uint range)
|
||||
{
|
||||
int val = 0;
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
val = (val << 1) | ReadBool(probs[i], ref value, ref count, ref range);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public void DiffUpdateProb(ref byte p)
|
||||
{
|
||||
if (Read(Entropy.DiffUpdateProb) != 0)
|
||||
{
|
||||
p = (byte)DSubExp.InvRemapProb(DecodeTermSubexp(), p);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateMvProbs(Span<byte> p, int n)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (Read(EntropyMv.UpdateProb) != 0)
|
||||
{
|
||||
p[i] = (byte)((ReadLiteral(7) << 1) | 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,42 +13,42 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
|
||||
// for (int i = 1; i < 32; ++i)
|
||||
// Console.WriteLine("public const short CosPi{0}_64 = {1};", i, MathF.Round(16384 * MathF.Cos(i * MathF.PI / 64)));
|
||||
// Note: sin(k * Pi / 64) = cos((32 - k) * Pi / 64)
|
||||
public const short CosPi1_64 = 16364;
|
||||
public const short CosPi2_64 = 16305;
|
||||
public const short CosPi3_64 = 16207;
|
||||
public const short CosPi4_64 = 16069;
|
||||
public const short CosPi5_64 = 15893;
|
||||
public const short CosPi6_64 = 15679;
|
||||
public const short CosPi7_64 = 15426;
|
||||
public const short CosPi8_64 = 15137;
|
||||
public const short CosPi9_64 = 14811;
|
||||
public const short CosPi10_64 = 14449;
|
||||
public const short CosPi11_64 = 14053;
|
||||
public const short CosPi12_64 = 13623;
|
||||
public const short CosPi13_64 = 13160;
|
||||
public const short CosPi14_64 = 12665;
|
||||
public const short CosPi15_64 = 12140;
|
||||
public const short CosPi16_64 = 11585;
|
||||
public const short CosPi17_64 = 11003;
|
||||
public const short CosPi18_64 = 10394;
|
||||
public const short CosPi19_64 = 9760;
|
||||
public const short CosPi20_64 = 9102;
|
||||
public const short CosPi21_64 = 8423;
|
||||
public const short CosPi22_64 = 7723;
|
||||
public const short CosPi23_64 = 7005;
|
||||
public const short CosPi24_64 = 6270;
|
||||
public const short CosPi25_64 = 5520;
|
||||
public const short CosPi26_64 = 4756;
|
||||
public const short CosPi27_64 = 3981;
|
||||
public const short CosPi28_64 = 3196;
|
||||
public const short CosPi29_64 = 2404;
|
||||
public const short CosPi30_64 = 1606;
|
||||
public const short CosPi31_64 = 804;
|
||||
public const short CosPi164 = 16364;
|
||||
public const short CosPi264 = 16305;
|
||||
public const short CosPi364 = 16207;
|
||||
public const short CosPi464 = 16069;
|
||||
public const short CosPi564 = 15893;
|
||||
public const short CosPi664 = 15679;
|
||||
public const short CosPi764 = 15426;
|
||||
public const short CosPi864 = 15137;
|
||||
public const short CosPi964 = 14811;
|
||||
public const short CosPi1064 = 14449;
|
||||
public const short CosPi1164 = 14053;
|
||||
public const short CosPi1264 = 13623;
|
||||
public const short CosPi1364 = 13160;
|
||||
public const short CosPi1464 = 12665;
|
||||
public const short CosPi1564 = 12140;
|
||||
public const short CosPi1664 = 11585;
|
||||
public const short CosPi1764 = 11003;
|
||||
public const short CosPi1864 = 10394;
|
||||
public const short CosPi1964 = 9760;
|
||||
public const short CosPi2064 = 9102;
|
||||
public const short CosPi2164 = 8423;
|
||||
public const short CosPi2264 = 7723;
|
||||
public const short CosPi2364 = 7005;
|
||||
public const short CosPi2464 = 6270;
|
||||
public const short CosPi2564 = 5520;
|
||||
public const short CosPi2664 = 4756;
|
||||
public const short CosPi2764 = 3981;
|
||||
public const short CosPi2864 = 3196;
|
||||
public const short CosPi2964 = 2404;
|
||||
public const short CosPi3064 = 1606;
|
||||
public const short CosPi3164 = 804;
|
||||
|
||||
// 16384 * sqrt(2) * sin(kPi / 9) * 2 / 3
|
||||
public const short SinPi1_9 = 5283;
|
||||
public const short SinPi2_9 = 9929;
|
||||
public const short SinPi3_9 = 13377;
|
||||
public const short SinPi4_9 = 15212;
|
||||
public const short SinPi19 = 5283;
|
||||
public const short SinPi29 = 9929;
|
||||
public const short SinPi39 = 13377;
|
||||
public const short SinPi49 = 15212;
|
||||
}
|
||||
}
|
||||
}
|
||||
623
src/Ryujinx.Graphics.Nvdec.Vp9/Entropy.cs
Normal file
623
src/Ryujinx.Graphics.Nvdec.Vp9/Entropy.cs
Normal file
@@ -0,0 +1,623 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class Entropy
|
||||
{
|
||||
public const int DiffUpdateProb = 252;
|
||||
|
||||
// Coefficient token alphabet
|
||||
public const int ZeroToken = 0; // 0 Extra Bits 0+0
|
||||
public const int OneToken = 1; // 1 Extra Bits 0+1
|
||||
public const int TwoToken = 2; // 2 Extra Bits 0+1
|
||||
public const int ThreeToken = 3; // 3 Extra Bits 0+1
|
||||
public const int FourToken = 4; // 4 Extra Bits 0+1
|
||||
public const int Category1Token = 5; // 5-6 Extra Bits 1+1
|
||||
public const int Category2Token = 6; // 7-10 Extra Bits 2+1
|
||||
public const int Category3Token = 7; // 11-18 Extra Bits 3+1
|
||||
public const int Category4Token = 8; // 19-34 Extra Bits 4+1
|
||||
public const int Category5Token = 9; // 35-66 Extra Bits 5+1
|
||||
public const int Category6Token = 10; // 67+ Extra Bits 14+1
|
||||
public const int EobToken = 11; // EOB Extra Bits 0+0
|
||||
|
||||
public const int EntropyTokens = 12;
|
||||
|
||||
public const int RefTypes = 2; // intra=0, inter=1
|
||||
|
||||
/* Middle dimension reflects the coefficient position within the transform. */
|
||||
public const int CoefBands = 6;
|
||||
|
||||
/* Inside dimension is measure of nearby complexity, that reflects the energy
|
||||
of nearby coefficients are nonzero. For the first coefficient (DC, unless
|
||||
block type is 0), we look at the (already encoded) blocks above and to the
|
||||
left of the current block. The context index is then the number (0,1,or 2)
|
||||
of these blocks having nonzero coefficients.
|
||||
After decoding a coefficient, the measure is determined by the size of the
|
||||
most recently decoded coefficient.
|
||||
Note that the intuitive meaning of this measure changes as coefficients
|
||||
are decoded, e.g., prior to the first token, a zero means that my neighbors
|
||||
are empty while, after the first token, because of the use of end-of-block,
|
||||
a zero means we just decoded a zero and hence guarantees that a non-zero
|
||||
coefficient will appear later in this block. However, this shift
|
||||
in meaning is perfectly OK because our context depends also on the
|
||||
coefficient band (and since zigzag positions 0, 1, and 2 are in
|
||||
distinct bands). */
|
||||
|
||||
public const int CoeffContexts = 6;
|
||||
|
||||
public static int BAND_COEFF_CONTEXTS(int band)
|
||||
{
|
||||
return band == 0 ? 3 : CoeffContexts;
|
||||
}
|
||||
|
||||
public const int UnconstrainedNodes = 3;
|
||||
|
||||
public const int PivotNode = 2;
|
||||
|
||||
public const int Cat1MinVal = 5;
|
||||
public const int Cat2MinVal = 7;
|
||||
public const int Cat3MinVal = 11;
|
||||
public const int Cat4MinVal = 19;
|
||||
public const int Cat5MinVal = 35;
|
||||
public const int Cat6MinVal = 67;
|
||||
|
||||
public static readonly byte[] Cat1Prob = { 159 };
|
||||
public static readonly byte[] Cat2Prob = { 165, 145 };
|
||||
public static readonly byte[] Cat3Prob = { 173, 148, 140 };
|
||||
public static readonly byte[] Cat4Prob = { 176, 155, 140, 135 };
|
||||
public static readonly byte[] Cat5Prob = { 180, 157, 141, 134, 130 };
|
||||
|
||||
public static readonly byte[] Cat6Prob =
|
||||
{
|
||||
254, 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129
|
||||
};
|
||||
|
||||
public static readonly byte[] Cat6ProbHigh12 =
|
||||
{
|
||||
255, 255, 255, 255, 254, 254, 54, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129
|
||||
};
|
||||
|
||||
public const int EobModelToken = 3;
|
||||
|
||||
private static readonly byte[] CoefbandTrans8x8Plus =
|
||||
{
|
||||
0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
|
||||
// beyond MAXBAND_INDEX+1 all values are filled as 5
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
|
||||
};
|
||||
|
||||
private static readonly byte[] CoefbandTrans4x4 = { 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5 };
|
||||
|
||||
public static readonly byte[][] Pareto8Full =
|
||||
{
|
||||
new byte[] { 3, 86, 128, 6, 86, 23, 88, 29 }, new byte[] { 6, 86, 128, 11, 87, 42, 91, 52 },
|
||||
new byte[] { 9, 86, 129, 17, 88, 61, 94, 76 }, new byte[] { 12, 86, 129, 22, 88, 77, 97, 93 },
|
||||
new byte[] { 15, 87, 129, 28, 89, 93, 100, 110 }, new byte[] { 17, 87, 129, 33, 90, 105, 103, 123 },
|
||||
new byte[] { 20, 88, 130, 38, 91, 118, 106, 136 }, new byte[] { 23, 88, 130, 43, 91, 128, 108, 146 },
|
||||
new byte[] { 26, 89, 131, 48, 92, 139, 111, 156 }, new byte[] { 28, 89, 131, 53, 93, 147, 114, 163 },
|
||||
new byte[] { 31, 90, 131, 58, 94, 156, 117, 171 }, new byte[] { 34, 90, 131, 62, 94, 163, 119, 177 },
|
||||
new byte[] { 37, 90, 132, 66, 95, 171, 122, 184 }, new byte[] { 39, 90, 132, 70, 96, 177, 124, 189 },
|
||||
new byte[] { 42, 91, 132, 75, 97, 183, 127, 194 }, new byte[] { 44, 91, 132, 79, 97, 188, 129, 198 },
|
||||
new byte[] { 47, 92, 133, 83, 98, 193, 132, 202 }, new byte[] { 49, 92, 133, 86, 99, 197, 134, 205 },
|
||||
new byte[] { 52, 93, 133, 90, 100, 201, 137, 208 }, new byte[] { 54, 93, 133, 94, 100, 204, 139, 211 },
|
||||
new byte[] { 57, 94, 134, 98, 101, 208, 142, 214 }, new byte[] { 59, 94, 134, 101, 102, 211, 144, 216 },
|
||||
new byte[] { 62, 94, 135, 105, 103, 214, 146, 218 },
|
||||
new byte[] { 64, 94, 135, 108, 103, 216, 148, 220 },
|
||||
new byte[] { 66, 95, 135, 111, 104, 219, 151, 222 },
|
||||
new byte[] { 68, 95, 135, 114, 105, 221, 153, 223 },
|
||||
new byte[] { 71, 96, 136, 117, 106, 224, 155, 225 },
|
||||
new byte[] { 73, 96, 136, 120, 106, 225, 157, 226 },
|
||||
new byte[] { 76, 97, 136, 123, 107, 227, 159, 228 },
|
||||
new byte[] { 78, 97, 136, 126, 108, 229, 160, 229 },
|
||||
new byte[] { 80, 98, 137, 129, 109, 231, 162, 231 },
|
||||
new byte[] { 82, 98, 137, 131, 109, 232, 164, 232 },
|
||||
new byte[] { 84, 98, 138, 134, 110, 234, 166, 233 },
|
||||
new byte[] { 86, 98, 138, 137, 111, 235, 168, 234 },
|
||||
new byte[] { 89, 99, 138, 140, 112, 236, 170, 235 },
|
||||
new byte[] { 91, 99, 138, 142, 112, 237, 171, 235 },
|
||||
new byte[] { 93, 100, 139, 145, 113, 238, 173, 236 },
|
||||
new byte[] { 95, 100, 139, 147, 114, 239, 174, 237 },
|
||||
new byte[] { 97, 101, 140, 149, 115, 240, 176, 238 },
|
||||
new byte[] { 99, 101, 140, 151, 115, 241, 177, 238 },
|
||||
new byte[] { 101, 102, 140, 154, 116, 242, 179, 239 },
|
||||
new byte[] { 103, 102, 140, 156, 117, 242, 180, 239 },
|
||||
new byte[] { 105, 103, 141, 158, 118, 243, 182, 240 },
|
||||
new byte[] { 107, 103, 141, 160, 118, 243, 183, 240 },
|
||||
new byte[] { 109, 104, 141, 162, 119, 244, 185, 241 },
|
||||
new byte[] { 111, 104, 141, 164, 119, 244, 186, 241 },
|
||||
new byte[] { 113, 104, 142, 166, 120, 245, 187, 242 },
|
||||
new byte[] { 114, 104, 142, 168, 121, 245, 188, 242 },
|
||||
new byte[] { 116, 105, 143, 170, 122, 246, 190, 243 },
|
||||
new byte[] { 118, 105, 143, 171, 122, 246, 191, 243 },
|
||||
new byte[] { 120, 106, 143, 173, 123, 247, 192, 244 },
|
||||
new byte[] { 121, 106, 143, 175, 124, 247, 193, 244 },
|
||||
new byte[] { 123, 107, 144, 177, 125, 248, 195, 244 },
|
||||
new byte[] { 125, 107, 144, 178, 125, 248, 196, 244 },
|
||||
new byte[] { 127, 108, 145, 180, 126, 249, 197, 245 },
|
||||
new byte[] { 128, 108, 145, 181, 127, 249, 198, 245 },
|
||||
new byte[] { 130, 109, 145, 183, 128, 249, 199, 245 },
|
||||
new byte[] { 132, 109, 145, 184, 128, 249, 200, 245 },
|
||||
new byte[] { 134, 110, 146, 186, 129, 250, 201, 246 },
|
||||
new byte[] { 135, 110, 146, 187, 130, 250, 202, 246 },
|
||||
new byte[] { 137, 111, 147, 189, 131, 251, 203, 246 },
|
||||
new byte[] { 138, 111, 147, 190, 131, 251, 204, 246 },
|
||||
new byte[] { 140, 112, 147, 192, 132, 251, 205, 247 },
|
||||
new byte[] { 141, 112, 147, 193, 132, 251, 206, 247 },
|
||||
new byte[] { 143, 113, 148, 194, 133, 251, 207, 247 },
|
||||
new byte[] { 144, 113, 148, 195, 134, 251, 207, 247 },
|
||||
new byte[] { 146, 114, 149, 197, 135, 252, 208, 248 },
|
||||
new byte[] { 147, 114, 149, 198, 135, 252, 209, 248 },
|
||||
new byte[] { 149, 115, 149, 199, 136, 252, 210, 248 },
|
||||
new byte[] { 150, 115, 149, 200, 137, 252, 210, 248 },
|
||||
new byte[] { 152, 115, 150, 201, 138, 252, 211, 248 },
|
||||
new byte[] { 153, 115, 150, 202, 138, 252, 212, 248 },
|
||||
new byte[] { 155, 116, 151, 204, 139, 253, 213, 249 },
|
||||
new byte[] { 156, 116, 151, 205, 139, 253, 213, 249 },
|
||||
new byte[] { 158, 117, 151, 206, 140, 253, 214, 249 },
|
||||
new byte[] { 159, 117, 151, 207, 141, 253, 215, 249 },
|
||||
new byte[] { 161, 118, 152, 208, 142, 253, 216, 249 },
|
||||
new byte[] { 162, 118, 152, 209, 142, 253, 216, 249 },
|
||||
new byte[] { 163, 119, 153, 210, 143, 253, 217, 249 },
|
||||
new byte[] { 164, 119, 153, 211, 143, 253, 217, 249 },
|
||||
new byte[] { 166, 120, 153, 212, 144, 254, 218, 250 },
|
||||
new byte[] { 167, 120, 153, 212, 145, 254, 219, 250 },
|
||||
new byte[] { 168, 121, 154, 213, 146, 254, 220, 250 },
|
||||
new byte[] { 169, 121, 154, 214, 146, 254, 220, 250 },
|
||||
new byte[] { 171, 122, 155, 215, 147, 254, 221, 250 },
|
||||
new byte[] { 172, 122, 155, 216, 147, 254, 221, 250 },
|
||||
new byte[] { 173, 123, 155, 217, 148, 254, 222, 250 },
|
||||
new byte[] { 174, 123, 155, 217, 149, 254, 222, 250 },
|
||||
new byte[] { 176, 124, 156, 218, 150, 254, 223, 250 },
|
||||
new byte[] { 177, 124, 156, 219, 150, 254, 223, 250 },
|
||||
new byte[] { 178, 125, 157, 220, 151, 254, 224, 251 },
|
||||
new byte[] { 179, 125, 157, 220, 151, 254, 224, 251 },
|
||||
new byte[] { 180, 126, 157, 221, 152, 254, 225, 251 },
|
||||
new byte[] { 181, 126, 157, 221, 152, 254, 225, 251 },
|
||||
new byte[] { 183, 127, 158, 222, 153, 254, 226, 251 },
|
||||
new byte[] { 184, 127, 158, 223, 154, 254, 226, 251 },
|
||||
new byte[] { 185, 128, 159, 224, 155, 255, 227, 251 },
|
||||
new byte[] { 186, 128, 159, 224, 155, 255, 227, 251 },
|
||||
new byte[] { 187, 129, 160, 225, 156, 255, 228, 251 },
|
||||
new byte[] { 188, 130, 160, 225, 156, 255, 228, 251 },
|
||||
new byte[] { 189, 131, 160, 226, 157, 255, 228, 251 },
|
||||
new byte[] { 190, 131, 160, 226, 158, 255, 228, 251 },
|
||||
new byte[] { 191, 132, 161, 227, 159, 255, 229, 251 },
|
||||
new byte[] { 192, 132, 161, 227, 159, 255, 229, 251 },
|
||||
new byte[] { 193, 133, 162, 228, 160, 255, 230, 252 },
|
||||
new byte[] { 194, 133, 162, 229, 160, 255, 230, 252 },
|
||||
new byte[] { 195, 134, 163, 230, 161, 255, 231, 252 },
|
||||
new byte[] { 196, 134, 163, 230, 161, 255, 231, 252 },
|
||||
new byte[] { 197, 135, 163, 231, 162, 255, 231, 252 },
|
||||
new byte[] { 198, 135, 163, 231, 162, 255, 231, 252 },
|
||||
new byte[] { 199, 136, 164, 232, 163, 255, 232, 252 },
|
||||
new byte[] { 200, 136, 164, 232, 164, 255, 232, 252 },
|
||||
new byte[] { 201, 137, 165, 233, 165, 255, 233, 252 },
|
||||
new byte[] { 201, 137, 165, 233, 165, 255, 233, 252 },
|
||||
new byte[] { 202, 138, 166, 233, 166, 255, 233, 252 },
|
||||
new byte[] { 203, 138, 166, 233, 166, 255, 233, 252 },
|
||||
new byte[] { 204, 139, 166, 234, 167, 255, 234, 252 },
|
||||
new byte[] { 205, 139, 166, 234, 167, 255, 234, 252 },
|
||||
new byte[] { 206, 140, 167, 235, 168, 255, 235, 252 },
|
||||
new byte[] { 206, 140, 167, 235, 168, 255, 235, 252 },
|
||||
new byte[] { 207, 141, 168, 236, 169, 255, 235, 252 },
|
||||
new byte[] { 208, 141, 168, 236, 170, 255, 235, 252 },
|
||||
new byte[] { 209, 142, 169, 237, 171, 255, 236, 252 },
|
||||
new byte[] { 209, 143, 169, 237, 171, 255, 236, 252 },
|
||||
new byte[] { 210, 144, 169, 237, 172, 255, 236, 252 },
|
||||
new byte[] { 211, 144, 169, 237, 172, 255, 236, 252 },
|
||||
new byte[] { 212, 145, 170, 238, 173, 255, 237, 252 },
|
||||
new byte[] { 213, 145, 170, 238, 173, 255, 237, 252 },
|
||||
new byte[] { 214, 146, 171, 239, 174, 255, 237, 253 },
|
||||
new byte[] { 214, 146, 171, 239, 174, 255, 237, 253 },
|
||||
new byte[] { 215, 147, 172, 240, 175, 255, 238, 253 },
|
||||
new byte[] { 215, 147, 172, 240, 175, 255, 238, 253 },
|
||||
new byte[] { 216, 148, 173, 240, 176, 255, 238, 253 },
|
||||
new byte[] { 217, 148, 173, 240, 176, 255, 238, 253 },
|
||||
new byte[] { 218, 149, 173, 241, 177, 255, 239, 253 },
|
||||
new byte[] { 218, 149, 173, 241, 178, 255, 239, 253 },
|
||||
new byte[] { 219, 150, 174, 241, 179, 255, 239, 253 },
|
||||
new byte[] { 219, 151, 174, 241, 179, 255, 239, 253 },
|
||||
new byte[] { 220, 152, 175, 242, 180, 255, 240, 253 },
|
||||
new byte[] { 221, 152, 175, 242, 180, 255, 240, 253 },
|
||||
new byte[] { 222, 153, 176, 242, 181, 255, 240, 253 },
|
||||
new byte[] { 222, 153, 176, 242, 181, 255, 240, 253 },
|
||||
new byte[] { 223, 154, 177, 243, 182, 255, 240, 253 },
|
||||
new byte[] { 223, 154, 177, 243, 182, 255, 240, 253 },
|
||||
new byte[] { 224, 155, 178, 244, 183, 255, 241, 253 },
|
||||
new byte[] { 224, 155, 178, 244, 183, 255, 241, 253 },
|
||||
new byte[] { 225, 156, 178, 244, 184, 255, 241, 253 },
|
||||
new byte[] { 225, 157, 178, 244, 184, 255, 241, 253 },
|
||||
new byte[] { 226, 158, 179, 244, 185, 255, 242, 253 },
|
||||
new byte[] { 227, 158, 179, 244, 185, 255, 242, 253 },
|
||||
new byte[] { 228, 159, 180, 245, 186, 255, 242, 253 },
|
||||
new byte[] { 228, 159, 180, 245, 186, 255, 242, 253 },
|
||||
new byte[] { 229, 160, 181, 245, 187, 255, 242, 253 },
|
||||
new byte[] { 229, 160, 181, 245, 187, 255, 242, 253 },
|
||||
new byte[] { 230, 161, 182, 246, 188, 255, 243, 253 },
|
||||
new byte[] { 230, 162, 182, 246, 188, 255, 243, 253 },
|
||||
new byte[] { 231, 163, 183, 246, 189, 255, 243, 253 },
|
||||
new byte[] { 231, 163, 183, 246, 189, 255, 243, 253 },
|
||||
new byte[] { 232, 164, 184, 247, 190, 255, 243, 253 },
|
||||
new byte[] { 232, 164, 184, 247, 190, 255, 243, 253 },
|
||||
new byte[] { 233, 165, 185, 247, 191, 255, 244, 253 },
|
||||
new byte[] { 233, 165, 185, 247, 191, 255, 244, 253 },
|
||||
new byte[] { 234, 166, 185, 247, 192, 255, 244, 253 },
|
||||
new byte[] { 234, 167, 185, 247, 192, 255, 244, 253 },
|
||||
new byte[] { 235, 168, 186, 248, 193, 255, 244, 253 },
|
||||
new byte[] { 235, 168, 186, 248, 193, 255, 244, 253 },
|
||||
new byte[] { 236, 169, 187, 248, 194, 255, 244, 253 },
|
||||
new byte[] { 236, 169, 187, 248, 194, 255, 244, 253 },
|
||||
new byte[] { 236, 170, 188, 248, 195, 255, 245, 253 },
|
||||
new byte[] { 236, 170, 188, 248, 195, 255, 245, 253 },
|
||||
new byte[] { 237, 171, 189, 249, 196, 255, 245, 254 },
|
||||
new byte[] { 237, 172, 189, 249, 196, 255, 245, 254 },
|
||||
new byte[] { 238, 173, 190, 249, 197, 255, 245, 254 },
|
||||
new byte[] { 238, 173, 190, 249, 197, 255, 245, 254 },
|
||||
new byte[] { 239, 174, 191, 249, 198, 255, 245, 254 },
|
||||
new byte[] { 239, 174, 191, 249, 198, 255, 245, 254 },
|
||||
new byte[] { 240, 175, 192, 249, 199, 255, 246, 254 },
|
||||
new byte[] { 240, 176, 192, 249, 199, 255, 246, 254 },
|
||||
new byte[] { 240, 177, 193, 250, 200, 255, 246, 254 },
|
||||
new byte[] { 240, 177, 193, 250, 200, 255, 246, 254 },
|
||||
new byte[] { 241, 178, 194, 250, 201, 255, 246, 254 },
|
||||
new byte[] { 241, 178, 194, 250, 201, 255, 246, 254 },
|
||||
new byte[] { 242, 179, 195, 250, 202, 255, 246, 254 },
|
||||
new byte[] { 242, 180, 195, 250, 202, 255, 246, 254 },
|
||||
new byte[] { 242, 181, 196, 250, 203, 255, 247, 254 },
|
||||
new byte[] { 242, 181, 196, 250, 203, 255, 247, 254 },
|
||||
new byte[] { 243, 182, 197, 251, 204, 255, 247, 254 },
|
||||
new byte[] { 243, 183, 197, 251, 204, 255, 247, 254 },
|
||||
new byte[] { 244, 184, 198, 251, 205, 255, 247, 254 },
|
||||
new byte[] { 244, 184, 198, 251, 205, 255, 247, 254 },
|
||||
new byte[] { 244, 185, 199, 251, 206, 255, 247, 254 },
|
||||
new byte[] { 244, 185, 199, 251, 206, 255, 247, 254 },
|
||||
new byte[] { 245, 186, 200, 251, 207, 255, 247, 254 },
|
||||
new byte[] { 245, 187, 200, 251, 207, 255, 247, 254 },
|
||||
new byte[] { 246, 188, 201, 252, 207, 255, 248, 254 },
|
||||
new byte[] { 246, 188, 201, 252, 207, 255, 248, 254 },
|
||||
new byte[] { 246, 189, 202, 252, 208, 255, 248, 254 },
|
||||
new byte[] { 246, 190, 202, 252, 208, 255, 248, 254 },
|
||||
new byte[] { 247, 191, 203, 252, 209, 255, 248, 254 },
|
||||
new byte[] { 247, 191, 203, 252, 209, 255, 248, 254 },
|
||||
new byte[] { 247, 192, 204, 252, 210, 255, 248, 254 },
|
||||
new byte[] { 247, 193, 204, 252, 210, 255, 248, 254 },
|
||||
new byte[] { 248, 194, 205, 252, 211, 255, 248, 254 },
|
||||
new byte[] { 248, 194, 205, 252, 211, 255, 248, 254 },
|
||||
new byte[] { 248, 195, 206, 252, 212, 255, 249, 254 },
|
||||
new byte[] { 248, 196, 206, 252, 212, 255, 249, 254 },
|
||||
new byte[] { 249, 197, 207, 253, 213, 255, 249, 254 },
|
||||
new byte[] { 249, 197, 207, 253, 213, 255, 249, 254 },
|
||||
new byte[] { 249, 198, 208, 253, 214, 255, 249, 254 },
|
||||
new byte[] { 249, 199, 209, 253, 214, 255, 249, 254 },
|
||||
new byte[] { 250, 200, 210, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 200, 210, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 201, 211, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 202, 211, 253, 215, 255, 249, 254 },
|
||||
new byte[] { 250, 203, 212, 253, 216, 255, 249, 254 },
|
||||
new byte[] { 250, 203, 212, 253, 216, 255, 249, 254 },
|
||||
new byte[] { 251, 204, 213, 253, 217, 255, 250, 254 },
|
||||
new byte[] { 251, 205, 213, 253, 217, 255, 250, 254 },
|
||||
new byte[] { 251, 206, 214, 254, 218, 255, 250, 254 },
|
||||
new byte[] { 251, 206, 215, 254, 218, 255, 250, 254 },
|
||||
new byte[] { 252, 207, 216, 254, 219, 255, 250, 254 },
|
||||
new byte[] { 252, 208, 216, 254, 219, 255, 250, 254 },
|
||||
new byte[] { 252, 209, 217, 254, 220, 255, 250, 254 },
|
||||
new byte[] { 252, 210, 217, 254, 220, 255, 250, 254 },
|
||||
new byte[] { 252, 211, 218, 254, 221, 255, 250, 254 },
|
||||
new byte[] { 252, 212, 218, 254, 221, 255, 250, 254 },
|
||||
new byte[] { 253, 213, 219, 254, 222, 255, 250, 254 },
|
||||
new byte[] { 253, 213, 220, 254, 222, 255, 250, 254 },
|
||||
new byte[] { 253, 214, 221, 254, 223, 255, 250, 254 },
|
||||
new byte[] { 253, 215, 221, 254, 223, 255, 250, 254 },
|
||||
new byte[] { 253, 216, 222, 254, 224, 255, 251, 254 },
|
||||
new byte[] { 253, 217, 223, 254, 224, 255, 251, 254 },
|
||||
new byte[] { 253, 218, 224, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 253, 219, 224, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 254, 220, 225, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 254, 221, 226, 254, 225, 255, 251, 254 },
|
||||
new byte[] { 254, 222, 227, 255, 226, 255, 251, 254 },
|
||||
new byte[] { 254, 223, 227, 255, 226, 255, 251, 254 },
|
||||
new byte[] { 254, 224, 228, 255, 227, 255, 251, 254 },
|
||||
new byte[] { 254, 225, 229, 255, 227, 255, 251, 254 },
|
||||
new byte[] { 254, 226, 230, 255, 228, 255, 251, 254 },
|
||||
new byte[] { 254, 227, 230, 255, 229, 255, 251, 254 },
|
||||
new byte[] { 255, 228, 231, 255, 230, 255, 251, 254 },
|
||||
new byte[] { 255, 229, 232, 255, 230, 255, 251, 254 },
|
||||
new byte[] { 255, 230, 233, 255, 231, 255, 252, 254 },
|
||||
new byte[] { 255, 231, 234, 255, 231, 255, 252, 254 },
|
||||
new byte[] { 255, 232, 235, 255, 232, 255, 252, 254 },
|
||||
new byte[] { 255, 233, 236, 255, 232, 255, 252, 254 },
|
||||
new byte[] { 255, 235, 237, 255, 233, 255, 252, 254 },
|
||||
new byte[] { 255, 236, 238, 255, 234, 255, 252, 254 },
|
||||
new byte[] { 255, 238, 240, 255, 235, 255, 252, 255 },
|
||||
new byte[] { 255, 239, 241, 255, 235, 255, 252, 254 },
|
||||
new byte[] { 255, 241, 243, 255, 236, 255, 252, 254 },
|
||||
new byte[] { 255, 243, 245, 255, 237, 255, 252, 254 },
|
||||
new byte[] { 255, 246, 247, 255, 239, 255, 253, 255 }
|
||||
};
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs4x4 =
|
||||
{
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
195, 29, 183, 84, 49, 136, 8, 42, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
31, 107, 169, 35, 99, 159, 17, 82, 140, 8, 66, 114, 2, 44, 76, 1, 19, 32,
|
||||
// Band 2
|
||||
40, 132, 201, 29, 114, 187, 13, 91, 157, 7, 75, 127, 3, 58, 95, 1, 28, 47,
|
||||
// Band 3
|
||||
69, 142, 221, 42, 122, 201, 15, 91, 159, 6, 67, 121, 1, 42, 77, 1, 17, 31,
|
||||
// Band 4
|
||||
102, 148, 228, 67, 117, 204, 17, 82, 154, 6, 59, 114, 2, 39, 75, 1, 15, 29,
|
||||
// Band 5
|
||||
156, 57, 233, 119, 57, 212, 58, 48, 163, 29, 40, 124, 12, 30, 81, 3, 12, 31,
|
||||
// Inter
|
||||
// Band 0
|
||||
191, 107, 226, 124, 117, 204, 25, 99, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
29, 148, 210, 37, 126, 194, 8, 93, 157, 2, 68, 118, 1, 39, 69, 1, 17, 33,
|
||||
// Band 2
|
||||
41, 151, 213, 27, 123, 193, 3, 82, 144, 1, 58, 105, 1, 32, 60, 1, 13, 26,
|
||||
// Band 3
|
||||
59, 159, 220, 23, 126, 198, 4, 88, 151, 1, 66, 114, 1, 38, 71, 1, 18, 34,
|
||||
// Band 4
|
||||
114, 136, 232, 51, 114, 207, 11, 83, 155, 3, 56, 105, 1, 33, 65, 1, 17, 34,
|
||||
// Band 5
|
||||
149, 65, 234, 121, 57, 215, 61, 49, 166, 28, 36, 114, 12, 25, 76, 3, 16, 42,
|
||||
// UV plane
|
||||
// Intra
|
||||
// Band 0
|
||||
214, 49, 220, 132, 63, 188, 42, 65, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
85, 137, 221, 104, 131, 216, 49, 111, 192, 21, 87, 155, 2, 49, 87, 1, 16, 28,
|
||||
// Band 2
|
||||
89, 163, 230, 90, 137, 220, 29, 100, 183, 10, 70, 135, 2, 42, 81, 1, 17, 33,
|
||||
// Band 3
|
||||
108, 167, 237, 55, 133, 222, 15, 97, 179, 4, 72, 135, 1, 45, 85, 1, 19, 38,
|
||||
// Band 4
|
||||
124, 146, 240, 66, 124, 224, 17, 88, 175, 4, 58, 122, 1, 36, 75, 1, 18, 37,
|
||||
// Band 5
|
||||
141, 79, 241, 126, 70, 227, 66, 58, 182, 30, 44, 136, 12, 34, 96, 2, 20, 47,
|
||||
// Inter
|
||||
// Band 0
|
||||
229, 99, 249, 143, 111, 235, 46, 109, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
82, 158, 236, 94, 146, 224, 25, 117, 191, 9, 87, 149, 3, 56, 99, 1, 33, 57,
|
||||
// Band 2
|
||||
83, 167, 237, 68, 145, 222, 10, 103, 177, 2, 72, 131, 1, 41, 79, 1, 20, 39,
|
||||
// Band 3
|
||||
99, 167, 239, 47, 141, 224, 10, 104, 178, 2, 73, 133, 1, 44, 85, 1, 22, 47,
|
||||
// Band 4
|
||||
127, 145, 243, 71, 129, 228, 17, 93, 177, 3, 61, 124, 1, 41, 84, 1, 21, 52,
|
||||
// Band 5
|
||||
157, 78, 244, 140, 72, 231, 69, 58, 184, 31, 44, 137, 14, 38, 105, 8, 23, 61
|
||||
};
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs8x8 =
|
||||
{
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
125, 34, 187, 52, 41, 133, 6, 31, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
37, 109, 153, 51, 102, 147, 23, 87, 128, 8, 67, 101, 1, 41, 63, 1, 19, 29,
|
||||
// Band 2
|
||||
31, 154, 185, 17, 127, 175, 6, 96, 145, 2, 73, 114, 1, 51, 82, 1, 28, 45,
|
||||
// Band 3
|
||||
23, 163, 200, 10, 131, 185, 2, 93, 148, 1, 67, 111, 1, 41, 69, 1, 14, 24,
|
||||
// Band 4
|
||||
29, 176, 217, 12, 145, 201, 3, 101, 156, 1, 69, 111, 1, 39, 63, 1, 14, 23,
|
||||
// Band 5
|
||||
57, 192, 233, 25, 154, 215, 6, 109, 167, 3, 78, 118, 1, 48, 69, 1, 21, 29,
|
||||
// Inter
|
||||
// Band 0
|
||||
202, 105, 245, 108, 106, 216, 18, 90, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
33, 172, 219, 64, 149, 206, 14, 117, 177, 5, 90, 141, 2, 61, 95, 1, 37, 57,
|
||||
// Band 2
|
||||
33, 179, 220, 11, 140, 198, 1, 89, 148, 1, 60, 104, 1, 33, 57, 1, 12, 21,
|
||||
// Band 3
|
||||
30, 181, 221, 8, 141, 198, 1, 87, 145, 1, 58, 100, 1, 31, 55, 1, 12, 20,
|
||||
// Band 4
|
||||
32, 186, 224, 7, 142, 198, 1, 86, 143, 1, 58, 100, 1, 31, 55, 1, 12, 22,
|
||||
// Band 5
|
||||
57, 192, 227, 20, 143, 204, 3, 96, 154, 1, 68, 112, 1, 42, 69, 1, 19, 32,
|
||||
// UV plane
|
||||
// Intra
|
||||
// Band 0
|
||||
212, 35, 215, 113, 47, 169, 29, 48, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
74, 129, 203, 106, 120, 203, 49, 107, 178, 19, 84, 144, 4, 50, 84, 1, 15, 25,
|
||||
// Band 2
|
||||
71, 172, 217, 44, 141, 209, 15, 102, 173, 6, 76, 133, 2, 51, 89, 1, 24, 42,
|
||||
// Band 3
|
||||
64, 185, 231, 31, 148, 216, 8, 103, 175, 3, 74, 131, 1, 46, 81, 1, 18, 30,
|
||||
// Band 4
|
||||
65, 196, 235, 25, 157, 221, 5, 105, 174, 1, 67, 120, 1, 38, 69, 1, 15, 30,
|
||||
// Band 5
|
||||
65, 204, 238, 30, 156, 224, 7, 107, 177, 2, 70, 124, 1, 42, 73, 1, 18, 34,
|
||||
// Inter
|
||||
// Band 0
|
||||
225, 86, 251, 144, 104, 235, 42, 99, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
85, 175, 239, 112, 165, 229, 29, 136, 200, 12, 103, 162, 6, 77, 123, 2, 53, 84,
|
||||
// Band 2
|
||||
75, 183, 239, 30, 155, 221, 3, 106, 171, 1, 74, 128, 1, 44, 76, 1, 17, 28,
|
||||
// Band 3
|
||||
73, 185, 240, 27, 159, 222, 2, 107, 172, 1, 75, 127, 1, 42, 73, 1, 17, 29,
|
||||
// Band 4
|
||||
62, 190, 238, 21, 159, 222, 2, 107, 172, 1, 72, 122, 1, 40, 71, 1, 18, 32,
|
||||
// Band 5
|
||||
61, 199, 240, 27, 161, 226, 4, 113, 180, 1, 76, 129, 1, 46, 80, 1, 23, 41
|
||||
};
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs16x16 =
|
||||
{
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
7, 27, 153, 5, 30, 95, 1, 16, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
50, 75, 127, 57, 75, 124, 27, 67, 108, 10, 54, 86, 1, 33, 52, 1, 12, 18,
|
||||
// Band 2
|
||||
43, 125, 151, 26, 108, 148, 7, 83, 122, 2, 59, 89, 1, 38, 60, 1, 17, 27,
|
||||
// Band 3
|
||||
23, 144, 163, 13, 112, 154, 2, 75, 117, 1, 50, 81, 1, 31, 51, 1, 14, 23,
|
||||
// Band 4
|
||||
18, 162, 185, 6, 123, 171, 1, 78, 125, 1, 51, 86, 1, 31, 54, 1, 14, 23,
|
||||
// Band 5
|
||||
15, 199, 227, 3, 150, 204, 1, 91, 146, 1, 55, 95, 1, 30, 53, 1, 11, 20,
|
||||
// Inter
|
||||
// Band 0
|
||||
19, 55, 240, 19, 59, 196, 3, 52, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
41, 166, 207, 104, 153, 199, 31, 123, 181, 14, 101, 152, 5, 72, 106, 1, 36, 52,
|
||||
// Band 2
|
||||
35, 176, 211, 12, 131, 190, 2, 88, 144, 1, 60, 101, 1, 36, 60, 1, 16, 28,
|
||||
// Band 3
|
||||
28, 183, 213, 8, 134, 191, 1, 86, 142, 1, 56, 96, 1, 30, 53, 1, 12, 20,
|
||||
// Band 4
|
||||
20, 190, 215, 4, 135, 192, 1, 84, 139, 1, 53, 91, 1, 28, 49, 1, 11, 20,
|
||||
// Band 5
|
||||
13, 196, 216, 2, 137, 192, 1, 86, 143, 1, 57, 99, 1, 32, 56, 1, 13, 24,
|
||||
// UV plane
|
||||
// Intra
|
||||
// Band 0
|
||||
211, 29, 217, 96, 47, 156, 22, 43, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
78, 120, 193, 111, 116, 186, 46, 102, 164, 15, 80, 128, 2, 49, 76, 1, 18, 28,
|
||||
// Band 2
|
||||
71, 161, 203, 42, 132, 192, 10, 98, 150, 3, 69, 109, 1, 44, 70, 1, 18, 29,
|
||||
// Band 3
|
||||
57, 186, 211, 30, 140, 196, 4, 93, 146, 1, 62, 102, 1, 38, 65, 1, 16, 27,
|
||||
// Band 4
|
||||
47, 199, 217, 14, 145, 196, 1, 88, 142, 1, 57, 98, 1, 36, 62, 1, 15, 26,
|
||||
// Band 5
|
||||
26, 219, 229, 5, 155, 207, 1, 94, 151, 1, 60, 104, 1, 36, 62, 1, 16, 28,
|
||||
// Inter
|
||||
// Band 0
|
||||
233, 29, 248, 146, 47, 220, 43, 52, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
100, 163, 232, 179, 161, 222, 63, 142, 204, 37, 113, 174, 26, 89, 137, 18, 68, 97,
|
||||
// Band 2
|
||||
85, 181, 230, 32, 146, 209, 7, 100, 164, 3, 71, 121, 1, 45, 77, 1, 18, 30,
|
||||
// Band 3
|
||||
65, 187, 230, 20, 148, 207, 2, 97, 159, 1, 68, 116, 1, 40, 70, 1, 14, 29,
|
||||
// Band 4
|
||||
40, 194, 227, 8, 147, 204, 1, 94, 155, 1, 65, 112, 1, 39, 66, 1, 14, 26,
|
||||
// Band 5
|
||||
16, 208, 228, 3, 151, 207, 1, 98, 160, 1, 67, 117, 1, 41, 74, 1, 17, 31
|
||||
};
|
||||
|
||||
internal static readonly byte[] DefaultCoefProbs32x32 =
|
||||
{
|
||||
// Y plane
|
||||
// Intra
|
||||
// Band 0
|
||||
17, 38, 140, 7, 34, 80, 1, 17, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
37, 75, 128, 41, 76, 128, 26, 66, 116, 12, 52, 94, 2, 32, 55, 1, 10, 16,
|
||||
// Band 2
|
||||
50, 127, 154, 37, 109, 152, 16, 82, 121, 5, 59, 85, 1, 35, 54, 1, 13, 20,
|
||||
// Band 3
|
||||
40, 142, 167, 17, 110, 157, 2, 71, 112, 1, 44, 72, 1, 27, 45, 1, 11, 17,
|
||||
// Band 4
|
||||
30, 175, 188, 9, 124, 169, 1, 74, 116, 1, 48, 78, 1, 30, 49, 1, 11, 18,
|
||||
// Band 5
|
||||
10, 222, 223, 2, 150, 194, 1, 83, 128, 1, 48, 79, 1, 27, 45, 1, 11, 17,
|
||||
// Inter
|
||||
// Band 0
|
||||
36, 41, 235, 29, 36, 193, 10, 27, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
85, 165, 222, 177, 162, 215, 110, 135, 195, 57, 113, 168, 23, 83, 120, 10, 49, 61,
|
||||
// Band 2
|
||||
85, 190, 223, 36, 139, 200, 5, 90, 146, 1, 60, 103, 1, 38, 65, 1, 18, 30,
|
||||
// Band 3
|
||||
72, 202, 223, 23, 141, 199, 2, 86, 140, 1, 56, 97, 1, 36, 61, 1, 16, 27,
|
||||
// Band 4
|
||||
55, 218, 225, 13, 145, 200, 1, 86, 141, 1, 57, 99, 1, 35, 61, 1, 13, 22,
|
||||
// Band 5
|
||||
15, 235, 212, 1, 132, 184, 1, 84, 139, 1, 57, 97, 1, 34, 56, 1, 14, 23,
|
||||
// UV plane
|
||||
// Intra
|
||||
// Band 0
|
||||
181, 21, 201, 61, 37, 123, 10, 38, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
47, 106, 172, 95, 104, 173, 42, 93, 159, 18, 77, 131, 4, 50, 81, 1, 17, 23,
|
||||
// Band 2
|
||||
62, 147, 199, 44, 130, 189, 28, 102, 154, 18, 75, 115, 2, 44, 65, 1, 12, 19,
|
||||
// Band 3
|
||||
55, 153, 210, 24, 130, 194, 3, 93, 146, 1, 61, 97, 1, 31, 50, 1, 10, 16,
|
||||
// Band 4
|
||||
49, 186, 223, 17, 148, 204, 1, 96, 142, 1, 53, 83, 1, 26, 44, 1, 11, 17,
|
||||
// Band 5
|
||||
13, 217, 212, 2, 136, 180, 1, 78, 124, 1, 50, 83, 1, 29, 49, 1, 14, 23,
|
||||
// Inter
|
||||
// Band 0
|
||||
197, 13, 247, 82, 17, 222, 25, 17, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Band 1
|
||||
126, 186, 247, 234, 191, 243, 176, 177, 234, 104, 158, 220, 66, 128, 186, 55, 90, 137,
|
||||
// Band 2
|
||||
111, 197, 242, 46, 158, 219, 9, 104, 171, 2, 65, 125, 1, 44, 80, 1, 17, 91,
|
||||
// Band 3
|
||||
104, 208, 245, 39, 168, 224, 3, 109, 162, 1, 79, 124, 1, 50, 102, 1, 43, 102,
|
||||
// Band 4
|
||||
84, 220, 246, 31, 177, 231, 2, 115, 180, 1, 79, 134, 1, 55, 77, 1, 60, 79,
|
||||
// Band 5
|
||||
43, 243, 240, 8, 180, 217, 1, 115, 166, 1, 84, 121, 1, 51, 67, 1, 16, 6
|
||||
};
|
||||
|
||||
public static byte[] GetBandTranslate(int txSize)
|
||||
{
|
||||
return txSize == (int)TxSize.Tx4x4 ? CoefbandTrans4x4 : CoefbandTrans8x8Plus;
|
||||
}
|
||||
|
||||
public static void CopyProbs<T>(ref T dest, ReadOnlySpan<byte> probs) where T : unmanaged
|
||||
{
|
||||
if (Unsafe.SizeOf<T>() != probs.Length)
|
||||
{
|
||||
throw new Exception("size mismatch expected: " + probs.Length + " got: " + Unsafe.SizeOf<T>());
|
||||
}
|
||||
|
||||
probs.CopyTo(MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateSpan(ref dest, 1)));
|
||||
}
|
||||
|
||||
internal const int CoefCountSat = 24;
|
||||
internal const int CoefMaxUpdateFactor = 112;
|
||||
internal const int CoefCountSatKey = 24;
|
||||
internal const int CoefMaxUpdateFactorKey = 112;
|
||||
internal const int CoefCountSatAfterKey = 24;
|
||||
internal const int CoefMaxUpdateFactorAfterKey = 128;
|
||||
}
|
||||
}
|
||||
400
src/Ryujinx.Graphics.Nvdec.Vp9/EntropyMode.cs
Normal file
400
src/Ryujinx.Graphics.Nvdec.Vp9/EntropyMode.cs
Normal file
@@ -0,0 +1,400 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal class EntropyMode
|
||||
{
|
||||
public const int BlockSizeGroups = 4;
|
||||
|
||||
public const int TxSizeContexts = 2;
|
||||
|
||||
public static readonly byte[][][] KfYModeProb =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
// above = dc
|
||||
new byte[] { 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc
|
||||
new byte[] { 92, 45, 102, 136, 116, 180, 74, 90, 100 }, // left = v
|
||||
new byte[] { 73, 32, 19, 187, 222, 215, 46, 34, 100 }, // left = h
|
||||
new byte[] { 91, 30, 32, 116, 121, 186, 93, 86, 94 }, // left = d45
|
||||
new byte[] { 72, 35, 36, 149, 68, 206, 68, 63, 105 }, // left = d135
|
||||
new byte[] { 73, 31, 28, 138, 57, 124, 55, 122, 151 }, // left = d117
|
||||
new byte[] { 67, 23, 21, 140, 126, 197, 40, 37, 171 }, // left = d153
|
||||
new byte[] { 86, 27, 28, 128, 154, 212, 45, 43, 53 }, // left = d207
|
||||
new byte[] { 74, 32, 27, 107, 86, 160, 63, 134, 102 }, // left = d63
|
||||
new byte[] { 59, 67, 44, 140, 161, 202, 78, 67, 119 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = v
|
||||
new byte[] { 63, 36, 126, 146, 123, 158, 60, 90, 96 }, // left = dc
|
||||
new byte[] { 43, 46, 168, 134, 107, 128, 69, 142, 92 }, // left = v
|
||||
new byte[] { 44, 29, 68, 159, 201, 177, 50, 57, 77 }, // left = h
|
||||
new byte[] { 58, 38, 76, 114, 97, 172, 78, 133, 92 }, // left = d45
|
||||
new byte[] { 46, 41, 76, 140, 63, 184, 69, 112, 57 }, // left = d135
|
||||
new byte[] { 38, 32, 85, 140, 46, 112, 54, 151, 133 }, // left = d117
|
||||
new byte[] { 39, 27, 61, 131, 110, 175, 44, 75, 136 }, // left = d153
|
||||
new byte[] { 52, 30, 74, 113, 130, 175, 51, 64, 58 }, // left = d207
|
||||
new byte[] { 47, 35, 80, 100, 74, 143, 64, 163, 74 }, // left = d63
|
||||
new byte[] { 36, 61, 116, 114, 128, 162, 80, 125, 82 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = h
|
||||
new byte[] { 82, 26, 26, 171, 208, 204, 44, 32, 105 }, // left = dc
|
||||
new byte[] { 55, 44, 68, 166, 179, 192, 57, 57, 108 }, // left = v
|
||||
new byte[] { 42, 26, 11, 199, 241, 228, 23, 15, 85 }, // left = h
|
||||
new byte[] { 68, 42, 19, 131, 160, 199, 55, 52, 83 }, // left = d45
|
||||
new byte[] { 58, 50, 25, 139, 115, 232, 39, 52, 118 }, // left = d135
|
||||
new byte[] { 50, 35, 33, 153, 104, 162, 64, 59, 131 }, // left = d117
|
||||
new byte[] { 44, 24, 16, 150, 177, 202, 33, 19, 156 }, // left = d153
|
||||
new byte[] { 55, 27, 12, 153, 203, 218, 26, 27, 49 }, // left = d207
|
||||
new byte[] { 53, 49, 21, 110, 116, 168, 59, 80, 76 }, // left = d63
|
||||
new byte[] { 38, 72, 19, 168, 203, 212, 50, 50, 107 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d45
|
||||
new byte[] { 103, 26, 36, 129, 132, 201, 83, 80, 93 }, // left = dc
|
||||
new byte[] { 59, 38, 83, 112, 103, 162, 98, 136, 90 }, // left = v
|
||||
new byte[] { 62, 30, 23, 158, 200, 207, 59, 57, 50 }, // left = h
|
||||
new byte[] { 67, 30, 29, 84, 86, 191, 102, 91, 59 }, // left = d45
|
||||
new byte[] { 60, 32, 33, 112, 71, 220, 64, 89, 104 }, // left = d135
|
||||
new byte[] { 53, 26, 34, 130, 56, 149, 84, 120, 103 }, // left = d117
|
||||
new byte[] { 53, 21, 23, 133, 109, 210, 56, 77, 172 }, // left = d153
|
||||
new byte[] { 77, 19, 29, 112, 142, 228, 55, 66, 36 }, // left = d207
|
||||
new byte[] { 61, 29, 29, 93, 97, 165, 83, 175, 162 }, // left = d63
|
||||
new byte[] { 47, 47, 43, 114, 137, 181, 100, 99, 95 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d135
|
||||
new byte[] { 69, 23, 29, 128, 83, 199, 46, 44, 101 }, // left = dc
|
||||
new byte[] { 53, 40, 55, 139, 69, 183, 61, 80, 110 }, // left = v
|
||||
new byte[] { 40, 29, 19, 161, 180, 207, 43, 24, 91 }, // left = h
|
||||
new byte[] { 60, 34, 19, 105, 61, 198, 53, 64, 89 }, // left = d45
|
||||
new byte[] { 52, 31, 22, 158, 40, 209, 58, 62, 89 }, // left = d135
|
||||
new byte[] { 44, 31, 29, 147, 46, 158, 56, 102, 198 }, // left = d117
|
||||
new byte[] { 35, 19, 12, 135, 87, 209, 41, 45, 167 }, // left = d153
|
||||
new byte[] { 55, 25, 21, 118, 95, 215, 38, 39, 66 }, // left = d207
|
||||
new byte[] { 51, 38, 25, 113, 58, 164, 70, 93, 97 }, // left = d63
|
||||
new byte[] { 47, 54, 34, 146, 108, 203, 72, 103, 151 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d117
|
||||
new byte[] { 64, 19, 37, 156, 66, 138, 49, 95, 133 }, // left = dc
|
||||
new byte[] { 46, 27, 80, 150, 55, 124, 55, 121, 135 }, // left = v
|
||||
new byte[] { 36, 23, 27, 165, 149, 166, 54, 64, 118 }, // left = h
|
||||
new byte[] { 53, 21, 36, 131, 63, 163, 60, 109, 81 }, // left = d45
|
||||
new byte[] { 40, 26, 35, 154, 40, 185, 51, 97, 123 }, // left = d135
|
||||
new byte[] { 35, 19, 34, 179, 19, 97, 48, 129, 124 }, // left = d117
|
||||
new byte[] { 36, 20, 26, 136, 62, 164, 33, 77, 154 }, // left = d153
|
||||
new byte[] { 45, 18, 32, 130, 90, 157, 40, 79, 91 }, // left = d207
|
||||
new byte[] { 45, 26, 28, 129, 45, 129, 49, 147, 123 }, // left = d63
|
||||
new byte[] { 38, 44, 51, 136, 74, 162, 57, 97, 121 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d153
|
||||
new byte[] { 75, 17, 22, 136, 138, 185, 32, 34, 166 }, // left = dc
|
||||
new byte[] { 56, 39, 58, 133, 117, 173, 48, 53, 187 }, // left = v
|
||||
new byte[] { 35, 21, 12, 161, 212, 207, 20, 23, 145 }, // left = h
|
||||
new byte[] { 56, 29, 19, 117, 109, 181, 55, 68, 112 }, // left = d45
|
||||
new byte[] { 47, 29, 17, 153, 64, 220, 59, 51, 114 }, // left = d135
|
||||
new byte[] { 46, 16, 24, 136, 76, 147, 41, 64, 172 }, // left = d117
|
||||
new byte[] { 34, 17, 11, 108, 152, 187, 13, 15, 209 }, // left = d153
|
||||
new byte[] { 51, 24, 14, 115, 133, 209, 32, 26, 104 }, // left = d207
|
||||
new byte[] { 55, 30, 18, 122, 79, 179, 44, 88, 116 }, // left = d63
|
||||
new byte[] { 37, 49, 25, 129, 168, 164, 41, 54, 148 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d207
|
||||
new byte[] { 82, 22, 32, 127, 143, 213, 39, 41, 70 }, // left = dc
|
||||
new byte[] { 62, 44, 61, 123, 105, 189, 48, 57, 64 }, // left = v
|
||||
new byte[] { 47, 25, 17, 175, 222, 220, 24, 30, 86 }, // left = h
|
||||
new byte[] { 68, 36, 17, 106, 102, 206, 59, 74, 74 }, // left = d45
|
||||
new byte[] { 57, 39, 23, 151, 68, 216, 55, 63, 58 }, // left = d135
|
||||
new byte[] { 49, 30, 35, 141, 70, 168, 82, 40, 115 }, // left = d117
|
||||
new byte[] { 51, 25, 15, 136, 129, 202, 38, 35, 139 }, // left = d153
|
||||
new byte[] { 68, 26, 16, 111, 141, 215, 29, 28, 28 }, // left = d207
|
||||
new byte[] { 59, 39, 19, 114, 75, 180, 77, 104, 42 }, // left = d63
|
||||
new byte[] { 40, 61, 26, 126, 152, 206, 61, 59, 93 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = d63
|
||||
new byte[] { 78, 23, 39, 111, 117, 170, 74, 124, 94 }, // left = dc
|
||||
new byte[] { 48, 34, 86, 101, 92, 146, 78, 179, 134 }, // left = v
|
||||
new byte[] { 47, 22, 24, 138, 187, 178, 68, 69, 59 }, // left = h
|
||||
new byte[] { 56, 25, 33, 105, 112, 187, 95, 177, 129 }, // left = d45
|
||||
new byte[] { 48, 31, 27, 114, 63, 183, 82, 116, 56 }, // left = d135
|
||||
new byte[] { 43, 28, 37, 121, 63, 123, 61, 192, 169 }, // left = d117
|
||||
new byte[] { 42, 17, 24, 109, 97, 177, 56, 76, 122 }, // left = d153
|
||||
new byte[] { 58, 18, 28, 105, 139, 182, 70, 92, 63 }, // left = d207
|
||||
new byte[] { 46, 23, 32, 74, 86, 150, 67, 183, 88 }, // left = d63
|
||||
new byte[] { 36, 38, 48, 92, 122, 165, 88, 137, 91 } // left = tm
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// above = tm
|
||||
new byte[] { 65, 70, 60, 155, 159, 199, 61, 60, 81 }, // left = dc
|
||||
new byte[] { 44, 78, 115, 132, 119, 173, 71, 112, 93 }, // left = v
|
||||
new byte[] { 39, 38, 21, 184, 227, 206, 42, 32, 64 }, // left = h
|
||||
new byte[] { 58, 47, 36, 124, 137, 193, 80, 82, 78 }, // left = d45
|
||||
new byte[] { 49, 50, 35, 144, 95, 205, 63, 78, 59 }, // left = d135
|
||||
new byte[] { 41, 53, 52, 148, 71, 142, 65, 128, 51 }, // left = d117
|
||||
new byte[] { 40, 36, 28, 143, 143, 202, 40, 55, 137 }, // left = d153
|
||||
new byte[] { 52, 34, 29, 129, 183, 227, 42, 35, 43 }, // left = d207
|
||||
new byte[] { 42, 44, 44, 104, 105, 164, 64, 130, 80 }, // left = d63
|
||||
new byte[] { 43, 81, 53, 140, 169, 204, 68, 84, 72 } // left = tm
|
||||
}
|
||||
};
|
||||
|
||||
public static readonly byte[][] KfUvModeProb =
|
||||
{
|
||||
new byte[] { 144, 11, 54, 157, 195, 130, 46, 58, 108 }, // y = dc
|
||||
new byte[] { 118, 15, 123, 148, 131, 101, 44, 93, 131 }, // y = v
|
||||
new byte[] { 113, 12, 23, 188, 226, 142, 26, 32, 125 }, // y = h
|
||||
new byte[] { 120, 11, 50, 123, 163, 135, 64, 77, 103 }, // y = d45
|
||||
new byte[] { 113, 9, 36, 155, 111, 157, 32, 44, 161 }, // y = d135
|
||||
new byte[] { 116, 9, 55, 176, 76, 96, 37, 61, 149 }, // y = d117
|
||||
new byte[] { 115, 9, 28, 141, 161, 167, 21, 25, 193 }, // y = d153
|
||||
new byte[] { 120, 12, 32, 145, 195, 142, 32, 38, 86 }, // y = d207
|
||||
new byte[] { 116, 12, 64, 120, 140, 125, 49, 115, 121 }, // y = d63
|
||||
new byte[] { 102, 19, 66, 162, 182, 122, 35, 59, 128 } // y = tm
|
||||
};
|
||||
|
||||
private static readonly byte[] DefaultIfYProbs =
|
||||
{
|
||||
65, 32, 18, 144, 162, 194, 41, 51, 98, // block_size < 8x8
|
||||
132, 68, 18, 165, 217, 196, 45, 40, 78, // block_size < 16x16
|
||||
173, 80, 19, 176, 240, 193, 64, 35, 46, // block_size < 32x32
|
||||
221, 135, 38, 194, 248, 121, 96, 85, 29 // block_size >= 32x32
|
||||
};
|
||||
|
||||
private static readonly byte[] DefaultIfUvProbs =
|
||||
{
|
||||
120, 7, 76, 176, 208, 126, 28, 54, 103, // y = dc
|
||||
48, 12, 154, 155, 139, 90, 34, 117, 119, // y = v
|
||||
67, 6, 25, 204, 243, 158, 13, 21, 96, // y = h
|
||||
97, 5, 44, 131, 176, 139, 48, 68, 97, // y = d45
|
||||
83, 5, 42, 156, 111, 152, 26, 49, 152, // y = d135
|
||||
80, 5, 58, 178, 74, 83, 33, 62, 145, // y = d117
|
||||
86, 5, 32, 154, 192, 168, 14, 22, 163, // y = d153
|
||||
85, 5, 32, 156, 216, 148, 19, 29, 73, // y = d207
|
||||
77, 7, 64, 116, 132, 122, 37, 126, 120, // y = d63
|
||||
101, 21, 107, 181, 192, 103, 19, 67, 125 // y = tm
|
||||
};
|
||||
|
||||
private static readonly byte[] DefaultPartitionProbs =
|
||||
{
|
||||
// 8x8 . 4x4
|
||||
199, 122, 141, // a/l both not split
|
||||
147, 63, 159, // a split, l not split
|
||||
148, 133, 118, // l split, a not split
|
||||
121, 104, 114, // a/l both split
|
||||
// 16x16 . 8x8
|
||||
174, 73, 87, // a/l both not split
|
||||
92, 41, 83, // a split, l not split
|
||||
82, 99, 50, // l split, a not split
|
||||
53, 39, 39, // a/l both split
|
||||
// 32x32 . 16x16
|
||||
177, 58, 59, // a/l both not split
|
||||
68, 26, 63, // a split, l not split
|
||||
52, 79, 25, // l split, a not split
|
||||
17, 14, 12, // a/l both split
|
||||
// 64x64 . 32x32
|
||||
222, 34, 30, // a/l both not split
|
||||
72, 16, 44, // a split, l not split
|
||||
58, 32, 12, // l split, a not split
|
||||
10, 7, 6 // a/l both split
|
||||
};
|
||||
|
||||
private static readonly byte[] DefaultInterModeProbs =
|
||||
{
|
||||
2, 173, 34, // 0 = both zero mv
|
||||
7, 145, 85, // 1 = one zero mv + one a predicted mv
|
||||
7, 166, 63, // 2 = two predicted mvs
|
||||
7, 94, 66, // 3 = one predicted/zero and one new mv
|
||||
8, 64, 46, // 4 = two new mvs
|
||||
17, 81, 31, // 5 = one intra neighbour + x
|
||||
25, 29, 30 // 6 = two intra neighbours
|
||||
};
|
||||
|
||||
/* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
|
||||
public static readonly sbyte[] IntraModeTree =
|
||||
{
|
||||
-(int)PredictionMode.DcPred, 2, /* 0 = DC_NODE */ -(int)PredictionMode.TmPred, 4, /* 1 = TM_NODE */
|
||||
-(int)PredictionMode.VPred, 6, /* 2 = V_NODE */ 8, 12, /* 3 = COM_NODE */ -(int)PredictionMode.HPred,
|
||||
10, /* 4 = H_NODE */ -(int)PredictionMode.D135Pred, -(int)PredictionMode.D117Pred, /* 5 = D135_NODE */
|
||||
-(int)PredictionMode.D45Pred, 14, /* 6 = D45_NODE */ -(int)PredictionMode.D63Pred,
|
||||
16, /* 7 = D63_NODE */ -(int)PredictionMode.D153Pred, -(int)PredictionMode.D207Pred /* 8 = D153_NODE */
|
||||
};
|
||||
|
||||
public static readonly sbyte[] InterModeTree =
|
||||
{
|
||||
-((int)PredictionMode.ZeroMv - (int)PredictionMode.NearestMv), 2,
|
||||
-((int)PredictionMode.NearestMv - (int)PredictionMode.NearestMv), 4,
|
||||
-((int)PredictionMode.NearMv - (int)PredictionMode.NearestMv),
|
||||
-((int)PredictionMode.NewMv - (int)PredictionMode.NearestMv)
|
||||
};
|
||||
|
||||
public static readonly sbyte[] PartitionTree =
|
||||
{
|
||||
-(sbyte)PartitionType.PartitionNone, 2, -(sbyte)PartitionType.PartitionHorz, 4,
|
||||
-(sbyte)PartitionType.PartitionVert, -(sbyte)PartitionType.PartitionSplit
|
||||
};
|
||||
|
||||
public static readonly sbyte[] SwitchableInterpTree =
|
||||
{
|
||||
-Constants.EightTap, 2, -Constants.EightTapSmooth, -Constants.EightTapSharp
|
||||
};
|
||||
|
||||
private static readonly byte[] DefaultIntraInterP = { 9, 102, 187, 225 };
|
||||
private static readonly byte[] DefaultCompInterP = { 239, 183, 119, 96, 41 };
|
||||
private static readonly byte[] DefaultCompRefP = { 50, 126, 123, 221, 226 };
|
||||
private static readonly byte[] DefaultSingleRefP = { 33, 16, 77, 74, 142, 142, 172, 170, 238, 247 };
|
||||
private static readonly byte[] DefaultTxProbs = { 3, 136, 37, 5, 52, 13, 20, 152, 15, 101, 100, 66 };
|
||||
|
||||
static EntropyMode()
|
||||
{
|
||||
byte[][] KfPartitionProbs =
|
||||
{
|
||||
// 8x8 . 4x4
|
||||
new byte[] { 158, 97, 94 }, // a/l both not split
|
||||
new byte[] { 93, 24, 99 }, // a split, l not split
|
||||
new byte[] { 85, 119, 44 }, // l split, a not split
|
||||
new byte[] { 62, 59, 67 }, // a/l both split
|
||||
|
||||
// 16x16 . 8x8
|
||||
new byte[] { 149, 53, 53 }, // a/l both not split
|
||||
new byte[] { 94, 20, 48 }, // a split, l not split
|
||||
new byte[] { 83, 53, 24 }, // l split, a not split
|
||||
new byte[] { 52, 18, 18 }, // a/l both split
|
||||
|
||||
// 32x32 . 16x16
|
||||
new byte[] { 150, 40, 39 }, // a/l both not split
|
||||
new byte[] { 78, 12, 26 }, // a split, l not split
|
||||
new byte[] { 67, 33, 11 }, // l split, a not split
|
||||
new byte[] { 24, 7, 5 }, // a/l both split
|
||||
|
||||
// 64x64 . 32x32
|
||||
new byte[] { 174, 35, 49 }, // a/l both not split
|
||||
new byte[] { 68, 11, 27 }, // a split, l not split
|
||||
new byte[] { 57, 15, 9 }, // l split, a not split
|
||||
new byte[] { 12, 3, 3 } // a/l both split
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly byte[] DefaultSkipProbs = { 192, 128, 64 };
|
||||
|
||||
private static readonly byte[] DefaultSwitchableInterpProb = { 235, 162, 36, 255, 34, 3, 149, 144 };
|
||||
|
||||
private static void InitModeProbs(ref Vp9EntropyProbs fc)
|
||||
{
|
||||
Entropy.CopyProbs(ref fc.UvModeProb, DefaultIfUvProbs);
|
||||
Entropy.CopyProbs(ref fc.YModeProb, DefaultIfYProbs);
|
||||
Entropy.CopyProbs(ref fc.SwitchableInterpProb, DefaultSwitchableInterpProb);
|
||||
Entropy.CopyProbs(ref fc.PartitionProb, DefaultPartitionProbs);
|
||||
Entropy.CopyProbs(ref fc.IntraInterProb, DefaultIntraInterP);
|
||||
Entropy.CopyProbs(ref fc.CompInterProb, DefaultCompInterP);
|
||||
Entropy.CopyProbs(ref fc.CompRefProb, DefaultCompRefP);
|
||||
Entropy.CopyProbs(ref fc.SingleRefProb, DefaultSingleRefP);
|
||||
Entropy.CopyProbs(ref fc.Tx32x32Prob, DefaultTxProbs.AsSpan().Slice(0, 6));
|
||||
Entropy.CopyProbs(ref fc.Tx16x16Prob, DefaultTxProbs.AsSpan().Slice(6, 4));
|
||||
Entropy.CopyProbs(ref fc.Tx8x8Prob, DefaultTxProbs.AsSpan().Slice(10, 2));
|
||||
Entropy.CopyProbs(ref fc.SkipProb, DefaultSkipProbs);
|
||||
Entropy.CopyProbs(ref fc.InterModeProb, DefaultInterModeProbs);
|
||||
}
|
||||
|
||||
internal static void TxCountsToBranchCounts32x32(ReadOnlySpan<uint> txCount32x32P,
|
||||
ref Array3<Array2<uint>> ct32x32P)
|
||||
{
|
||||
ct32x32P[0][0] = txCount32x32P[(int)TxSize.Tx4x4];
|
||||
ct32x32P[0][1] = txCount32x32P[(int)TxSize.Tx8x8] + txCount32x32P[(int)TxSize.Tx16x16] +
|
||||
txCount32x32P[(int)TxSize.Tx32x32];
|
||||
ct32x32P[1][0] = txCount32x32P[(int)TxSize.Tx8x8];
|
||||
ct32x32P[1][1] = txCount32x32P[(int)TxSize.Tx16x16] + txCount32x32P[(int)TxSize.Tx32x32];
|
||||
ct32x32P[2][0] = txCount32x32P[(int)TxSize.Tx16x16];
|
||||
ct32x32P[2][1] = txCount32x32P[(int)TxSize.Tx32x32];
|
||||
}
|
||||
|
||||
internal static void TxCountsToBranchCounts16x16(ReadOnlySpan<uint> txCount16x16P,
|
||||
ref Array2<Array2<uint>> ct16x16P)
|
||||
{
|
||||
ct16x16P[0][0] = txCount16x16P[(int)TxSize.Tx4x4];
|
||||
ct16x16P[0][1] = txCount16x16P[(int)TxSize.Tx8x8] + txCount16x16P[(int)TxSize.Tx16x16];
|
||||
ct16x16P[1][0] = txCount16x16P[(int)TxSize.Tx8x8];
|
||||
ct16x16P[1][1] = txCount16x16P[(int)TxSize.Tx16x16];
|
||||
}
|
||||
|
||||
internal static void TxCountsToBranchCounts8x8(ReadOnlySpan<uint> txCount8x8P,
|
||||
ref Array1<Array2<uint>> ct8x8P)
|
||||
{
|
||||
ct8x8P[0][0] = txCount8x8P[(int)TxSize.Tx4x4];
|
||||
ct8x8P[0][1] = txCount8x8P[(int)TxSize.Tx8x8];
|
||||
}
|
||||
|
||||
public static unsafe void SetupPastIndependence(ref Vp9Common cm)
|
||||
{
|
||||
// Reset the segment feature data to the default stats:
|
||||
// Features disabled, 0, with delta coding (Default state).
|
||||
ref Types.LoopFilter lf = ref cm.Lf;
|
||||
|
||||
cm.Seg.ClearAllSegFeatures();
|
||||
cm.Seg.AbsDelta = Segmentation.SegmentDeltadata;
|
||||
|
||||
if (!cm.LastFrameSegMap.IsNull)
|
||||
{
|
||||
MemoryUtil.Fill(cm.LastFrameSegMap.ToPointer(), (byte)0, cm.MiRows * cm.MiCols);
|
||||
}
|
||||
|
||||
if (!cm.CurrentFrameSegMap.IsNull)
|
||||
{
|
||||
MemoryUtil.Fill(cm.CurrentFrameSegMap.ToPointer(), (byte)0, cm.MiRows * cm.MiCols);
|
||||
}
|
||||
|
||||
// Reset the mode ref deltas for loop filter
|
||||
lf.LastRefDeltas = new Array4<sbyte>();
|
||||
lf.LastModeDeltas = new Array2<sbyte>();
|
||||
lf.SetDefaultLfDeltas();
|
||||
|
||||
// To force update of the sharpness
|
||||
lf.LastSharpnessLevel = -1;
|
||||
|
||||
cm.DefaultCoefProbs();
|
||||
InitModeProbs(ref cm.Fc.Value);
|
||||
cm.InitMvProbs();
|
||||
|
||||
if (cm.FrameType == FrameType.KeyFrame || cm.ErrorResilientMode != 0 || cm.ResetFrameContext == 3)
|
||||
{
|
||||
// Reset all frame contexts.
|
||||
for (int i = 0; i < Constants.FrameContexts; ++i)
|
||||
{
|
||||
cm.FrameContexts[i] = cm.Fc.Value;
|
||||
}
|
||||
}
|
||||
else if (cm.ResetFrameContext == 2)
|
||||
{
|
||||
// Reset only the frame context specified in the frame header.
|
||||
cm.FrameContexts[(int)cm.FrameContextIdx] = cm.Fc.Value;
|
||||
}
|
||||
|
||||
// prev_mip will only be allocated in encoder.
|
||||
if (cm.FrameIsIntraOnly() && !cm.PrevMip.IsNull)
|
||||
{
|
||||
cm.PrevMi.Value = new ModeInfo();
|
||||
}
|
||||
|
||||
cm.RefFrameSignBias = new Array4<sbyte>();
|
||||
|
||||
cm.FrameContextIdx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
165
src/Ryujinx.Graphics.Nvdec.Vp9/EntropyMv.cs
Normal file
165
src/Ryujinx.Graphics.Nvdec.Vp9/EntropyMv.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Video;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class EntropyMv
|
||||
{
|
||||
public const int UpdateProb = 252;
|
||||
|
||||
/* Symbols for coding which components are zero jointly */
|
||||
public const int Joints = 4;
|
||||
|
||||
|
||||
public static readonly sbyte[] JointTree =
|
||||
{
|
||||
-(sbyte)MvJointType.Zero, 2, -(sbyte)MvJointType.Hnzvz, 4,
|
||||
-(sbyte)MvJointType.Hzvnz, -(sbyte)MvJointType.Hnzvnz
|
||||
};
|
||||
|
||||
public static readonly sbyte[] ClassTree =
|
||||
{
|
||||
-(sbyte)MvClassType.Class0, 2, -(sbyte)MvClassType.Class1, 4, 6, 8, -(sbyte)MvClassType.Class2,
|
||||
-(sbyte)MvClassType.Class3, 10, 12, -(sbyte)MvClassType.Class4, -(sbyte)MvClassType.Class5,
|
||||
-(sbyte)MvClassType.Class6, 14, 16, 18, -(sbyte)MvClassType.Class7, -(sbyte)MvClassType.Class8,
|
||||
-(sbyte)MvClassType.Class9, -(sbyte)MvClassType.Class10
|
||||
};
|
||||
|
||||
public static readonly sbyte[] Class0Tree = { -0, -1 };
|
||||
|
||||
public static readonly sbyte[] FpTree = { -0, 2, -1, 4, -2, -3 };
|
||||
|
||||
private static bool JointVertical(MvJointType type)
|
||||
{
|
||||
return type == MvJointType.Hzvnz || type == MvJointType.Hnzvnz;
|
||||
}
|
||||
|
||||
private static bool JointHorizontal(MvJointType type)
|
||||
{
|
||||
return type == MvJointType.Hnzvz || type == MvJointType.Hnzvnz;
|
||||
}
|
||||
|
||||
private static readonly byte[] LogInBase2 =
|
||||
{
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 10
|
||||
};
|
||||
|
||||
private static int ClassBase(MvClassType c)
|
||||
{
|
||||
return c != 0 ? Class0Size << ((int)c + 2) : 0;
|
||||
}
|
||||
|
||||
private static MvClassType GetClass(int z, Ptr<int> offset)
|
||||
{
|
||||
MvClassType c = z >= Class0Size * 4096
|
||||
? MvClassType.Class10
|
||||
: (MvClassType)LogInBase2[z >> 3];
|
||||
if (!offset.IsNull)
|
||||
{
|
||||
offset.Value = z - ClassBase(c);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private static void IncComponent(int v, ref Vp9BackwardUpdates compCounts, int compIndex, int incr, int usehp)
|
||||
{
|
||||
int s, z, c, o = 0, d, e, f;
|
||||
Debug.Assert(v != 0); /* should not be zero */
|
||||
s = v < 0 ? 1 : 0;
|
||||
compCounts.Sign[compIndex][s] += (uint)incr;
|
||||
z = (s != 0 ? -v : v) - 1; /* magnitude - 1 */
|
||||
|
||||
c = (int)GetClass(z, new Ptr<int>(ref o));
|
||||
compCounts.Classes[compIndex][c] += (uint)incr;
|
||||
|
||||
d = o >> 3; /* int mv data */
|
||||
f = (o >> 1) & 3; /* fractional pel mv data */
|
||||
e = o & 1; /* high precision mv data */
|
||||
|
||||
if (c == (int)MvClassType.Class0)
|
||||
{
|
||||
compCounts.Class0[compIndex][d] += (uint)incr;
|
||||
compCounts.Class0Fp[compIndex][d][f] += (uint)incr;
|
||||
compCounts.Class0Hp[compIndex][e] += (uint)(usehp * incr);
|
||||
}
|
||||
else
|
||||
{
|
||||
int b = c + Class0Bits - 1; // number of bits
|
||||
for (int i = 0; i < b; ++i)
|
||||
{
|
||||
compCounts.Bits[compIndex][i][(d >> i) & 1] += (uint)incr;
|
||||
}
|
||||
|
||||
compCounts.Fp[compIndex][f] += (uint)incr;
|
||||
compCounts.Hp[compIndex][e] += (uint)(usehp * incr);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Inc(ref Mv mv, Ptr<Vp9BackwardUpdates> counts)
|
||||
{
|
||||
if (!counts.IsNull)
|
||||
{
|
||||
MvJointType j = mv.GetJoint();
|
||||
++counts.Value.Joints[(int)j];
|
||||
|
||||
if (JointVertical(j))
|
||||
{
|
||||
IncComponent(mv.Row, ref counts.Value, 0, 1, 1);
|
||||
}
|
||||
|
||||
if (JointHorizontal(j))
|
||||
{
|
||||
IncComponent(mv.Col, ref counts.Value, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Symbols for coding magnitude class of nonzero components */
|
||||
public const int Classes = 11;
|
||||
|
||||
public const int Class0Bits = 1; /* bits at integer precision for class 0 */
|
||||
public const int Class0Size = 1 << Class0Bits;
|
||||
public const int OffsetBits = Classes + Class0Bits - 2;
|
||||
public const int FpSize = 4;
|
||||
|
||||
public const int MaxBits = Classes + Class0Bits + 2;
|
||||
public const int Max = (1 << MaxBits) - 1;
|
||||
public const int Vals = (Max << 1) + 1;
|
||||
|
||||
public const int InUseBits = 14;
|
||||
public const int Upp = (1 << InUseBits) - 1;
|
||||
public const int Low = -(1 << InUseBits);
|
||||
}
|
||||
}
|
||||
79
src/Ryujinx.Graphics.Nvdec.Vp9/FrameBuffers.cs
Normal file
79
src/Ryujinx.Graphics.Nvdec.Vp9/FrameBuffers.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal struct InternalFrameBuffer
|
||||
{
|
||||
public ArrayPtr<byte> Data;
|
||||
public bool InUse;
|
||||
}
|
||||
|
||||
internal struct InternalFrameBufferList
|
||||
{
|
||||
public ArrayPtr<InternalFrameBuffer> IntFb;
|
||||
}
|
||||
|
||||
internal static class FrameBuffers
|
||||
{
|
||||
public static int GetFrameBuffer(MemoryAllocator allocator, Ptr<InternalFrameBufferList> cbPriv, ulong minSize,
|
||||
ref VpxCodecFrameBuffer fb)
|
||||
{
|
||||
int i;
|
||||
Ptr<InternalFrameBufferList> intFbList = cbPriv;
|
||||
if (intFbList.IsNull)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Find a free frame buffer.
|
||||
for (i = 0; i < intFbList.Value.IntFb.Length; ++i)
|
||||
{
|
||||
if (!intFbList.Value.IntFb[i].InUse)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == intFbList.Value.IntFb.Length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ulong)intFbList.Value.IntFb[i].Data.Length < minSize)
|
||||
{
|
||||
if (!intFbList.Value.IntFb[i].Data.IsNull)
|
||||
{
|
||||
allocator.Free(intFbList.Value.IntFb[i].Data);
|
||||
}
|
||||
|
||||
// The data must be zeroed to fix a valgrind error from the C loop filter
|
||||
// due to access uninitialized memory in frame border. It could be
|
||||
// skipped if border were totally removed.
|
||||
intFbList.Value.IntFb[i].Data = allocator.Allocate<byte>((int)minSize);
|
||||
if (intFbList.Value.IntFb[i].Data.IsNull)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fb.Data = intFbList.Value.IntFb[i].Data;
|
||||
intFbList.Value.IntFb[i].InUse = true;
|
||||
|
||||
// Set the frame buffer's private data to point at the internal frame buffer.
|
||||
fb.Priv = new Ptr<InternalFrameBuffer>(ref intFbList.Value.IntFb[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int ReleaseFrameBuffer(Ptr<InternalFrameBufferList> cbPriv, ref VpxCodecFrameBuffer fb)
|
||||
{
|
||||
if (!fb.Priv.IsNull)
|
||||
{
|
||||
fb.Priv.Value.InUse = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System;
|
||||
using static Ryujinx.Graphics.Nvdec.Vp9.Dsp.InvTxfm;
|
||||
@@ -8,11 +8,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
internal static class Idct
|
||||
{
|
||||
private delegate void Transform1D(ReadOnlySpan<int> input, Span<int> output);
|
||||
|
||||
private delegate void HighbdTransform1D(ReadOnlySpan<int> input, Span<int> output, int bd);
|
||||
|
||||
private struct Transform2D
|
||||
{
|
||||
public Transform1D Cols, Rows; // Vertical and horizontal
|
||||
public readonly Transform1D Cols; // Vertical and horizontal
|
||||
public readonly Transform1D Rows; // Vertical and horizontal
|
||||
|
||||
public Transform2D(Transform1D cols, Transform1D rows)
|
||||
{
|
||||
@@ -23,7 +25,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
|
||||
private struct HighbdTransform2D
|
||||
{
|
||||
public HighbdTransform1D Cols, Rows; // Vertical and horizontal
|
||||
public readonly HighbdTransform1D Cols; // Vertical and horizontal
|
||||
public readonly HighbdTransform1D Rows; // Vertical and horizontal
|
||||
|
||||
public HighbdTransform2D(HighbdTransform1D cols, HighbdTransform1D rows)
|
||||
{
|
||||
@@ -32,121 +35,124 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] _iht4 = {
|
||||
private static readonly Transform2D[] Iht4 =
|
||||
{
|
||||
new(Idct4, Idct4), // DCT_DCT = 0
|
||||
new(Iadst4, Idct4), // ADST_DCT = 1
|
||||
new(Idct4, Iadst4), // DCT_ADST = 2
|
||||
new(Iadst4, Iadst4), // ADST_ADST = 3
|
||||
new(Iadst4, Iadst4) // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void Iht4x416Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[4 * 4];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[4];
|
||||
Span<int> tempOut = stackalloc int[4];
|
||||
|
||||
// Inverse transform row vectors
|
||||
for (i = 0; i < 4; ++i)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
_iht4[txType].Rows(input, outptr);
|
||||
input = input[4..];
|
||||
outptr = outptr[4..];
|
||||
Iht4[txType].Rows(input, outptr);
|
||||
input = input.Slice(4);
|
||||
outptr = outptr.Slice(4);
|
||||
}
|
||||
|
||||
// Inverse transform column vectors
|
||||
for (i = 0; i < 4; ++i)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
for (j = 0; j < 4; ++j)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
tempIn[j] = output[j * 4 + i];
|
||||
tempIn[j] = output[(j * 4) + i];
|
||||
}
|
||||
|
||||
_iht4[txType].Cols(tempIn, tempOut);
|
||||
for (j = 0; j < 4; ++j)
|
||||
Iht4[txType].Cols(tempIn, tempOut);
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 4));
|
||||
dest[(j * stride) + i] =
|
||||
ClipPixelAdd(dest[(j * stride) + i], BitUtils.RoundPowerOfTwo(tempOut[j], 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] _iht8 = {
|
||||
private static readonly Transform2D[] Iht8 =
|
||||
{
|
||||
new(Idct8, Idct8), // DCT_DCT = 0
|
||||
new(Iadst8, Idct8), // ADST_DCT = 1
|
||||
new(Idct8, Iadst8), // DCT_ADST = 2
|
||||
new(Iadst8, Iadst8), // ADST_ADST = 3
|
||||
new(Iadst8, Iadst8) // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void Iht8x864Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[8 * 8];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[8];
|
||||
Span<int> tempOut = stackalloc int[8];
|
||||
Transform2D ht = _iht8[txType];
|
||||
Transform2D ht = Iht8[txType];
|
||||
|
||||
// Inverse transform row vectors
|
||||
for (i = 0; i < 8; ++i)
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr);
|
||||
input = input[8..];
|
||||
outptr = outptr[8..];
|
||||
input = input.Slice(8);
|
||||
outptr = outptr.Slice(8);
|
||||
}
|
||||
|
||||
// Inverse transform column vectors
|
||||
for (i = 0; i < 8; ++i)
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
for (j = 0; j < 8; ++j)
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
tempIn[j] = output[j * 8 + i];
|
||||
tempIn[j] = output[(j * 8) + i];
|
||||
}
|
||||
|
||||
ht.Cols(tempIn, tempOut);
|
||||
for (j = 0; j < 8; ++j)
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 5));
|
||||
dest[(j * stride) + i] =
|
||||
ClipPixelAdd(dest[(j * stride) + i], BitUtils.RoundPowerOfTwo(tempOut[j], 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Transform2D[] _iht16 = {
|
||||
private static readonly Transform2D[] Iht16 =
|
||||
{
|
||||
new(Idct16, Idct16), // DCT_DCT = 0
|
||||
new(Iadst16, Idct16), // ADST_DCT = 1
|
||||
new(Idct16, Iadst16), // DCT_ADST = 2
|
||||
new(Iadst16, Iadst16), // ADST_ADST = 3
|
||||
new(Iadst16, Iadst16) // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void Iht16x16256Add(ReadOnlySpan<int> input, Span<byte> dest, int stride, int txType)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
Transform2D ht = _iht16[txType];
|
||||
Transform2D ht = Iht16[txType];
|
||||
|
||||
// Rows
|
||||
for (i = 0; i < 16; ++i)
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr);
|
||||
input = input[16..];
|
||||
outptr = outptr[16..];
|
||||
input = input.Slice(16);
|
||||
outptr = outptr.Slice(16);
|
||||
}
|
||||
|
||||
// Columns
|
||||
for (i = 0; i < 16; ++i)
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
for (j = 0; j < 16; ++j)
|
||||
for (int j = 0; j < 16; ++j)
|
||||
{
|
||||
tempIn[j] = output[j * 16 + i];
|
||||
tempIn[j] = output[(j * 16) + i];
|
||||
}
|
||||
|
||||
ht.Cols(tempIn, tempOut);
|
||||
for (j = 0; j < 16; ++j)
|
||||
for (int j = 0; j < 16; ++j)
|
||||
{
|
||||
dest[j * stride + i] = ClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 6));
|
||||
dest[(j * stride) + i] =
|
||||
ClipPixelAdd(dest[(j * stride) + i], BitUtils.RoundPowerOfTwo(tempOut[j], 6));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,7 +274,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
public static void Iht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<byte> dest,
|
||||
int stride, int eob)
|
||||
int stride, int eob)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
@@ -280,121 +286,125 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] _highbdIht4 = {
|
||||
private static readonly HighbdTransform2D[] HighbdIht4 =
|
||||
{
|
||||
new(HighbdIdct4, HighbdIdct4), // DCT_DCT = 0
|
||||
new(HighbdIadst4, HighbdIdct4), // ADST_DCT = 1
|
||||
new(HighbdIdct4, HighbdIadst4), // DCT_ADST = 2
|
||||
new(HighbdIadst4, HighbdIadst4), // ADST_ADST = 3
|
||||
new(HighbdIadst4, HighbdIadst4) // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void HighbdIht4x416Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[4 * 4];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[4];
|
||||
Span<int> tempOut = stackalloc int[4];
|
||||
|
||||
// Inverse transform row vectors.
|
||||
for (i = 0; i < 4; ++i)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
_highbdIht4[txType].Rows(input, outptr, bd);
|
||||
input = input[4..];
|
||||
outptr = outptr[4..];
|
||||
HighbdIht4[txType].Rows(input, outptr, bd);
|
||||
input = input.Slice(4);
|
||||
outptr = outptr.Slice(4);
|
||||
}
|
||||
|
||||
// Inverse transform column vectors.
|
||||
for (i = 0; i < 4; ++i)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
for (j = 0; j < 4; ++j)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
tempIn[j] = output[j * 4 + i];
|
||||
tempIn[j] = output[(j * 4) + i];
|
||||
}
|
||||
|
||||
_highbdIht4[txType].Cols(tempIn, tempOut, bd);
|
||||
for (j = 0; j < 4; ++j)
|
||||
HighbdIht4[txType].Cols(tempIn, tempOut, bd);
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 4), bd);
|
||||
dest[(j * stride) + i] = HighbdClipPixelAdd(dest[(j * stride) + i],
|
||||
BitUtils.RoundPowerOfTwo(tempOut[j], 4), bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] _highIht8 = {
|
||||
private static readonly HighbdTransform2D[] HighIht8 =
|
||||
{
|
||||
new(HighbdIdct8, HighbdIdct8), // DCT_DCT = 0
|
||||
new(HighbdIadst8, HighbdIdct8), // ADST_DCT = 1
|
||||
new(HighbdIdct8, HighbdIadst8), // DCT_ADST = 2
|
||||
new(HighbdIadst8, HighbdIadst8), // ADST_ADST = 3
|
||||
new(HighbdIadst8, HighbdIadst8) // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void HighbdIht8x864Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[8 * 8];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[8];
|
||||
Span<int> tempOut = stackalloc int[8];
|
||||
HighbdTransform2D ht = _highIht8[txType];
|
||||
HighbdTransform2D ht = HighIht8[txType];
|
||||
|
||||
// Inverse transform row vectors.
|
||||
for (i = 0; i < 8; ++i)
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr, bd);
|
||||
input = input[8..];
|
||||
outptr = output[8..];
|
||||
input = input.Slice(8);
|
||||
outptr = output.Slice(8);
|
||||
}
|
||||
|
||||
// Inverse transform column vectors.
|
||||
for (i = 0; i < 8; ++i)
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
for (j = 0; j < 8; ++j)
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
tempIn[j] = output[j * 8 + i];
|
||||
tempIn[j] = output[(j * 8) + i];
|
||||
}
|
||||
|
||||
ht.Cols(tempIn, tempOut, bd);
|
||||
for (j = 0; j < 8; ++j)
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 5), bd);
|
||||
dest[(j * stride) + i] = HighbdClipPixelAdd(dest[(j * stride) + i],
|
||||
BitUtils.RoundPowerOfTwo(tempOut[j], 5), bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HighbdTransform2D[] _highIht16 = {
|
||||
private static readonly HighbdTransform2D[] HighIht16 =
|
||||
{
|
||||
new(HighbdIdct16, HighbdIdct16), // DCT_DCT = 0
|
||||
new(HighbdIadst16, HighbdIdct16), // ADST_DCT = 1
|
||||
new(HighbdIdct16, HighbdIadst16), // DCT_ADST = 2
|
||||
new(HighbdIadst16, HighbdIadst16), // ADST_ADST = 3
|
||||
new(HighbdIadst16, HighbdIadst16) // ADST_ADST = 3
|
||||
};
|
||||
|
||||
public static void HighbdIht16x16256Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType, int bd)
|
||||
public static void HighbdIht16x16256Add(ReadOnlySpan<int> input, Span<ushort> dest, int stride, int txType,
|
||||
int bd)
|
||||
{
|
||||
int i, j;
|
||||
Span<int> output = stackalloc int[16 * 16];
|
||||
Span<int> outptr = output;
|
||||
Span<int> tempIn = stackalloc int[16];
|
||||
Span<int> tempOut = stackalloc int[16];
|
||||
HighbdTransform2D ht = _highIht16[txType];
|
||||
HighbdTransform2D ht = HighIht16[txType];
|
||||
|
||||
// Rows
|
||||
for (i = 0; i < 16; ++i)
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
ht.Rows(input, outptr, bd);
|
||||
input = input[16..];
|
||||
outptr = output[16..];
|
||||
input = input.Slice(16);
|
||||
outptr = output.Slice(16);
|
||||
}
|
||||
|
||||
// Columns
|
||||
for (i = 0; i < 16; ++i)
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
for (j = 0; j < 16; ++j)
|
||||
for (int j = 0; j < 16; ++j)
|
||||
{
|
||||
tempIn[j] = output[j * 16 + i];
|
||||
tempIn[j] = output[(j * 16) + i];
|
||||
}
|
||||
|
||||
ht.Cols(tempIn, tempOut, bd);
|
||||
for (j = 0; j < 16; ++j)
|
||||
for (int j = 0; j < 16; ++j)
|
||||
{
|
||||
dest[j * stride + i] = HighbdClipPixelAdd(dest[j * stride + i], BitUtils.RoundPowerOfTwo(tempOut[j], 6), bd);
|
||||
dest[(j * stride) + i] = HighbdClipPixelAdd(dest[(j * stride) + i],
|
||||
BitUtils.RoundPowerOfTwo(tempOut[j], 6), bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -434,7 +444,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// DC only DCT coefficient
|
||||
if (eob == 1)
|
||||
{
|
||||
Vpx_Highbdidct8x8_1_add_c(input, dest, stride, bd);
|
||||
VpxHighbdidct8x81AddC(input, dest, stride, bd);
|
||||
}
|
||||
else if (eob <= 12)
|
||||
{
|
||||
@@ -491,7 +501,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
|
||||
// Iht
|
||||
public static void HighbdIht4x4Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
public static void HighbdIht4x4Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
int eob, int bd)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
@@ -503,7 +514,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIht8x8Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
public static void HighbdIht8x8Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
int eob, int bd)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
@@ -515,7 +527,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
|
||||
public static void HighbdIht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride, int eob, int bd)
|
||||
public static void HighbdIht16x16Add(TxType txType, ReadOnlySpan<int> input, Span<ushort> dest, int stride,
|
||||
int eob, int bd)
|
||||
{
|
||||
if (txType == TxType.DctDct)
|
||||
{
|
||||
@@ -527,4 +540,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
class InternalErrorException : Exception
|
||||
internal class InternalErrorException : Exception
|
||||
{
|
||||
public InternalErrorException(string message) : base(message)
|
||||
{
|
||||
@@ -12,4 +12,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,4 +11,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
throw new InternalErrorException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
@@ -13,7 +13,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// left of the entries corresponding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialized to 0.
|
||||
if (!xd.AboveMi.IsNull && !xd.LeftMi.IsNull)
|
||||
{ // both edges available
|
||||
{
|
||||
// both edges available
|
||||
if (!xd.AboveMi.Value.HasSecondRef() && !xd.LeftMi.Value.HasSecondRef())
|
||||
{
|
||||
// Neither edge uses comp pred (0/1)
|
||||
@@ -23,12 +24,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
else if (!xd.AboveMi.Value.HasSecondRef())
|
||||
{
|
||||
// One of two edges uses comp pred (2/3)
|
||||
ctx = 2 + (xd.AboveMi.Value.RefFrame[0] == cm.CompFixedRef || !xd.AboveMi.Value.IsInterBlock() ? 1 : 0);
|
||||
ctx = 2 + (xd.AboveMi.Value.RefFrame[0] == cm.CompFixedRef || !xd.AboveMi.Value.IsInterBlock()
|
||||
? 1
|
||||
: 0);
|
||||
}
|
||||
else if (!xd.LeftMi.Value.HasSecondRef())
|
||||
{
|
||||
// One of two edges uses comp pred (2/3)
|
||||
ctx = 2 + (xd.LeftMi.Value.RefFrame[0] == cm.CompFixedRef || !xd.LeftMi.Value.IsInterBlock() ? 1 : 0);
|
||||
ctx = 2 +
|
||||
(xd.LeftMi.Value.RefFrame[0] == cm.CompFixedRef || !xd.LeftMi.Value.IsInterBlock() ? 1 : 0);
|
||||
}
|
||||
else // Both edges use comp pred (4)
|
||||
{
|
||||
@@ -36,7 +40,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
else if (!xd.AboveMi.IsNull || !xd.LeftMi.IsNull)
|
||||
{ // One edge available
|
||||
{
|
||||
// One edge available
|
||||
ref ModeInfo edgeMi = ref !xd.AboveMi.IsNull ? ref xd.AboveMi.Value : ref xd.LeftMi.Value;
|
||||
|
||||
if (!edgeMi.HasSecondRef())
|
||||
@@ -51,11 +56,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // No edges available (1)
|
||||
{
|
||||
// No edges available (1)
|
||||
ctx = 1;
|
||||
}
|
||||
Debug.Assert(ctx >= 0 && ctx < Constants.CompInterContexts);
|
||||
|
||||
Debug.Assert(ctx >= 0 && ctx < Constants.CompInterContexts);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -71,29 +77,33 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int varRefIdx = fixRefIdx == 0 ? 1 : 0;
|
||||
|
||||
if (!xd.AboveMi.IsNull && !xd.LeftMi.IsNull)
|
||||
{ // Both edges available
|
||||
{
|
||||
// Both edges available
|
||||
bool aboveIntra = !xd.AboveMi.Value.IsInterBlock();
|
||||
bool leftIntra = !xd.LeftMi.Value.IsInterBlock();
|
||||
|
||||
if (aboveIntra && leftIntra)
|
||||
{ // Intra/Intra (2)
|
||||
{
|
||||
// Intra/Intra (2)
|
||||
predContext = 2;
|
||||
}
|
||||
else if (aboveIntra || leftIntra)
|
||||
{ // Intra/Inter
|
||||
{
|
||||
// Intra/Inter
|
||||
ref ModeInfo edgeMi = ref aboveIntra ? ref xd.LeftMi.Value : ref xd.AboveMi.Value;
|
||||
|
||||
if (!edgeMi.HasSecondRef()) // single pred (1/3)
|
||||
{
|
||||
predContext = 1 + 2 * (edgeMi.RefFrame[0] != cm.CompVarRef[1] ? 1 : 0);
|
||||
predContext = 1 + (2 * (edgeMi.RefFrame[0] != cm.CompVarRef[1] ? 1 : 0));
|
||||
}
|
||||
else // Comp pred (1/3)
|
||||
{
|
||||
predContext = 1 + 2 * (edgeMi.RefFrame[varRefIdx] != cm.CompVarRef[1] ? 1 : 0);
|
||||
predContext = 1 + (2 * (edgeMi.RefFrame[varRefIdx] != cm.CompVarRef[1] ? 1 : 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Inter/Inter
|
||||
{
|
||||
// Inter/Inter
|
||||
bool lSg = !xd.LeftMi.Value.HasSecondRef();
|
||||
bool aSg = !xd.AboveMi.Value.HasSecondRef();
|
||||
sbyte vrfa = aSg ? xd.AboveMi.Value.RefFrame[0] : xd.AboveMi.Value.RefFrame[varRefIdx];
|
||||
@@ -104,7 +114,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
predContext = 0;
|
||||
}
|
||||
else if (lSg && aSg)
|
||||
{ // Single/Single
|
||||
{
|
||||
// Single/Single
|
||||
if ((vrfa == cm.CompFixedRef && vrfl == cm.CompVarRef[0]) ||
|
||||
(vrfl == cm.CompFixedRef && vrfa == cm.CompVarRef[0]))
|
||||
{
|
||||
@@ -120,7 +131,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
else if (lSg || aSg)
|
||||
{ // Single/Comp
|
||||
{
|
||||
// Single/Comp
|
||||
sbyte vrfc = lSg ? vrfa : vrfl;
|
||||
sbyte rfs = aSg ? vrfa : vrfl;
|
||||
if (vrfc == cm.CompVarRef[1] && rfs != cm.CompVarRef[1])
|
||||
@@ -137,7 +149,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
else if (vrfa == vrfl)
|
||||
{ // Comp/Comp
|
||||
{
|
||||
// Comp/Comp
|
||||
predContext = 4;
|
||||
}
|
||||
else
|
||||
@@ -147,7 +160,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
else if (!xd.AboveMi.IsNull || !xd.LeftMi.IsNull)
|
||||
{ // One edge available
|
||||
{
|
||||
// One edge available
|
||||
ref ModeInfo edgeMi = ref !xd.AboveMi.IsNull ? ref xd.AboveMi.Value : ref xd.LeftMi.Value;
|
||||
|
||||
if (!edgeMi.IsInterBlock())
|
||||
@@ -167,11 +181,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // No edges available (2)
|
||||
{
|
||||
// No edges available (2)
|
||||
predContext = 2;
|
||||
}
|
||||
Debug.Assert(predContext >= 0 && predContext < Constants.RefContexts);
|
||||
|
||||
Debug.Assert(predContext >= 0 && predContext < Constants.RefContexts);
|
||||
return predContext;
|
||||
}
|
||||
|
||||
@@ -183,16 +198,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// left of the entries corresponding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialized to 0.
|
||||
if (!xd.AboveMi.IsNull && !xd.LeftMi.IsNull)
|
||||
{ // Both edges available
|
||||
{
|
||||
// Both edges available
|
||||
bool aboveIntra = !xd.AboveMi.Value.IsInterBlock();
|
||||
bool leftIntra = !xd.LeftMi.Value.IsInterBlock();
|
||||
|
||||
if (aboveIntra && leftIntra)
|
||||
{ // Intra/Intra
|
||||
{
|
||||
// Intra/Intra
|
||||
predContext = 2;
|
||||
}
|
||||
else if (aboveIntra || leftIntra)
|
||||
{ // Intra/Inter or Inter/Intra
|
||||
{
|
||||
// Intra/Inter or Inter/Intra
|
||||
ref ModeInfo edgeMi = ref aboveIntra ? ref xd.LeftMi.Value : ref xd.AboveMi.Value;
|
||||
if (!edgeMi.HasSecondRef())
|
||||
{
|
||||
@@ -201,11 +219,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
else
|
||||
{
|
||||
predContext = 1 + (edgeMi.RefFrame[0] == Constants.LastFrame ||
|
||||
edgeMi.RefFrame[1] == Constants.LastFrame ? 1 : 0);
|
||||
edgeMi.RefFrame[1] == Constants.LastFrame
|
||||
? 1
|
||||
: 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Inter/Inter
|
||||
{
|
||||
// Inter/Inter
|
||||
bool aboveHasSecond = xd.AboveMi.Value.HasSecondRef();
|
||||
bool leftHasSecond = xd.LeftMi.Value.HasSecondRef();
|
||||
sbyte above0 = xd.AboveMi.Value.RefFrame[0];
|
||||
@@ -216,7 +237,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (aboveHasSecond && leftHasSecond)
|
||||
{
|
||||
predContext = 1 + (above0 == Constants.LastFrame || above1 == Constants.LastFrame ||
|
||||
left0 == Constants.LastFrame || left1 == Constants.LastFrame ? 1 : 0);
|
||||
left0 == Constants.LastFrame || left1 == Constants.LastFrame
|
||||
? 1
|
||||
: 0);
|
||||
}
|
||||
else if (aboveHasSecond || leftHasSecond)
|
||||
{
|
||||
@@ -230,24 +253,28 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
else
|
||||
{
|
||||
predContext = (crf1 == Constants.LastFrame || crf2 == Constants.LastFrame ? 1 : 0);
|
||||
predContext = crf1 == Constants.LastFrame || crf2 == Constants.LastFrame ? 1 : 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
predContext = 2 * (above0 == Constants.LastFrame ? 1 : 0) + 2 * (left0 == Constants.LastFrame ? 1 : 0);
|
||||
predContext = (2 * (above0 == Constants.LastFrame ? 1 : 0)) +
|
||||
(2 * (left0 == Constants.LastFrame ? 1 : 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!xd.AboveMi.IsNull || !xd.LeftMi.IsNull)
|
||||
{ // One edge available
|
||||
{
|
||||
// One edge available
|
||||
ref ModeInfo edgeMi = ref !xd.AboveMi.IsNull ? ref xd.AboveMi.Value : ref xd.LeftMi.Value;
|
||||
if (!edgeMi.IsInterBlock())
|
||||
{ // Intra
|
||||
{
|
||||
// Intra
|
||||
predContext = 2;
|
||||
}
|
||||
else
|
||||
{ // Inter
|
||||
{
|
||||
// Inter
|
||||
if (!edgeMi.HasSecondRef())
|
||||
{
|
||||
predContext = 4 * (edgeMi.RefFrame[0] == Constants.LastFrame ? 1 : 0);
|
||||
@@ -255,16 +282,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
else
|
||||
{
|
||||
predContext = 1 + (edgeMi.RefFrame[0] == Constants.LastFrame ||
|
||||
edgeMi.RefFrame[1] == Constants.LastFrame ? 1 : 0);
|
||||
edgeMi.RefFrame[1] == Constants.LastFrame
|
||||
? 1
|
||||
: 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // No edges available
|
||||
{
|
||||
// No edges available
|
||||
predContext = 2;
|
||||
}
|
||||
Debug.Assert(predContext >= 0 && predContext < Constants.RefContexts);
|
||||
|
||||
Debug.Assert(predContext >= 0 && predContext < Constants.RefContexts);
|
||||
return predContext;
|
||||
}
|
||||
|
||||
@@ -277,16 +307,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// left of the entries corresponding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialized to 0.
|
||||
if (!xd.AboveMi.IsNull && !xd.LeftMi.IsNull)
|
||||
{ // Both edges available
|
||||
{
|
||||
// Both edges available
|
||||
bool aboveIntra = !xd.AboveMi.Value.IsInterBlock();
|
||||
bool leftIntra = !xd.LeftMi.Value.IsInterBlock();
|
||||
|
||||
if (aboveIntra && leftIntra)
|
||||
{ // Intra/Intra
|
||||
{
|
||||
// Intra/Intra
|
||||
predContext = 2;
|
||||
}
|
||||
else if (aboveIntra || leftIntra)
|
||||
{ // Intra/Inter or Inter/Intra
|
||||
{
|
||||
// Intra/Inter or Inter/Intra
|
||||
ref ModeInfo edgeMi = ref aboveIntra ? ref xd.LeftMi.Value : ref xd.AboveMi.Value;
|
||||
if (!edgeMi.HasSecondRef())
|
||||
{
|
||||
@@ -301,12 +334,15 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
else
|
||||
{
|
||||
predContext = 1 + 2 * (edgeMi.RefFrame[0] == Constants.GoldenFrame ||
|
||||
edgeMi.RefFrame[1] == Constants.GoldenFrame ? 1 : 0);
|
||||
predContext = 1 + (2 * (edgeMi.RefFrame[0] == Constants.GoldenFrame ||
|
||||
edgeMi.RefFrame[1] == Constants.GoldenFrame
|
||||
? 1
|
||||
: 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Inter/Inter
|
||||
{
|
||||
// Inter/Inter
|
||||
bool aboveHasSecond = xd.AboveMi.Value.HasSecondRef();
|
||||
bool leftHasSecond = xd.LeftMi.Value.HasSecondRef();
|
||||
sbyte above0 = xd.AboveMi.Value.RefFrame[0];
|
||||
@@ -319,7 +355,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (above0 == left0 && above1 == left1)
|
||||
{
|
||||
predContext = 3 * (above0 == Constants.GoldenFrame || above1 == Constants.GoldenFrame ||
|
||||
left0 == Constants.GoldenFrame || left1 == Constants.GoldenFrame ? 1 : 0);
|
||||
left0 == Constants.GoldenFrame || left1 == Constants.GoldenFrame
|
||||
? 1
|
||||
: 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -342,7 +380,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
else
|
||||
{
|
||||
predContext = 1 + 2 * (crf1 == Constants.GoldenFrame || crf2 == Constants.GoldenFrame ? 1 : 0);
|
||||
predContext =
|
||||
1 + (2 * (crf1 == Constants.GoldenFrame || crf2 == Constants.GoldenFrame ? 1 : 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -353,18 +392,20 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
else if (above0 == Constants.LastFrame || left0 == Constants.LastFrame)
|
||||
{
|
||||
sbyte edge0 = (above0 == Constants.LastFrame) ? left0 : above0;
|
||||
sbyte edge0 = above0 == Constants.LastFrame ? left0 : above0;
|
||||
predContext = 4 * (edge0 == Constants.GoldenFrame ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
predContext = 2 * (above0 == Constants.GoldenFrame ? 1 : 0) + 2 * (left0 == Constants.GoldenFrame ? 1 : 0);
|
||||
predContext = (2 * (above0 == Constants.GoldenFrame ? 1 : 0)) +
|
||||
(2 * (left0 == Constants.GoldenFrame ? 1 : 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!xd.AboveMi.IsNull || !xd.LeftMi.IsNull)
|
||||
{ // One edge available
|
||||
{
|
||||
// One edge available
|
||||
ref ModeInfo edgeMi = ref !xd.AboveMi.IsNull ? ref xd.AboveMi.Value : ref xd.LeftMi.Value;
|
||||
|
||||
if (!edgeMi.IsInterBlock() || (edgeMi.RefFrame[0] == Constants.LastFrame && !edgeMi.HasSecondRef()))
|
||||
@@ -378,16 +419,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
else
|
||||
{
|
||||
predContext = 3 * (edgeMi.RefFrame[0] == Constants.GoldenFrame ||
|
||||
edgeMi.RefFrame[1] == Constants.GoldenFrame ? 1 : 0);
|
||||
edgeMi.RefFrame[1] == Constants.GoldenFrame
|
||||
? 1
|
||||
: 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // No edges available (2)
|
||||
{
|
||||
// No edges available (2)
|
||||
predContext = 2;
|
||||
}
|
||||
Debug.Assert(predContext >= 0 && predContext < Constants.RefContexts);
|
||||
|
||||
Debug.Assert(predContext >= 0 && predContext < Constants.RefContexts);
|
||||
return predContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
94
src/Ryujinx.Graphics.Nvdec.Vp9/Prob.cs
Normal file
94
src/Ryujinx.Graphics.Nvdec.Vp9/Prob.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
public static class Prob
|
||||
{
|
||||
public const int MaxProb = 255;
|
||||
|
||||
private static byte GetProb(uint num, uint den)
|
||||
{
|
||||
Debug.Assert(den != 0);
|
||||
{
|
||||
int p = (int)((((ulong)num * 256) + (den >> 1)) / den);
|
||||
// (p > 255) ? 255 : (p < 1) ? 1 : p;
|
||||
int clippedProb = p | ((255 - p) >> 23) | (p == 0 ? 1 : 0);
|
||||
return (byte)clippedProb;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte GetBinaryProb(uint n0, uint n1)
|
||||
{
|
||||
uint den = n0 + n1;
|
||||
if (den == 0)
|
||||
{
|
||||
return 128;
|
||||
}
|
||||
|
||||
return GetProb(n0, den);
|
||||
}
|
||||
|
||||
/* This function assumes prob1 and prob2 are already within [1,255] range. */
|
||||
public static byte WeightedProb(int prob1, int prob2, int factor)
|
||||
{
|
||||
return (byte)BitUtils.RoundPowerOfTwo((prob1 * (256 - factor)) + (prob2 * factor), 8);
|
||||
}
|
||||
|
||||
public static byte MergeProbs(byte preProb, ref Array2<uint> ct, uint countSat, uint maxUpdateFactor)
|
||||
{
|
||||
byte prob = GetBinaryProb(ct[0], ct[1]);
|
||||
uint count = Math.Min(ct[0] + ct[1], countSat);
|
||||
uint factor = maxUpdateFactor * count / countSat;
|
||||
return WeightedProb(preProb, prob, (int)factor);
|
||||
}
|
||||
|
||||
// MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT;
|
||||
private static readonly uint[] CountToUpdateFactor =
|
||||
{
|
||||
0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64, 70, 76, 83, 89, 96, 102, 108, 115, 121, 128
|
||||
};
|
||||
|
||||
private const int ModeMvCountSat = 20;
|
||||
|
||||
public static byte ModeMvMergeProbs(byte preProb, ref Array2<uint> ct)
|
||||
{
|
||||
uint den = ct[0] + ct[1];
|
||||
if (den == 0)
|
||||
{
|
||||
return preProb;
|
||||
}
|
||||
|
||||
uint count = Math.Min(den, ModeMvCountSat);
|
||||
uint factor = CountToUpdateFactor[(int)count];
|
||||
byte prob = GetProb(ct[0], den);
|
||||
return WeightedProb(preProb, prob, (int)factor);
|
||||
}
|
||||
|
||||
private static uint TreeMergeProbsImpl(
|
||||
uint i,
|
||||
sbyte[] tree,
|
||||
ReadOnlySpan<byte> preProbs,
|
||||
ReadOnlySpan<uint> counts,
|
||||
Span<byte> probs)
|
||||
{
|
||||
int l = tree[i];
|
||||
uint leftCount = l <= 0 ? counts[-l] : TreeMergeProbsImpl((uint)l, tree, preProbs, counts, probs);
|
||||
int r = tree[i + 1];
|
||||
uint rightCount = r <= 0 ? counts[-r] : TreeMergeProbsImpl((uint)r, tree, preProbs, counts, probs);
|
||||
Array2<uint> ct = new();
|
||||
ct[0] = leftCount;
|
||||
ct[1] = rightCount;
|
||||
probs[(int)(i >> 1)] = ModeMvMergeProbs(preProbs[(int)(i >> 1)], ref ct);
|
||||
return leftCount + rightCount;
|
||||
}
|
||||
|
||||
public static void VpxTreeMergeProbs(sbyte[] tree, ReadOnlySpan<byte> preProbs, ReadOnlySpan<uint> counts,
|
||||
Span<byte> probs)
|
||||
{
|
||||
TreeMergeProbsImpl(0, tree, preProbs, counts, probs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,172 +1,127 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class QuantCommon
|
||||
{
|
||||
public const int MinQ = 0;
|
||||
public const int MaxQ = 255;
|
||||
public const int QindexBits = 8;
|
||||
|
||||
private static readonly short[] _dcQlookup = {
|
||||
4, 8, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 29, 30,
|
||||
31, 32, 32, 33, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42,
|
||||
43, 43, 44, 45, 46, 47, 48, 48, 49, 50, 51, 52, 53, 53,
|
||||
54, 55, 56, 57, 57, 58, 59, 60, 61, 62, 62, 63, 64, 65,
|
||||
66, 66, 67, 68, 69, 70, 70, 71, 72, 73, 74, 74, 75, 76,
|
||||
77, 78, 78, 79, 80, 81, 81, 82, 83, 84, 85, 85, 87, 88,
|
||||
90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 108, 110,
|
||||
111, 113, 114, 116, 117, 118, 120, 121, 123, 125, 127, 129, 131, 134,
|
||||
136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 161, 164,
|
||||
166, 169, 172, 174, 177, 180, 182, 185, 187, 190, 192, 195, 199, 202,
|
||||
205, 208, 211, 214, 217, 220, 223, 226, 230, 233, 237, 240, 243, 247,
|
||||
250, 253, 257, 261, 265, 269, 272, 276, 280, 284, 288, 292, 296, 300,
|
||||
304, 309, 313, 317, 322, 326, 330, 335, 340, 344, 349, 354, 359, 364,
|
||||
369, 374, 379, 384, 389, 395, 400, 406, 411, 417, 423, 429, 435, 441,
|
||||
447, 454, 461, 467, 475, 482, 489, 497, 505, 513, 522, 530, 539, 549,
|
||||
559, 569, 579, 590, 602, 614, 626, 640, 654, 668, 684, 700, 717, 736,
|
||||
755, 775, 796, 819, 843, 869, 896, 925, 955, 988, 1022, 1058, 1098, 1139,
|
||||
1184, 1232, 1282, 1336,
|
||||
private static readonly short[] DcQlookup =
|
||||
{
|
||||
4, 8, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 29,
|
||||
30, 31, 32, 32, 33, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48, 48, 49, 50, 51,
|
||||
52, 53, 53, 54, 55, 56, 57, 57, 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 70, 71, 72,
|
||||
73, 74, 74, 75, 76, 77, 78, 78, 79, 80, 81, 81, 82, 83, 84, 85, 85, 87, 88, 90, 92, 93, 95, 96, 98, 99,
|
||||
101, 102, 104, 105, 107, 108, 110, 111, 113, 114, 116, 117, 118, 120, 121, 123, 125, 127, 129, 131, 134,
|
||||
136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 161, 164, 166, 169, 172, 174, 177, 180, 182,
|
||||
185, 187, 190, 192, 195, 199, 202, 205, 208, 211, 214, 217, 220, 223, 226, 230, 233, 237, 240, 243, 247,
|
||||
250, 253, 257, 261, 265, 269, 272, 276, 280, 284, 288, 292, 296, 300, 304, 309, 313, 317, 322, 326, 330,
|
||||
335, 340, 344, 349, 354, 359, 364, 369, 374, 379, 384, 389, 395, 400, 406, 411, 417, 423, 429, 435, 441,
|
||||
447, 454, 461, 467, 475, 482, 489, 497, 505, 513, 522, 530, 539, 549, 559, 569, 579, 590, 602, 614, 626,
|
||||
640, 654, 668, 684, 700, 717, 736, 755, 775, 796, 819, 843, 869, 896, 925, 955, 988, 1022, 1058, 1098,
|
||||
1139, 1184, 1232, 1282, 1336
|
||||
};
|
||||
|
||||
private static readonly short[] _dcQlookup10 = {
|
||||
4, 9, 10, 13, 15, 17, 20, 22, 25, 28, 31, 34, 37,
|
||||
40, 43, 47, 50, 53, 57, 60, 64, 68, 71, 75, 78, 82,
|
||||
86, 90, 93, 97, 101, 105, 109, 113, 116, 120, 124, 128, 132,
|
||||
136, 140, 143, 147, 151, 155, 159, 163, 166, 170, 174, 178, 182,
|
||||
185, 189, 193, 197, 200, 204, 208, 212, 215, 219, 223, 226, 230,
|
||||
233, 237, 241, 244, 248, 251, 255, 259, 262, 266, 269, 273, 276,
|
||||
280, 283, 287, 290, 293, 297, 300, 304, 307, 310, 314, 317, 321,
|
||||
324, 327, 331, 334, 337, 343, 350, 356, 362, 369, 375, 381, 387,
|
||||
394, 400, 406, 412, 418, 424, 430, 436, 442, 448, 454, 460, 466,
|
||||
472, 478, 484, 490, 499, 507, 516, 525, 533, 542, 550, 559, 567,
|
||||
576, 584, 592, 601, 609, 617, 625, 634, 644, 655, 666, 676, 687,
|
||||
698, 708, 718, 729, 739, 749, 759, 770, 782, 795, 807, 819, 831,
|
||||
844, 856, 868, 880, 891, 906, 920, 933, 947, 961, 975, 988, 1001,
|
||||
1015, 1030, 1045, 1061, 1076, 1090, 1105, 1120, 1137, 1153, 1170, 1186, 1202,
|
||||
1218, 1236, 1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379, 1398, 1416, 1436,
|
||||
1456, 1476, 1496, 1516, 1537, 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717,
|
||||
1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, 1958, 1990, 2021, 2054, 2088,
|
||||
2123, 2159, 2197, 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, 2616, 2675,
|
||||
2737, 2802, 2871, 2944, 3020, 3102, 3188, 3280, 3375, 3478, 3586, 3702, 3823,
|
||||
3953, 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347,
|
||||
private static readonly short[] DcQlookup10 =
|
||||
{
|
||||
4, 9, 10, 13, 15, 17, 20, 22, 25, 28, 31, 34, 37, 40, 43, 47, 50, 53, 57, 60, 64, 68, 71, 75, 78, 82,
|
||||
86, 90, 93, 97, 101, 105, 109, 113, 116, 120, 124, 128, 132, 136, 140, 143, 147, 151, 155, 159, 163,
|
||||
166, 170, 174, 178, 182, 185, 189, 193, 197, 200, 204, 208, 212, 215, 219, 223, 226, 230, 233, 237, 241,
|
||||
244, 248, 251, 255, 259, 262, 266, 269, 273, 276, 280, 283, 287, 290, 293, 297, 300, 304, 307, 310, 314,
|
||||
317, 321, 324, 327, 331, 334, 337, 343, 350, 356, 362, 369, 375, 381, 387, 394, 400, 406, 412, 418, 424,
|
||||
430, 436, 442, 448, 454, 460, 466, 472, 478, 484, 490, 499, 507, 516, 525, 533, 542, 550, 559, 567, 576,
|
||||
584, 592, 601, 609, 617, 625, 634, 644, 655, 666, 676, 687, 698, 708, 718, 729, 739, 749, 759, 770, 782,
|
||||
795, 807, 819, 831, 844, 856, 868, 880, 891, 906, 920, 933, 947, 961, 975, 988, 1001, 1015, 1030, 1045,
|
||||
1061, 1076, 1090, 1105, 1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236, 1253, 1271, 1288, 1306, 1323,
|
||||
1342, 1361, 1379, 1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537, 1559, 1580, 1601, 1624, 1647, 1670,
|
||||
1692, 1717, 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, 1958, 1990, 2021, 2054, 2088, 2123, 2159,
|
||||
2197, 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, 2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102,
|
||||
3188, 3280, 3375, 3478, 3586, 3702, 3823, 3953, 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347
|
||||
};
|
||||
|
||||
private static readonly short[] _dcQlookup12 = {
|
||||
4, 12, 18, 25, 33, 41, 50, 60, 70, 80, 91,
|
||||
103, 115, 127, 140, 153, 166, 180, 194, 208, 222, 237,
|
||||
251, 266, 281, 296, 312, 327, 343, 358, 374, 390, 405,
|
||||
421, 437, 453, 469, 484, 500, 516, 532, 548, 564, 580,
|
||||
596, 611, 627, 643, 659, 674, 690, 706, 721, 737, 752,
|
||||
768, 783, 798, 814, 829, 844, 859, 874, 889, 904, 919,
|
||||
934, 949, 964, 978, 993, 1008, 1022, 1037, 1051, 1065, 1080,
|
||||
1094, 1108, 1122, 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234,
|
||||
1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, 1368, 1393, 1419,
|
||||
1444, 1469, 1494, 1519, 1544, 1569, 1594, 1618, 1643, 1668, 1692,
|
||||
1717, 1741, 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, 1957,
|
||||
1992, 2027, 2061, 2096, 2130, 2165, 2199, 2233, 2267, 2300, 2334,
|
||||
2367, 2400, 2434, 2467, 2499, 2532, 2575, 2618, 2661, 2704, 2746,
|
||||
2788, 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, 3177, 3226,
|
||||
3275, 3324, 3373, 3421, 3469, 3517, 3565, 3621, 3677, 3733, 3788,
|
||||
3843, 3897, 3951, 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420,
|
||||
4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, 5013, 5083, 5153,
|
||||
5222, 5291, 5367, 5442, 5517, 5591, 5665, 5745, 5825, 5905, 5984,
|
||||
6063, 6149, 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867, 6966,
|
||||
7064, 7163, 7269, 7376, 7483, 7599, 7715, 7832, 7958, 8085, 8214,
|
||||
8352, 8492, 8635, 8788, 8945, 9104, 9275, 9450, 9639, 9832, 10031,
|
||||
10245, 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409, 12750, 13118,
|
||||
13501, 13913, 14343, 14807, 15290, 15812, 16356, 16943, 17575, 18237, 18949,
|
||||
19718, 20521, 21387,
|
||||
private static readonly short[] DcQlookup12 =
|
||||
{
|
||||
4, 12, 18, 25, 33, 41, 50, 60, 70, 80, 91, 103, 115, 127, 140, 153, 166, 180, 194, 208, 222, 237, 251,
|
||||
266, 281, 296, 312, 327, 343, 358, 374, 390, 405, 421, 437, 453, 469, 484, 500, 516, 532, 548, 564, 580,
|
||||
596, 611, 627, 643, 659, 674, 690, 706, 721, 737, 752, 768, 783, 798, 814, 829, 844, 859, 874, 889, 904,
|
||||
919, 934, 949, 964, 978, 993, 1008, 1022, 1037, 1051, 1065, 1080, 1094, 1108, 1122, 1136, 1151, 1165,
|
||||
1179, 1192, 1206, 1220, 1234, 1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, 1368, 1393, 1419, 1444,
|
||||
1469, 1494, 1519, 1544, 1569, 1594, 1618, 1643, 1668, 1692, 1717, 1741, 1765, 1789, 1814, 1838, 1862,
|
||||
1885, 1909, 1933, 1957, 1992, 2027, 2061, 2096, 2130, 2165, 2199, 2233, 2267, 2300, 2334, 2367, 2400,
|
||||
2434, 2467, 2499, 2532, 2575, 2618, 2661, 2704, 2746, 2788, 2830, 2872, 2913, 2954, 2995, 3036, 3076,
|
||||
3127, 3177, 3226, 3275, 3324, 3373, 3421, 3469, 3517, 3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951,
|
||||
4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420, 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, 5013,
|
||||
5083, 5153, 5222, 5291, 5367, 5442, 5517, 5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149, 6234, 6319,
|
||||
6404, 6495, 6587, 6678, 6769, 6867, 6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715, 7832, 7958, 8085,
|
||||
8214, 8352, 8492, 8635, 8788, 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, 10465, 10702, 10946,
|
||||
11210, 11482, 11776, 12081, 12409, 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, 16356, 16943,
|
||||
17575, 18237, 18949, 19718, 20521, 21387
|
||||
};
|
||||
|
||||
private static readonly short[] _acQlookup = {
|
||||
4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
|
||||
46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
|
||||
59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
|
||||
85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
|
||||
98, 99, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118,
|
||||
120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144,
|
||||
146, 148, 150, 152, 155, 158, 161, 164, 167, 170, 173, 176, 179,
|
||||
182, 185, 188, 191, 194, 197, 200, 203, 207, 211, 215, 219, 223,
|
||||
227, 231, 235, 239, 243, 247, 251, 255, 260, 265, 270, 275, 280,
|
||||
285, 290, 295, 300, 305, 311, 317, 323, 329, 335, 341, 347, 353,
|
||||
359, 366, 373, 380, 387, 394, 401, 408, 416, 424, 432, 440, 448,
|
||||
456, 465, 474, 483, 492, 501, 510, 520, 530, 540, 550, 560, 571,
|
||||
582, 593, 604, 615, 627, 639, 651, 663, 676, 689, 702, 715, 729,
|
||||
743, 757, 771, 786, 801, 816, 832, 848, 864, 881, 898, 915, 933,
|
||||
951, 969, 988, 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, 1173, 1196,
|
||||
1219, 1243, 1267, 1292, 1317, 1343, 1369, 1396, 1423, 1451, 1479, 1508, 1537,
|
||||
1567, 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
|
||||
private static readonly short[] AcQlookup =
|
||||
{
|
||||
4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
|
||||
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
|
||||
86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 104, 106, 108, 110, 112, 114,
|
||||
116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 155, 158,
|
||||
161, 164, 167, 170, 173, 176, 179, 182, 185, 188, 191, 194, 197, 200, 203, 207, 211, 215, 219, 223, 227,
|
||||
231, 235, 239, 243, 247, 251, 255, 260, 265, 270, 275, 280, 285, 290, 295, 300, 305, 311, 317, 323, 329,
|
||||
335, 341, 347, 353, 359, 366, 373, 380, 387, 394, 401, 408, 416, 424, 432, 440, 448, 456, 465, 474, 483,
|
||||
492, 501, 510, 520, 530, 540, 550, 560, 571, 582, 593, 604, 615, 627, 639, 651, 663, 676, 689, 702, 715,
|
||||
729, 743, 757, 771, 786, 801, 816, 832, 848, 864, 881, 898, 915, 933, 951, 969, 988, 1007, 1026, 1046,
|
||||
1066, 1087, 1108, 1129, 1151, 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, 1369, 1396, 1423, 1451,
|
||||
1479, 1508, 1537, 1567, 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828
|
||||
};
|
||||
|
||||
private static readonly short[] _acQlookup10 = {
|
||||
4, 9, 11, 13, 16, 18, 21, 24, 27, 30, 33, 37, 40,
|
||||
44, 48, 51, 55, 59, 63, 67, 71, 75, 79, 83, 88, 92,
|
||||
96, 100, 105, 109, 114, 118, 122, 127, 131, 136, 140, 145, 149,
|
||||
154, 158, 163, 168, 172, 177, 181, 186, 190, 195, 199, 204, 208,
|
||||
213, 217, 222, 226, 231, 235, 240, 244, 249, 253, 258, 262, 267,
|
||||
271, 275, 280, 284, 289, 293, 297, 302, 306, 311, 315, 319, 324,
|
||||
328, 332, 337, 341, 345, 349, 354, 358, 362, 367, 371, 375, 379,
|
||||
384, 388, 392, 396, 401, 409, 417, 425, 433, 441, 449, 458, 466,
|
||||
474, 482, 490, 498, 506, 514, 523, 531, 539, 547, 555, 563, 571,
|
||||
579, 588, 596, 604, 616, 628, 640, 652, 664, 676, 688, 700, 713,
|
||||
725, 737, 749, 761, 773, 785, 797, 809, 825, 841, 857, 873, 889,
|
||||
905, 922, 938, 954, 970, 986, 1002, 1018, 1038, 1058, 1078, 1098, 1118,
|
||||
1138, 1158, 1178, 1198, 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, 1411,
|
||||
1435, 1463, 1491, 1519, 1547, 1575, 1603, 1631, 1663, 1695, 1727, 1759, 1791,
|
||||
1823, 1859, 1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159, 2199, 2239, 2283,
|
||||
2327, 2371, 2415, 2459, 2507, 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915,
|
||||
2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, 3455, 3523, 3591, 3659, 3731,
|
||||
3803, 3876, 3952, 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, 4692, 4784,
|
||||
4876, 4972, 5068, 5168, 5268, 5372, 5476, 5584, 5692, 5804, 5916, 6032, 6148,
|
||||
6268, 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312,
|
||||
private static readonly short[] AcQlookup10 =
|
||||
{
|
||||
4, 9, 11, 13, 16, 18, 21, 24, 27, 30, 33, 37, 40, 44, 48, 51, 55, 59, 63, 67, 71, 75, 79, 83, 88, 92,
|
||||
96, 100, 105, 109, 114, 118, 122, 127, 131, 136, 140, 145, 149, 154, 158, 163, 168, 172, 177, 181, 186,
|
||||
190, 195, 199, 204, 208, 213, 217, 222, 226, 231, 235, 240, 244, 249, 253, 258, 262, 267, 271, 275, 280,
|
||||
284, 289, 293, 297, 302, 306, 311, 315, 319, 324, 328, 332, 337, 341, 345, 349, 354, 358, 362, 367, 371,
|
||||
375, 379, 384, 388, 392, 396, 401, 409, 417, 425, 433, 441, 449, 458, 466, 474, 482, 490, 498, 506, 514,
|
||||
523, 531, 539, 547, 555, 563, 571, 579, 588, 596, 604, 616, 628, 640, 652, 664, 676, 688, 700, 713, 725,
|
||||
737, 749, 761, 773, 785, 797, 809, 825, 841, 857, 873, 889, 905, 922, 938, 954, 970, 986, 1002, 1018,
|
||||
1038, 1058, 1078, 1098, 1118, 1138, 1158, 1178, 1198, 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386,
|
||||
1411, 1435, 1463, 1491, 1519, 1547, 1575, 1603, 1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859, 1895,
|
||||
1931, 1967, 2003, 2039, 2079, 2119, 2159, 2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507, 2555, 2603,
|
||||
2651, 2703, 2755, 2807, 2859, 2915, 2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, 3455, 3523, 3591,
|
||||
3659, 3731, 3803, 3876, 3952, 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, 4692, 4784, 4876, 4972,
|
||||
5068, 5168, 5268, 5372, 5476, 5584, 5692, 5804, 5916, 6032, 6148, 6268, 6388, 6512, 6640, 6768, 6900,
|
||||
7036, 7172, 7312
|
||||
};
|
||||
|
||||
private static readonly short[] _acQlookup12 = {
|
||||
4, 13, 19, 27, 35, 44, 54, 64, 75, 87, 99,
|
||||
112, 126, 139, 154, 168, 183, 199, 214, 230, 247, 263,
|
||||
280, 297, 314, 331, 349, 366, 384, 402, 420, 438, 456,
|
||||
475, 493, 511, 530, 548, 567, 586, 604, 623, 642, 660,
|
||||
679, 698, 716, 735, 753, 772, 791, 809, 828, 846, 865,
|
||||
884, 902, 920, 939, 957, 976, 994, 1012, 1030, 1049, 1067,
|
||||
1085, 1103, 1121, 1139, 1157, 1175, 1193, 1211, 1229, 1246, 1264,
|
||||
1282, 1299, 1317, 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457,
|
||||
1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, 1627, 1660, 1693,
|
||||
1725, 1758, 1791, 1824, 1856, 1889, 1922, 1954, 1987, 2020, 2052,
|
||||
2085, 2118, 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, 2411,
|
||||
2459, 2508, 2556, 2605, 2653, 2701, 2750, 2798, 2847, 2895, 2943,
|
||||
2992, 3040, 3088, 3137, 3185, 3234, 3298, 3362, 3426, 3491, 3555,
|
||||
3619, 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, 4230, 4310,
|
||||
4390, 4470, 4550, 4631, 4711, 4791, 4871, 4967, 5064, 5160, 5256,
|
||||
5352, 5448, 5544, 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410,
|
||||
6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, 7579, 7723, 7867,
|
||||
8011, 8155, 8315, 8475, 8635, 8795, 8956, 9132, 9308, 9484, 9660,
|
||||
9836, 10028, 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, 11885,
|
||||
12109, 12333, 12573, 12813, 13053, 13309, 13565, 13821, 14093, 14365, 14637,
|
||||
14925, 15213, 15502, 15806, 16110, 16414, 16734, 17054, 17390, 17726, 18062,
|
||||
18414, 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, 21902, 22334,
|
||||
22766, 23214, 23662, 24126, 24590, 25070, 25551, 26047, 26559, 27071, 27599,
|
||||
28143, 28687, 29247,
|
||||
private static readonly short[] AcQlookup12 =
|
||||
{
|
||||
4, 13, 19, 27, 35, 44, 54, 64, 75, 87, 99, 112, 126, 139, 154, 168, 183, 199, 214, 230, 247, 263, 280,
|
||||
297, 314, 331, 349, 366, 384, 402, 420, 438, 456, 475, 493, 511, 530, 548, 567, 586, 604, 623, 642, 660,
|
||||
679, 698, 716, 735, 753, 772, 791, 809, 828, 846, 865, 884, 902, 920, 939, 957, 976, 994, 1012, 1030,
|
||||
1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175, 1193, 1211, 1229, 1246, 1264, 1282, 1299, 1317, 1335,
|
||||
1352, 1370, 1387, 1405, 1422, 1440, 1457, 1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, 1627, 1660,
|
||||
1693, 1725, 1758, 1791, 1824, 1856, 1889, 1922, 1954, 1987, 2020, 2052, 2085, 2118, 2150, 2183, 2216,
|
||||
2248, 2281, 2313, 2346, 2378, 2411, 2459, 2508, 2556, 2605, 2653, 2701, 2750, 2798, 2847, 2895, 2943,
|
||||
2992, 3040, 3088, 3137, 3185, 3234, 3298, 3362, 3426, 3491, 3555, 3619, 3684, 3748, 3812, 3876, 3941,
|
||||
4005, 4069, 4149, 4230, 4310, 4390, 4470, 4550, 4631, 4711, 4791, 4871, 4967, 5064, 5160, 5256, 5352,
|
||||
5448, 5544, 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410, 6522, 6650, 6778, 6906, 7034, 7162, 7290,
|
||||
7435, 7579, 7723, 7867, 8011, 8155, 8315, 8475, 8635, 8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028,
|
||||
10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, 11885, 12109, 12333, 12573, 12813, 13053, 13309,
|
||||
13565, 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806, 16110, 16414, 16734, 17054, 17390, 17726,
|
||||
18062, 18414, 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, 21902, 22334, 22766, 23214, 23662,
|
||||
24126, 24590, 25070, 25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247
|
||||
};
|
||||
|
||||
public static short DcQuant(int qindex, int delta, BitDepth bitDepth)
|
||||
{
|
||||
switch (bitDepth)
|
||||
{
|
||||
case BitDepth.Bits8:
|
||||
return _dcQlookup[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits10:
|
||||
return _dcQlookup10[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits12:
|
||||
return _dcQlookup12[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits8: return DcQlookup[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits10: return DcQlookup10[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits12: return DcQlookup12[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
default:
|
||||
Debug.Assert(false, "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12");
|
||||
|
||||
Debug.Assert(false, "bitDepth should be Bits8, Bits10 or Bits12");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -175,30 +130,13 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
switch (bitDepth)
|
||||
{
|
||||
case BitDepth.Bits8:
|
||||
return _acQlookup[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits10:
|
||||
return _acQlookup10[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits12:
|
||||
return _acQlookup12[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits8: return AcQlookup[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits10: return AcQlookup10[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
case BitDepth.Bits12: return AcQlookup12[Math.Clamp(qindex + delta, 0, MaxQ)];
|
||||
default:
|
||||
Debug.Assert(false, "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12");
|
||||
|
||||
Debug.Assert(false, "bitDepth should be Bits8, Bits10 or Bits12");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetQIndex(ref Segmentation seg, int segmentId, int baseQIndex)
|
||||
{
|
||||
if (seg.IsSegFeatureActive(segmentId, SegLvlFeatures.SegLvlAltQ) != 0)
|
||||
{
|
||||
int data = seg.GetSegData(segmentId, SegLvlFeatures.SegLvlAltQ);
|
||||
int segQIndex = seg.AbsDelta == Constants.SegmentAbsData ? data : baseQIndex + data;
|
||||
|
||||
return Math.Clamp(segQIndex, 0, MaxQ);
|
||||
}
|
||||
|
||||
return baseQIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
84
src/Ryujinx.Graphics.Nvdec.Vp9/ReadBitBuffer.cs
Normal file
84
src/Ryujinx.Graphics.Nvdec.Vp9/ReadBitBuffer.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
public ref struct ReadBitBuffer
|
||||
{
|
||||
public ReadOnlySpan<byte> BitBuffer;
|
||||
public ulong BitOffset;
|
||||
public object ErrorHandlerData;
|
||||
|
||||
public int DecodeUnsignedMax(int max)
|
||||
{
|
||||
int data = ReadLiteral(BitUtils.GetUnsignedBits((uint)max));
|
||||
return data > max ? max : data;
|
||||
}
|
||||
|
||||
public ulong BytesRead()
|
||||
{
|
||||
return (BitOffset + 7) >> 3;
|
||||
}
|
||||
|
||||
public int ReadBit()
|
||||
{
|
||||
ulong off = BitOffset;
|
||||
ulong p = off >> 3;
|
||||
int q = 7 - (int)(off & 0x7);
|
||||
if (p < (ulong)BitBuffer.Length)
|
||||
{
|
||||
int bit = (BitBuffer[(int)p] >> q) & 1;
|
||||
BitOffset = off + 1;
|
||||
return bit;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int ReadLiteral(int bits)
|
||||
{
|
||||
int value = 0, bit;
|
||||
for (bit = bits - 1; bit >= 0; bit--)
|
||||
{
|
||||
value |= ReadBit() << bit;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public int ReadSignedLiteral(int bits)
|
||||
{
|
||||
int value = ReadLiteral(bits);
|
||||
return ReadBit() != 0 ? -value : value;
|
||||
}
|
||||
|
||||
public int ReadInvSignedLiteral(int bits)
|
||||
{
|
||||
return ReadSignedLiteral(bits);
|
||||
}
|
||||
|
||||
public int ReadDeltaQ()
|
||||
{
|
||||
return ReadBit() != 0 ? ReadSignedLiteral(4) : 0;
|
||||
}
|
||||
|
||||
public void ReadFrameSize(out int width, out int height)
|
||||
{
|
||||
width = ReadLiteral(16) + 1;
|
||||
height = ReadLiteral(16) + 1;
|
||||
}
|
||||
|
||||
public BitstreamProfile ReadProfile()
|
||||
{
|
||||
int profile = ReadBit();
|
||||
profile |= ReadBit() << 1;
|
||||
if (profile > 2)
|
||||
{
|
||||
profile += ReadBit();
|
||||
}
|
||||
|
||||
return (BitstreamProfile)profile;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
@@ -77,65 +77,38 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
bd);
|
||||
}
|
||||
|
||||
private static int RoundMvCompQ4(int value)
|
||||
public static int RoundMvCompQ4(int value)
|
||||
{
|
||||
return (value < 0 ? value - 2 : value + 2) / 4;
|
||||
}
|
||||
|
||||
private static Mv MiMvPredQ4(ref ModeInfo mi, int idx)
|
||||
{
|
||||
return new Mv
|
||||
{
|
||||
Row = (short)RoundMvCompQ4(
|
||||
mi.Bmi[0].Mv[idx].Row + mi.Bmi[1].Mv[idx].Row +
|
||||
mi.Bmi[2].Mv[idx].Row + mi.Bmi[3].Mv[idx].Row),
|
||||
Col = (short)RoundMvCompQ4(
|
||||
mi.Bmi[0].Mv[idx].Col + mi.Bmi[1].Mv[idx].Col +
|
||||
mi.Bmi[2].Mv[idx].Col + mi.Bmi[3].Mv[idx].Col),
|
||||
};
|
||||
}
|
||||
|
||||
private static int RoundMvCompQ2(int value)
|
||||
public static int RoundMvCompQ2(int value)
|
||||
{
|
||||
return (value < 0 ? value - 1 : value + 1) / 2;
|
||||
}
|
||||
|
||||
private static Mv MiMvPredQ2(ref ModeInfo mi, int idx, int block0, int block1)
|
||||
{
|
||||
return new Mv
|
||||
{
|
||||
Row = (short)RoundMvCompQ2(
|
||||
mi.Bmi[block0].Mv[idx].Row +
|
||||
mi.Bmi[block1].Mv[idx].Row),
|
||||
Col = (short)RoundMvCompQ2(
|
||||
mi.Bmi[block0].Mv[idx].Col +
|
||||
mi.Bmi[block1].Mv[idx].Col),
|
||||
};
|
||||
}
|
||||
|
||||
public static Mv ClampMvToUmvBorderSb(ref MacroBlockD xd, ref Mv srcMv, int bw, int bh, int ssX, int ssY)
|
||||
{
|
||||
// If the MV points so far into the UMV border that no visible pixels
|
||||
// are used for reconstruction, the subpel part of the MV can be
|
||||
// discarded and the MV limited to 16 pixels with equivalent results.
|
||||
int spelLeft = (Constants.Vp9InterpExtend + bw) << SubpelBits;
|
||||
int spelLeft = (Constants.InterpExtend + bw) << SubpelBits;
|
||||
int spelRight = spelLeft - SubpelShifts;
|
||||
int spelTop = (Constants.Vp9InterpExtend + bh) << SubpelBits;
|
||||
int spelTop = (Constants.InterpExtend + bh) << SubpelBits;
|
||||
int spelBottom = spelTop - SubpelShifts;
|
||||
Mv clampedMv = new()
|
||||
{
|
||||
Row = (short)(srcMv.Row * (1 << (1 - ssY))),
|
||||
Col = (short)(srcMv.Col * (1 << (1 - ssX))),
|
||||
Row = (short)(srcMv.Row * (1 << (1 - ssY))), Col = (short)(srcMv.Col * (1 << (1 - ssX)))
|
||||
};
|
||||
|
||||
Debug.Assert(ssX <= 1);
|
||||
Debug.Assert(ssY <= 1);
|
||||
|
||||
clampedMv.ClampMv(
|
||||
xd.MbToLeftEdge * (1 << (1 - ssX)) - spelLeft,
|
||||
xd.MbToRightEdge * (1 << (1 - ssX)) + spelRight,
|
||||
xd.MbToTopEdge * (1 << (1 - ssY)) - spelTop,
|
||||
xd.MbToBottomEdge * (1 << (1 - ssY)) + spelBottom);
|
||||
clampedMv.Clamp(
|
||||
(xd.MbToLeftEdge * (1 << (1 - ssX))) - spelLeft,
|
||||
(xd.MbToRightEdge * (1 << (1 - ssX))) + spelRight,
|
||||
(xd.MbToTopEdge * (1 << (1 - ssY))) - spelTop,
|
||||
(xd.MbToBottomEdge * (1 << (1 - ssY))) + spelBottom);
|
||||
|
||||
return clampedMv;
|
||||
}
|
||||
@@ -150,18 +123,19 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
res = mi.Bmi[block].Mv[refr];
|
||||
break;
|
||||
case 1:
|
||||
res = MiMvPredQ2(ref mi, refr, block, block + 2);
|
||||
res = mi.MvPredQ2(refr, block, block + 2);
|
||||
break;
|
||||
case 2:
|
||||
res = MiMvPredQ2(ref mi, refr, block, block + 1);
|
||||
res = mi.MvPredQ2(refr, block, block + 1);
|
||||
break;
|
||||
case 3:
|
||||
res = MiMvPredQ4(ref mi, refr);
|
||||
res = mi.MvPredQ4(refr);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(ssIdx <= 3 && ssIdx >= 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -169,8 +143,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
int x = !sf.IsNull ? sf.Value.ScaleValueX(xOffset) : xOffset;
|
||||
int y = !sf.IsNull ? sf.Value.ScaleValueY(yOffset) : yOffset;
|
||||
|
||||
return y * stride + x;
|
||||
return (y * stride) + x;
|
||||
}
|
||||
|
||||
private static void SetupPredPlanes(
|
||||
@@ -203,12 +176,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
strides[0] = src.Stride;
|
||||
strides[1] = src.UvStride;
|
||||
strides[2] = src.UvStride;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Constants.MaxMbPlane; ++i)
|
||||
for (int i = 0; i < Constants.MaxMbPlane; ++i)
|
||||
{
|
||||
ref MacroBlockDPlane pd = ref planes[i];
|
||||
SetupPredPlanes(ref pd.Dst, buffers[i], strides[i], miRow, miCol, Ptr<ScaleFactors>.Null, pd.SubsamplingX, pd.SubsamplingY);
|
||||
SetupPredPlanes(ref pd.Dst, buffers[i], strides[i], miRow, miCol, Ptr<ScaleFactors>.Null,
|
||||
pd.SubsamplingX, pd.SubsamplingY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,14 +203,14 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
strides[0] = src.Stride;
|
||||
strides[1] = src.UvStride;
|
||||
strides[2] = src.UvStride;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Constants.MaxMbPlane; ++i)
|
||||
for (int i = 0; i < Constants.MaxMbPlane; ++i)
|
||||
{
|
||||
ref MacroBlockDPlane pd = ref xd.Plane[i];
|
||||
SetupPredPlanes(ref pd.Pre[idx], buffers[i], strides[i], miRow, miCol, sf, pd.SubsamplingX, pd.SubsamplingY);
|
||||
SetupPredPlanes(ref pd.Pre[idx], buffers[i], strides[i], miRow, miCol, sf, pd.SubsamplingX,
|
||||
pd.SubsamplingY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Common;
|
||||
using Ryujinx.Graphics.Nvdec.Vp9.Types;
|
||||
using System;
|
||||
using static Ryujinx.Graphics.Nvdec.Vp9.Dsp.IntraPred;
|
||||
@@ -7,7 +7,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
internal static class ReconIntra
|
||||
{
|
||||
public static readonly TxType[] IntraModeToTxTypeLookup = {
|
||||
public static readonly TxType[] IntraModeToTxTypeLookup =
|
||||
{
|
||||
TxType.DctDct, // DC
|
||||
TxType.AdstDct, // V
|
||||
TxType.DctAdst, // H
|
||||
@@ -17,7 +18,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
TxType.DctAdst, // D153
|
||||
TxType.DctAdst, // D207
|
||||
TxType.AdstDct, // D63
|
||||
TxType.AdstAdst, // TM
|
||||
TxType.AdstAdst // TM
|
||||
};
|
||||
|
||||
private const int NeedLeft = 1 << 1;
|
||||
@@ -35,231 +36,123 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
NeedLeft | NeedAbove, // D153
|
||||
NeedLeft, // D207
|
||||
NeedAboveRight, // D63
|
||||
NeedLeft | NeedAbove, // TM
|
||||
NeedLeft | NeedAbove // TM
|
||||
};
|
||||
|
||||
private unsafe delegate void IntraPredFn(byte* dst, int stride, byte* above, byte* left);
|
||||
|
||||
private static readonly unsafe IntraPredFn[][] _pred = {
|
||||
new IntraPredFn[]
|
||||
{
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
VPredictor4x4,
|
||||
VPredictor8x8,
|
||||
VPredictor16x16,
|
||||
VPredictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
HPredictor4x4,
|
||||
HPredictor8x8,
|
||||
HPredictor16x16,
|
||||
HPredictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D45Predictor4x4,
|
||||
D45Predictor8x8,
|
||||
D45Predictor16x16,
|
||||
D45Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D135Predictor4x4,
|
||||
D135Predictor8x8,
|
||||
D135Predictor16x16,
|
||||
D135Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D117Predictor4x4,
|
||||
D117Predictor8x8,
|
||||
D117Predictor16x16,
|
||||
D117Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D153Predictor4x4,
|
||||
D153Predictor8x8,
|
||||
D153Predictor16x16,
|
||||
D153Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D207Predictor4x4,
|
||||
D207Predictor8x8,
|
||||
D207Predictor16x16,
|
||||
D207Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
D63Predictor4x4,
|
||||
D63Predictor8x8,
|
||||
D63Predictor16x16,
|
||||
D63Predictor32x32,
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
TMPredictor4x4,
|
||||
TMPredictor8x8,
|
||||
TMPredictor16x16,
|
||||
TMPredictor32x32,
|
||||
},
|
||||
private static readonly unsafe IntraPredFn[][] Pred =
|
||||
{
|
||||
new IntraPredFn[] { null, null, null, null },
|
||||
new IntraPredFn[] { VPredictor4x4, VPredictor8x8, VPredictor16x16, VPredictor32x32 },
|
||||
new IntraPredFn[] { HPredictor4x4, HPredictor8x8, HPredictor16x16, HPredictor32x32 },
|
||||
new IntraPredFn[] { D45Predictor4x4, D45Predictor8x8, D45Predictor16x16, D45Predictor32x32 },
|
||||
new IntraPredFn[] { D135Predictor4x4, D135Predictor8x8, D135Predictor16x16, D135Predictor32x32 },
|
||||
new IntraPredFn[] { D117Predictor4x4, D117Predictor8x8, D117Predictor16x16, D117Predictor32x32 },
|
||||
new IntraPredFn[] { D153Predictor4x4, D153Predictor8x8, D153Predictor16x16, D153Predictor32x32 },
|
||||
new IntraPredFn[] { D207Predictor4x4, D207Predictor8x8, D207Predictor16x16, D207Predictor32x32 },
|
||||
new IntraPredFn[] { D63Predictor4x4, D63Predictor8x8, D63Predictor16x16, D63Predictor32x32 },
|
||||
new IntraPredFn[] { TmPredictor4x4, TmPredictor8x8, TmPredictor16x16, TmPredictor32x32 }
|
||||
};
|
||||
|
||||
private static readonly unsafe IntraPredFn[][][] _dcPred = {
|
||||
private static readonly unsafe IntraPredFn[][][] DcPred =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new IntraPredFn[]
|
||||
{
|
||||
Dc128Predictor4x4,
|
||||
Dc128Predictor8x8,
|
||||
Dc128Predictor16x16,
|
||||
Dc128Predictor32x32,
|
||||
Dc128Predictor4x4, Dc128Predictor8x8, Dc128Predictor16x16, Dc128Predictor32x32
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
DcTopPredictor4x4,
|
||||
DcTopPredictor8x8,
|
||||
DcTopPredictor16x16,
|
||||
DcTopPredictor32x32,
|
||||
},
|
||||
DcTopPredictor4x4, DcTopPredictor8x8, DcTopPredictor16x16, DcTopPredictor32x32
|
||||
}
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new IntraPredFn[]
|
||||
{
|
||||
DcLeftPredictor4x4,
|
||||
DcLeftPredictor8x8,
|
||||
DcLeftPredictor16x16,
|
||||
DcLeftPredictor32x32,
|
||||
DcLeftPredictor4x4, DcLeftPredictor8x8, DcLeftPredictor16x16, DcLeftPredictor32x32
|
||||
},
|
||||
new IntraPredFn[]
|
||||
{
|
||||
DcPredictor4x4,
|
||||
DcPredictor8x8,
|
||||
DcPredictor16x16,
|
||||
DcPredictor32x32,
|
||||
},
|
||||
},
|
||||
new IntraPredFn[] { DcPredictor4x4, DcPredictor8x8, DcPredictor16x16, DcPredictor32x32 }
|
||||
}
|
||||
};
|
||||
|
||||
private unsafe delegate void IntraHighPredFn(ushort* dst, int stride, ushort* above, ushort* left, int bd);
|
||||
|
||||
private static readonly unsafe IntraHighPredFn[][] _predHigh = {
|
||||
private static readonly unsafe IntraHighPredFn[][] PredHigh =
|
||||
{
|
||||
new IntraHighPredFn[] { null, null, null, null },
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
HighbdVPredictor4x4, HighbdVPredictor8x8, HighbdVPredictor16x16, HighbdVPredictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdVPredictor4x4,
|
||||
HighbdVPredictor8x8,
|
||||
HighbdVPredictor16x16,
|
||||
HighbdVPredictor32x32,
|
||||
HighbdHPredictor4x4, HighbdHPredictor8x8, HighbdHPredictor16x16, HighbdHPredictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdHPredictor4x4,
|
||||
HighbdHPredictor8x8,
|
||||
HighbdHPredictor16x16,
|
||||
HighbdHPredictor32x32,
|
||||
HighbdD45Predictor4x4, HighbdD45Predictor8x8, HighbdD45Predictor16x16, HighbdD45Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD45Predictor4x4,
|
||||
HighbdD45Predictor8x8,
|
||||
HighbdD45Predictor16x16,
|
||||
HighbdD45Predictor32x32,
|
||||
HighbdD135Predictor4x4, HighbdD135Predictor8x8, HighbdD135Predictor16x16,
|
||||
HighbdD135Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD135Predictor4x4,
|
||||
HighbdD135Predictor8x8,
|
||||
HighbdD135Predictor16x16,
|
||||
HighbdD135Predictor32x32,
|
||||
HighbdD117Predictor4x4, HighbdD117Predictor8x8, HighbdD117Predictor16x16,
|
||||
HighbdD117Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD117Predictor4x4,
|
||||
HighbdD117Predictor8x8,
|
||||
HighbdD117Predictor16x16,
|
||||
HighbdD117Predictor32x32,
|
||||
HighbdD153Predictor4x4, HighbdD153Predictor8x8, HighbdD153Predictor16x16,
|
||||
HighbdD153Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD153Predictor4x4,
|
||||
HighbdD153Predictor8x8,
|
||||
HighbdD153Predictor16x16,
|
||||
HighbdD153Predictor32x32,
|
||||
HighbdD207Predictor4x4, HighbdD207Predictor8x8, HighbdD207Predictor16x16,
|
||||
HighbdD207Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD207Predictor4x4,
|
||||
HighbdD207Predictor8x8,
|
||||
HighbdD207Predictor16x16,
|
||||
HighbdD207Predictor32x32,
|
||||
HighbdD63Predictor4x4, HighbdD63Predictor8x8, HighbdD63Predictor16x16, HighbdD63Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdD63Predictor4x4,
|
||||
HighbdD63Predictor8x8,
|
||||
HighbdD63Predictor16x16,
|
||||
HighbdD63Predictor32x32,
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdTMPredictor4x4,
|
||||
HighbdTMPredictor8x8,
|
||||
HighbdTMPredictor16x16,
|
||||
HighbdTMPredictor32x32,
|
||||
},
|
||||
HighbdTmPredictor4x4, HighbdTmPredictor8x8, HighbdTmPredictor16x16, HighbdTmPredictor32x32
|
||||
}
|
||||
};
|
||||
|
||||
private static readonly unsafe IntraHighPredFn[][][] _dcPredHigh = {
|
||||
private static readonly unsafe IntraHighPredFn[][][] DcPredHigh =
|
||||
{
|
||||
new[]
|
||||
{
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDc128Predictor4x4,
|
||||
HighbdDc128Predictor8x8,
|
||||
HighbdDc128Predictor16x16,
|
||||
HighbdDc128Predictor32x32,
|
||||
HighbdDc128Predictor4x4, HighbdDc128Predictor8x8, HighbdDc128Predictor16x16,
|
||||
HighbdDc128Predictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDcTopPredictor4x4,
|
||||
HighbdDcTopPredictor8x8,
|
||||
HighbdDcTopPredictor16x16,
|
||||
HighbdDcTopPredictor32x32,
|
||||
},
|
||||
HighbdDcTopPredictor4x4, HighbdDcTopPredictor8x8, HighbdDcTopPredictor16x16,
|
||||
HighbdDcTopPredictor32x32
|
||||
}
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDcLeftPredictor4x4,
|
||||
HighbdDcLeftPredictor8x8,
|
||||
HighbdDcLeftPredictor16x16,
|
||||
HighbdDcLeftPredictor32x32,
|
||||
HighbdDcLeftPredictor4x4, HighbdDcLeftPredictor8x8, HighbdDcLeftPredictor16x16,
|
||||
HighbdDcLeftPredictor32x32
|
||||
},
|
||||
new IntraHighPredFn[]
|
||||
{
|
||||
HighbdDcPredictor4x4,
|
||||
HighbdDcPredictor8x8,
|
||||
HighbdDcPredictor16x16,
|
||||
HighbdDcPredictor32x32,
|
||||
},
|
||||
},
|
||||
HighbdDcPredictor4x4, HighbdDcPredictor8x8, HighbdDcPredictor16x16,
|
||||
HighbdDcPredictor32x32
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static unsafe void BuildIntraPredictorsHigh(
|
||||
@@ -327,7 +220,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
for (i = 0; i < bs; ++i)
|
||||
{
|
||||
leftCol[i] = refr[i * refStride - 1];
|
||||
leftCol[i] = refr[(i * refStride) - 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -335,12 +228,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int extendBottom = frameHeight - y0;
|
||||
for (i = 0; i < extendBottom; ++i)
|
||||
{
|
||||
leftCol[i] = refr[i * refStride - 1];
|
||||
leftCol[i] = refr[(i * refStride) - 1];
|
||||
}
|
||||
|
||||
for (; i < bs; ++i)
|
||||
{
|
||||
leftCol[i] = refr[(extendBottom - 1) * refStride - 1];
|
||||
leftCol[i] = refr[((extendBottom - 1) * refStride) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -349,7 +242,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
/* faster path if the block does not need extension */
|
||||
for (i = 0; i < bs; ++i)
|
||||
{
|
||||
leftCol[i] = refr[i * refStride - 1];
|
||||
leftCol[i] = refr[(i * refStride) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -391,6 +284,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
MemoryUtil.Copy(aboveRow, aboveRef, bs);
|
||||
}
|
||||
}
|
||||
|
||||
aboveRow[-1] = leftAvailable != 0 ? aboveRef[-1] : (ushort)(baseVal + 1);
|
||||
}
|
||||
else
|
||||
@@ -409,7 +303,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (xd.MbToRightEdge < 0)
|
||||
{
|
||||
/* slower path if the block needs border extension */
|
||||
if (x0 + 2 * bs <= frameWidth)
|
||||
if (x0 + (2 * bs) <= frameWidth)
|
||||
{
|
||||
if (rightAvailable != 0 && bs == 4)
|
||||
{
|
||||
@@ -427,7 +321,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (rightAvailable != 0 && bs == 4)
|
||||
{
|
||||
MemoryUtil.Copy(aboveRow, aboveRef, r);
|
||||
MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + 2 * bs - frameWidth);
|
||||
MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + (2 * bs) - frameWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -439,8 +333,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
int r = frameWidth - x0;
|
||||
MemoryUtil.Copy(aboveRow, aboveRef, r);
|
||||
MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + 2 * bs - frameWidth);
|
||||
MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + (2 * bs) - frameWidth);
|
||||
}
|
||||
|
||||
aboveRow[-1] = leftAvailable != 0 ? aboveRef[-1] : (ushort)(baseVal + 1);
|
||||
}
|
||||
else
|
||||
@@ -476,11 +371,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// Predict
|
||||
if (mode == PredictionMode.DcPred)
|
||||
{
|
||||
_dcPredHigh[leftAvailable][upAvailable][(int)txSize](dst, dstStride, constAboveRow, leftCol, xd.Bd);
|
||||
DcPredHigh[leftAvailable][upAvailable][(int)txSize](dst, dstStride, constAboveRow, leftCol, xd.Bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
_predHigh[(int)mode][(int)txSize](dst, dstStride, constAboveRow, leftCol, xd.Bd);
|
||||
PredHigh[(int)mode][(int)txSize](dst, dstStride, constAboveRow, leftCol, xd.Bd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,7 +439,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
for (i = 0; i < bs; ++i)
|
||||
{
|
||||
leftCol[i] = refr[i * refStride - 1];
|
||||
leftCol[i] = refr[(i * refStride) - 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -552,12 +447,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int extendBottom = frameHeight - y0;
|
||||
for (i = 0; i < extendBottom; ++i)
|
||||
{
|
||||
leftCol[i] = refr[i * refStride - 1];
|
||||
leftCol[i] = refr[(i * refStride) - 1];
|
||||
}
|
||||
|
||||
for (; i < bs; ++i)
|
||||
{
|
||||
leftCol[i] = refr[(extendBottom - 1) * refStride - 1];
|
||||
leftCol[i] = refr[((extendBottom - 1) * refStride) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -566,7 +461,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
/* Faster path if the block does not need extension */
|
||||
for (i = 0; i < bs; ++i)
|
||||
{
|
||||
leftCol[i] = refr[i * refStride - 1];
|
||||
leftCol[i] = refr[(i * refStride) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -608,6 +503,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
MemoryUtil.Copy(aboveRow, aboveRef, bs);
|
||||
}
|
||||
}
|
||||
|
||||
aboveRow[-1] = leftAvailable != 0 ? aboveRef[-1] : (byte)129;
|
||||
}
|
||||
else
|
||||
@@ -626,7 +522,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (xd.MbToRightEdge < 0)
|
||||
{
|
||||
/* Slower path if the block needs border extension */
|
||||
if (x0 + 2 * bs <= frameWidth)
|
||||
if (x0 + (2 * bs) <= frameWidth)
|
||||
{
|
||||
if (rightAvailable != 0 && bs == 4)
|
||||
{
|
||||
@@ -644,7 +540,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
if (rightAvailable != 0 && bs == 4)
|
||||
{
|
||||
MemoryUtil.Copy(aboveRow, aboveRef, r);
|
||||
MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + 2 * bs - frameWidth);
|
||||
MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + (2 * bs) - frameWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -656,7 +552,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
{
|
||||
int r = frameWidth - x0;
|
||||
MemoryUtil.Copy(aboveRow, aboveRef, r);
|
||||
MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + 2 * bs - frameWidth);
|
||||
MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + (2 * bs) - frameWidth);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -679,6 +575,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aboveRow[-1] = leftAvailable != 0 ? aboveRef[-1] : (byte)129;
|
||||
}
|
||||
else
|
||||
@@ -691,11 +588,11 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
// Predict
|
||||
if (mode == PredictionMode.DcPred)
|
||||
{
|
||||
_dcPred[leftAvailable][upAvailable][(int)txSize](dst, dstStride, constAboveRow, leftCol);
|
||||
DcPred[leftAvailable][upAvailable][(int)txSize](dst, dstStride, constAboveRow, leftCol);
|
||||
}
|
||||
else
|
||||
{
|
||||
_pred[(int)mode][(int)txSize](dst, dstStride, constAboveRow, leftCol);
|
||||
Pred[(int)mode][(int)txSize](dst, dstStride, constAboveRow, leftCol);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,7 +613,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
int txw = 1 << (int)txSize;
|
||||
int haveTop = loff != 0 || !xd.AboveMi.IsNull ? 1 : 0;
|
||||
int haveLeft = aoff != 0 || !xd.LeftMi.IsNull ? 1 : 0;
|
||||
int haveRight = (aoff + txw) < bw ? 1 : 0;
|
||||
int haveRight = aoff + txw < bw ? 1 : 0;
|
||||
int x = aoff * 4;
|
||||
int y = loff * 4;
|
||||
|
||||
@@ -736,9 +633,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
x,
|
||||
y,
|
||||
plane);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BuildIntraPredictors(
|
||||
ref xd,
|
||||
refr,
|
||||
@@ -755,4 +652,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
plane);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,4 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
||||
public ArrayPtr<byte> Data;
|
||||
public int Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user